|  | /* -*- linux-c -*- ------------------------------------------------------- * | 
|  | * | 
|  | *   Copyright (C) 1991, 1992 Linus Torvalds | 
|  | *   Copyright 2007 rPath, Inc. - All Rights Reserved | 
|  | * | 
|  | *   This file is part of the Linux kernel, and is made available under | 
|  | *   the terms of the GNU General Public License version 2. | 
|  | * | 
|  | * ----------------------------------------------------------------------- */ | 
|  |  | 
|  | /* | 
|  | * Very basic string functions | 
|  | */ | 
|  |  | 
|  | #include <linux/types.h> | 
|  | #include "ctype.h" | 
|  | #include "string.h" | 
|  |  | 
|  | /* | 
|  | * Undef these macros so that the functions that we provide | 
|  | * here will have the correct names regardless of how string.h | 
|  | * may have chosen to #define them. | 
|  | */ | 
|  | #undef memcpy | 
|  | #undef memset | 
|  | #undef memcmp | 
|  |  | 
|  | int memcmp(const void *s1, const void *s2, size_t len) | 
|  | { | 
|  | bool diff; | 
|  | asm("repe; cmpsb; setnz %0" | 
|  | : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len)); | 
|  | return diff; | 
|  | } | 
|  |  | 
|  | int strcmp(const char *str1, const char *str2) | 
|  | { | 
|  | const unsigned char *s1 = (const unsigned char *)str1; | 
|  | const unsigned char *s2 = (const unsigned char *)str2; | 
|  | int delta = 0; | 
|  |  | 
|  | while (*s1 || *s2) { | 
|  | delta = *s1 - *s2; | 
|  | if (delta) | 
|  | return delta; | 
|  | s1++; | 
|  | s2++; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | int strncmp(const char *cs, const char *ct, size_t count) | 
|  | { | 
|  | unsigned char c1, c2; | 
|  |  | 
|  | while (count) { | 
|  | c1 = *cs++; | 
|  | c2 = *ct++; | 
|  | if (c1 != c2) | 
|  | return c1 < c2 ? -1 : 1; | 
|  | if (!c1) | 
|  | break; | 
|  | count--; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | size_t strnlen(const char *s, size_t maxlen) | 
|  | { | 
|  | const char *es = s; | 
|  | while (*es && maxlen) { | 
|  | es++; | 
|  | maxlen--; | 
|  | } | 
|  |  | 
|  | return (es - s); | 
|  | } | 
|  |  | 
|  | unsigned int atou(const char *s) | 
|  | { | 
|  | unsigned int i = 0; | 
|  | while (isdigit(*s)) | 
|  | i = i * 10 + (*s++ - '0'); | 
|  | return i; | 
|  | } | 
|  |  | 
|  | /* Works only for digits and letters, but small and fast */ | 
|  | #define TOLOWER(x) ((x) | 0x20) | 
|  |  | 
|  | static unsigned int simple_guess_base(const char *cp) | 
|  | { | 
|  | if (cp[0] == '0') { | 
|  | if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2])) | 
|  | return 16; | 
|  | else | 
|  | return 8; | 
|  | } else { | 
|  | return 10; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * simple_strtoull - convert a string to an unsigned long long | 
|  | * @cp: The start of the string | 
|  | * @endp: A pointer to the end of the parsed string will be placed here | 
|  | * @base: The number base to use | 
|  | */ | 
|  |  | 
|  | unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base) | 
|  | { | 
|  | unsigned long long result = 0; | 
|  |  | 
|  | if (!base) | 
|  | base = simple_guess_base(cp); | 
|  |  | 
|  | if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x') | 
|  | cp += 2; | 
|  |  | 
|  | while (isxdigit(*cp)) { | 
|  | unsigned int value; | 
|  |  | 
|  | value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10; | 
|  | if (value >= base) | 
|  | break; | 
|  | result = result * base + value; | 
|  | cp++; | 
|  | } | 
|  | if (endp) | 
|  | *endp = (char *)cp; | 
|  |  | 
|  | return result; | 
|  | } | 
|  |  | 
|  | long simple_strtol(const char *cp, char **endp, unsigned int base) | 
|  | { | 
|  | if (*cp == '-') | 
|  | return -simple_strtoull(cp + 1, endp, base); | 
|  |  | 
|  | return simple_strtoull(cp, endp, base); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * strlen - Find the length of a string | 
|  | * @s: The string to be sized | 
|  | */ | 
|  | size_t strlen(const char *s) | 
|  | { | 
|  | const char *sc; | 
|  |  | 
|  | for (sc = s; *sc != '\0'; ++sc) | 
|  | /* nothing */; | 
|  | return sc - s; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * strstr - Find the first substring in a %NUL terminated string | 
|  | * @s1: The string to be searched | 
|  | * @s2: The string to search for | 
|  | */ | 
|  | char *strstr(const char *s1, const char *s2) | 
|  | { | 
|  | size_t l1, l2; | 
|  |  | 
|  | l2 = strlen(s2); | 
|  | if (!l2) | 
|  | return (char *)s1; | 
|  | l1 = strlen(s1); | 
|  | while (l1 >= l2) { | 
|  | l1--; | 
|  | if (!memcmp(s1, s2, l2)) | 
|  | return (char *)s1; | 
|  | s1++; | 
|  | } | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * strchr - Find the first occurrence of the character c in the string s. | 
|  | * @s: the string to be searched | 
|  | * @c: the character to search for | 
|  | */ | 
|  | char *strchr(const char *s, int c) | 
|  | { | 
|  | while (*s != (char)c) | 
|  | if (*s++ == '\0') | 
|  | return NULL; | 
|  | return (char *)s; | 
|  | } |