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