parse-util: add permille parser + tests
This commit is contained in:
parent
194c03c839
commit
958acea18b
|
@ -632,6 +632,58 @@ int parse_percent(const char *p) {
|
|||
return v;
|
||||
}
|
||||
|
||||
int parse_permille_unbounded(const char *p) {
|
||||
const char *pc, *pm, *dot, *n;
|
||||
int r, q, v;
|
||||
|
||||
pm = endswith(p, "‰");
|
||||
if (pm) {
|
||||
n = strndupa(p, pm - p);
|
||||
r = safe_atoi(n, &v);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else {
|
||||
pc = endswith(p, "%");
|
||||
if (!pc)
|
||||
return -EINVAL;
|
||||
|
||||
dot = memchr(p, '.', pc - p);
|
||||
if (dot) {
|
||||
if (dot + 2 != pc)
|
||||
return -EINVAL;
|
||||
if (dot[1] < '0' || dot[1] > '9')
|
||||
return -EINVAL;
|
||||
q = dot[1] - '0';
|
||||
n = strndupa(p, dot - p);
|
||||
} else {
|
||||
q = 0;
|
||||
n = strndupa(p, pc - p);
|
||||
}
|
||||
r = safe_atoi(n, &v);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (v > ((INT_MAX - q) / 10))
|
||||
return -ERANGE;
|
||||
|
||||
v = v * 10 + q;
|
||||
}
|
||||
|
||||
if (v < 0)
|
||||
return -ERANGE;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
int parse_permille(const char *p) {
|
||||
int v;
|
||||
|
||||
v = parse_permille_unbounded(p);
|
||||
if (v > 1000)
|
||||
return -ERANGE;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
int parse_nice(const char *p, int *ret) {
|
||||
int n, r;
|
||||
|
||||
|
|
|
@ -115,6 +115,9 @@ int parse_fractional_part_u(const char **s, size_t digits, unsigned *res);
|
|||
int parse_percent_unbounded(const char *p);
|
||||
int parse_percent(const char *p);
|
||||
|
||||
int parse_permille_unbounded(const char *p);
|
||||
int parse_permille(const char *p);
|
||||
|
||||
int parse_nice(const char *p, int *ret);
|
||||
|
||||
int parse_ip_port(const char *s, uint16_t *ret);
|
||||
|
|
|
@ -648,6 +648,54 @@ static void test_parse_percent_unbounded(void) {
|
|||
assert_se(parse_percent_unbounded("400%") == 400);
|
||||
}
|
||||
|
||||
static void test_parse_permille(void) {
|
||||
assert_se(parse_permille("") == -EINVAL);
|
||||
assert_se(parse_permille("foo") == -EINVAL);
|
||||
assert_se(parse_permille("0") == -EINVAL);
|
||||
assert_se(parse_permille("50") == -EINVAL);
|
||||
assert_se(parse_permille("100") == -EINVAL);
|
||||
assert_se(parse_permille("-1") == -EINVAL);
|
||||
|
||||
assert_se(parse_permille("0‰") == 0);
|
||||
assert_se(parse_permille("555‰") == 555);
|
||||
assert_se(parse_permille("1000‰") == 1000);
|
||||
assert_se(parse_permille("-7‰") == -ERANGE);
|
||||
assert_se(parse_permille("1007‰") == -ERANGE);
|
||||
assert_se(parse_permille("‰") == -EINVAL);
|
||||
assert_se(parse_permille("‰‰") == -EINVAL);
|
||||
assert_se(parse_permille("‰1") == -EINVAL);
|
||||
assert_se(parse_permille("1‰‰") == -EINVAL);
|
||||
assert_se(parse_permille("3.2‰") == -EINVAL);
|
||||
|
||||
assert_se(parse_permille("0%") == 0);
|
||||
assert_se(parse_permille("55%") == 550);
|
||||
assert_se(parse_permille("55.5%") == 555);
|
||||
assert_se(parse_permille("100%") == 1000);
|
||||
assert_se(parse_permille("-7%") == -ERANGE);
|
||||
assert_se(parse_permille("107%") == -ERANGE);
|
||||
assert_se(parse_permille("%") == -EINVAL);
|
||||
assert_se(parse_permille("%%") == -EINVAL);
|
||||
assert_se(parse_permille("%1") == -EINVAL);
|
||||
assert_se(parse_permille("1%%") == -EINVAL);
|
||||
assert_se(parse_permille("3.21%") == -EINVAL);
|
||||
}
|
||||
|
||||
static void test_parse_permille_unbounded(void) {
|
||||
assert_se(parse_permille_unbounded("1001‰") == 1001);
|
||||
assert_se(parse_permille_unbounded("4000‰") == 4000);
|
||||
assert_se(parse_permille_unbounded("2147483647‰") == 2147483647);
|
||||
assert_se(parse_permille_unbounded("2147483648‰") == -ERANGE);
|
||||
assert_se(parse_permille_unbounded("4294967295‰") == -ERANGE);
|
||||
assert_se(parse_permille_unbounded("4294967296‰") == -ERANGE);
|
||||
|
||||
assert_se(parse_permille_unbounded("101%") == 1010);
|
||||
assert_se(parse_permille_unbounded("400%") == 4000);
|
||||
assert_se(parse_permille_unbounded("214748364.7%") == 2147483647);
|
||||
assert_se(parse_permille_unbounded("214748364.8%") == -ERANGE);
|
||||
assert_se(parse_permille_unbounded("429496729.5%") == -ERANGE);
|
||||
assert_se(parse_permille_unbounded("429496729.6%") == -ERANGE);
|
||||
}
|
||||
|
||||
static void test_parse_nice(void) {
|
||||
int n;
|
||||
|
||||
|
@ -797,6 +845,8 @@ int main(int argc, char *argv[]) {
|
|||
test_safe_atod();
|
||||
test_parse_percent();
|
||||
test_parse_percent_unbounded();
|
||||
test_parse_permille();
|
||||
test_parse_permille_unbounded();
|
||||
test_parse_nice();
|
||||
test_parse_dev();
|
||||
test_parse_errno();
|
||||
|
|
Loading…
Reference in New Issue