mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Add support for binary numbers
This commit is contained in:
parent
dddbf9c5fa
commit
7ad3f077dc
@ -371,8 +371,10 @@ CTRL-X Subtract [count] from the number or alphabetic
|
|||||||
character at or after the cursor.
|
character at or after the cursor.
|
||||||
|
|
||||||
The CTRL-A and CTRL-X commands work for (signed) decimal numbers, unsigned
|
The CTRL-A and CTRL-X commands work for (signed) decimal numbers, unsigned
|
||||||
octal and hexadecimal numbers and alphabetic characters. This depends on the
|
binary/octal/hexadecimal numbers and alphabetic characters. This
|
||||||
'nrformats' option.
|
depends on the 'nrformats' option.
|
||||||
|
- When 'nrformats' includes "bin", Vim considers numbers starting with '0b' or
|
||||||
|
'0B' as binary.
|
||||||
- When 'nrformats' includes "octal", Vim considers numbers starting with a '0'
|
- When 'nrformats' includes "octal", Vim considers numbers starting with a '0'
|
||||||
to be octal, unless the number includes a '8' or '9'. Other numbers are
|
to be octal, unless the number includes a '8' or '9'. Other numbers are
|
||||||
decimal and may have a preceding minus sign.
|
decimal and may have a preceding minus sign.
|
||||||
@ -386,6 +388,10 @@ octal and hexadecimal numbers and alphabetic characters. This depends on the
|
|||||||
under or after the cursor. This is useful to make lists with an alphabetic
|
under or after the cursor. This is useful to make lists with an alphabetic
|
||||||
index.
|
index.
|
||||||
|
|
||||||
|
For decimals a leading negative sign is considered for incrementing or
|
||||||
|
decrementing, for binary and octal and hex values, it won't be considered. To
|
||||||
|
ignore the sign Visually select the number before using CTRL-A or CTRL-X.
|
||||||
|
|
||||||
For numbers with leading zeros (including all octal and hexadecimal numbers),
|
For numbers with leading zeros (including all octal and hexadecimal numbers),
|
||||||
Vim preserves the number of characters in the number when possible. CTRL-A on
|
Vim preserves the number of characters in the number when possible. CTRL-A on
|
||||||
"0077" results in "0100", CTRL-X on "0x100" results in "0x0ff".
|
"0077" results in "0100", CTRL-X on "0x100" results in "0x0ff".
|
||||||
@ -397,6 +403,10 @@ octal number.
|
|||||||
Note that when 'nrformats' includes "octal", decimal numbers with leading
|
Note that when 'nrformats' includes "octal", decimal numbers with leading
|
||||||
zeros cause mistakes, because they can be confused with octal numbers.
|
zeros cause mistakes, because they can be confused with octal numbers.
|
||||||
|
|
||||||
|
Note similarly, when 'nrformats' includes "bin", binary numbers with a leading
|
||||||
|
'0x' or '0X' can be interpreted as hexadecimal rather than binary since '0b'
|
||||||
|
are valid hexadecimal digits.
|
||||||
|
|
||||||
The CTRL-A command is very useful in a macro. Example: Use the following
|
The CTRL-A command is very useful in a macro. Example: Use the following
|
||||||
steps to make a numbered list.
|
steps to make a numbered list.
|
||||||
|
|
||||||
@ -1602,7 +1612,7 @@ Vim has a sorting function and a sorting command. The sorting function can be
|
|||||||
found here: |sort()|, |uniq()|.
|
found here: |sort()|, |uniq()|.
|
||||||
|
|
||||||
*:sor* *:sort*
|
*:sor* *:sort*
|
||||||
:[range]sor[t][!] [i][u][r][n][x][o] [/{pattern}/]
|
:[range]sor[t][!] [i][u][r][n][x][o][b] [/{pattern}/]
|
||||||
Sort lines in [range]. When no range is given all
|
Sort lines in [range]. When no range is given all
|
||||||
lines are sorted.
|
lines are sorted.
|
||||||
|
|
||||||
@ -1622,6 +1632,9 @@ found here: |sort()|, |uniq()|.
|
|||||||
With [o] sorting is done on the first octal number in
|
With [o] sorting is done on the first octal number in
|
||||||
the line (after or inside a {pattern} match).
|
the line (after or inside a {pattern} match).
|
||||||
|
|
||||||
|
With [b] sorting is done on the first binary number in
|
||||||
|
the line (after or inside a {pattern} match).
|
||||||
|
|
||||||
With [u] only keep the first of a sequence of
|
With [u] only keep the first of a sequence of
|
||||||
identical lines (ignoring case when [i] is used).
|
identical lines (ignoring case when [i] is used).
|
||||||
Without this flag, a sequence of identical lines
|
Without this flag, a sequence of identical lines
|
||||||
|
@ -65,14 +65,16 @@ the Number. Examples:
|
|||||||
Number 0 --> String "0" ~
|
Number 0 --> String "0" ~
|
||||||
Number -1 --> String "-1" ~
|
Number -1 --> String "-1" ~
|
||||||
*octal*
|
*octal*
|
||||||
Conversion from a String to a Number is done by converting the first digits
|
Conversion from a String to a Number is done by converting the first digits to
|
||||||
to a number. Hexadecimal "0xf9" and Octal "017" numbers are recognized. If
|
a number. Hexadecimal "0xf9", Octal "017", and Binary "0b10" numbers are
|
||||||
the String doesn't start with digits, the result is zero. Examples:
|
recognized. If the String doesn't start with digits, the result is zero.
|
||||||
|
Examples:
|
||||||
String "456" --> Number 456 ~
|
String "456" --> Number 456 ~
|
||||||
String "6bar" --> Number 6 ~
|
String "6bar" --> Number 6 ~
|
||||||
String "foo" --> Number 0 ~
|
String "foo" --> Number 0 ~
|
||||||
String "0xf1" --> Number 241 ~
|
String "0xf1" --> Number 241 ~
|
||||||
String "0100" --> Number 64 ~
|
String "0100" --> Number 64 ~
|
||||||
|
String "0b101" --> Number 5 ~
|
||||||
String "-8" --> Number -8 ~
|
String "-8" --> Number -8 ~
|
||||||
String "+8" --> Number 0 ~
|
String "+8" --> Number 0 ~
|
||||||
|
|
||||||
@ -4912,6 +4914,9 @@ printf({fmt}, {expr1} ...) *printf()*
|
|||||||
%c single byte
|
%c single byte
|
||||||
%d decimal number
|
%d decimal number
|
||||||
%5d decimal number padded with spaces to 5 characters
|
%5d decimal number padded with spaces to 5 characters
|
||||||
|
%b binary number
|
||||||
|
%08b binary number padded with zeros to at least 8 characters
|
||||||
|
%B binary number using upper case letters
|
||||||
%x hex number
|
%x hex number
|
||||||
%04x hex number padded with zeros to at least 4 characters
|
%04x hex number padded with zeros to at least 4 characters
|
||||||
%X hex number using upper case letters
|
%X hex number using upper case letters
|
||||||
@ -4998,20 +5003,19 @@ printf({fmt}, {expr1} ...) *printf()*
|
|||||||
|
|
||||||
The conversion specifiers and their meanings are:
|
The conversion specifiers and their meanings are:
|
||||||
|
|
||||||
*printf-d* *printf-o* *printf-x* *printf-X*
|
*printf-d* *printf-b* *printf-B* *printf-o* *printf-x* *printf-X*
|
||||||
doxX The Number argument is converted to signed decimal
|
dbBoxX The Number argument is converted to signed decimal (d),
|
||||||
(d), unsigned octal (o), or unsigned hexadecimal (x
|
unsigned binary (b and B), unsigned octal (o), or
|
||||||
and X) notation. The letters "abcdef" are used for
|
unsigned hexadecimal (x and X) notation. The letters
|
||||||
x conversions; the letters "ABCDEF" are used for X
|
"abcdef" are used for x conversions; the letters
|
||||||
conversions.
|
"ABCDEF" are used for X conversions. The precision, if
|
||||||
The precision, if any, gives the minimum number of
|
any, gives the minimum number of digits that must
|
||||||
digits that must appear; if the converted value
|
appear; if the converted value requires fewer digits, it
|
||||||
requires fewer digits, it is padded on the left with
|
is padded on the left with zeros. In no case does a
|
||||||
zeros.
|
non-existent or small field width cause truncation of a
|
||||||
In no case does a non-existent or small field width
|
numeric field; if the result of a conversion is wider
|
||||||
cause truncation of a numeric field; if the result of
|
than the field width, the field is expanded to contain
|
||||||
a conversion is wider than the field width, the field
|
the conversion result.
|
||||||
is expanded to contain the conversion result.
|
|
||||||
|
|
||||||
*printf-c*
|
*printf-c*
|
||||||
c The Number argument is converted to a byte, and the
|
c The Number argument is converted to a byte, and the
|
||||||
@ -6127,12 +6131,14 @@ str2float( {expr}) *str2float()*
|
|||||||
|
|
||||||
str2nr( {expr} [, {base}]) *str2nr()*
|
str2nr( {expr} [, {base}]) *str2nr()*
|
||||||
Convert string {expr} to a number.
|
Convert string {expr} to a number.
|
||||||
{base} is the conversion base, it can be 8, 10 or 16.
|
{base} is the conversion base, it can be 2, 8, 10 or 16.
|
||||||
When {base} is omitted base 10 is used. This also means that
|
When {base} is omitted base 10 is used. This also means that
|
||||||
a leading zero doesn't cause octal conversion to be used, as
|
a leading zero doesn't cause octal conversion to be used, as
|
||||||
with the default String to Number conversion.
|
with the default String to Number conversion.
|
||||||
When {base} is 16 a leading "0x" or "0X" is ignored. With a
|
When {base} is 16 a leading "0x" or "0X" is ignored. With a
|
||||||
different base the result will be zero.
|
different base the result will be zero. Similarly, when {base}
|
||||||
|
is 8 a leading "0" is ignored, and when {base} is 2 a leading
|
||||||
|
"0b" or "0B" is ignored.
|
||||||
Text after the number is silently ignored.
|
Text after the number is silently ignored.
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,6 +122,14 @@ static inline bool ascii_isxdigit(int c)
|
|||||||
|| (c >= 'A' && c <= 'F');
|
|| (c >= 'A' && c <= 'F');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks if `c` is a binary digit, that is, 0-1.
|
||||||
|
///
|
||||||
|
/// @see {ascii_isdigit}
|
||||||
|
static inline bool ascii_isbdigit(int c)
|
||||||
|
{
|
||||||
|
return (c == '0' || c == '1');
|
||||||
|
}
|
||||||
|
|
||||||
/// Checks if `c` is a white-space character, that is,
|
/// Checks if `c` is a white-space character, that is,
|
||||||
/// one of \f, \n, \r, \t, \v.
|
/// one of \f, \n, \r, \t, \v.
|
||||||
///
|
///
|
||||||
|
@ -1454,6 +1454,20 @@ char_u* skipdigits(char_u *q)
|
|||||||
return p;
|
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
|
/// skip over digits and hex characters
|
||||||
///
|
///
|
||||||
/// @param q
|
/// @param q
|
||||||
@ -1485,6 +1499,20 @@ char_u* skiptodigit(char_u *q)
|
|||||||
return p;
|
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)
|
/// skip to hex character (or NUL after the string)
|
||||||
///
|
///
|
||||||
/// @param q
|
/// @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
|
/// Convert a string into a long and/or unsigned long, taking care of
|
||||||
/// hexadecimal and octal numbers. Accepts a '-' sign.
|
/// hexadecimal, octal and binary numbers. Accepts a '-' sign.
|
||||||
/// If "hexp" is not NULL, returns a flag to indicate the type of the number:
|
/// If "prep" is not NULL, returns a flag to indicate the type of the number:
|
||||||
/// 0 decimal
|
/// 0 decimal
|
||||||
/// '0' octal
|
/// '0' octal
|
||||||
|
/// 'B' bin
|
||||||
|
/// 'b' bin
|
||||||
/// 'X' hex
|
/// 'X' hex
|
||||||
/// 'x' hex
|
/// 'x' hex
|
||||||
/// If "len" is not NULL, the length of the number in characters is returned.
|
/// 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 "nptr" is not NULL, the signed result is returned in it.
|
||||||
/// If "unptr" is not NULL, the unsigned 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
|
/// If "dooct" is non-zero recognize octal numbers, when > 1 always assume
|
||||||
/// octal number.
|
/// octal number.
|
||||||
/// If "dohex" is non-zero recognize hex numbers, when > 1 always assume
|
/// If "dohex" is non-zero recognize hex numbers, when > 1 always assume
|
||||||
/// hex number.
|
/// hex number.
|
||||||
///
|
///
|
||||||
/// @param start
|
/// @param start
|
||||||
/// @param hexp Returns type of number 0 = decimal, 'x' or 'X' is hex,
|
/// @param prep Returns type of number 0 = decimal, 'x' or 'X' is hex,
|
||||||
// '0' = octal
|
// '0' = octal, 'b' or 'B' is bin
|
||||||
/// @param len Returns the detected length of number.
|
/// @param len Returns the detected length of number.
|
||||||
|
/// @param dobin recognize binary number
|
||||||
/// @param dooct recognize octal number
|
/// @param dooct recognize octal number
|
||||||
/// @param dohex recognize hex number
|
/// @param dohex recognize hex number
|
||||||
/// @param nptr Returns the signed result.
|
/// @param nptr Returns the signed result.
|
||||||
/// @param unptr Returns the unsigned 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)
|
long *nptr, unsigned long *unptr)
|
||||||
{
|
{
|
||||||
char_u *ptr = start;
|
char_u *ptr = start;
|
||||||
int hex = 0; // default is decimal
|
int pre = 0; // default is decimal
|
||||||
int negative = FALSE;
|
int negative = FALSE;
|
||||||
unsigned long un = 0;
|
unsigned long un = 0;
|
||||||
int n;
|
int n;
|
||||||
@ -1756,31 +1789,35 @@ void vim_str2nr(char_u *start, int *hexp, int *len, int dooct, int dohex,
|
|||||||
++ptr;
|
++ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recognize hex and octal.
|
// Recognize hex, octal, and bin.
|
||||||
if ((ptr[0] == '0') && (ptr[1] != '8') && (ptr[1] != '9')) {
|
if ((ptr[0] == '0') && (ptr[1] != '8') && (ptr[1] != '9')) {
|
||||||
hex = ptr[1];
|
pre = ptr[1];
|
||||||
|
|
||||||
if (dohex
|
if (dohex
|
||||||
&& ((hex == 'X') || (hex == 'x'))
|
&& ((pre == 'X') || (pre == 'x'))
|
||||||
&& ascii_isxdigit(ptr[2])) {
|
&& ascii_isxdigit(ptr[2])) {
|
||||||
// hexadecimal
|
// hexadecimal
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
|
} else if (dobin
|
||||||
|
&& ((pre == 'B') || (pre == 'b'))
|
||||||
|
&& ascii_isbdigit(ptr[2])) {
|
||||||
|
// binary
|
||||||
|
ptr += 2;
|
||||||
} else {
|
} else {
|
||||||
// default is decimal
|
// default is decimal
|
||||||
hex = 0;
|
pre = 0;
|
||||||
|
|
||||||
if (dooct) {
|
if (dooct) {
|
||||||
// Don't interpret "0", "08" or "0129" as octal.
|
// Don't interpret "0", "08" or "0129" as octal.
|
||||||
for (n = 1; ascii_isdigit(ptr[n]); ++n) {
|
for (n = 1; ascii_isdigit(ptr[n]); ++n) {
|
||||||
if (ptr[n] > '7') {
|
if (ptr[n] > '7') {
|
||||||
// can't be octal
|
// can't be octal
|
||||||
hex = 0;
|
pre = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr[n] >= '0') {
|
if (ptr[n] >= '0') {
|
||||||
// assume octal
|
// 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.
|
// 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
|
// octal
|
||||||
while ('0' <= *ptr && *ptr <= '7') {
|
while ('0' <= *ptr && *ptr <= '7') {
|
||||||
un = 8 * un + (unsigned long)(*ptr - '0');
|
un = 8 * un + (unsigned long)(*ptr - '0');
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
} else if ((hex != 0) || (dohex > 1)) {
|
} else if (pre != 0 || dohex > 1) {
|
||||||
// hex
|
// hex
|
||||||
|
if (pre != 0)
|
||||||
|
n += 2; // skip over "0x"
|
||||||
while (ascii_isxdigit(*ptr)) {
|
while (ascii_isxdigit(*ptr)) {
|
||||||
un = 16 * un + (unsigned long)hex2nr(*ptr);
|
un = 16 * un + (unsigned long)hex2nr(*ptr);
|
||||||
ptr++;
|
++ptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// decimal
|
// decimal
|
||||||
while (ascii_isdigit(*ptr)) {
|
while (ascii_isdigit(*ptr)) {
|
||||||
un = 10 * un + (unsigned long)(*ptr - '0');
|
un = 10 * un + (unsigned long)(*ptr - '0');
|
||||||
ptr++;
|
++ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hexp != NULL) {
|
if (prep != NULL) {
|
||||||
*hexp = hex;
|
*prep = pre;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len != NULL) {
|
if (len != NULL) {
|
||||||
|
@ -1149,7 +1149,7 @@ call_vim_function (
|
|||||||
len = 0;
|
len = 0;
|
||||||
else
|
else
|
||||||
/* Recognize a number argument, the others must be strings. */
|
/* Recognize a number argument, the others must be strings. */
|
||||||
vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL);
|
vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, TRUE, &n, NULL);
|
||||||
if (len != 0 && len == (int)STRLEN(argv[i])) {
|
if (len != 0 && len == (int)STRLEN(argv[i])) {
|
||||||
argvars[i].v_type = VAR_NUMBER;
|
argvars[i].v_type = VAR_NUMBER;
|
||||||
argvars[i].vval.v_number = n;
|
argvars[i].vval.v_number = n;
|
||||||
@ -4127,7 +4127,7 @@ eval7 (
|
|||||||
rettv->vval.v_float = f;
|
rettv->vval.v_float = f;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL);
|
vim_str2nr(*arg, NULL, &len, TRUE, TRUE, TRUE, &n, NULL);
|
||||||
*arg += len;
|
*arg += len;
|
||||||
if (evaluate) {
|
if (evaluate) {
|
||||||
rettv->v_type = VAR_NUMBER;
|
rettv->v_type = VAR_NUMBER;
|
||||||
@ -15982,7 +15982,7 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv)
|
|||||||
|
|
||||||
if (argvars[1].v_type != VAR_UNKNOWN) {
|
if (argvars[1].v_type != VAR_UNKNOWN) {
|
||||||
base = get_tv_number(&argvars[1]);
|
base = get_tv_number(&argvars[1]);
|
||||||
if (base != 8 && base != 10 && base != 16) {
|
if (base != 2 && base != 8 && base != 10 && base != 16) {
|
||||||
EMSG(_(e_invarg));
|
EMSG(_(e_invarg));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -15991,7 +15991,7 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv)
|
|||||||
p = skipwhite(get_tv_string(&argvars[0]));
|
p = skipwhite(get_tv_string(&argvars[0]));
|
||||||
if (*p == '+')
|
if (*p == '+')
|
||||||
p = skipwhite(p + 1);
|
p = skipwhite(p + 1);
|
||||||
vim_str2nr(p, NULL, NULL, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL);
|
vim_str2nr(p, NULL, NULL, base == 2 ? 2 : 0, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL);
|
||||||
rettv->vval.v_number = n;
|
rettv->vval.v_number = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18273,7 +18273,7 @@ long get_tv_number_chk(typval_T *varp, int *denote)
|
|||||||
case VAR_STRING:
|
case VAR_STRING:
|
||||||
if (varp->vval.v_string != NULL)
|
if (varp->vval.v_string != NULL)
|
||||||
vim_str2nr(varp->vval.v_string, NULL, NULL,
|
vim_str2nr(varp->vval.v_string, NULL, NULL,
|
||||||
TRUE, TRUE, &n, NULL);
|
TRUE, TRUE, TRUE, &n, NULL);
|
||||||
return n;
|
return n;
|
||||||
case VAR_LIST:
|
case VAR_LIST:
|
||||||
EMSG(_("E745: Using a List as a Number"));
|
EMSG(_("E745: Using a List as a Number"));
|
||||||
|
@ -348,6 +348,7 @@ void ex_sort(exarg_T *eap)
|
|||||||
long deleted;
|
long deleted;
|
||||||
colnr_T start_col;
|
colnr_T start_col;
|
||||||
colnr_T end_col;
|
colnr_T end_col;
|
||||||
|
int sort_bin; /* sort on bin number */
|
||||||
int sort_oct; /* sort on octal number */
|
int sort_oct; /* sort on octal number */
|
||||||
int sort_hex; /* sort on hex number */
|
int sort_hex; /* sort on hex number */
|
||||||
|
|
||||||
@ -362,7 +363,7 @@ void ex_sort(exarg_T *eap)
|
|||||||
regmatch.regprog = NULL;
|
regmatch.regprog = NULL;
|
||||||
sorti_T *nrs = xmalloc(count * sizeof(sorti_T));
|
sorti_T *nrs = xmalloc(count * sizeof(sorti_T));
|
||||||
|
|
||||||
sort_abort = sort_ic = sort_rx = sort_nr = sort_oct = sort_hex = 0;
|
sort_abort = sort_ic = sort_rx = sort_nr = sort_bin = sort_oct = sort_hex = 0;
|
||||||
|
|
||||||
for (p = eap->arg; *p != NUL; ++p) {
|
for (p = eap->arg; *p != NUL; ++p) {
|
||||||
if (ascii_iswhite(*p))
|
if (ascii_iswhite(*p))
|
||||||
@ -373,6 +374,8 @@ void ex_sort(exarg_T *eap)
|
|||||||
sort_rx = TRUE;
|
sort_rx = TRUE;
|
||||||
else if (*p == 'n')
|
else if (*p == 'n')
|
||||||
sort_nr = 2;
|
sort_nr = 2;
|
||||||
|
else if (*p == 'b')
|
||||||
|
sort_bin = 2;
|
||||||
else if (*p == 'o')
|
else if (*p == 'o')
|
||||||
sort_oct = 2;
|
sort_oct = 2;
|
||||||
else if (*p == 'x')
|
else if (*p == 'x')
|
||||||
@ -410,14 +413,14 @@ void ex_sort(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can only have one of 'n', 'o' and 'x'. */
|
/* Can only have one of 'n', 'b', 'o' and 'x'. */
|
||||||
if (sort_nr + sort_oct + sort_hex > 2) {
|
if (sort_nr + sort_bin + sort_oct + sort_hex > 2) {
|
||||||
EMSG(_(e_invarg));
|
EMSG(_(e_invarg));
|
||||||
goto sortend;
|
goto sortend;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* From here on "sort_nr" is used as a flag for any number sorting. */
|
/* From here on "sort_nr" is used as a flag for any number sorting. */
|
||||||
sort_nr += sort_oct + sort_hex;
|
sort_nr += sort_bin + sort_oct + sort_hex;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make an array with all line numbers. This avoids having to copy all
|
* Make an array with all line numbers. This avoids having to copy all
|
||||||
@ -454,6 +457,8 @@ void ex_sort(exarg_T *eap)
|
|||||||
p = s + start_col;
|
p = s + start_col;
|
||||||
if (sort_hex)
|
if (sort_hex)
|
||||||
s = skiptohex(p);
|
s = skiptohex(p);
|
||||||
|
else if (sort_bin)
|
||||||
|
s = skiptobin(p);
|
||||||
else
|
else
|
||||||
s = skiptodigit(p);
|
s = skiptodigit(p);
|
||||||
if (s > p && s[-1] == '-')
|
if (s > p && s[-1] == '-')
|
||||||
@ -462,7 +467,7 @@ void ex_sort(exarg_T *eap)
|
|||||||
/* empty line should sort before any number */
|
/* empty line should sort before any number */
|
||||||
nrs[lnum - eap->line1].start_col_nr = -MAXLNUM;
|
nrs[lnum - eap->line1].start_col_nr = -MAXLNUM;
|
||||||
else
|
else
|
||||||
vim_str2nr(s, NULL, NULL, sort_oct, sort_hex,
|
vim_str2nr(s, NULL, NULL, sort_bin, sort_oct, sort_hex,
|
||||||
&nrs[lnum - eap->line1].start_col_nr, NULL);
|
&nrs[lnum - eap->line1].start_col_nr, NULL);
|
||||||
*s2 = c;
|
*s2 = c;
|
||||||
} else {
|
} else {
|
||||||
|
@ -4780,7 +4780,7 @@ int get_list_range(char_u **str, int *num1, int *num2)
|
|||||||
|
|
||||||
*str = skipwhite(*str);
|
*str = skipwhite(*str);
|
||||||
if (**str == '-' || ascii_isdigit(**str)) { /* parse "from" part of range */
|
if (**str == '-' || ascii_isdigit(**str)) { /* parse "from" part of range */
|
||||||
vim_str2nr(*str, NULL, &len, FALSE, FALSE, &num, NULL);
|
vim_str2nr(*str, NULL, &len, FALSE, FALSE, FALSE, &num, NULL);
|
||||||
*str += len;
|
*str += len;
|
||||||
*num1 = (int)num;
|
*num1 = (int)num;
|
||||||
first = TRUE;
|
first = TRUE;
|
||||||
@ -4788,7 +4788,7 @@ int get_list_range(char_u **str, int *num1, int *num2)
|
|||||||
*str = skipwhite(*str);
|
*str = skipwhite(*str);
|
||||||
if (**str == ',') { /* parse "to" part of range */
|
if (**str == ',') { /* parse "to" part of range */
|
||||||
*str = skipwhite(*str + 1);
|
*str = skipwhite(*str + 1);
|
||||||
vim_str2nr(*str, NULL, &len, FALSE, FALSE, &num, NULL);
|
vim_str2nr(*str, NULL, &len, FALSE, FALSE, FALSE, &num, NULL);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
*num2 = (int)num;
|
*num2 = (int)num;
|
||||||
*str = skipwhite(*str + len);
|
*str = skipwhite(*str + len);
|
||||||
|
@ -575,7 +575,7 @@ find_special_key (
|
|||||||
if (bp[0] == 't' && bp[1] == '_' && bp[2] && bp[3])
|
if (bp[0] == 't' && bp[1] == '_' && bp[2] && bp[3])
|
||||||
bp += 3; /* skip t_xx, xx may be '-' or '>' */
|
bp += 3; /* skip t_xx, xx may be '-' or '>' */
|
||||||
else if (STRNICMP(bp, "char-", 5) == 0) {
|
else if (STRNICMP(bp, "char-", 5) == 0) {
|
||||||
vim_str2nr(bp + 5, NULL, &l, TRUE, TRUE, NULL, NULL);
|
vim_str2nr(bp + 5, NULL, &l, TRUE, TRUE, TRUE, NULL, NULL);
|
||||||
bp += l + 5;
|
bp += l + 5;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -602,7 +602,7 @@ find_special_key (
|
|||||||
if (STRNICMP(last_dash + 1, "char-", 5) == 0
|
if (STRNICMP(last_dash + 1, "char-", 5) == 0
|
||||||
&& ascii_isdigit(last_dash[6])) {
|
&& ascii_isdigit(last_dash[6])) {
|
||||||
/* <Char-123> or <Char-033> or <Char-0x33> */
|
/* <Char-123> or <Char-033> or <Char-0x33> */
|
||||||
vim_str2nr(last_dash + 6, NULL, NULL, TRUE, TRUE, NULL, &n);
|
vim_str2nr(last_dash + 6, NULL, NULL, TRUE, TRUE, TRUE, NULL, &n);
|
||||||
key = (int)n;
|
key = (int)n;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
@ -3037,7 +3037,7 @@ static double tv_float(typval_T *tvs, int *idxp)
|
|||||||
* http://www.ijs.si/software/snprintf/
|
* http://www.ijs.si/software/snprintf/
|
||||||
*
|
*
|
||||||
* This snprintf() only supports the following conversion specifiers:
|
* This snprintf() only supports the following conversion specifiers:
|
||||||
* s, c, d, u, o, x, X, p (and synonyms: i, D, U, O - see below)
|
* s, c, b, B, d, u, o, x, X, p (and synonyms: i, D, U, O - see below)
|
||||||
* with flags: '-', '+', ' ', '0' and '#'.
|
* with flags: '-', '+', ' ', '0' and '#'.
|
||||||
* An asterisk is supported for field width as well as precision.
|
* An asterisk is supported for field width as well as precision.
|
||||||
*
|
*
|
||||||
@ -3295,8 +3295,8 @@ int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd': case 'u': case 'o': case 'x': case 'X': case 'p': {
|
case 'd': case 'u': case 'b': case 'B': case 'o': case 'x': case 'X': case 'p': {
|
||||||
// u, o, x, X and p conversion specifiers imply the value is unsigned;
|
// u, b, B, o, x, X and p conversion specifiers imply the value is unsigned;
|
||||||
// d implies a signed value
|
// d implies a signed value
|
||||||
|
|
||||||
// 0 if numeric argument is zero (or if pointer is NULL for 'p'),
|
// 0 if numeric argument is zero (or if pointer is NULL for 'p'),
|
||||||
@ -3399,7 +3399,8 @@ int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs)
|
|||||||
// leave negative numbers for sprintf to handle, to
|
// leave negative numbers for sprintf to handle, to
|
||||||
// avoid handling tricky cases like (short int)-32768
|
// avoid handling tricky cases like (short int)-32768
|
||||||
} else if (alternate_form) {
|
} else if (alternate_form) {
|
||||||
if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X') ) {
|
if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X' ||
|
||||||
|
fmt_spec == 'b' || fmt_spec == 'B')) {
|
||||||
tmp[str_arg_l++] = '0';
|
tmp[str_arg_l++] = '0';
|
||||||
tmp[str_arg_l++] = fmt_spec;
|
tmp[str_arg_l++] = fmt_spec;
|
||||||
}
|
}
|
||||||
@ -3411,7 +3412,7 @@ int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs)
|
|||||||
precision = 1; // default precision is 1
|
precision = 1; // default precision is 1
|
||||||
if (precision == 0 && arg_sign == 0) {
|
if (precision == 0 && arg_sign == 0) {
|
||||||
// when zero value is formatted with an explicit precision 0,
|
// when zero value is formatted with an explicit precision 0,
|
||||||
// resulting formatted string is empty (d, i, u, o, x, X, p)
|
// resulting formatted string is empty (d, i, u, b, B, o, x, X, p)
|
||||||
} else {
|
} else {
|
||||||
char f[5];
|
char f[5];
|
||||||
int f_l = 0;
|
int f_l = 0;
|
||||||
@ -3441,6 +3442,36 @@ int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs)
|
|||||||
case '2': str_arg_l += sprintf(tmp + str_arg_l, f, long_long_arg);
|
case '2': str_arg_l += sprintf(tmp + str_arg_l, f, long_long_arg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else if (fmt_spec == 'b' || fmt_spec == 'B') {
|
||||||
|
//binary
|
||||||
|
size_t bits = 0;
|
||||||
|
switch (length_modifier) {
|
||||||
|
case '\0':
|
||||||
|
case 'h': for (bits = sizeof(unsigned) * 8; bits > 0; bits--)
|
||||||
|
if ((uint_arg >> (bits - 1)) & 0x1) break;
|
||||||
|
|
||||||
|
while (bits > 0)
|
||||||
|
tmp[str_arg_l++] = ((uint_arg >> --bits) & 0x1) ? '1' : '0';
|
||||||
|
break;
|
||||||
|
case 'l': for (bits = sizeof(unsigned long) * 8; bits > 0; bits--)
|
||||||
|
if ((ulong_arg >> (bits - 1)) & 0x1) break;
|
||||||
|
|
||||||
|
while (bits > 0)
|
||||||
|
tmp[str_arg_l++] = ((ulong_arg >> --bits) & 0x1) ? '1' : '0';
|
||||||
|
break;
|
||||||
|
case '2': for (bits = sizeof(unsigned long long) * 8; bits > 0; bits--)
|
||||||
|
if ((ulong_long_arg >> (bits - 1)) & 0x1) break;
|
||||||
|
|
||||||
|
while (bits > 0)
|
||||||
|
tmp[str_arg_l++] = ((ulong_long_arg >> --bits) & 0x1) ? '1' : '0';
|
||||||
|
break;
|
||||||
|
case 'z': for (bits = sizeof(size_t) * 8; bits > 0; bits--)
|
||||||
|
if ((size_t_arg >> (bits - 1)) & 0x1) break;
|
||||||
|
|
||||||
|
while (bits > 0)
|
||||||
|
tmp[str_arg_l++] = ((size_t_arg >> --bits) & 0x1) ? '1' : '0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// unsigned
|
// unsigned
|
||||||
switch (length_modifier) {
|
switch (length_modifier) {
|
||||||
@ -3464,7 +3495,9 @@ int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs)
|
|||||||
if (zero_padding_insertion_ind + 1 < str_arg_l
|
if (zero_padding_insertion_ind + 1 < str_arg_l
|
||||||
&& tmp[zero_padding_insertion_ind] == '0'
|
&& tmp[zero_padding_insertion_ind] == '0'
|
||||||
&& (tmp[zero_padding_insertion_ind + 1] == 'x'
|
&& (tmp[zero_padding_insertion_ind + 1] == 'x'
|
||||||
|| tmp[zero_padding_insertion_ind + 1] == 'X'))
|
|| tmp[zero_padding_insertion_ind + 1] == 'X'
|
||||||
|
|| tmp[zero_padding_insertion_ind + 1] == 'b'
|
||||||
|
|| tmp[zero_padding_insertion_ind + 1] == 'B'))
|
||||||
zero_padding_insertion_ind += 2;
|
zero_padding_insertion_ind += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4197,7 +4197,7 @@ int do_addsub(int command, linenr_T Prenum1)
|
|||||||
int col;
|
int col;
|
||||||
char_u *buf1;
|
char_u *buf1;
|
||||||
char_u buf2[NUMBUFLEN];
|
char_u buf2[NUMBUFLEN];
|
||||||
int hex; /* 'X' or 'x': hex; '0': octal */
|
int pre; /* 'X' or 'x': hex; '0': octal; 'B' or 'b': bin */
|
||||||
static int hexupper = FALSE; /* 0xABC */
|
static int hexupper = FALSE; /* 0xABC */
|
||||||
unsigned long n, oldn;
|
unsigned long n, oldn;
|
||||||
char_u *ptr;
|
char_u *ptr;
|
||||||
@ -4206,6 +4206,7 @@ int do_addsub(int command, linenr_T Prenum1)
|
|||||||
int todel;
|
int todel;
|
||||||
int dohex;
|
int dohex;
|
||||||
int dooct;
|
int dooct;
|
||||||
|
int dobin;
|
||||||
int doalp;
|
int doalp;
|
||||||
int firstdigit;
|
int firstdigit;
|
||||||
int negative;
|
int negative;
|
||||||
@ -4213,6 +4214,7 @@ int do_addsub(int command, linenr_T Prenum1)
|
|||||||
|
|
||||||
dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL); /* "heX" */
|
dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL); /* "heX" */
|
||||||
dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL); /* "Octal" */
|
dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL); /* "Octal" */
|
||||||
|
dobin = (vim_strchr(curbuf->b_p_nf, 'b') != NULL); /* "Bin" */
|
||||||
doalp = (vim_strchr(curbuf->b_p_nf, 'p') != NULL); /* "alPha" */
|
doalp = (vim_strchr(curbuf->b_p_nf, 'p') != NULL); /* "alPha" */
|
||||||
|
|
||||||
ptr = get_cursor_line_ptr();
|
ptr = get_cursor_line_ptr();
|
||||||
@ -4222,19 +4224,44 @@ int do_addsub(int command, linenr_T Prenum1)
|
|||||||
* First check if we are on a hexadecimal number, after the "0x".
|
* First check if we are on a hexadecimal number, after the "0x".
|
||||||
*/
|
*/
|
||||||
col = curwin->w_cursor.col;
|
col = curwin->w_cursor.col;
|
||||||
|
|
||||||
|
if (dobin)
|
||||||
|
while (col > 0 && ascii_isbdigit(ptr[col]))
|
||||||
|
--col;
|
||||||
|
|
||||||
if (dohex)
|
if (dohex)
|
||||||
while (col > 0 && ascii_isxdigit(ptr[col]))
|
while (col > 0 && ascii_isxdigit(ptr[col]))
|
||||||
--col;
|
--col;
|
||||||
if ( dohex
|
if ( dobin
|
||||||
&& col > 0
|
&& dohex
|
||||||
|
&& ! ((col > 0
|
||||||
&& (ptr[col] == 'X'
|
&& (ptr[col] == 'X'
|
||||||
|| ptr[col] == 'x')
|
|| ptr[col] == 'x')
|
||||||
&& ptr[col - 1] == '0'
|
&& ptr[col - 1] == '0'
|
||||||
&& ascii_isxdigit(ptr[col + 1])) {
|
&& ascii_isxdigit(ptr[col + 1])))) {
|
||||||
/*
|
|
||||||
* Found hexadecimal number, move to its start.
|
/* In case of binary/hexadecimal pattern overlap match, rescan */
|
||||||
*/
|
|
||||||
--col;
|
col = curwin->w_cursor.col;
|
||||||
|
|
||||||
|
while (col > 0 && ascii_isdigit(ptr[col]))
|
||||||
|
col--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (( dohex
|
||||||
|
&& col > 0
|
||||||
|
&& (ptr[col] == 'X'
|
||||||
|
|| ptr[col] == 'x')
|
||||||
|
&& ptr[col - 1] == '0'
|
||||||
|
&& ascii_isxdigit(ptr[col + 1])) ||
|
||||||
|
( dobin
|
||||||
|
&& col > 0
|
||||||
|
&& (ptr[col] == 'B'
|
||||||
|
|| ptr[col] == 'b')
|
||||||
|
&& ptr[col - 1] == '0'
|
||||||
|
&& ascii_isbdigit(ptr[col + 1]))) {
|
||||||
|
/* Found hexadecimal or binary number, move to its start. */
|
||||||
|
--col;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Search forward and then backward to find the start of number.
|
* Search forward and then backward to find the start of number.
|
||||||
@ -4297,10 +4324,10 @@ int do_addsub(int command, linenr_T Prenum1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get the number value (unsigned) */
|
/* get the number value (unsigned) */
|
||||||
vim_str2nr(ptr + col, &hex, &length, dooct, dohex, NULL, &n);
|
vim_str2nr(ptr + col, &pre, &length, dobin, dooct, dohex, NULL, &n);
|
||||||
|
|
||||||
/* ignore leading '-' for hex and octal numbers */
|
/* ignore leading '-' for hex, octal and bin numbers */
|
||||||
if (hex && negative) {
|
if (pre && negative) {
|
||||||
++col;
|
++col;
|
||||||
--length;
|
--length;
|
||||||
negative = FALSE;
|
negative = FALSE;
|
||||||
@ -4320,7 +4347,7 @@ int do_addsub(int command, linenr_T Prenum1)
|
|||||||
n += (unsigned long)Prenum1;
|
n += (unsigned long)Prenum1;
|
||||||
|
|
||||||
/* handle wraparound for decimal numbers */
|
/* handle wraparound for decimal numbers */
|
||||||
if (!hex) {
|
if (!pre) {
|
||||||
if (subtract) {
|
if (subtract) {
|
||||||
if (n > oldn) {
|
if (n > oldn) {
|
||||||
n = 1 + (n ^ (unsigned long)-1);
|
n = 1 + (n ^ (unsigned long)-1);
|
||||||
@ -4370,23 +4397,38 @@ int do_addsub(int command, linenr_T Prenum1)
|
|||||||
if (negative) {
|
if (negative) {
|
||||||
*ptr++ = '-';
|
*ptr++ = '-';
|
||||||
}
|
}
|
||||||
if (hex) {
|
if (pre) {
|
||||||
*ptr++ = '0';
|
*ptr++ = '0';
|
||||||
--length;
|
--length;
|
||||||
}
|
}
|
||||||
if (hex == 'x' || hex == 'X') {
|
if (pre == 'b' || pre == 'B'
|
||||||
*ptr++ = hex;
|
|| pre == 'x' || pre == 'X') {
|
||||||
|
*ptr++ = pre;
|
||||||
--length;
|
--length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Put the number characters in buf2[].
|
* Put the number characters in buf2[].
|
||||||
*/
|
*/
|
||||||
if (hex == 0)
|
if (pre == 'b' || pre == 'B') {
|
||||||
|
|
||||||
|
size_t bits = 0;
|
||||||
|
size_t pos = 0;
|
||||||
|
|
||||||
|
/* leading zeros */
|
||||||
|
for (bits = 8 * sizeof(unsigned long); bits > 0; bits--)
|
||||||
|
if ((n >> (bits - 1)) & 0x1) break;
|
||||||
|
|
||||||
|
while (bits > 0)
|
||||||
|
buf2[pos++] = ((n >> --bits) & 0x1) ? '1' : '0';
|
||||||
|
|
||||||
|
buf2[pos] = '\0';
|
||||||
|
|
||||||
|
} else if (pre == 0)
|
||||||
sprintf((char *)buf2, "%" PRIu64, (uint64_t)n);
|
sprintf((char *)buf2, "%" PRIu64, (uint64_t)n);
|
||||||
else if (hex == '0')
|
else if (pre == '0')
|
||||||
sprintf((char *)buf2, "%" PRIo64, (uint64_t)n);
|
sprintf((char *)buf2, "%" PRIo64, (uint64_t)n);
|
||||||
else if (hex && hexupper)
|
else if (pre && hexupper)
|
||||||
sprintf((char *)buf2, "%" PRIX64, (uint64_t)n);
|
sprintf((char *)buf2, "%" PRIX64, (uint64_t)n);
|
||||||
else
|
else
|
||||||
sprintf((char *)buf2, "%" PRIx64, (uint64_t)n);
|
sprintf((char *)buf2, "%" PRIx64, (uint64_t)n);
|
||||||
@ -4398,7 +4440,7 @@ int do_addsub(int command, linenr_T Prenum1)
|
|||||||
* Don't do this when
|
* Don't do this when
|
||||||
* the result may look like an octal number.
|
* the result may look like an octal number.
|
||||||
*/
|
*/
|
||||||
if (firstdigit == '0' && !(dooct && hex == 0))
|
if (firstdigit == '0' && !(dooct && pre == 0))
|
||||||
while (length-- > 0)
|
while (length-- > 0)
|
||||||
*ptr++ = '0';
|
*ptr++ = '0';
|
||||||
*ptr = NUL;
|
*ptr = NUL;
|
||||||
|
@ -260,7 +260,7 @@ typedef struct vimoption {
|
|||||||
|
|
||||||
static char *(p_ambw_values[]) = {"single", "double", NULL};
|
static char *(p_ambw_values[]) = {"single", "double", NULL};
|
||||||
static char *(p_bg_values[]) = {"light", "dark", NULL};
|
static char *(p_bg_values[]) = {"light", "dark", NULL};
|
||||||
static char *(p_nf_values[]) = {"octal", "hex", "alpha", NULL};
|
static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", NULL};
|
||||||
static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
|
static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
|
||||||
static char *(p_wop_values[]) = {"tagfile", NULL};
|
static char *(p_wop_values[]) = {"tagfile", NULL};
|
||||||
static char *(p_wak_values[]) = {"yes", "menu", "no", NULL};
|
static char *(p_wak_values[]) = {"yes", "menu", "no", NULL};
|
||||||
@ -1431,7 +1431,7 @@ do_set (
|
|||||||
} else if (*arg == '-' || ascii_isdigit(*arg)) {
|
} else if (*arg == '-' || ascii_isdigit(*arg)) {
|
||||||
// Allow negative (for 'undolevels'), octal and
|
// Allow negative (for 'undolevels'), octal and
|
||||||
// hex numbers.
|
// hex numbers.
|
||||||
vim_str2nr(arg, NULL, &i, true, true, &value, NULL);
|
vim_str2nr(arg, NULL, &i, true, true, true, &value, NULL);
|
||||||
if (arg[i] != NUL && !ascii_iswhite(arg[i])) {
|
if (arg[i] != NUL && !ascii_iswhite(arg[i])) {
|
||||||
errmsg = e_invarg;
|
errmsg = e_invarg;
|
||||||
goto skip;
|
goto skip;
|
||||||
|
@ -1599,7 +1599,7 @@ return {
|
|||||||
deny_duplicates=true,
|
deny_duplicates=true,
|
||||||
alloced=true,
|
alloced=true,
|
||||||
varname='p_nf',
|
varname='p_nf',
|
||||||
defaults={if_true={vi="octal,hex", vim="hex"}}
|
defaults={if_true={vi="bin,octal,hex", vim="bin,hex"}}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
full_name='number', abbreviation='nu',
|
full_name='number', abbreviation='nu',
|
||||||
|
@ -1095,7 +1095,9 @@ spell_check (
|
|||||||
// 0X99FF. But always do check spelling to find "3GPP" and "11
|
// 0X99FF. But always do check spelling to find "3GPP" and "11
|
||||||
// julifeest".
|
// julifeest".
|
||||||
if (*ptr >= '0' && *ptr <= '9') {
|
if (*ptr >= '0' && *ptr <= '9') {
|
||||||
if (*ptr == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
|
if (*ptr == '0' && (ptr[1] == 'b' || ptr[1] == 'B'))
|
||||||
|
mi.mi_end = skipbin(ptr + 2);
|
||||||
|
else if (*ptr == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
|
||||||
mi.mi_end = skiphex(ptr + 2);
|
mi.mi_end = skiphex(ptr + 2);
|
||||||
else
|
else
|
||||||
mi.mi_end = skipdigits(ptr);
|
mi.mi_end = skipdigits(ptr);
|
||||||
|
@ -35,7 +35,7 @@ Error: configure did not run properly.Check auto/config.log.
|
|||||||
|
|
||||||
#include "nvim/os/os_defs.h" /* bring lots of system header files */
|
#include "nvim/os/os_defs.h" /* bring lots of system header files */
|
||||||
|
|
||||||
#define NUMBUFLEN 30 /* length of a buffer to store a number in ASCII */
|
#define NUMBUFLEN 65 /* length of a buffer to store a number in ASCII */
|
||||||
|
|
||||||
#define MAX_TYPENR 65535
|
#define MAX_TYPENR 65535
|
||||||
|
|
||||||
|
58
test/functional/eval/printf_spec.lua
Normal file
58
test/functional/eval/printf_spec.lua
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
local helpers = require('test.functional.helpers')
|
||||||
|
local clear = helpers.clear
|
||||||
|
local eq = helpers.eq
|
||||||
|
local funcs = helpers.funcs
|
||||||
|
local exc_exec = helpers.exc_exec
|
||||||
|
|
||||||
|
describe('printf()', function()
|
||||||
|
it('works with zero and %b', function()
|
||||||
|
eq('0', funcs.printf('%lb', 0))
|
||||||
|
eq('0', funcs.printf('%llb', 0))
|
||||||
|
eq('0', funcs.printf('%zb', 0))
|
||||||
|
end)
|
||||||
|
it('works with one and %b', function()
|
||||||
|
eq('1', funcs.printf('%b', 1))
|
||||||
|
eq('1', funcs.printf('%lb', 1))
|
||||||
|
eq('1', funcs.printf('%llb', 1))
|
||||||
|
eq('1', funcs.printf('%zb', 1))
|
||||||
|
end)
|
||||||
|
it('works with 0xff and %b', function()
|
||||||
|
eq('11111111', funcs.printf('%b', 0xff))
|
||||||
|
eq('11111111', funcs.printf('%lb', 0xff))
|
||||||
|
eq('11111111', funcs.printf('%llb', 0xff))
|
||||||
|
eq('11111111', funcs.printf('%zb', 0xff))
|
||||||
|
end)
|
||||||
|
it('accepts width modifier with %b', function()
|
||||||
|
eq(' 1', funcs.printf('%3b', 1))
|
||||||
|
end)
|
||||||
|
it('accepts prefix modifier with %b', function()
|
||||||
|
eq('0b1', funcs.printf('%#b', 1))
|
||||||
|
end)
|
||||||
|
it('writes capital B with %B', function()
|
||||||
|
eq('0B1', funcs.printf('%#B', 1))
|
||||||
|
end)
|
||||||
|
it('accepts prefix, zero-fill and width modifiers with %b', function()
|
||||||
|
eq('0b001', funcs.printf('%#05b', 1))
|
||||||
|
end)
|
||||||
|
it('accepts prefix and width modifiers with %b', function()
|
||||||
|
eq(' 0b1', funcs.printf('%#5b', 1))
|
||||||
|
end)
|
||||||
|
it('does not write prefix for zero with prefix and width modifier used with %b', function()
|
||||||
|
eq(' 0', funcs.printf('%#5b', 0))
|
||||||
|
end)
|
||||||
|
it('accepts precision modifier with %b', function()
|
||||||
|
eq('00000', funcs.printf('%.5b', 0))
|
||||||
|
end)
|
||||||
|
it('accepts all modifiers with %b at once', function()
|
||||||
|
-- zero-fill modifier is ignored when used with left-align
|
||||||
|
-- force-sign and add-blank are ignored
|
||||||
|
-- use-grouping-characters modifier is ignored always
|
||||||
|
eq('0b00011 ', funcs.printf('% \'+#0-10.5b', 3))
|
||||||
|
end)
|
||||||
|
it('errors out when %b modifier is used for a list', function()
|
||||||
|
eq('Vim(call):E745: Using a List as a Number', exc_exec('call printf("%b", [])'))
|
||||||
|
end)
|
||||||
|
it('errors out when %b modifier is used for a float', function()
|
||||||
|
eq('Vim(call):E805: Using a Float as a Number', exc_exec('call printf("%b", 3.1415926535)'))
|
||||||
|
end)
|
||||||
|
end)
|
@ -11,34 +11,40 @@ describe('increment and decrement commands', function()
|
|||||||
it('should work', function()
|
it('should work', function()
|
||||||
-- Insert some numbers in various bases.
|
-- Insert some numbers in various bases.
|
||||||
insert([[
|
insert([[
|
||||||
100 0x100 077 0
|
0b101 100 0x100 077 0
|
||||||
100 0x100 077
|
0b101 100 0x100 077
|
||||||
100 0x100 077 0xfF 0xFf
|
100 0x100 077 0xfF 0xFf
|
||||||
100 0x100 077]])
|
100 0x100 077
|
||||||
|
0x0b101 0b1101]])
|
||||||
|
|
||||||
-- Increment and decrement numbers in the first row, interpreting the
|
-- Increment and decrement numbers in the first row, interpreting the
|
||||||
-- numbers as decimal, octal or hexadecimal.
|
-- numbers as decimal, octal or hexadecimal.
|
||||||
execute('set nrformats=octal,hex', '1')
|
execute('set nrformats=bin,octal,hex', '1')
|
||||||
feed('102ll64128$')
|
feed('63l102ll64128$')
|
||||||
|
|
||||||
-- For the second row, treat the numbers as decimal or octal.
|
-- For the second row, treat the numbers as decimal or octal.
|
||||||
-- 0x100 should be interpreted as decimal 0, the character x, and decimal 100.
|
-- 0x100 should be interpreted as decimal 0, the character x, and decimal 100.
|
||||||
execute('set nrformats=octal', '2')
|
execute('set nrformats=octal', '2')
|
||||||
feed('0102l2w65129blx6lD')
|
feed('0w102l2w65129blx6lD')
|
||||||
|
|
||||||
-- For the third row, treat the numbers as decimal or hexadecimal.
|
-- For the third row, treat the numbers as decimal or hexadecimal.
|
||||||
-- 077 should be interpreted as decimal 77.
|
-- 077 should be interpreted as decimal 77.
|
||||||
execute('set nrformats=hex', '3')
|
execute('set nrformats=hex', '3')
|
||||||
feed('0101l257Txldt ')
|
feed('0101l257Txldt ')
|
||||||
|
|
||||||
-- For the last row, interpret all numbers as decimal.
|
-- For the fourth row, interpret all numbers as decimal.
|
||||||
execute('set nrformats=', '4')
|
execute('set nrformats=', '4')
|
||||||
feed('0200l100w78')
|
feed('0200l100w78')
|
||||||
|
|
||||||
|
-- For the last row, interpret as binary and hexadecimal.
|
||||||
|
execute('set nrformats=bin,hex', '5')
|
||||||
|
feed('010065l6432')
|
||||||
|
|
||||||
expect([[
|
expect([[
|
||||||
0 0x0ff 0000 -1
|
0b011 0 0x0ff 0000 -1
|
||||||
0 1x100 0777777
|
1b101 0 1x100 0777777
|
||||||
-1 0x0 078 0xFE 0xfe
|
-1 0x0 078 0xFE 0xfe
|
||||||
-100 -100x100 000]])
|
-100 -100x100 000
|
||||||
|
0x0b0de 0b0101101]])
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
@ -600,4 +600,39 @@ describe(':sort', function()
|
|||||||
eq('Vim(sort):E474: Invalid argument', eval('tmpvar'))
|
eq('Vim(sort):E474: Invalid argument', eval('tmpvar'))
|
||||||
expect(text)
|
expect(text)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('binary', function()
|
||||||
|
insert([[
|
||||||
|
0b111000
|
||||||
|
0b101100
|
||||||
|
0b101001
|
||||||
|
0b101001
|
||||||
|
0b101000
|
||||||
|
0b000000
|
||||||
|
0b001000
|
||||||
|
0b010000
|
||||||
|
0b101000
|
||||||
|
0b100000
|
||||||
|
0b101010
|
||||||
|
0b100010
|
||||||
|
0b100100
|
||||||
|
0b100010]])
|
||||||
|
execute([[sort b]])
|
||||||
|
expect([[
|
||||||
|
0b000000
|
||||||
|
0b001000
|
||||||
|
0b010000
|
||||||
|
0b100000
|
||||||
|
0b100010
|
||||||
|
0b100010
|
||||||
|
0b100100
|
||||||
|
0b101000
|
||||||
|
0b101000
|
||||||
|
0b101001
|
||||||
|
0b101001
|
||||||
|
0b101010
|
||||||
|
0b101100
|
||||||
|
0b111000]])
|
||||||
|
end)
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user