mirror of
https://github.com/neovim/neovim.git
synced 2025-09-16 08:18:17 +00:00
Add support for binary numbers
This commit is contained in:
@@ -1454,6 +1454,20 @@ char_u* skipdigits(char_u *q)
|
||||
return p;
|
||||
}
|
||||
|
||||
/// skip over binary digits
|
||||
///
|
||||
/// @param q
|
||||
///
|
||||
/// @return Pointer to the character after the skipped digits.
|
||||
char_u* skipbin(char_u *q)
|
||||
{
|
||||
char_u *p = q;
|
||||
|
||||
while (ascii_isbdigit(*p)) /* skip to next non-digit */
|
||||
++p;
|
||||
return p;
|
||||
}
|
||||
|
||||
/// skip over digits and hex characters
|
||||
///
|
||||
/// @param q
|
||||
@@ -1485,6 +1499,20 @@ char_u* skiptodigit(char_u *q)
|
||||
return p;
|
||||
}
|
||||
|
||||
/// skip to binary character (or NUL after the string)
|
||||
///
|
||||
/// @param q
|
||||
///
|
||||
/// @return Pointer to the binary character or (NUL after the string).
|
||||
char_u* skiptobin(char_u *q)
|
||||
{
|
||||
char_u *p = q;
|
||||
|
||||
while (*p != NUL && !ascii_isbdigit(*p)) /* skip to next digit */
|
||||
++p;
|
||||
return p;
|
||||
}
|
||||
|
||||
/// skip to hex character (or NUL after the string)
|
||||
///
|
||||
/// @param q
|
||||
@@ -1720,33 +1748,38 @@ int vim_isblankline(char_u *lbuf)
|
||||
}
|
||||
|
||||
/// Convert a string into a long and/or unsigned long, taking care of
|
||||
/// hexadecimal and octal numbers. Accepts a '-' sign.
|
||||
/// If "hexp" is not NULL, returns a flag to indicate the type of the number:
|
||||
/// hexadecimal, octal and binary numbers. Accepts a '-' sign.
|
||||
/// If "prep" is not NULL, returns a flag to indicate the type of the number:
|
||||
/// 0 decimal
|
||||
/// '0' octal
|
||||
/// 'B' bin
|
||||
/// 'b' bin
|
||||
/// 'X' hex
|
||||
/// 'x' hex
|
||||
/// If "len" is not NULL, the length of the number in characters is returned.
|
||||
/// If "nptr" is not NULL, the signed result is returned in it.
|
||||
/// If "unptr" is not NULL, the unsigned result is returned in it.
|
||||
/// If "dobin" is non-zero recognize binary numbers, when > 1 always assume
|
||||
/// binary number.
|
||||
/// If "dooct" is non-zero recognize octal numbers, when > 1 always assume
|
||||
/// octal number.
|
||||
/// If "dohex" is non-zero recognize hex numbers, when > 1 always assume
|
||||
/// hex number.
|
||||
///
|
||||
/// @param start
|
||||
/// @param hexp Returns type of number 0 = decimal, 'x' or 'X' is hex,
|
||||
// '0' = octal
|
||||
/// @param prep Returns type of number 0 = decimal, 'x' or 'X' is hex,
|
||||
// '0' = octal, 'b' or 'B' is bin
|
||||
/// @param len Returns the detected length of number.
|
||||
/// @param dobin recognize binary number
|
||||
/// @param dooct recognize octal number
|
||||
/// @param dohex recognize hex number
|
||||
/// @param nptr Returns the signed result.
|
||||
/// @param unptr Returns the unsigned result.
|
||||
void vim_str2nr(char_u *start, int *hexp, int *len, int dooct, int dohex,
|
||||
void vim_str2nr(char_u *start, int *prep, int *len, int dobin, int dooct, int dohex,
|
||||
long *nptr, unsigned long *unptr)
|
||||
{
|
||||
char_u *ptr = start;
|
||||
int hex = 0; // default is decimal
|
||||
int pre = 0; // default is decimal
|
||||
int negative = FALSE;
|
||||
unsigned long un = 0;
|
||||
int n;
|
||||
@@ -1756,31 +1789,35 @@ void vim_str2nr(char_u *start, int *hexp, int *len, int dooct, int dohex,
|
||||
++ptr;
|
||||
}
|
||||
|
||||
// Recognize hex and octal.
|
||||
// Recognize hex, octal, and bin.
|
||||
if ((ptr[0] == '0') && (ptr[1] != '8') && (ptr[1] != '9')) {
|
||||
hex = ptr[1];
|
||||
pre = ptr[1];
|
||||
|
||||
if (dohex
|
||||
&& ((hex == 'X') || (hex == 'x'))
|
||||
&& ((pre == 'X') || (pre == 'x'))
|
||||
&& ascii_isxdigit(ptr[2])) {
|
||||
// hexadecimal
|
||||
ptr += 2;
|
||||
} else if (dobin
|
||||
&& ((pre == 'B') || (pre == 'b'))
|
||||
&& ascii_isbdigit(ptr[2])) {
|
||||
// binary
|
||||
ptr += 2;
|
||||
} else {
|
||||
// default is decimal
|
||||
hex = 0;
|
||||
pre = 0;
|
||||
|
||||
if (dooct) {
|
||||
// Don't interpret "0", "08" or "0129" as octal.
|
||||
for (n = 1; ascii_isdigit(ptr[n]); ++n) {
|
||||
if (ptr[n] > '7') {
|
||||
// can't be octal
|
||||
hex = 0;
|
||||
pre = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ptr[n] >= '0') {
|
||||
// assume octal
|
||||
hex = '0';
|
||||
pre = '0';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1788,28 +1825,38 @@ void vim_str2nr(char_u *start, int *hexp, int *len, int dooct, int dohex,
|
||||
}
|
||||
|
||||
// Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
|
||||
if ((hex == '0') || (dooct > 1)) {
|
||||
if ((pre == 'B') || (pre == 'b') || (dobin > 1)) {
|
||||
// bin
|
||||
if (pre != 0)
|
||||
n += 2; // skip over "0b"
|
||||
while ('0' <= *ptr && *ptr <= '1') {
|
||||
un = 2 * un + (unsigned long)(*ptr - '0');
|
||||
++ptr;
|
||||
}
|
||||
} else if ((pre == '0') || (dooct > 1)) {
|
||||
// octal
|
||||
while ('0' <= *ptr && *ptr <= '7') {
|
||||
un = 8 * un + (unsigned long)(*ptr - '0');
|
||||
ptr++;
|
||||
}
|
||||
} else if ((hex != 0) || (dohex > 1)) {
|
||||
} else if (pre != 0 || dohex > 1) {
|
||||
// hex
|
||||
if (pre != 0)
|
||||
n += 2; // skip over "0x"
|
||||
while (ascii_isxdigit(*ptr)) {
|
||||
un = 16 * un + (unsigned long)hex2nr(*ptr);
|
||||
ptr++;
|
||||
++ptr;
|
||||
}
|
||||
} else {
|
||||
// decimal
|
||||
while (ascii_isdigit(*ptr)) {
|
||||
un = 10 * un + (unsigned long)(*ptr - '0');
|
||||
ptr++;
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (hexp != NULL) {
|
||||
*hexp = hex;
|
||||
if (prep != NULL) {
|
||||
*prep = pre;
|
||||
}
|
||||
|
||||
if (len != NULL) {
|
||||
|
Reference in New Issue
Block a user