0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/types.h>
0014 #include <linux/compiler.h>
0015 #include <linux/errno.h>
0016 #include <linux/limits.h>
0017 #include <asm/asm.h>
0018 #include "ctype.h"
0019 #include "string.h"
0020
0021 #define KSTRTOX_OVERFLOW (1U << 31)
0022
0023
0024
0025
0026
0027
0028 #undef memcpy
0029 #undef memset
0030 #undef memcmp
0031
0032 int memcmp(const void *s1, const void *s2, size_t len)
0033 {
0034 bool diff;
0035 asm("repe; cmpsb" CC_SET(nz)
0036 : CC_OUT(nz) (diff), "+D" (s1), "+S" (s2), "+c" (len));
0037 return diff;
0038 }
0039
0040
0041
0042
0043 int bcmp(const void *s1, const void *s2, size_t len)
0044 {
0045 return memcmp(s1, s2, len);
0046 }
0047
0048 int strcmp(const char *str1, const char *str2)
0049 {
0050 const unsigned char *s1 = (const unsigned char *)str1;
0051 const unsigned char *s2 = (const unsigned char *)str2;
0052 int delta = 0;
0053
0054 while (*s1 || *s2) {
0055 delta = *s1 - *s2;
0056 if (delta)
0057 return delta;
0058 s1++;
0059 s2++;
0060 }
0061 return 0;
0062 }
0063
0064 int strncmp(const char *cs, const char *ct, size_t count)
0065 {
0066 unsigned char c1, c2;
0067
0068 while (count) {
0069 c1 = *cs++;
0070 c2 = *ct++;
0071 if (c1 != c2)
0072 return c1 < c2 ? -1 : 1;
0073 if (!c1)
0074 break;
0075 count--;
0076 }
0077 return 0;
0078 }
0079
0080 size_t strnlen(const char *s, size_t maxlen)
0081 {
0082 const char *es = s;
0083 while (*es && maxlen) {
0084 es++;
0085 maxlen--;
0086 }
0087
0088 return (es - s);
0089 }
0090
0091 unsigned int atou(const char *s)
0092 {
0093 unsigned int i = 0;
0094 while (isdigit(*s))
0095 i = i * 10 + (*s++ - '0');
0096 return i;
0097 }
0098
0099
0100 #define TOLOWER(x) ((x) | 0x20)
0101
0102 static unsigned int simple_guess_base(const char *cp)
0103 {
0104 if (cp[0] == '0') {
0105 if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
0106 return 16;
0107 else
0108 return 8;
0109 } else {
0110 return 10;
0111 }
0112 }
0113
0114
0115
0116
0117
0118
0119
0120 unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
0121 {
0122 unsigned long long result = 0;
0123
0124 if (!base)
0125 base = simple_guess_base(cp);
0126
0127 if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
0128 cp += 2;
0129
0130 while (isxdigit(*cp)) {
0131 unsigned int value;
0132
0133 value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
0134 if (value >= base)
0135 break;
0136 result = result * base + value;
0137 cp++;
0138 }
0139 if (endp)
0140 *endp = (char *)cp;
0141
0142 return result;
0143 }
0144
0145 long simple_strtol(const char *cp, char **endp, unsigned int base)
0146 {
0147 if (*cp == '-')
0148 return -simple_strtoull(cp + 1, endp, base);
0149
0150 return simple_strtoull(cp, endp, base);
0151 }
0152
0153
0154
0155
0156
0157 size_t strlen(const char *s)
0158 {
0159 const char *sc;
0160
0161 for (sc = s; *sc != '\0'; ++sc)
0162 ;
0163 return sc - s;
0164 }
0165
0166
0167
0168
0169
0170
0171 char *strstr(const char *s1, const char *s2)
0172 {
0173 size_t l1, l2;
0174
0175 l2 = strlen(s2);
0176 if (!l2)
0177 return (char *)s1;
0178 l1 = strlen(s1);
0179 while (l1 >= l2) {
0180 l1--;
0181 if (!memcmp(s1, s2, l2))
0182 return (char *)s1;
0183 s1++;
0184 }
0185 return NULL;
0186 }
0187
0188
0189
0190
0191
0192
0193 char *strchr(const char *s, int c)
0194 {
0195 while (*s != (char)c)
0196 if (*s++ == '\0')
0197 return NULL;
0198 return (char *)s;
0199 }
0200
0201 static inline u64 __div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
0202 {
0203 union {
0204 u64 v64;
0205 u32 v32[2];
0206 } d = { dividend };
0207 u32 upper;
0208
0209 upper = d.v32[1];
0210 d.v32[1] = 0;
0211 if (upper >= divisor) {
0212 d.v32[1] = upper / divisor;
0213 upper %= divisor;
0214 }
0215 asm ("divl %2" : "=a" (d.v32[0]), "=d" (*remainder) :
0216 "rm" (divisor), "0" (d.v32[0]), "1" (upper));
0217 return d.v64;
0218 }
0219
0220 static inline u64 __div_u64(u64 dividend, u32 divisor)
0221 {
0222 u32 remainder;
0223
0224 return __div_u64_rem(dividend, divisor, &remainder);
0225 }
0226
0227 static inline char _tolower(const char c)
0228 {
0229 return c | 0x20;
0230 }
0231
0232 static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
0233 {
0234 if (*base == 0) {
0235 if (s[0] == '0') {
0236 if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
0237 *base = 16;
0238 else
0239 *base = 8;
0240 } else
0241 *base = 10;
0242 }
0243 if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
0244 s += 2;
0245 return s;
0246 }
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256 static unsigned int _parse_integer(const char *s,
0257 unsigned int base,
0258 unsigned long long *p)
0259 {
0260 unsigned long long res;
0261 unsigned int rv;
0262
0263 res = 0;
0264 rv = 0;
0265 while (1) {
0266 unsigned int c = *s;
0267 unsigned int lc = c | 0x20;
0268 unsigned int val;
0269
0270 if ('0' <= c && c <= '9')
0271 val = c - '0';
0272 else if ('a' <= lc && lc <= 'f')
0273 val = lc - 'a' + 10;
0274 else
0275 break;
0276
0277 if (val >= base)
0278 break;
0279
0280
0281
0282
0283 if (unlikely(res & (~0ull << 60))) {
0284 if (res > __div_u64(ULLONG_MAX - val, base))
0285 rv |= KSTRTOX_OVERFLOW;
0286 }
0287 res = res * base + val;
0288 rv++;
0289 s++;
0290 }
0291 *p = res;
0292 return rv;
0293 }
0294
0295 static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
0296 {
0297 unsigned long long _res;
0298 unsigned int rv;
0299
0300 s = _parse_integer_fixup_radix(s, &base);
0301 rv = _parse_integer(s, base, &_res);
0302 if (rv & KSTRTOX_OVERFLOW)
0303 return -ERANGE;
0304 if (rv == 0)
0305 return -EINVAL;
0306 s += rv;
0307 if (*s == '\n')
0308 s++;
0309 if (*s)
0310 return -EINVAL;
0311 *res = _res;
0312 return 0;
0313 }
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331 int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
0332 {
0333 if (s[0] == '+')
0334 s++;
0335 return _kstrtoull(s, base, res);
0336 }
0337
0338 static int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
0339 {
0340 unsigned long long tmp;
0341 int rv;
0342
0343 rv = kstrtoull(s, base, &tmp);
0344 if (rv < 0)
0345 return rv;
0346 if (tmp != (unsigned long)tmp)
0347 return -ERANGE;
0348 *res = tmp;
0349 return 0;
0350 }
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367 int boot_kstrtoul(const char *s, unsigned int base, unsigned long *res)
0368 {
0369
0370
0371
0372
0373 if (sizeof(unsigned long) == sizeof(unsigned long long) &&
0374 __alignof__(unsigned long) == __alignof__(unsigned long long))
0375 return kstrtoull(s, base, (unsigned long long *)res);
0376 else
0377 return _kstrtoul(s, base, res);
0378 }