==> src/rs_parse.c <==1/* Rust's integer parsing (core::num, from_str_radix): sign, digits, overflow checks. */
2#include "mesh/rs_parse.h"
3
4static int digit(char c, unsigned radix) {
5 unsigned d;
6 if (c >= '0' && c <= '9') d = (unsigned)(c - '0');
7 else if (c >= 'a' && c <= 'z') d = (unsigned)(c - 'a') + 10;
8 else if (c >= 'A' && c <= 'Z') d = (unsigned)(c - 'A') + 10;
9 else return -1;
10 return d < radix ? (int)d : -1;
11}
12
13bool rs_parse_uint(const char *s, size_t n, unsigned radix, uint64_t max, uint64_t *out) {
14 size_t i = 0;
15 if (n && s[0] == '+') i = 1;
16 if (i >= n) return false;
17 uint64_t v = 0;
18 for (; i < n; i++) {
19 int d = digit(s[i], radix);
20 if (d < 0) return false;
21 if (v > (max - (uint64_t)d) / radix) return false;
22 v = v * radix + (uint64_t)d;
23 }
24 *out = v;
25 return true;
26}
27
28bool rs_parse_int(const char *s, size_t n, int64_t min, int64_t max, int64_t *out) {
29 size_t i = 0;
30 bool neg = false;
31 if (n && (s[0] == '+' || s[0] == '-')) {
32 neg = s[0] == '-';
33 i = 1;
34 }
35 if (i >= n) return false;
36 /* Accumulate the magnitude as unsigned against the bound of its sign. */
37 uint64_t lim = neg ? (uint64_t)(-(min + 1)) + 1 : (uint64_t)max, v = 0;
38 for (; i < n; i++) {
39 int d = digit(s[i], 10);
40 if (d < 0) return false;
41 if (v > (lim - (uint64_t)d) / 10) return false;
42 v = v * 10 + (uint64_t)d;
43 }
44 *out = neg ? (v == 0 ? 0 : -(int64_t)(v - 1) - 1) : (int64_t)v;
45 return true;
46}