mirror of
https://github.com/neovim/neovim.git
synced 2025-09-29 22:48:34 +00:00
charset: Some more refactoring of vim_str2nr
This commit is contained in:
@@ -1656,18 +1656,19 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
|
|||||||
// decimal or octal, default is decimal
|
// decimal or octal, default is decimal
|
||||||
pre = 0;
|
pre = 0;
|
||||||
|
|
||||||
if (what & STR2NR_OCT) {
|
if (what & STR2NR_OCT
|
||||||
// Don't interpret "0", "08" or "0129" as octal.
|
&& !STRING_ENDED(ptr + 1)
|
||||||
for (int i = 1; !STRING_ENDED(ptr + i) && ascii_isdigit(ptr[i]); i++) {
|
&& ('0' <= ptr[1] && ptr[1] <= '7')) {
|
||||||
|
// Assume octal now: what we already know is that string starts with
|
||||||
|
// zero and some octal digit.
|
||||||
|
pre = '0';
|
||||||
|
// Don’t interpret "0", "008" or "0129" as octal.
|
||||||
|
for (int i = 2; !STRING_ENDED(ptr + i) && ascii_isdigit(ptr[i]); i++) {
|
||||||
if (ptr[i] > '7') {
|
if (ptr[i] > '7') {
|
||||||
// can't be octal
|
// Can’t be octal.
|
||||||
pre = 0;
|
pre = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ptr[i] >= '0') {
|
|
||||||
// assume octal
|
|
||||||
pre = '0';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1675,51 +1676,32 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
|
|||||||
|
|
||||||
// Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
|
// Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
|
||||||
uvarnumber_T un = 0;
|
uvarnumber_T un = 0;
|
||||||
|
#define PARSE_NUMBER(base, cond, conv) \
|
||||||
|
do { \
|
||||||
|
while (!STRING_ENDED(ptr) && (cond)) { \
|
||||||
|
/* avoid ubsan error for overflow */ \
|
||||||
|
if (un < UVARNUMBER_MAX / base) { \
|
||||||
|
un = base * un + (uvarnumber_T)(conv); \
|
||||||
|
} else { \
|
||||||
|
un = UVARNUMBER_MAX; \
|
||||||
|
} \
|
||||||
|
ptr++; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
if (pre == 'B' || pre == 'b' || what == (STR2NR_BIN|STR2NR_FORCE)) {
|
if (pre == 'B' || pre == 'b' || what == (STR2NR_BIN|STR2NR_FORCE)) {
|
||||||
// bin
|
// Binary number.
|
||||||
while (!STRING_ENDED(ptr) && '0' <= *ptr && *ptr <= '1') {
|
PARSE_NUMBER(2, (*ptr == '0' || *ptr == '1'), (*ptr - '0'));
|
||||||
// avoid ubsan error for overflow
|
|
||||||
if (un < UVARNUMBER_MAX / 2) {
|
|
||||||
un = 2 * un + (uvarnumber_T)(*ptr - '0');
|
|
||||||
} else {
|
|
||||||
un = UVARNUMBER_MAX;
|
|
||||||
}
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
} else if (pre == '0' || what == (STR2NR_OCT|STR2NR_FORCE)) {
|
} else if (pre == '0' || what == (STR2NR_OCT|STR2NR_FORCE)) {
|
||||||
// octal
|
// Octal number.
|
||||||
while (!STRING_ENDED(ptr) && '0' <= *ptr && *ptr <= '7') {
|
PARSE_NUMBER(8, ('0' <= *ptr && *ptr <= '7'), (*ptr - '0'));
|
||||||
// avoid ubsan error for overflow
|
|
||||||
if (un < UVARNUMBER_MAX / 8) {
|
|
||||||
un = 8 * un + (uvarnumber_T)(*ptr - '0');
|
|
||||||
} else {
|
|
||||||
un = UVARNUMBER_MAX;
|
|
||||||
}
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
} else if (pre == 'X' || pre == 'x' || what == (STR2NR_HEX|STR2NR_FORCE)) {
|
} else if (pre == 'X' || pre == 'x' || what == (STR2NR_HEX|STR2NR_FORCE)) {
|
||||||
// hex
|
// Hexadecimal number.
|
||||||
while (!STRING_ENDED(ptr) && ascii_isxdigit(*ptr)) {
|
PARSE_NUMBER(16, (ascii_isxdigit(*ptr)), (hex2nr(*ptr)));
|
||||||
// avoid ubsan error for overflow
|
|
||||||
if (un < UVARNUMBER_MAX / 16) {
|
|
||||||
un = 16 * un + (uvarnumber_T)hex2nr(*ptr);
|
|
||||||
} else {
|
|
||||||
un = UVARNUMBER_MAX;
|
|
||||||
}
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// decimal
|
// Decimal number.
|
||||||
while (!STRING_ENDED(ptr) && ascii_isdigit(*ptr)) {
|
PARSE_NUMBER(10, (ascii_isdigit(*ptr)), (*ptr - '0'));
|
||||||
// avoid ubsan error for overflow
|
|
||||||
if (un < UVARNUMBER_MAX / 10) {
|
|
||||||
un = 10 * un + (uvarnumber_T)(*ptr - '0');
|
|
||||||
} else {
|
|
||||||
un = UVARNUMBER_MAX;
|
|
||||||
}
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#undef PARSE_NUMBER
|
||||||
|
|
||||||
if (prep != NULL) {
|
if (prep != NULL) {
|
||||||
*prep = pre;
|
*prep = pre;
|
||||||
|
@@ -77,6 +77,8 @@ static char *features[] = {
|
|||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const int included_patches[] = {
|
static const int included_patches[] = {
|
||||||
|
1229,
|
||||||
|
1230,
|
||||||
// 1026,
|
// 1026,
|
||||||
1025,
|
1025,
|
||||||
1024,
|
1024,
|
||||||
|
Reference in New Issue
Block a user