1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Taken from:
4*4882a593Smuzhiyun * linux/lib/string.c
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Copyright (C) 1991, 1992 Linus Torvalds
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <linux/ctype.h>
10*4882a593Smuzhiyun #include <linux/kernel.h>
11*4882a593Smuzhiyun #include <linux/types.h>
12*4882a593Smuzhiyun #include <linux/string.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #ifndef __HAVE_ARCH_STRSTR
15*4882a593Smuzhiyun /**
16*4882a593Smuzhiyun * strstr - Find the first substring in a %NUL terminated string
17*4882a593Smuzhiyun * @s1: The string to be searched
18*4882a593Smuzhiyun * @s2: The string to search for
19*4882a593Smuzhiyun */
strstr(const char * s1,const char * s2)20*4882a593Smuzhiyun char *strstr(const char *s1, const char *s2)
21*4882a593Smuzhiyun {
22*4882a593Smuzhiyun size_t l1, l2;
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun l2 = strlen(s2);
25*4882a593Smuzhiyun if (!l2)
26*4882a593Smuzhiyun return (char *)s1;
27*4882a593Smuzhiyun l1 = strlen(s1);
28*4882a593Smuzhiyun while (l1 >= l2) {
29*4882a593Smuzhiyun l1--;
30*4882a593Smuzhiyun if (!memcmp(s1, s2, l2))
31*4882a593Smuzhiyun return (char *)s1;
32*4882a593Smuzhiyun s1++;
33*4882a593Smuzhiyun }
34*4882a593Smuzhiyun return NULL;
35*4882a593Smuzhiyun }
36*4882a593Smuzhiyun #endif
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun #ifndef __HAVE_ARCH_STRNCMP
39*4882a593Smuzhiyun /**
40*4882a593Smuzhiyun * strncmp - Compare two length-limited strings
41*4882a593Smuzhiyun * @cs: One string
42*4882a593Smuzhiyun * @ct: Another string
43*4882a593Smuzhiyun * @count: The maximum number of bytes to compare
44*4882a593Smuzhiyun */
strncmp(const char * cs,const char * ct,size_t count)45*4882a593Smuzhiyun int strncmp(const char *cs, const char *ct, size_t count)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun unsigned char c1, c2;
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun while (count) {
50*4882a593Smuzhiyun c1 = *cs++;
51*4882a593Smuzhiyun c2 = *ct++;
52*4882a593Smuzhiyun if (c1 != c2)
53*4882a593Smuzhiyun return c1 < c2 ? -1 : 1;
54*4882a593Smuzhiyun if (!c1)
55*4882a593Smuzhiyun break;
56*4882a593Smuzhiyun count--;
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun return 0;
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun #endif
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun /* Works only for digits and letters, but small and fast */
63*4882a593Smuzhiyun #define TOLOWER(x) ((x) | 0x20)
64*4882a593Smuzhiyun
simple_guess_base(const char * cp)65*4882a593Smuzhiyun static unsigned int simple_guess_base(const char *cp)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun if (cp[0] == '0') {
68*4882a593Smuzhiyun if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
69*4882a593Smuzhiyun return 16;
70*4882a593Smuzhiyun else
71*4882a593Smuzhiyun return 8;
72*4882a593Smuzhiyun } else {
73*4882a593Smuzhiyun return 10;
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun /**
78*4882a593Smuzhiyun * simple_strtoull - convert a string to an unsigned long long
79*4882a593Smuzhiyun * @cp: The start of the string
80*4882a593Smuzhiyun * @endp: A pointer to the end of the parsed string will be placed here
81*4882a593Smuzhiyun * @base: The number base to use
82*4882a593Smuzhiyun */
83*4882a593Smuzhiyun
simple_strtoull(const char * cp,char ** endp,unsigned int base)84*4882a593Smuzhiyun unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun unsigned long long result = 0;
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun if (!base)
89*4882a593Smuzhiyun base = simple_guess_base(cp);
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
92*4882a593Smuzhiyun cp += 2;
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun while (isxdigit(*cp)) {
95*4882a593Smuzhiyun unsigned int value;
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
98*4882a593Smuzhiyun if (value >= base)
99*4882a593Smuzhiyun break;
100*4882a593Smuzhiyun result = result * base + value;
101*4882a593Smuzhiyun cp++;
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun if (endp)
104*4882a593Smuzhiyun *endp = (char *)cp;
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun return result;
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun
simple_strtol(const char * cp,char ** endp,unsigned int base)109*4882a593Smuzhiyun long simple_strtol(const char *cp, char **endp, unsigned int base)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun if (*cp == '-')
112*4882a593Smuzhiyun return -simple_strtoull(cp + 1, endp, base);
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun return simple_strtoull(cp, endp, base);
115*4882a593Smuzhiyun }
116