1 | /* -*- linux-c -*- ------------------------------------------------------- * |
---|---|

2 | * |

3 | * Copyright (C) 1991, 1992 Linus Torvalds |

4 | * Copyright 2007 rPath, Inc. - All Rights Reserved |

5 | * |

6 | * This file is part of the Linux kernel, and is made available under |

7 | * the terms of the GNU General Public License version 2. |

8 | * |

9 | * ----------------------------------------------------------------------- */ |

10 | |

11 | /* |

12 | * Very basic string functions |

13 | */ |

14 | |

15 | #include <linux/types.h> |

16 | #include <linux/compiler.h> |

17 | #include <linux/errno.h> |

18 | #include <linux/limits.h> |

19 | #include <asm/asm.h> |

20 | #include "ctype.h" |

21 | #include "string.h" |

22 | |

23 | #define KSTRTOX_OVERFLOW (1U << 31) |

24 | |

25 | /* |

26 | * Undef these macros so that the functions that we provide |

27 | * here will have the correct names regardless of how string.h |

28 | * may have chosen to #define them. |

29 | */ |

30 | #undef memcpy |

31 | #undef memset |

32 | #undef memcmp |

33 | |

34 | int memcmp(const void *s1, const void *s2, size_t len) |

35 | { |

36 | bool diff; |

37 | asm("repe; cmpsb"CC_SET(nz) |

38 | : CC_OUT(nz) (diff), "+D"(s1), "+S"(s2), "+c"(len)); |

39 | return diff; |

40 | } |

41 | |

42 | int strcmp(const char *str1, const char *str2) |

43 | { |

44 | const unsigned char *s1 = (const unsigned char *)str1; |

45 | const unsigned char *s2 = (const unsigned char *)str2; |

46 | int delta = 0; |

47 | |

48 | while (*s1 || *s2) { |

49 | delta = *s1 - *s2; |

50 | if (delta) |

51 | return delta; |

52 | s1++; |

53 | s2++; |

54 | } |

55 | return 0; |

56 | } |

57 | |

58 | int strncmp(const char *cs, const char *ct, size_t count) |

59 | { |

60 | unsigned char c1, c2; |

61 | |

62 | while (count) { |

63 | c1 = *cs++; |

64 | c2 = *ct++; |

65 | if (c1 != c2) |

66 | return c1 < c2 ? -1 : 1; |

67 | if (!c1) |

68 | break; |

69 | count--; |

70 | } |

71 | return 0; |

72 | } |

73 | |

74 | size_t strnlen(const char *s, size_t maxlen) |

75 | { |

76 | const char *es = s; |

77 | while (*es && maxlen) { |

78 | es++; |

79 | maxlen--; |

80 | } |

81 | |

82 | return (es - s); |

83 | } |

84 | |

85 | unsigned int atou(const char *s) |

86 | { |

87 | unsigned int i = 0; |

88 | while (isdigit(*s)) |

89 | i = i * 10 + (*s++ - '0'); |

90 | return i; |

91 | } |

92 | |

93 | /* Works only for digits and letters, but small and fast */ |

94 | #define TOLOWER(x) ((x) | 0x20) |

95 | |

96 | static unsigned int simple_guess_base(const char *cp) |

97 | { |

98 | if (cp[0] == '0') { |

99 | if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2])) |

100 | return 16; |

101 | else |

102 | return 8; |

103 | } else { |

104 | return 10; |

105 | } |

106 | } |

107 | |

108 | /** |

109 | * simple_strtoull - convert a string to an unsigned long long |

110 | * @cp: The start of the string |

111 | * @endp: A pointer to the end of the parsed string will be placed here |

112 | * @base: The number base to use |

113 | */ |

114 | |

115 | unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base) |

116 | { |

117 | unsigned long long result = 0; |

118 | |

119 | if (!base) |

120 | base = simple_guess_base(cp); |

121 | |

122 | if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x') |

123 | cp += 2; |

124 | |

125 | while (isxdigit(*cp)) { |

126 | unsigned int value; |

127 | |

128 | value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10; |

129 | if (value >= base) |

130 | break; |

131 | result = result * base + value; |

132 | cp++; |

133 | } |

134 | if (endp) |

135 | *endp = (char *)cp; |

136 | |

137 | return result; |

138 | } |

139 | |

140 | long simple_strtol(const char *cp, char **endp, unsigned int base) |

141 | { |

142 | if (*cp == '-') |

143 | return -simple_strtoull(cp + 1, endp, base); |

144 | |

145 | return simple_strtoull(cp, endp, base); |

146 | } |

147 | |

148 | /** |

149 | * strlen - Find the length of a string |

150 | * @s: The string to be sized |

151 | */ |

152 | size_t strlen(const char *s) |

153 | { |

154 | const char *sc; |

155 | |

156 | for (sc = s; *sc != '\0'; ++sc) |

157 | /* nothing */; |

158 | return sc - s; |

159 | } |

160 | |

161 | /** |

162 | * strstr - Find the first substring in a %NUL terminated string |

163 | * @s1: The string to be searched |

164 | * @s2: The string to search for |

165 | */ |

166 | char *strstr(const char *s1, const char *s2) |

