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