root/arch/s390/boot/string.c
// SPDX-License-Identifier: GPL-2.0
#define IN_BOOT_STRING_C 1
#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#undef CONFIG_KASAN
#undef CONFIG_KASAN_GENERIC
#undef CONFIG_KMSAN
#include "../lib/string.c"

/*
 * Duplicate some functions from the common lib/string.c
 * instead of fully including it.
 */

int strncmp(const char *cs, const char *ct, size_t count)
{
        unsigned char c1, c2;

        while (count) {
                c1 = *cs++;
                c2 = *ct++;
                if (c1 != c2)
                        return c1 < c2 ? -1 : 1;
                if (!c1)
                        break;
                count--;
        }
        return 0;
}

ssize_t sized_strscpy(char *dst, const char *src, size_t count)
{
        size_t len;

        if (count == 0)
                return -E2BIG;
        len = strnlen(src, count - 1);
        memcpy(dst, src, len);
        dst[len] = '\0';
        return src[len] ? -E2BIG : len;
}

void *memset64(uint64_t *s, uint64_t v, size_t count)
{
        uint64_t *xs = s;

        while (count--)
                *xs++ = v;
        return s;
}

char *skip_spaces(const char *str)
{
        while (isspace(*str))
                ++str;
        return (char *)str;
}

char *strim(char *s)
{
        size_t size;
        char *end;

        size = strlen(s);
        if (!size)
                return s;

        end = s + size - 1;
        while (end >= s && isspace(*end))
                end--;
        *(end + 1) = '\0';

        return skip_spaces(s);
}

/* Works only for digits and letters, but small and fast */
#define TOLOWER(x) ((x) | 0x20)

static unsigned int simple_guess_base(const char *cp)
{
        if (cp[0] == '0') {
                if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
                        return 16;
                else
                        return 8;
        } else {
                return 10;
        }
}

/**
 * simple_strtoull - convert a string to an unsigned long long
 * @cp: The start of the string
 * @endp: A pointer to the end of the parsed string will be placed here
 * @base: The number base to use
 */

unsigned long long simple_strtoull(const char *cp, char **endp,
                                   unsigned int base)
{
        unsigned long long result = 0;

        if (!base)
                base = simple_guess_base(cp);

        if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
                cp += 2;

        while (isxdigit(*cp)) {
                unsigned int value;

                value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
                if (value >= base)
                        break;
                result = result * base + value;
                cp++;
        }
        if (endp)
                *endp = (char *)cp;

        return result;
}

long simple_strtol(const char *cp, char **endp, unsigned int base)
{
        if (*cp == '-')
                return -simple_strtoull(cp + 1, endp, base);

        return simple_strtoull(cp, endp, base);
}

int kstrtobool(const char *s, bool *res)
{
        if (!s)
                return -EINVAL;

        switch (s[0]) {
        case 'y':
        case 'Y':
        case '1':
                *res = true;
                return 0;
        case 'n':
        case 'N':
        case '0':
                *res = false;
                return 0;
        case 'o':
        case 'O':
                switch (s[1]) {
                case 'n':
                case 'N':
                        *res = true;
                        return 0;
                case 'f':
                case 'F':
                        *res = false;
                        return 0;
                default:
                        break;
                }
        default:
                break;
        }

        return -EINVAL;
}