166 lines
5.0 KiB
Diff
166 lines
5.0 KiB
Diff
From fc80cabcf584a8b486bdff5be0c074fec4059cdc Mon Sep 17 00:00:00 2001
|
|
From: Lennart Poettering <lennart@poettering.net>
|
|
Date: Mon, 1 Jun 2020 17:31:51 +0200
|
|
Subject: [PATCH] parse-util: also parse integers prefixed with 0b and 0o
|
|
|
|
Let's adopt Python 3 style 0b and 0x syntaxes, because it makes a ton of
|
|
sense, in particular in bitmask settings.
|
|
Reference: https://github.com/systemd/systemd/commit/fc80cabcf584a8b486bdff5be0c074fec4059cdc
|
|
Conflict: Also include strv.h.
|
|
---
|
|
src/basic/parse-util.c | 57 ++++++++++++++++++++++++++++++++++++++----
|
|
1 file changed, 52 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
|
|
index b4c7f0d..bf56410 100644
|
|
--- a/src/basic/parse-util.c
|
|
+++ b/src/basic/parse-util.c
|
|
@@ -20,6 +20,7 @@
|
|
#include "process-util.h"
|
|
#include "stat-util.h"
|
|
#include "string-util.h"
|
|
+#include "strv.h"
|
|
|
|
int parse_boolean(const char *v) {
|
|
if (!v)
|
|
@@ -360,6 +361,32 @@ int parse_syscall_and_errno(const char *in, char **name, int *error) {
|
|
return 0;
|
|
}
|
|
|
|
+static const char *mangle_base(const char *s, unsigned *base) {
|
|
+ const char *k;
|
|
+
|
|
+ assert(s);
|
|
+ assert(base);
|
|
+
|
|
+ /* Base already explicitly specified, then don't do anything. */
|
|
+ if (SAFE_ATO_MASK_FLAGS(*base) != 0)
|
|
+ return s;
|
|
+
|
|
+ /* Support Python 3 style "0b" and 0x" prefixes, because they truly make sense, much more than C's "0" prefix for octal. */
|
|
+ k = STARTSWITH_SET(s, "0b", "0B");
|
|
+ if (k) {
|
|
+ *base = 2 | (*base & SAFE_ATO_ALL_FLAGS);
|
|
+ return k;
|
|
+ }
|
|
+
|
|
+ k = STARTSWITH_SET(s, "0o", "0O");
|
|
+ if (k) {
|
|
+ *base = 8 | (*base & SAFE_ATO_ALL_FLAGS);
|
|
+ return k;
|
|
+ }
|
|
+
|
|
+ return s;
|
|
+}
|
|
+
|
|
int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
|
char *x = NULL;
|
|
unsigned long l;
|
|
@@ -391,6 +418,8 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
|
return -EINVAL; /* This is particularly useful to avoid ambiguities between C's octal
|
|
* notation and assumed-to-be-decimal integers with a leading zero. */
|
|
|
|
+ s = mangle_base(s, &base);
|
|
+
|
|
errno = 0;
|
|
l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base) /* Let's mask off the flags bits so that only the actual
|
|
* base is left */);
|
|
@@ -410,13 +439,17 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
|
}
|
|
|
|
int safe_atoi(const char *s, int *ret_i) {
|
|
+ unsigned base = 0;
|
|
char *x = NULL;
|
|
long l;
|
|
|
|
assert(s);
|
|
|
|
+ s += strspn(s, WHITESPACE);
|
|
+ s = mangle_base(s, &base);
|
|
+
|
|
errno = 0;
|
|
- l = strtol(s, &x, 0);
|
|
+ l = strtol(s, &x, base);
|
|
if (errno > 0)
|
|
return -errno;
|
|
if (!x || x == s || *x != 0)
|
|
@@ -451,6 +484,8 @@ int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu)
|
|
s[0] == '0' && s[1] != 0)
|
|
return -EINVAL;
|
|
|
|
+ s = mangle_base(s, &base);
|
|
+
|
|
errno = 0;
|
|
l = strtoull(s, &x, SAFE_ATO_MASK_FLAGS(base));
|
|
if (errno > 0)
|
|
@@ -467,13 +502,17 @@ int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu)
|
|
}
|
|
|
|
int safe_atolli(const char *s, long long int *ret_lli) {
|
|
+ unsigned base = 0;
|
|
char *x = NULL;
|
|
long long l;
|
|
|
|
assert(s);
|
|
|
|
+ s += strspn(s, WHITESPACE);
|
|
+ s = mangle_base(s, &base);
|
|
+
|
|
errno = 0;
|
|
- l = strtoll(s, &x, 0);
|
|
+ l = strtoll(s, &x, base);
|
|
if (errno > 0)
|
|
return -errno;
|
|
if (!x || x == s || *x != 0)
|
|
@@ -486,15 +525,17 @@ int safe_atolli(const char *s, long long int *ret_lli) {
|
|
}
|
|
|
|
int safe_atou8(const char *s, uint8_t *ret) {
|
|
- char *x = NULL;
|
|
+ unsigned base = 0;
|
|
unsigned long l;
|
|
+ char *x = NULL;
|
|
|
|
assert(s);
|
|
|
|
s += strspn(s, WHITESPACE);
|
|
+ s = mangle_base(s, &base);
|
|
|
|
errno = 0;
|
|
- l = strtoul(s, &x, 0);
|
|
+ l = strtoul(s, &x, base);
|
|
if (errno > 0)
|
|
return -errno;
|
|
if (!x || x == s || *x != 0)
|
|
@@ -530,6 +571,8 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) {
|
|
s[0] == '0' && s[1] != 0)
|
|
return -EINVAL;
|
|
|
|
+ s = mangle_base(s, &base);
|
|
+
|
|
errno = 0;
|
|
l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base));
|
|
if (errno > 0)
|
|
@@ -548,13 +591,17 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) {
|
|
}
|
|
|
|
int safe_atoi16(const char *s, int16_t *ret) {
|
|
+ unsigned base = 0;
|
|
char *x = NULL;
|
|
long l;
|
|
|
|
assert(s);
|
|
|
|
+ s += strspn(s, WHITESPACE);
|
|
+ s = mangle_base(s, &base);
|
|
+
|
|
errno = 0;
|
|
- l = strtol(s, &x, 0);
|
|
+ l = strtol(s, &x, base);
|
|
if (errno > 0)
|
|
return -errno;
|
|
if (!x || x == s || *x != 0)
|
|
--
|
|
2.23.0
|
|
|