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.
This commit is contained in:
+51
-5
@@ -352,6 +352,32 @@ int parse_syscall_and_errno(const char *in, char **name, int *error) {
|
|||||||
return 0;
|
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) {
|
int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
||||||
char *x = NULL;
|
char *x = NULL;
|
||||||
unsigned long l;
|
unsigned long l;
|
||||||
@@ -383,6 +409,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
|
return -EINVAL; /* This is particularly useful to avoid ambiguities between C's octal
|
||||||
* notation and assumed-to-be-decimal integers with a leading zero. */
|
* notation and assumed-to-be-decimal integers with a leading zero. */
|
||||||
|
|
||||||
|
s = mangle_base(s, &base);
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base) /* Let's mask off the flags bits so that only the actual
|
l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base) /* Let's mask off the flags bits so that only the actual
|
||||||
* base is left */);
|
* base is left */);
|
||||||
@@ -402,13 +430,17 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int safe_atoi(const char *s, int *ret_i) {
|
int safe_atoi(const char *s, int *ret_i) {
|
||||||
|
unsigned base = 0;
|
||||||
char *x = NULL;
|
char *x = NULL;
|
||||||
long l;
|
long l;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
|
s += strspn(s, WHITESPACE);
|
||||||
|
s = mangle_base(s, &base);
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
l = strtol(s, &x, 0);
|
l = strtol(s, &x, base);
|
||||||
if (errno > 0)
|
if (errno > 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (!x || x == s || *x != 0)
|
if (!x || x == s || *x != 0)
|
||||||
@@ -443,6 +475,8 @@ int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu)
|
|||||||
s[0] == '0' && s[1] != 0)
|
s[0] == '0' && s[1] != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
s = mangle_base(s, &base);
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
l = strtoull(s, &x, SAFE_ATO_MASK_FLAGS(base));
|
l = strtoull(s, &x, SAFE_ATO_MASK_FLAGS(base));
|
||||||
if (errno > 0)
|
if (errno > 0)
|
||||||
@@ -459,13 +493,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) {
|
int safe_atolli(const char *s, long long int *ret_lli) {
|
||||||
|
unsigned base = 0;
|
||||||
char *x = NULL;
|
char *x = NULL;
|
||||||
long long l;
|
long long l;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
|
s += strspn(s, WHITESPACE);
|
||||||
|
s = mangle_base(s, &base);
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
l = strtoll(s, &x, 0);
|
l = strtoll(s, &x, base);
|
||||||
if (errno > 0)
|
if (errno > 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (!x || x == s || *x != 0)
|
if (!x || x == s || *x != 0)
|
||||||
@@ -478,15 +516,17 @@ int safe_atolli(const char *s, long long int *ret_lli) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int safe_atou8(const char *s, uint8_t *ret) {
|
int safe_atou8(const char *s, uint8_t *ret) {
|
||||||
char *x = NULL;
|
unsigned base = 0;
|
||||||
unsigned long l;
|
unsigned long l;
|
||||||
|
char *x = NULL;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
s += strspn(s, WHITESPACE);
|
s += strspn(s, WHITESPACE);
|
||||||
|
s = mangle_base(s, &base);
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
l = strtoul(s, &x, 0);
|
l = strtoul(s, &x, base);
|
||||||
if (errno > 0)
|
if (errno > 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (!x || x == s || *x != 0)
|
if (!x || x == s || *x != 0)
|
||||||
@@ -522,6 +562,8 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) {
|
|||||||
s[0] == '0' && s[1] != 0)
|
s[0] == '0' && s[1] != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
s = mangle_base(s, &base);
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base));
|
l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base));
|
||||||
if (errno > 0)
|
if (errno > 0)
|
||||||
@@ -540,13 +582,17 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int safe_atoi16(const char *s, int16_t *ret) {
|
int safe_atoi16(const char *s, int16_t *ret) {
|
||||||
|
unsigned base = 0;
|
||||||
char *x = NULL;
|
char *x = NULL;
|
||||||
long l;
|
long l;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
|
s += strspn(s, WHITESPACE);
|
||||||
|
s = mangle_base(s, &base);
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
l = strtol(s, &x, 0);
|
l = strtol(s, &x, base);
|
||||||
if (errno > 0)
|
if (errno > 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (!x || x == s || *x != 0)
|
if (!x || x == s || *x != 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user