18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Taken from:
48c2ecf20Sopenharmony_ci *  linux/lib/string.c
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci *  Copyright (C) 1991, 1992  Linus Torvalds
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/ctype.h>
108c2ecf20Sopenharmony_ci#include <linux/kernel.h>
118c2ecf20Sopenharmony_ci#include <linux/types.h>
128c2ecf20Sopenharmony_ci#include <linux/string.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#ifndef __HAVE_ARCH_STRSTR
158c2ecf20Sopenharmony_ci/**
168c2ecf20Sopenharmony_ci * strstr - Find the first substring in a %NUL terminated string
178c2ecf20Sopenharmony_ci * @s1: The string to be searched
188c2ecf20Sopenharmony_ci * @s2: The string to search for
198c2ecf20Sopenharmony_ci */
208c2ecf20Sopenharmony_cichar *strstr(const char *s1, const char *s2)
218c2ecf20Sopenharmony_ci{
228c2ecf20Sopenharmony_ci	size_t l1, l2;
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci	l2 = strlen(s2);
258c2ecf20Sopenharmony_ci	if (!l2)
268c2ecf20Sopenharmony_ci		return (char *)s1;
278c2ecf20Sopenharmony_ci	l1 = strlen(s1);
288c2ecf20Sopenharmony_ci	while (l1 >= l2) {
298c2ecf20Sopenharmony_ci		l1--;
308c2ecf20Sopenharmony_ci		if (!memcmp(s1, s2, l2))
318c2ecf20Sopenharmony_ci			return (char *)s1;
328c2ecf20Sopenharmony_ci		s1++;
338c2ecf20Sopenharmony_ci	}
348c2ecf20Sopenharmony_ci	return NULL;
358c2ecf20Sopenharmony_ci}
368c2ecf20Sopenharmony_ci#endif
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#ifndef __HAVE_ARCH_STRNCMP
398c2ecf20Sopenharmony_ci/**
408c2ecf20Sopenharmony_ci * strncmp - Compare two length-limited strings
418c2ecf20Sopenharmony_ci * @cs: One string
428c2ecf20Sopenharmony_ci * @ct: Another string
438c2ecf20Sopenharmony_ci * @count: The maximum number of bytes to compare
448c2ecf20Sopenharmony_ci */
458c2ecf20Sopenharmony_ciint strncmp(const char *cs, const char *ct, size_t count)
468c2ecf20Sopenharmony_ci{
478c2ecf20Sopenharmony_ci	unsigned char c1, c2;
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	while (count) {
508c2ecf20Sopenharmony_ci		c1 = *cs++;
518c2ecf20Sopenharmony_ci		c2 = *ct++;
528c2ecf20Sopenharmony_ci		if (c1 != c2)
538c2ecf20Sopenharmony_ci			return c1 < c2 ? -1 : 1;
548c2ecf20Sopenharmony_ci		if (!c1)
558c2ecf20Sopenharmony_ci			break;
568c2ecf20Sopenharmony_ci		count--;
578c2ecf20Sopenharmony_ci	}
588c2ecf20Sopenharmony_ci	return 0;
598c2ecf20Sopenharmony_ci}
608c2ecf20Sopenharmony_ci#endif
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci/* Works only for digits and letters, but small and fast */
638c2ecf20Sopenharmony_ci#define TOLOWER(x) ((x) | 0x20)
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_cistatic unsigned int simple_guess_base(const char *cp)
668c2ecf20Sopenharmony_ci{
678c2ecf20Sopenharmony_ci	if (cp[0] == '0') {
688c2ecf20Sopenharmony_ci		if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
698c2ecf20Sopenharmony_ci			return 16;
708c2ecf20Sopenharmony_ci		else
718c2ecf20Sopenharmony_ci			return 8;
728c2ecf20Sopenharmony_ci	} else {
738c2ecf20Sopenharmony_ci		return 10;
748c2ecf20Sopenharmony_ci	}
758c2ecf20Sopenharmony_ci}
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci/**
788c2ecf20Sopenharmony_ci * simple_strtoull - convert a string to an unsigned long long
798c2ecf20Sopenharmony_ci * @cp: The start of the string
808c2ecf20Sopenharmony_ci * @endp: A pointer to the end of the parsed string will be placed here
818c2ecf20Sopenharmony_ci * @base: The number base to use
828c2ecf20Sopenharmony_ci */
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ciunsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
858c2ecf20Sopenharmony_ci{
868c2ecf20Sopenharmony_ci	unsigned long long result = 0;
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci	if (!base)
898c2ecf20Sopenharmony_ci		base = simple_guess_base(cp);
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci	if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
928c2ecf20Sopenharmony_ci		cp += 2;
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	while (isxdigit(*cp)) {
958c2ecf20Sopenharmony_ci		unsigned int value;
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci		value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
988c2ecf20Sopenharmony_ci		if (value >= base)
998c2ecf20Sopenharmony_ci			break;
1008c2ecf20Sopenharmony_ci		result = result * base + value;
1018c2ecf20Sopenharmony_ci		cp++;
1028c2ecf20Sopenharmony_ci	}
1038c2ecf20Sopenharmony_ci	if (endp)
1048c2ecf20Sopenharmony_ci		*endp = (char *)cp;
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci	return result;
1078c2ecf20Sopenharmony_ci}
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_cilong simple_strtol(const char *cp, char **endp, unsigned int base)
1108c2ecf20Sopenharmony_ci{
1118c2ecf20Sopenharmony_ci	if (*cp == '-')
1128c2ecf20Sopenharmony_ci		return -simple_strtoull(cp + 1, endp, base);
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	return simple_strtoull(cp, endp, base);
1158c2ecf20Sopenharmony_ci}
116