^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Taken from:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * linux/lib/string.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 1991, 1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #ifndef __HAVE_ARCH_STRSTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * strstr - Find the first substring in a %NUL terminated string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * @s1: The string to be searched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * @s2: The string to search for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) char *strstr(const char *s1, const char *s2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) size_t l1, l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) l2 = strlen(s2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) if (!l2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) return (char *)s1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) l1 = strlen(s1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) while (l1 >= l2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) l1--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) if (!memcmp(s1, s2, l2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return (char *)s1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) s1++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #ifndef __HAVE_ARCH_STRNCMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * strncmp - Compare two length-limited strings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * @cs: One string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * @ct: Another string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * @count: The maximum number of bytes to compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) int strncmp(const char *cs, const char *ct, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) unsigned char c1, c2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) while (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) c1 = *cs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) c2 = *ct++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (c1 != c2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return c1 < c2 ? -1 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (!c1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* Works only for digits and letters, but small and fast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define TOLOWER(x) ((x) | 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static unsigned int simple_guess_base(const char *cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (cp[0] == '0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * simple_strtoull - convert a string to an unsigned long long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * @cp: The start of the string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * @endp: A pointer to the end of the parsed string will be placed here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * @base: The number base to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned long long result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (!base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) base = simple_guess_base(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) cp += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) while (isxdigit(*cp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (value >= base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) result = result * base + value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) cp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (endp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) *endp = (char *)cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) long simple_strtol(const char *cp, char **endp, unsigned int base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (*cp == '-')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return -simple_strtoull(cp + 1, endp, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return simple_strtoull(cp, endp, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }