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
committerSven Eden <yamakuzure@gmx.net>2018-08-24 16:47:08 +0200
commit14db62d166679aa43ac4a6d050d79aa9c7b301d7 (patch)
tree1113bb6f16ee4bb381e8717a6e325f332271f87c /src/basic/parse-util.c
parentdad68a6342f86f817e07187ea06b44d2f0c90321 (diff)
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 e9bd8ade1..53e030efc 100644
--- a/src/basic/parse-util.c
+++ b/src/basic/parse-util.c
@@ -637,6 +637,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;
+}
+
#if 0 /// UNNEEDED by elogind
int parse_nice(const char *p, int *ret) {
int n, r;