|
|
bd1529 |
From e67e29d91a1ef90af545e4130c7b4c4cfde6202a Mon Sep 17 00:00:00 2001
|
|
|
bd1529 |
From: Lennart Poettering <lennart@poettering.net>
|
|
|
bd1529 |
Date: Mon, 1 Jun 2020 17:31:51 +0200
|
|
|
bd1529 |
Subject: [PATCH] parse-util: also parse integers prefixed with 0b and 0o
|
|
|
bd1529 |
|
|
|
bd1529 |
Let's adopt Python 3 style 0b and 0x syntaxes, because it makes a ton of
|
|
|
bd1529 |
sense, in particular in bitmask settings.
|
|
|
bd1529 |
|
|
|
bd1529 |
(cherry picked from commit fc80cabcf584a8b486bdff5be0c074fec4059cdc)
|
|
|
bd1529 |
|
|
|
bd1529 |
Related: #1848373
|
|
|
bd1529 |
---
|
|
|
bd1529 |
src/basic/parse-util.c | 56 ++++++++++++++++++++++++++++++++++++++----
|
|
|
bd1529 |
1 file changed, 51 insertions(+), 5 deletions(-)
|
|
|
bd1529 |
|
|
|
bd1529 |
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
|
|
|
bd1529 |
index 68c156c543..992ea3605b 100644
|
|
|
bd1529 |
--- a/src/basic/parse-util.c
|
|
|
bd1529 |
+++ b/src/basic/parse-util.c
|
|
|
bd1529 |
@@ -17,6 +17,7 @@
|
|
|
bd1529 |
#include "parse-util.h"
|
|
|
bd1529 |
#include "process-util.h"
|
|
|
bd1529 |
#include "string-util.h"
|
|
|
bd1529 |
+#include "strv.h"
|
|
|
bd1529 |
|
|
|
bd1529 |
int parse_boolean(const char *v) {
|
|
|
bd1529 |
assert(v);
|
|
|
bd1529 |
@@ -373,7 +374,32 @@ char *format_bytes(char *buf, size_t l, uint64_t t) {
|
|
|
bd1529 |
finish:
|
|
|
bd1529 |
buf[l-1] = 0;
|
|
|
bd1529 |
return buf;
|
|
|
bd1529 |
+}
|
|
|
bd1529 |
+
|
|
|
bd1529 |
+static const char *mangle_base(const char *s, unsigned *base) {
|
|
|
bd1529 |
+ const char *k;
|
|
|
bd1529 |
+
|
|
|
bd1529 |
+ assert(s);
|
|
|
bd1529 |
+ assert(base);
|
|
|
bd1529 |
+
|
|
|
bd1529 |
+ /* Base already explicitly specified, then don't do anything. */
|
|
|
bd1529 |
+ if (SAFE_ATO_MASK_FLAGS(*base) != 0)
|
|
|
bd1529 |
+ return s;
|
|
|
bd1529 |
|
|
|
bd1529 |
+ /* Support Python 3 style "0b" and 0x" prefixes, because they truly make sense, much more than C's "0" prefix for octal. */
|
|
|
bd1529 |
+ k = STARTSWITH_SET(s, "0b", "0B");
|
|
|
bd1529 |
+ if (k) {
|
|
|
bd1529 |
+ *base = 2 | (*base & SAFE_ATO_ALL_FLAGS);
|
|
|
bd1529 |
+ return k;
|
|
|
bd1529 |
+ }
|
|
|
bd1529 |
+
|
|
|
bd1529 |
+ k = STARTSWITH_SET(s, "0o", "0O");
|
|
|
bd1529 |
+ if (k) {
|
|
|
bd1529 |
+ *base = 8 | (*base & SAFE_ATO_ALL_FLAGS);
|
|
|
bd1529 |
+ return k;
|
|
|
bd1529 |
+ }
|
|
|
bd1529 |
+
|
|
|
bd1529 |
+ return s;
|
|
|
bd1529 |
}
|
|
|
bd1529 |
|
|
|
bd1529 |
int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
|
|
bd1529 |
@@ -407,6 +433,8 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
|
|
bd1529 |
return -EINVAL; /* This is particularly useful to avoid ambiguities between C's octal
|
|
|
bd1529 |
* notation and assumed-to-be-decimal integers with a leading zero. */
|
|
|
bd1529 |
|
|
|
bd1529 |
+ s = mangle_base(s, &base);
|
|
|
bd1529 |
+
|
|
|
bd1529 |
errno = 0;
|
|
|
bd1529 |
l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base) /* Let's mask off the flags bits so that only the actual
|
|
|
bd1529 |
* base is left */);
|
|
|
bd1529 |
@@ -426,13 +454,17 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
|
|
bd1529 |
}
|
|
|
bd1529 |
|
|
|
bd1529 |
int safe_atoi(const char *s, int *ret_i) {
|
|
|
bd1529 |
+ unsigned base = 0;
|
|
|
bd1529 |
char *x = NULL;
|
|
|
bd1529 |
long l;
|
|
|
bd1529 |
|
|
|
bd1529 |
assert(s);
|
|
|
bd1529 |
|
|
|
bd1529 |
+ s += strspn(s, WHITESPACE);
|
|
|
bd1529 |
+ s = mangle_base(s, &base);
|
|
|
bd1529 |
+
|
|
|
bd1529 |
errno = 0;
|
|
|
bd1529 |
- l = strtol(s, &x, 0);
|
|
|
bd1529 |
+ l = strtol(s, &x, base);
|
|
|
bd1529 |
if (errno > 0)
|
|
|
bd1529 |
return -errno;
|
|
|
bd1529 |
if (!x || x == s || *x != 0)
|
|
|
bd1529 |
@@ -467,6 +499,8 @@ int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu)
|
|
|
bd1529 |
s[0] == '0' && s[1] != 0)
|
|
|
bd1529 |
return -EINVAL;
|
|
|
bd1529 |
|
|
|
bd1529 |
+ s = mangle_base(s, &base);
|
|
|
bd1529 |
+
|
|
|
bd1529 |
errno = 0;
|
|
|
bd1529 |
l = strtoull(s, &x, SAFE_ATO_MASK_FLAGS(base));
|
|
|
bd1529 |
if (errno > 0)
|
|
|
bd1529 |
@@ -483,13 +517,17 @@ int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu)
|
|
|
bd1529 |
}
|
|
|
bd1529 |
|
|
|
bd1529 |
int safe_atolli(const char *s, long long int *ret_lli) {
|
|
|
bd1529 |
+ unsigned base = 0;
|
|
|
bd1529 |
char *x = NULL;
|
|
|
bd1529 |
long long l;
|
|
|
bd1529 |
|
|
|
bd1529 |
assert(s);
|
|
|
bd1529 |
|
|
|
bd1529 |
+ s += strspn(s, WHITESPACE);
|
|
|
bd1529 |
+ s = mangle_base(s, &base);
|
|
|
bd1529 |
+
|
|
|
bd1529 |
errno = 0;
|
|
|
bd1529 |
- l = strtoll(s, &x, 0);
|
|
|
bd1529 |
+ l = strtoll(s, &x, base);
|
|
|
bd1529 |
if (errno > 0)
|
|
|
bd1529 |
return -errno;
|
|
|
bd1529 |
if (!x || x == s || *x != 0)
|
|
|
bd1529 |
@@ -502,15 +540,17 @@ int safe_atolli(const char *s, long long int *ret_lli) {
|
|
|
bd1529 |
}
|
|
|
bd1529 |
|
|
|
bd1529 |
int safe_atou8(const char *s, uint8_t *ret) {
|
|
|
bd1529 |
- char *x = NULL;
|
|
|
bd1529 |
+ unsigned base = 0;
|
|
|
bd1529 |
unsigned long l;
|
|
|
bd1529 |
+ char *x = NULL;
|
|
|
bd1529 |
|
|
|
bd1529 |
assert(s);
|
|
|
bd1529 |
|
|
|
bd1529 |
s += strspn(s, WHITESPACE);
|
|
|
bd1529 |
+ s = mangle_base(s, &base);
|
|
|
bd1529 |
|
|
|
bd1529 |
errno = 0;
|
|
|
bd1529 |
- l = strtoul(s, &x, 0);
|
|
|
bd1529 |
+ l = strtoul(s, &x, base);
|
|
|
bd1529 |
if (errno > 0)
|
|
|
bd1529 |
return -errno;
|
|
|
bd1529 |
if (!x || x == s || *x != 0)
|
|
|
bd1529 |
@@ -546,6 +586,8 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) {
|
|
|
bd1529 |
s[0] == '0' && s[1] != 0)
|
|
|
bd1529 |
return -EINVAL;
|
|
|
bd1529 |
|
|
|
bd1529 |
+ s = mangle_base(s, &base);
|
|
|
bd1529 |
+
|
|
|
bd1529 |
errno = 0;
|
|
|
bd1529 |
l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base));
|
|
|
bd1529 |
if (errno > 0)
|
|
|
bd1529 |
@@ -564,13 +606,17 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) {
|
|
|
bd1529 |
}
|
|
|
bd1529 |
|
|
|
bd1529 |
int safe_atoi16(const char *s, int16_t *ret) {
|
|
|
bd1529 |
+ unsigned base = 0;
|
|
|
bd1529 |
char *x = NULL;
|
|
|
bd1529 |
long l;
|
|
|
bd1529 |
|
|
|
bd1529 |
assert(s);
|
|
|
bd1529 |
|
|
|
bd1529 |
+ s += strspn(s, WHITESPACE);
|
|
|
bd1529 |
+ s = mangle_base(s, &base);
|
|
|
bd1529 |
+
|
|
|
bd1529 |
errno = 0;
|
|
|
bd1529 |
- l = strtol(s, &x, 0);
|
|
|
bd1529 |
+ l = strtol(s, &x, base);
|
|
|
bd1529 |
if (errno > 0)
|
|
|
bd1529 |
return -errno;
|
|
|
bd1529 |
if (!x || x == s || *x != 0)
|