network: use a common helper to parse bounded ranges

This compresses repetetive code and makes it easier to add new options
in networkd. The formatting of error messages becomes uniform. The
error message always specifies the rvalue literally, instead of using
a "descriptive name". This makes the message much easier to handle for
the user.

I opted to add just one parser, and wrap it with inline functions to proxy
the type. This is less verbose than copying functions for each type
separately, and the compiler should be able to get rid of the inline wrapper
almost entirely.

asserts are reordered to use the same order as the parameter list.
This makes the code easier to read.

No functional change intended, apart from the difference in error message
formatting.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2023-09-22 08:16:47 +02:00
parent 3b6cabd806
commit 851cdffd1b
8 changed files with 220 additions and 249 deletions
+38
View File
@@ -1908,6 +1908,44 @@ int config_parse_in_addr_non_null(
return 0;
}
int config_parse_unsigned_bounded(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *name,
const char *value,
unsigned min,
unsigned max,
bool ignoring,
unsigned *ret) {
int r;
assert(filename);
assert(name);
assert(value);
assert(ret);
r = safe_atou_bounded(value, min, max, ret);
if (r == -ERANGE)
log_syntax(unit, LOG_WARNING, filename, line, r,
"Invalid '%s=%s', allowed range is %u..%u%s.",
name, value, min, max, ignoring ? ", ignoring" : "");
else if (r < 0)
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse '%s=%s'%s: %m",
name, value, ignoring ? ", ignoring" : "");
if (r >= 0)
return 1; /* Return 1 if something was set */
else if (ignoring)
return 0;
else
return r;
}
DEFINE_CONFIG_PARSE(config_parse_percent, parse_percent, "Failed to parse percent value");
DEFINE_CONFIG_PARSE(config_parse_permyriad, parse_permyriad, "Failed to parse permyriad value");
DEFINE_CONFIG_PARSE_PTR(config_parse_sec_fix_0, parse_sec_fix_0, usec_t, "Failed to parse time value");
+94
View File
@@ -385,3 +385,97 @@ typedef enum ConfigParseStringFlags {
\
return free_and_replace(*enums, xs); \
}
int config_parse_unsigned_bounded(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *name,
const char *value,
unsigned min,
unsigned max,
bool ignoring,
unsigned *ret);
static inline int config_parse_uint32_bounded(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *name,
const char *value,
uint32_t min,
uint32_t max,
bool ignoring,
uint32_t *ret) {
unsigned t;
int r;
r = config_parse_unsigned_bounded(
unit, filename, line, section, section_line, name, value,
min, max, ignoring,
&t);
if (r <= 0)
return r;
assert(t <= UINT32_MAX);
*ret = t;
return 1;
}
static inline int config_parse_uint16_bounded(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *name,
const char *value,
uint16_t min,
uint16_t max,
bool ignoring,
uint16_t *ret) {
unsigned t;
int r;
r = config_parse_unsigned_bounded(
unit, filename, line, section, section_line, name, value,
min, max, ignoring,
&t);
if (r <= 0)
return r;
assert(t <= UINT16_MAX);
*ret = t;
return 1;
}
static inline int config_parse_uint8_bounded(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *name,
const char *value,
uint8_t min,
uint8_t max,
bool ignoring,
uint8_t *ret) {
unsigned t;
int r;
r = config_parse_unsigned_bounded(
unit, filename, line, section, section_line, name, value,
min, max, ignoring,
&t);
if (r <= 0)
return r;
assert(t <= UINT8_MAX);
*ret = t;
return 1;
}