summaryrefslogtreecommitdiff
path: root/src/basic/parse-util.c
diff options
context:
space:
mode:
authorMarc Kleine-Budde <mkl@pengutronix.de>2018-06-05 15:15:33 +0200
committerMarc Kleine-Budde <mkl@pengutronix.de>2018-06-09 15:12:31 +0200
commit958acea18b8316c1ba9ec752b83f831c1a95c85f (patch)
tree3011e46d264ffdfa744abecdd5f5098d389c140a /src/basic/parse-util.c
parent194c03c839b23261d005d3b3a8ab197be53492a7 (diff)
downloadsystemd-958acea18b8316c1ba9ec752b83f831c1a95c85f.tar.gz
parse-util: add permille parser + tests
Diffstat (limited to 'src/basic/parse-util.c')
-rw-r--r--src/basic/parse-util.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
index 07f43b94e5..b25bc6e215 100644
--- a/src/basic/parse-util.c
+++ b/src/basic/parse-util.c
@@ -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;