xref: /openbmc/linux/arch/s390/boot/string.c (revision 7e0d92f0)
149698745SVasily Gorbik // SPDX-License-Identifier: GPL-2.0
249698745SVasily Gorbik #include <linux/ctype.h>
349698745SVasily Gorbik #include <linux/kernel.h>
4d58106c3SVasily Gorbik #include <linux/errno.h>
57e0d92f0SVasily Gorbik #undef CONFIG_KASAN
649698745SVasily Gorbik #include "../lib/string.c"
749698745SVasily Gorbik 
849698745SVasily Gorbik int strncmp(const char *cs, const char *ct, size_t count)
949698745SVasily Gorbik {
1049698745SVasily Gorbik 	unsigned char c1, c2;
1149698745SVasily Gorbik 
1249698745SVasily Gorbik 	while (count) {
1349698745SVasily Gorbik 		c1 = *cs++;
1449698745SVasily Gorbik 		c2 = *ct++;
1549698745SVasily Gorbik 		if (c1 != c2)
1649698745SVasily Gorbik 			return c1 < c2 ? -1 : 1;
1749698745SVasily Gorbik 		if (!c1)
1849698745SVasily Gorbik 			break;
1949698745SVasily Gorbik 		count--;
2049698745SVasily Gorbik 	}
2149698745SVasily Gorbik 	return 0;
2249698745SVasily Gorbik }
2349698745SVasily Gorbik 
2449698745SVasily Gorbik char *skip_spaces(const char *str)
2549698745SVasily Gorbik {
2649698745SVasily Gorbik 	while (isspace(*str))
2749698745SVasily Gorbik 		++str;
2849698745SVasily Gorbik 	return (char *)str;
2949698745SVasily Gorbik }
3049698745SVasily Gorbik 
3149698745SVasily Gorbik char *strim(char *s)
3249698745SVasily Gorbik {
3349698745SVasily Gorbik 	size_t size;
3449698745SVasily Gorbik 	char *end;
3549698745SVasily Gorbik 
3649698745SVasily Gorbik 	size = strlen(s);
3749698745SVasily Gorbik 	if (!size)
3849698745SVasily Gorbik 		return s;
3949698745SVasily Gorbik 
4049698745SVasily Gorbik 	end = s + size - 1;
4149698745SVasily Gorbik 	while (end >= s && isspace(*end))
4249698745SVasily Gorbik 		end--;
4349698745SVasily Gorbik 	*(end + 1) = '\0';
4449698745SVasily Gorbik 
4549698745SVasily Gorbik 	return skip_spaces(s);
4649698745SVasily Gorbik }
4749698745SVasily Gorbik 
4849698745SVasily Gorbik /* Works only for digits and letters, but small and fast */
4949698745SVasily Gorbik #define TOLOWER(x) ((x) | 0x20)
5049698745SVasily Gorbik 
5149698745SVasily Gorbik static unsigned int simple_guess_base(const char *cp)
5249698745SVasily Gorbik {
5349698745SVasily Gorbik 	if (cp[0] == '0') {
5449698745SVasily Gorbik 		if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
5549698745SVasily Gorbik 			return 16;
5649698745SVasily Gorbik 		else
5749698745SVasily Gorbik 			return 8;
5849698745SVasily Gorbik 	} else {
5949698745SVasily Gorbik 		return 10;
6049698745SVasily Gorbik 	}
6149698745SVasily Gorbik }
6249698745SVasily Gorbik 
6349698745SVasily Gorbik /**
6449698745SVasily Gorbik  * simple_strtoull - convert a string to an unsigned long long
6549698745SVasily Gorbik  * @cp: The start of the string
6649698745SVasily Gorbik  * @endp: A pointer to the end of the parsed string will be placed here
6749698745SVasily Gorbik  * @base: The number base to use
6849698745SVasily Gorbik  */
6949698745SVasily Gorbik 
7049698745SVasily Gorbik unsigned long long simple_strtoull(const char *cp, char **endp,
7149698745SVasily Gorbik 				   unsigned int base)
7249698745SVasily Gorbik {
7349698745SVasily Gorbik 	unsigned long long result = 0;
7449698745SVasily Gorbik 
7549698745SVasily Gorbik 	if (!base)
7649698745SVasily Gorbik 		base = simple_guess_base(cp);
7749698745SVasily Gorbik 
7849698745SVasily Gorbik 	if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
7949698745SVasily Gorbik 		cp += 2;
8049698745SVasily Gorbik 
8149698745SVasily Gorbik 	while (isxdigit(*cp)) {
8249698745SVasily Gorbik 		unsigned int value;
8349698745SVasily Gorbik 
8449698745SVasily Gorbik 		value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
8549698745SVasily Gorbik 		if (value >= base)
8649698745SVasily Gorbik 			break;
8749698745SVasily Gorbik 		result = result * base + value;
8849698745SVasily Gorbik 		cp++;
8949698745SVasily Gorbik 	}
9049698745SVasily Gorbik 	if (endp)
9149698745SVasily Gorbik 		*endp = (char *)cp;
9249698745SVasily Gorbik 
9349698745SVasily Gorbik 	return result;
9449698745SVasily Gorbik }
9549698745SVasily Gorbik 
9649698745SVasily Gorbik long simple_strtol(const char *cp, char **endp, unsigned int base)
9749698745SVasily Gorbik {
9849698745SVasily Gorbik 	if (*cp == '-')
9949698745SVasily Gorbik 		return -simple_strtoull(cp + 1, endp, base);
10049698745SVasily Gorbik 
10149698745SVasily Gorbik 	return simple_strtoull(cp, endp, base);
10249698745SVasily Gorbik }
103d58106c3SVasily Gorbik 
104d58106c3SVasily Gorbik int kstrtobool(const char *s, bool *res)
105d58106c3SVasily Gorbik {
106d58106c3SVasily Gorbik 	if (!s)
107d58106c3SVasily Gorbik 		return -EINVAL;
108d58106c3SVasily Gorbik 
109d58106c3SVasily Gorbik 	switch (s[0]) {
110d58106c3SVasily Gorbik 	case 'y':
111d58106c3SVasily Gorbik 	case 'Y':
112d58106c3SVasily Gorbik 	case '1':
113d58106c3SVasily Gorbik 		*res = true;
114d58106c3SVasily Gorbik 		return 0;
115d58106c3SVasily Gorbik 	case 'n':
116d58106c3SVasily Gorbik 	case 'N':
117d58106c3SVasily Gorbik 	case '0':
118d58106c3SVasily Gorbik 		*res = false;
119d58106c3SVasily Gorbik 		return 0;
120d58106c3SVasily Gorbik 	case 'o':
121d58106c3SVasily Gorbik 	case 'O':
122d58106c3SVasily Gorbik 		switch (s[1]) {
123d58106c3SVasily Gorbik 		case 'n':
124d58106c3SVasily Gorbik 		case 'N':
125d58106c3SVasily Gorbik 			*res = true;
126d58106c3SVasily Gorbik 			return 0;
127d58106c3SVasily Gorbik 		case 'f':
128d58106c3SVasily Gorbik 		case 'F':
129d58106c3SVasily Gorbik 			*res = false;
130d58106c3SVasily Gorbik 			return 0;
131d58106c3SVasily Gorbik 		default:
132d58106c3SVasily Gorbik 			break;
133d58106c3SVasily Gorbik 		}
134d58106c3SVasily Gorbik 	default:
135d58106c3SVasily Gorbik 		break;
136d58106c3SVasily Gorbik 	}
137d58106c3SVasily Gorbik 
138d58106c3SVasily Gorbik 	return -EINVAL;
139d58106c3SVasily Gorbik }
140