Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/firmware/efi/libstub/string.c
26483 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* Taken from:
4
* linux/lib/string.c
5
*
6
* Copyright (C) 1991, 1992 Linus Torvalds
7
*/
8
9
#include <linux/ctype.h>
10
#include <linux/kernel.h>
11
#include <linux/types.h>
12
#include <linux/string.h>
13
14
#ifndef EFI_HAVE_STRLEN
15
/**
16
* strlen - Find the length of a string
17
* @s: The string to be sized
18
*/
19
size_t strlen(const char *s)
20
{
21
const char *sc;
22
23
for (sc = s; *sc != '\0'; ++sc)
24
/* nothing */;
25
return sc - s;
26
}
27
#endif
28
29
#ifndef EFI_HAVE_STRNLEN
30
/**
31
* strnlen - Find the length of a length-limited string
32
* @s: The string to be sized
33
* @count: The maximum number of bytes to search
34
*/
35
size_t strnlen(const char *s, size_t count)
36
{
37
const char *sc;
38
39
for (sc = s; count-- && *sc != '\0'; ++sc)
40
/* nothing */;
41
return sc - s;
42
}
43
#endif
44
45
/**
46
* strstr - Find the first substring in a %NUL terminated string
47
* @s1: The string to be searched
48
* @s2: The string to search for
49
*/
50
char *strstr(const char *s1, const char *s2)
51
{
52
size_t l1, l2;
53
54
l2 = strlen(s2);
55
if (!l2)
56
return (char *)s1;
57
l1 = strlen(s1);
58
while (l1 >= l2) {
59
l1--;
60
if (!memcmp(s1, s2, l2))
61
return (char *)s1;
62
s1++;
63
}
64
return NULL;
65
}
66
67
#ifndef EFI_HAVE_STRCMP
68
/**
69
* strcmp - Compare two strings
70
* @cs: One string
71
* @ct: Another string
72
*/
73
int strcmp(const char *cs, const char *ct)
74
{
75
unsigned char c1, c2;
76
77
while (1) {
78
c1 = *cs++;
79
c2 = *ct++;
80
if (c1 != c2)
81
return c1 < c2 ? -1 : 1;
82
if (!c1)
83
break;
84
}
85
return 0;
86
}
87
#endif
88
89
/**
90
* strncmp - Compare two length-limited strings
91
* @cs: One string
92
* @ct: Another string
93
* @count: The maximum number of bytes to compare
94
*/
95
int strncmp(const char *cs, const char *ct, size_t count)
96
{
97
unsigned char c1, c2;
98
99
while (count) {
100
c1 = *cs++;
101
c2 = *ct++;
102
if (c1 != c2)
103
return c1 < c2 ? -1 : 1;
104
if (!c1)
105
break;
106
count--;
107
}
108
return 0;
109
}
110
111
/* Works only for digits and letters, but small and fast */
112
#define TOLOWER(x) ((x) | 0x20)
113
114
static unsigned int simple_guess_base(const char *cp)
115
{
116
if (cp[0] == '0') {
117
if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
118
return 16;
119
else
120
return 8;
121
} else {
122
return 10;
123
}
124
}
125
126
/**
127
* simple_strtoull - convert a string to an unsigned long long
128
* @cp: The start of the string
129
* @endp: A pointer to the end of the parsed string will be placed here
130
* @base: The number base to use
131
*/
132
133
unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
134
{
135
unsigned long long result = 0;
136
137
if (!base)
138
base = simple_guess_base(cp);
139
140
if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
141
cp += 2;
142
143
while (isxdigit(*cp)) {
144
unsigned int value;
145
146
value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
147
if (value >= base)
148
break;
149
result = result * base + value;
150
cp++;
151
}
152
if (endp)
153
*endp = (char *)cp;
154
155
return result;
156
}
157
158
long simple_strtol(const char *cp, char **endp, unsigned int base)
159
{
160
if (*cp == '-')
161
return -simple_strtoull(cp + 1, endp, base);
162
163
return simple_strtoull(cp, endp, base);
164
}
165
166
#ifdef CONFIG_EFI_PARAMS_FROM_FDT
167
#ifndef EFI_HAVE_STRRCHR
168
/**
169
* strrchr - Find the last occurrence of a character in a string
170
* @s: The string to be searched
171
* @c: The character to search for
172
*/
173
char *strrchr(const char *s, int c)
174
{
175
const char *last = NULL;
176
do {
177
if (*s == (char)c)
178
last = s;
179
} while (*s++);
180
return (char *)last;
181
}
182
#endif
183
#ifndef EFI_HAVE_MEMCHR
184
/**
185
* memchr - Find a character in an area of memory.
186
* @s: The memory area
187
* @c: The byte to search for
188
* @n: The size of the area.
189
*
190
* returns the address of the first occurrence of @c, or %NULL
191
* if @c is not found
192
*/
193
void *memchr(const void *s, int c, size_t n)
194
{
195
const unsigned char *p = s;
196
while (n-- != 0) {
197
if ((unsigned char)c == *p++) {
198
return (void *)(p - 1);
199
}
200
}
201
return NULL;
202
}
203
#endif
204
#endif
205
206