1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 2e8f3010fSArd Biesheuvel /* 3e8f3010fSArd Biesheuvel * Taken from: 4e8f3010fSArd Biesheuvel * linux/lib/string.c 5e8f3010fSArd Biesheuvel * 6e8f3010fSArd Biesheuvel * Copyright (C) 1991, 1992 Linus Torvalds 7e8f3010fSArd Biesheuvel */ 8e8f3010fSArd Biesheuvel 991d150c0SArd Biesheuvel #include <linux/ctype.h> 10aad0f3d6STian Tao #include <linux/kernel.h> 11e8f3010fSArd Biesheuvel #include <linux/types.h> 12e8f3010fSArd Biesheuvel #include <linux/string.h> 13e8f3010fSArd Biesheuvel 14e8f3010fSArd Biesheuvel #ifndef __HAVE_ARCH_STRSTR 15e8f3010fSArd Biesheuvel /** 16e8f3010fSArd Biesheuvel * strstr - Find the first substring in a %NUL terminated string 17e8f3010fSArd Biesheuvel * @s1: The string to be searched 18e8f3010fSArd Biesheuvel * @s2: The string to search for 19e8f3010fSArd Biesheuvel */ 20e8f3010fSArd Biesheuvel char *strstr(const char *s1, const char *s2) 21e8f3010fSArd Biesheuvel { 22e8f3010fSArd Biesheuvel size_t l1, l2; 23e8f3010fSArd Biesheuvel 24e8f3010fSArd Biesheuvel l2 = strlen(s2); 25e8f3010fSArd Biesheuvel if (!l2) 26e8f3010fSArd Biesheuvel return (char *)s1; 27e8f3010fSArd Biesheuvel l1 = strlen(s1); 28e8f3010fSArd Biesheuvel while (l1 >= l2) { 29e8f3010fSArd Biesheuvel l1--; 30e8f3010fSArd Biesheuvel if (!memcmp(s1, s2, l2)) 31e8f3010fSArd Biesheuvel return (char *)s1; 32e8f3010fSArd Biesheuvel s1++; 33e8f3010fSArd Biesheuvel } 34e8f3010fSArd Biesheuvel return NULL; 35e8f3010fSArd Biesheuvel } 36e8f3010fSArd Biesheuvel #endif 37e8f3010fSArd Biesheuvel 38e8f3010fSArd Biesheuvel #ifndef __HAVE_ARCH_STRNCMP 39e8f3010fSArd Biesheuvel /** 40e8f3010fSArd Biesheuvel * strncmp - Compare two length-limited strings 41e8f3010fSArd Biesheuvel * @cs: One string 42e8f3010fSArd Biesheuvel * @ct: Another string 43e8f3010fSArd Biesheuvel * @count: The maximum number of bytes to compare 44e8f3010fSArd Biesheuvel */ 45e8f3010fSArd Biesheuvel int strncmp(const char *cs, const char *ct, size_t count) 46e8f3010fSArd Biesheuvel { 47e8f3010fSArd Biesheuvel unsigned char c1, c2; 48e8f3010fSArd Biesheuvel 49e8f3010fSArd Biesheuvel while (count) { 50e8f3010fSArd Biesheuvel c1 = *cs++; 51e8f3010fSArd Biesheuvel c2 = *ct++; 52e8f3010fSArd Biesheuvel if (c1 != c2) 53e8f3010fSArd Biesheuvel return c1 < c2 ? -1 : 1; 54e8f3010fSArd Biesheuvel if (!c1) 55e8f3010fSArd Biesheuvel break; 56e8f3010fSArd Biesheuvel count--; 57e8f3010fSArd Biesheuvel } 58e8f3010fSArd Biesheuvel return 0; 59e8f3010fSArd Biesheuvel } 60e8f3010fSArd Biesheuvel #endif 6191d150c0SArd Biesheuvel 6291d150c0SArd Biesheuvel /* Works only for digits and letters, but small and fast */ 6391d150c0SArd Biesheuvel #define TOLOWER(x) ((x) | 0x20) 6491d150c0SArd Biesheuvel 6591d150c0SArd Biesheuvel static unsigned int simple_guess_base(const char *cp) 6691d150c0SArd Biesheuvel { 6791d150c0SArd Biesheuvel if (cp[0] == '0') { 6891d150c0SArd Biesheuvel if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2])) 6991d150c0SArd Biesheuvel return 16; 7091d150c0SArd Biesheuvel else 7191d150c0SArd Biesheuvel return 8; 7291d150c0SArd Biesheuvel } else { 7391d150c0SArd Biesheuvel return 10; 7491d150c0SArd Biesheuvel } 7591d150c0SArd Biesheuvel } 7691d150c0SArd Biesheuvel 7791d150c0SArd Biesheuvel /** 7891d150c0SArd Biesheuvel * simple_strtoull - convert a string to an unsigned long long 7991d150c0SArd Biesheuvel * @cp: The start of the string 8091d150c0SArd Biesheuvel * @endp: A pointer to the end of the parsed string will be placed here 8191d150c0SArd Biesheuvel * @base: The number base to use 8291d150c0SArd Biesheuvel */ 8391d150c0SArd Biesheuvel 8491d150c0SArd Biesheuvel unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base) 8591d150c0SArd Biesheuvel { 8691d150c0SArd Biesheuvel unsigned long long result = 0; 8791d150c0SArd Biesheuvel 8891d150c0SArd Biesheuvel if (!base) 8991d150c0SArd Biesheuvel base = simple_guess_base(cp); 9091d150c0SArd Biesheuvel 9191d150c0SArd Biesheuvel if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x') 9291d150c0SArd Biesheuvel cp += 2; 9391d150c0SArd Biesheuvel 9491d150c0SArd Biesheuvel while (isxdigit(*cp)) { 9591d150c0SArd Biesheuvel unsigned int value; 9691d150c0SArd Biesheuvel 9791d150c0SArd Biesheuvel value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10; 9891d150c0SArd Biesheuvel if (value >= base) 9991d150c0SArd Biesheuvel break; 10091d150c0SArd Biesheuvel result = result * base + value; 10191d150c0SArd Biesheuvel cp++; 10291d150c0SArd Biesheuvel } 10391d150c0SArd Biesheuvel if (endp) 10491d150c0SArd Biesheuvel *endp = (char *)cp; 10591d150c0SArd Biesheuvel 10691d150c0SArd Biesheuvel return result; 10791d150c0SArd Biesheuvel } 10891d150c0SArd Biesheuvel 10991d150c0SArd Biesheuvel long simple_strtol(const char *cp, char **endp, unsigned int base) 11091d150c0SArd Biesheuvel { 11191d150c0SArd Biesheuvel if (*cp == '-') 11291d150c0SArd Biesheuvel return -simple_strtoull(cp + 1, endp, base); 11391d150c0SArd Biesheuvel 11491d150c0SArd Biesheuvel return simple_strtoull(cp, endp, base); 11591d150c0SArd Biesheuvel } 116