MINOR: tools: make parse_size_err() support 32/64 bits

parse_size_err() currently is a function working only on an uint. It's
not convenient for certain elements such as rings on large machines.

This commit addresses this by having one function for uints and one
for ullong, and making parse_size_err() a macro that automatically
calls one or the other. It also has the benefit of automatically
supporting compatible types (long, size_t etc).
This commit is contained in:
Willy Tarreau 2024-11-19 09:15:19 +01:00
parent 9c6ccb8dbb
commit 82f190f882
2 changed files with 92 additions and 2 deletions

View File

@ -642,7 +642,26 @@ extern time_t my_timegm(const struct tm *tm);
* <ret> is left untouched.
*/
extern const char *parse_time_err(const char *text, unsigned *ret, unsigned unit_flags);
extern const char *parse_size_err(const char *text, unsigned *ret);
extern const char *parse_size_ui(const char *text, unsigned *ret);
extern const char *parse_size_ull(const char *text, ullong *ret);
/* Parse a size from <_test> into <_ret> which must be compatible with a
* uint or ullong. The return value is a pointer to the first unparsable
* character (if any) or NULL if everything's OK.
*/
#define parse_size_err(_text, _ret) ({ \
const char *_err; \
if (sizeof(*(_ret)) > sizeof(int)) { \
unsigned long long _tmp; \
_err = parse_size_ull(_text, &_tmp); \
*_ret = _tmp; \
} else { \
unsigned int _tmp; \
_err = parse_size_ui(_text, &_tmp); \
*_ret = _tmp; \
} \
_err; \
})
/*
* Parse binary string written in hexadecimal (source) and store the decoded

View File

@ -2780,7 +2780,8 @@ const char *parse_time_err(const char *text, unsigned *ret, unsigned unit_flags)
* stored in <ret>. If an error is detected, the pointer to the unexpected
* character is returned. If the conversion is successful, NULL is returned.
*/
const char *parse_size_err(const char *text, unsigned *ret) {
const char *parse_size_ui(const char *text, unsigned *ret)
{
unsigned value = 0;
if (!isdigit((unsigned char)*text))
@ -2833,6 +2834,76 @@ const char *parse_size_err(const char *text, unsigned *ret) {
return NULL;
}
/* this function converts the string starting at <text> to an ullong stored in
* <ret>. If an error is detected, the pointer to the unexpected character is
* returned. If the conversion is successful, NULL is returned.
*/
const char *parse_size_ull(const char *text, ullong *ret)
{
ullong value = 0;
if (!isdigit((unsigned char)*text))
return text;
while (1) {
unsigned int j;
j = *text - '0';
if (j > 9)
break;
if (value > ~0ULL / 10)
return text;
value *= 10;
if (value > (value + j))
return text;
value += j;
text++;
}
switch (*text) {
case '\0':
break;
case 'K':
case 'k':
if (value > ~0ULL >> 10)
return text;
value = value << 10;
break;
case 'M':
case 'm':
if (value > ~0ULL >> 20)
return text;
value = value << 20;
break;
case 'G':
case 'g':
if (value > ~0ULL >> 30)
return text;
value = value << 30;
break;
case 'T':
case 't':
if (value > ~0ULL >> 40)
return text;
value = value << 40;
break;
case 'P':
case 'p':
if (value > ~0ULL >> 50)
return text;
value = value << 50;
break;
default:
return text;
}
if (*text != '\0' && *++text != '\0')
return text;
*ret = value;
return NULL;
}
/*
* Parse binary string written in hexadecimal (source) and store the decoded
* result into binstr and set binstrlen to the length of binstr. Memory for