// SPDX-License-Identifier: GPL-2.0-only1/* -*- linux-c -*- ------------------------------------------------------- *2*3* Copyright (C) 1991, 1992 Linus Torvalds4* Copyright 2007 rPath, Inc. - All Rights Reserved5*6* ----------------------------------------------------------------------- */78/*9* Very basic string functions10*/1112#include <linux/types.h>13#include <linux/compiler.h>14#include <linux/errno.h>15#include <linux/limits.h>16#include <asm/asm.h>17#include "ctype.h"18#include "string.h"1920#define KSTRTOX_OVERFLOW (1U << 31)2122/*23* Undef these macros so that the functions that we provide24* here will have the correct names regardless of how string.h25* may have chosen to #define them.26*/27#undef memcpy28#undef memset29#undef memcmp3031int memcmp(const void *s1, const void *s2, size_t len)32{33bool diff;34asm("repe cmpsb" CC_SET(nz)35: CC_OUT(nz) (diff), "+D" (s1), "+S" (s2), "+c" (len));36return diff;37}3839/*40* Clang may lower `memcmp == 0` to `bcmp == 0`.41*/42int bcmp(const void *s1, const void *s2, size_t len)43{44return memcmp(s1, s2, len);45}4647int strcmp(const char *str1, const char *str2)48{49const unsigned char *s1 = (const unsigned char *)str1;50const unsigned char *s2 = (const unsigned char *)str2;51int delta;5253while (*s1 || *s2) {54delta = *s1 - *s2;55if (delta)56return delta;57s1++;58s2++;59}60return 0;61}6263int strncmp(const char *cs, const char *ct, size_t count)64{65unsigned char c1, c2;6667while (count) {68c1 = *cs++;69c2 = *ct++;70if (c1 != c2)71return c1 < c2 ? -1 : 1;72if (!c1)73break;74count--;75}76return 0;77}7879size_t strnlen(const char *s, size_t maxlen)80{81const char *es = s;82while (*es && maxlen) {83es++;84maxlen--;85}8687return (es - s);88}8990/* Works only for digits and letters, but small and fast */91#define TOLOWER(x) ((x) | 0x20)9293static unsigned int simple_guess_base(const char *cp)94{95if (cp[0] == '0') {96if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))97return 16;98else99return 8;100} else {101return 10;102}103}104105/**106* simple_strtoull - convert a string to an unsigned long long107* @cp: The start of the string108* @endp: A pointer to the end of the parsed string will be placed here109* @base: The number base to use110*/111unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)112{113unsigned long long result = 0;114115if (!base)116base = simple_guess_base(cp);117118if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')119cp += 2;120121while (isxdigit(*cp)) {122unsigned int value;123124value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;125if (value >= base)126break;127result = result * base + value;128cp++;129}130if (endp)131*endp = (char *)cp;132133return result;134}135136long simple_strtol(const char *cp, char **endp, unsigned int base)137{138if (*cp == '-')139return -simple_strtoull(cp + 1, endp, base);140141return simple_strtoull(cp, endp, base);142}143144/**145* strlen - Find the length of a string146* @s: The string to be sized147*/148size_t strlen(const char *s)149{150const char *sc;151152for (sc = s; *sc != '\0'; ++sc)153/* nothing */;154return sc - s;155}156157/**158* strstr - Find the first substring in a %NUL terminated string159* @s1: The string to be searched160* @s2: The string to search for161*/162char *strstr(const char *s1, const char *s2)163{164size_t l1, l2;165166l2 = strlen(s2);167if (!l2)168return (char *)s1;169l1 = strlen(s1);170while (l1 >= l2) {171l1--;172if (!memcmp(s1, s2, l2))173return (char *)s1;174s1++;175}176return NULL;177}178179/**180* strchr - Find the first occurrence of the character c in the string s.181* @s: the string to be searched182* @c: the character to search for183*/184char *strchr(const char *s, int c)185{186while (*s != (char)c)187if (*s++ == '\0')188return NULL;189return (char *)s;190}191192static inline u64 __div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)193{194union {195u64 v64;196u32 v32[2];197} d = { dividend };198u32 upper;199200upper = d.v32[1];201d.v32[1] = 0;202if (upper >= divisor) {203d.v32[1] = upper / divisor;204upper %= divisor;205}206asm ("divl %2" : "=a" (d.v32[0]), "=d" (*remainder) :207"rm" (divisor), "0" (d.v32[0]), "1" (upper));208return d.v64;209}210211static inline u64 __div_u64(u64 dividend, u32 divisor)212{213u32 remainder;214215return __div_u64_rem(dividend, divisor, &remainder);216}217218static inline char _tolower(const char c)219{220return c | 0x20;221}222223static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)224{225if (*base == 0) {226if (s[0] == '0') {227if (_tolower(s[1]) == 'x' && isxdigit(s[2]))228*base = 16;229else230*base = 8;231} else232*base = 10;233}234if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')235s += 2;236return s;237}238239/*240* Convert non-negative integer string representation in explicitly given radix241* to an integer.242* Return number of characters consumed maybe or-ed with overflow bit.243* If overflow occurs, result integer (incorrect) is still returned.244*245* Don't you dare use this function.246*/247static unsigned int _parse_integer(const char *s,248unsigned int base,249unsigned long long *p)250{251unsigned long long res;252unsigned int rv;253254res = 0;255rv = 0;256while (1) {257unsigned int c = *s;258unsigned int lc = c | 0x20; /* don't tolower() this line */259unsigned int val;260261if ('0' <= c && c <= '9')262val = c - '0';263else if ('a' <= lc && lc <= 'f')264val = lc - 'a' + 10;265else266break;267268if (val >= base)269break;270/*271* Check for overflow only if we are within range of272* it in the max base we support (16)273*/274if (unlikely(res & (~0ull << 60))) {275if (res > __div_u64(ULLONG_MAX - val, base))276rv |= KSTRTOX_OVERFLOW;277}278res = res * base + val;279rv++;280s++;281}282*p = res;283return rv;284}285286static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)287{288unsigned long long _res;289unsigned int rv;290291s = _parse_integer_fixup_radix(s, &base);292rv = _parse_integer(s, base, &_res);293if (rv & KSTRTOX_OVERFLOW)294return -ERANGE;295if (rv == 0)296return -EINVAL;297s += rv;298if (*s == '\n')299s++;300if (*s)301return -EINVAL;302*res = _res;303return 0;304}305306/**307* kstrtoull - convert a string to an unsigned long long308* @s: The start of the string. The string must be null-terminated, and may also309* include a single newline before its terminating null. The first character310* may also be a plus sign, but not a minus sign.311* @base: The number base to use. The maximum supported base is 16. If base is312* given as 0, then the base of the string is automatically detected with the313* conventional semantics - If it begins with 0x the number will be parsed as a314* hexadecimal (case insensitive), if it otherwise begins with 0, it will be315* parsed as an octal number. Otherwise it will be parsed as a decimal.316* @res: Where to write the result of the conversion on success.317*318* Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.319* Used as a replacement for the obsolete simple_strtoull. Return code must320* be checked.321*/322int kstrtoull(const char *s, unsigned int base, unsigned long long *res)323{324if (s[0] == '+')325s++;326return _kstrtoull(s, base, res);327}328329static int _kstrtoul(const char *s, unsigned int base, unsigned long *res)330{331unsigned long long tmp;332int rv;333334rv = kstrtoull(s, base, &tmp);335if (rv < 0)336return rv;337if (tmp != (unsigned long)tmp)338return -ERANGE;339*res = tmp;340return 0;341}342343/**344* boot_kstrtoul - convert a string to an unsigned long345* @s: The start of the string. The string must be null-terminated, and may also346* include a single newline before its terminating null. The first character347* may also be a plus sign, but not a minus sign.348* @base: The number base to use. The maximum supported base is 16. If base is349* given as 0, then the base of the string is automatically detected with the350* conventional semantics - If it begins with 0x the number will be parsed as a351* hexadecimal (case insensitive), if it otherwise begins with 0, it will be352* parsed as an octal number. Otherwise it will be parsed as a decimal.353* @res: Where to write the result of the conversion on success.354*355* Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.356* Used as a replacement for the simple_strtoull.357*/358int boot_kstrtoul(const char *s, unsigned int base, unsigned long *res)359{360/*361* We want to shortcut function call, but362* __builtin_types_compatible_p(unsigned long, unsigned long long) = 0.363*/364if (sizeof(unsigned long) == sizeof(unsigned long long) &&365__alignof__(unsigned long) == __alignof__(unsigned long long))366return kstrtoull(s, base, (unsigned long long *)res);367else368return _kstrtoul(s, base, res);369}370371372