167 | { |

168 | size_t l1, l2; |

169 | |

170 | l2 = strlen(s2); |

171 | if (!l2) |

172 | return (char *)s1; |

173 | l1 = strlen(s1); |

174 | while (l1 >= l2) { |

175 | l1--; |

176 | if (!memcmp(s1, s2, l2)) |

177 | return (char *)s1; |

178 | s1++; |

179 | } |

180 | return NULL; |

181 | } |

182 | |

183 | /** |

184 | * strchr - Find the first occurrence of the character c in the string s. |

185 | * @s: the string to be searched |

186 | * @c: the character to search for |

187 | */ |

188 | char *strchr(const char *s, int c) |

189 | { |

190 | while (*s != (char)c) |

191 | if (*s++ == '\0') |

192 | return NULL; |

193 | return (char *)s; |

194 | } |

195 | |

196 | static inline u64 __div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) |

197 | { |

198 | union { |

199 | u64 v64; |

200 | u32 v32[2]; |

201 | } d = { dividend }; |

202 | u32 upper; |

203 | |

204 | upper = d.v32[1]; |

205 | d.v32[1] = 0; |

206 | if (upper >= divisor) { |

207 | d.v32[1] = upper / divisor; |

208 | upper %= divisor; |

209 | } |

210 | asm ("divl %2": "=a"(d.v32[ 0]), "=d"(*remainder) : |

211 | "rm"(divisor), "0"(d.v32[ 0]), "1"(upper)); |

212 | return d.v64; |

213 | } |

214 | |

215 | static inline u64 __div_u64(u64 dividend, u32 divisor) |

216 | { |

217 | u32 remainder; |

218 | |

219 | return __div_u64_rem(dividend, divisor, &remainder); |

220 | } |

221 | |

222 | static inline char _tolower(const char c) |

223 | { |

224 | return c | 0x20; |

225 | } |

226 | |

227 | static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base) |

228 | { |

229 | if (*base == 0) { |

230 | if (s[0] == '0') { |

231 | if (_tolower(s[1]) == 'x' && isxdigit(s[2])) |

232 | *base = 16; |

233 | else |

234 | *base = 8; |

235 | } else |

236 | *base = 10; |

237 | } |

238 | if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x') |

239 | s += 2; |

240 | return s; |

241 | } |

242 | |

243 | /* |

244 | * Convert non-negative integer string representation in explicitly given radix |

245 | * to an integer. |

246 | * Return number of characters consumed maybe or-ed with overflow bit. |

247 | * If overflow occurs, result integer (incorrect) is still returned. |

248 | * |

249 | * Don't you dare use this function. |

250 | */ |

251 | static unsigned int _parse_integer(const char *s, |

252 | unsigned int base, |

253 | unsigned long long *p) |

254 | { |

255 | unsigned long long res; |

256 | unsigned int rv; |

257 | |

258 | res = 0; |

259 | rv = 0; |

260 | while (1) { |

261 | unsigned int c = *s; |

262 | unsigned int lc = c | 0x20; /* don't tolower() this line */ |

263 | unsigned int val; |

264 | |

265 | if ('0' <= c && c <= '9') |

266 | val = c - '0'; |

267 | else if ('a' <= lc && lc <= 'f') |

268 | val = lc - 'a' + 10; |

269 | else |

270 | break; |

271 | |

272 | if (val >= base) |

273 | break; |

274 | /* |

275 | * Check for overflow only if we are within range of |

276 | * it in the max base we support (16) |

277 | */ |

278 | if (unlikely(res & (~0ull << 60))) { |

279 | if (res > __div_u64(ULLONG_MAX - val, base)) |

280 | rv |= KSTRTOX_OVERFLOW; |

281 | } |

282 | res = res * base + val; |

283 | rv++; |

284 | s++; |

285 | } |

286 | *p = res; |

287 | return rv; |

288 | } |

289 | |

290 | static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res) |

291 | { |

292 | unsigned long long _res; |

293 | unsigned int rv; |

294 | |

295 | s = _parse_integer_fixup_radix(s, &base); |

296 | rv = _parse_integer(s, base, &_res); |

297 | if (rv & KSTRTOX_OVERFLOW) |

298 | return -ERANGE; |

299 | if (rv == 0) |

300 | return -EINVAL; |

301 | s += rv; |

302 | if (*s == '\n') |

303 | s++; |

304 | if (*s) |

305 | return -EINVAL; |

306 | *res = _res; |

307 | return 0; |

308 | } |

309 | |

310 | /** |

311 | * kstrtoull - convert a string to an unsigned long long |

312 | * @s: The start of the string. The string must be null-terminated, and may also |

313 | * include a single newline before its terminating null. The first character |

314 | * may also be a plus sign, but not a minus sign. |

315 | * @base: The number base to use. The maximum supported base is 16. If base is |

316 | * given as 0, then the base of the string is automatically detected with the |

317 | * conventional semantics - If it begins with 0x the number will be parsed as a |

318 | * hexadecimal (case insensitive), if it otherwise begins with 0, it will be |

319 | * parsed as an octal number. Otherwise it will be parsed as a decimal. |

320 | * @res: Where to write the result of the conversion on success. |

321 | * |

322 | * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error. |

323 | * Used as a replacement for the obsolete simple_strtoull. Return code must |

324 | * be checked. |

325 | */ |

326 | int kstrtoull(const char *s, unsigned int base, unsigned long long *res) |

327 | { |

328 | if (s[0] == '+') |

329 | s++; |

330 | return _kstrtoull(s, base, res); |

331 | } |

332 |