mirror of
https://github.com/vim/vim
synced 2025-03-18 07:47:09 +01:00
patch 7.4.1027
Problem: No support for binary numbers. Solution: Add "bin" to nrformats. (Jason Schulz)
This commit is contained in:
parent
acf92d27c9
commit
887c1fea4a
19 changed files with 489 additions and 79 deletions
|
@ -416,9 +416,14 @@ CTRL-X Subtract [count] from the number or alphabetic
|
|||
additional [count] (so effectively creating a [count]
|
||||
decrementing sequence). {not in Vi}
|
||||
|
||||
The CTRL-A and CTRL-X commands work for (signed) decimal numbers, unsigned
|
||||
octal and hexadecimal numbers and alphabetic characters. This depends on the
|
||||
'nrformats' option.
|
||||
The CTRL-A and CTRL-X commands can work for:
|
||||
- signed and unsigned decimal numbers
|
||||
- unsigned binary, octal and hexadecimal numbers
|
||||
- alphabetic characters
|
||||
|
||||
This depends on the 'nrformats' option:
|
||||
- When 'nrformats' includes "bin", Vim assumes numbers starting with '0b' or
|
||||
'0B' are binary.
|
||||
- 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
|
||||
decimal and may have a preceding minus sign.
|
||||
|
@ -447,6 +452,10 @@ octal number.
|
|||
Note that when 'nrformats' includes "octal", decimal numbers with leading
|
||||
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
|
||||
steps to make a numbered list.
|
||||
|
||||
|
@ -1736,7 +1745,7 @@ Vim has a sorting function and a sorting command. The sorting function can be
|
|||
found here: |sort()|, |uniq()|.
|
||||
|
||||
*: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
|
||||
lines are sorted.
|
||||
|
||||
|
@ -1756,6 +1765,9 @@ found here: |sort()|, |uniq()|.
|
|||
With [o] sorting is done on the first octal number in
|
||||
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
|
||||
identical lines (ignoring case when [i] is used).
|
||||
Without this flag, a sequence of identical lines
|
||||
|
|
|
@ -931,7 +931,7 @@ New and extended functions: ~
|
|||
|spellbadword()| get a badly spelled word
|
||||
|spellsuggest()| get suggestions for correct spelling
|
||||
|split()| split a String into a List
|
||||
|str2nr()| convert a string to a number, base 8, 10 or 16
|
||||
|str2nr()| convert a string to a number, base 2, 8, 10 or 16
|
||||
|stridx()| extra argument: start position
|
||||
|strridx()| extra argument: start position
|
||||
|string()| string representation of a List or Dictionary
|
||||
|
|
118
src/charset.c
118
src/charset.c
|
@ -1569,6 +1569,20 @@ skipdigits(q)
|
|||
}
|
||||
|
||||
#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) || defined(PROTO)
|
||||
/*
|
||||
* skip over binary digits
|
||||
*/
|
||||
char_u *
|
||||
skipbin(q)
|
||||
char_u *q;
|
||||
{
|
||||
char_u *p = q;
|
||||
|
||||
while (vim_isbdigit(*p)) /* skip to next non-digit */
|
||||
++p;
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* skip over digits and hex characters
|
||||
*/
|
||||
|
@ -1585,6 +1599,20 @@ skiphex(q)
|
|||
#endif
|
||||
|
||||
#if defined(FEAT_EX_EXTRA) || defined(PROTO)
|
||||
/*
|
||||
* skip to bin digit (or NUL after the string)
|
||||
*/
|
||||
char_u *
|
||||
skiptobin(q)
|
||||
char_u *q;
|
||||
{
|
||||
char_u *p = q;
|
||||
|
||||
while (*p != NUL && !vim_isbdigit(*p)) /* skip to next digit */
|
||||
++p;
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* skip to digit (or NUL after the string)
|
||||
*/
|
||||
|
@ -1641,6 +1669,17 @@ vim_isxdigit(c)
|
|||
|| (c >= 'A' && c <= 'F');
|
||||
}
|
||||
|
||||
/*
|
||||
* Corollary of vim_isdigit and vim_isxdigit() that can handle
|
||||
* characters > 0x100.
|
||||
*/
|
||||
int
|
||||
vim_isbdigit(c)
|
||||
int c;
|
||||
{
|
||||
return (c == '0' || c == '1');
|
||||
}
|
||||
|
||||
#if defined(FEAT_MBYTE) || defined(PROTO)
|
||||
/*
|
||||
* Vim's own character class functions. These exist because many library
|
||||
|
@ -1822,35 +1861,37 @@ vim_isblankline(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 "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.
|
||||
* If "what" contains STR2NR_BIN recognize binary numbers
|
||||
* If "what" contains STR2NR_OCT recognize octal numbers
|
||||
* If "what" contains STR2NR_HEX recognize hex numbers
|
||||
* If "what" contains STR2NR_FORCE always assume bin/oct/hex.
|
||||
* If maxlen > 0, check at a maximum maxlen chars
|
||||
*/
|
||||
void
|
||||
vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr, maxlen)
|
||||
vim_str2nr(start, prep, len, what, nptr, unptr, maxlen)
|
||||
char_u *start;
|
||||
int *hexp; /* return: type of number 0 = decimal, 'x'
|
||||
or 'X' is hex, '0' = octal */
|
||||
int *prep; /* return: type of number 0 = decimal, 'x'
|
||||
or 'X' is hex, '0' = octal, 'b' or 'B'
|
||||
is bin */
|
||||
int *len; /* return: detected length of number */
|
||||
int dooct; /* recognize octal number */
|
||||
int dohex; /* recognize hex number */
|
||||
int what; /* what numbers to recognize */
|
||||
long *nptr; /* return: signed result */
|
||||
unsigned long *unptr; /* return: unsigned result */
|
||||
int maxlen; /* max length of string to check */
|
||||
{
|
||||
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;
|
||||
|
@ -1861,29 +1902,37 @@ vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr, maxlen)
|
|||
++ptr;
|
||||
}
|
||||
|
||||
/* Recognize hex and octal. */
|
||||
/* Recognize hex, octal, and bin. */
|
||||
if (ptr[0] == '0' && ptr[1] != '8' && ptr[1] != '9'
|
||||
&& (maxlen == 0 || maxlen > 1))
|
||||
{
|
||||
hex = ptr[1];
|
||||
if (dohex && (hex == 'X' || hex == 'x') && vim_isxdigit(ptr[2])
|
||||
&& (maxlen == 0 || maxlen > 2))
|
||||
ptr += 2; /* hexadecimal */
|
||||
pre = ptr[1];
|
||||
if ((what & STR2NR_HEX)
|
||||
&& (pre == 'X' || pre == 'x') && vim_isxdigit(ptr[2])
|
||||
&& (maxlen == 0 || maxlen > 2))
|
||||
/* hexadecimal */
|
||||
ptr += 2;
|
||||
else if ((what & STR2NR_BIN)
|
||||
&& (pre == 'B' || pre == 'b') && vim_isbdigit(ptr[2])
|
||||
&& (maxlen == 0 || maxlen > 2))
|
||||
/* binary */
|
||||
ptr += 2;
|
||||
else
|
||||
{
|
||||
hex = 0; /* default is decimal */
|
||||
if (dooct)
|
||||
/* decimal or octal, default is decimal */
|
||||
pre = 0;
|
||||
if (what & STR2NR_OCT)
|
||||
{
|
||||
/* Don't interpret "0", "08" or "0129" as octal. */
|
||||
for (n = 1; VIM_ISDIGIT(ptr[n]); ++n)
|
||||
{
|
||||
if (ptr[n] > '7')
|
||||
{
|
||||
hex = 0; /* can't be octal */
|
||||
pre = 0; /* can't be octal */
|
||||
break;
|
||||
}
|
||||
if (ptr[n] >= '0')
|
||||
hex = '0'; /* assume octal */
|
||||
pre = '0'; /* assume octal */
|
||||
if (n == maxlen)
|
||||
break;
|
||||
}
|
||||
|
@ -1892,10 +1941,23 @@ vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr, maxlen)
|
|||
}
|
||||
|
||||
/*
|
||||
* Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
|
||||
*/
|
||||
* Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
|
||||
*/
|
||||
n = 1;
|
||||
if (hex == '0' || dooct > 1)
|
||||
if (pre == 'B' || pre == 'b' || what == STR2NR_BIN + STR2NR_FORCE)
|
||||
{
|
||||
/* bin */
|
||||
if (pre != 0)
|
||||
n += 2; /* skip over "0b" */
|
||||
while ('0' <= *ptr && *ptr <= '1')
|
||||
{
|
||||
un = 2 * un + (unsigned long)(*ptr - '0');
|
||||
++ptr;
|
||||
if (n++ == maxlen)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (pre == '0' || what == STR2NR_OCT + STR2NR_FORCE)
|
||||
{
|
||||
/* octal */
|
||||
while ('0' <= *ptr && *ptr <= '7')
|
||||
|
@ -1906,10 +1968,10 @@ vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr, maxlen)
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (hex != 0 || dohex > 1)
|
||||
else if (pre != 0 || what == STR2NR_HEX + STR2NR_FORCE)
|
||||
{
|
||||
/* hex */
|
||||
if (hex != 0)
|
||||
if (pre != 0)
|
||||
n += 2; /* skip over "0x" */
|
||||
while (vim_isxdigit(*ptr))
|
||||
{
|
||||
|
@ -1931,8 +1993,8 @@ vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr, maxlen)
|
|||
}
|
||||
}
|
||||
|
||||
if (hexp != NULL)
|
||||
*hexp = hex;
|
||||
if (prep != NULL)
|
||||
*prep = pre;
|
||||
if (len != NULL)
|
||||
*len = (int)(ptr - start);
|
||||
if (nptr != NULL)
|
||||
|
|
18
src/eval.c
18
src/eval.c
|
@ -1625,7 +1625,7 @@ call_vim_function(func, argc, argv, safe, str_arg_only, rettv)
|
|||
len = 0;
|
||||
else
|
||||
/* Recognize a number argument, the others must be strings. */
|
||||
vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL, 0);
|
||||
vim_str2nr(argv[i], NULL, &len, STR2NR_ALL, &n, NULL, 0);
|
||||
if (len != 0 && len == (int)STRLEN(argv[i]))
|
||||
{
|
||||
argvars[i].v_type = VAR_NUMBER;
|
||||
|
@ -5139,7 +5139,7 @@ eval7(arg, rettv, evaluate, want_string)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL, 0);
|
||||
vim_str2nr(*arg, NULL, &len, STR2NR_ALL, &n, NULL, 0);
|
||||
*arg += len;
|
||||
if (evaluate)
|
||||
{
|
||||
|
@ -18529,11 +18529,12 @@ f_str2nr(argvars, rettv)
|
|||
int base = 10;
|
||||
char_u *p;
|
||||
long n;
|
||||
int what;
|
||||
|
||||
if (argvars[1].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
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));
|
||||
return;
|
||||
|
@ -18543,7 +18544,14 @@ f_str2nr(argvars, rettv)
|
|||
p = skipwhite(get_tv_string(&argvars[0]));
|
||||
if (*p == '+')
|
||||
p = skipwhite(p + 1);
|
||||
vim_str2nr(p, NULL, NULL, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL, 0);
|
||||
switch (base)
|
||||
{
|
||||
case 2: what = STR2NR_BIN + STR2NR_FORCE; break;
|
||||
case 8: what = STR2NR_OCT + STR2NR_FORCE; break;
|
||||
case 16: what = STR2NR_HEX + STR2NR_FORCE; break;
|
||||
default: what = 0;
|
||||
}
|
||||
vim_str2nr(p, NULL, NULL, what, &n, NULL, 0);
|
||||
rettv->vval.v_number = n;
|
||||
}
|
||||
|
||||
|
@ -21349,7 +21357,7 @@ get_tv_number_chk(varp, denote)
|
|||
case VAR_STRING:
|
||||
if (varp->vval.v_string != NULL)
|
||||
vim_str2nr(varp->vval.v_string, NULL, NULL,
|
||||
TRUE, TRUE, &n, NULL, 0);
|
||||
STR2NR_ALL, &n, NULL, 0);
|
||||
return n;
|
||||
case VAR_LIST:
|
||||
EMSG(_("E745: Using a List as a Number"));
|
||||
|
|
|
@ -365,8 +365,8 @@ ex_sort(eap)
|
|||
long deleted;
|
||||
colnr_T start_col;
|
||||
colnr_T end_col;
|
||||
int sort_oct; /* sort on octal number */
|
||||
int sort_hex; /* sort on hex number */
|
||||
int sort_what = 0;
|
||||
int format_found = 0;
|
||||
|
||||
/* Sorting one line is really quick! */
|
||||
if (count <= 1)
|
||||
|
@ -381,7 +381,7 @@ ex_sort(eap)
|
|||
if (nrs == NULL)
|
||||
goto sortend;
|
||||
|
||||
sort_abort = sort_ic = sort_rx = sort_nr = sort_oct = sort_hex = 0;
|
||||
sort_abort = sort_ic = sort_rx = sort_nr = 0;
|
||||
|
||||
for (p = eap->arg; *p != NUL; ++p)
|
||||
{
|
||||
|
@ -392,11 +392,25 @@ ex_sort(eap)
|
|||
else if (*p == 'r')
|
||||
sort_rx = TRUE;
|
||||
else if (*p == 'n')
|
||||
{
|
||||
sort_nr = 2;
|
||||
++format_found;
|
||||
}
|
||||
else if (*p == 'b')
|
||||
{
|
||||
sort_what = STR2NR_BIN + STR2NR_FORCE;
|
||||
++format_found;
|
||||
}
|
||||
else if (*p == 'o')
|
||||
sort_oct = 2;
|
||||
{
|
||||
sort_what = STR2NR_OCT + STR2NR_FORCE;
|
||||
++format_found;
|
||||
}
|
||||
else if (*p == 'x')
|
||||
sort_hex = 2;
|
||||
{
|
||||
sort_what = STR2NR_HEX + STR2NR_FORCE;
|
||||
++format_found;
|
||||
}
|
||||
else if (*p == 'u')
|
||||
unique = TRUE;
|
||||
else if (*p == '"') /* comment start */
|
||||
|
@ -439,15 +453,15 @@ ex_sort(eap)
|
|||
}
|
||||
}
|
||||
|
||||
/* Can only have one of 'n', 'o' and 'x'. */
|
||||
if (sort_nr + sort_oct + sort_hex > 2)
|
||||
/* Can only have one of 'n', 'b', 'o' and 'x'. */
|
||||
if (format_found > 1)
|
||||
{
|
||||
EMSG(_(e_invarg));
|
||||
goto sortend;
|
||||
}
|
||||
|
||||
/* From here on "sort_nr" is used as a flag for any number sorting. */
|
||||
sort_nr += sort_oct + sort_hex;
|
||||
sort_nr += sort_what;
|
||||
|
||||
/*
|
||||
* Make an array with all line numbers. This avoids having to copy all
|
||||
|
@ -489,8 +503,10 @@ ex_sort(eap)
|
|||
*s2 = NUL;
|
||||
/* Sorting on number: Store the number itself. */
|
||||
p = s + start_col;
|
||||
if (sort_hex)
|
||||
if (sort_what & STR2NR_HEX)
|
||||
s = skiptohex(p);
|
||||
else if (sort_what & STR2NR_BIN)
|
||||
s = skiptobin(p);
|
||||
else
|
||||
s = skiptodigit(p);
|
||||
if (s > p && s[-1] == '-')
|
||||
|
@ -499,8 +515,8 @@ ex_sort(eap)
|
|||
/* empty line should sort before any number */
|
||||
nrs[lnum - eap->line1].start_col_nr = -MAXLNUM;
|
||||
else
|
||||
vim_str2nr(s, NULL, NULL, sort_oct, sort_hex,
|
||||
&nrs[lnum - eap->line1].start_col_nr, NULL, 0);
|
||||
vim_str2nr(s, NULL, NULL, sort_what,
|
||||
&nrs[lnum - eap->line1].start_col_nr, NULL, 0);
|
||||
*s2 = c;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -5935,7 +5935,7 @@ get_list_range(str, num1, num2)
|
|||
*str = skipwhite(*str);
|
||||
if (**str == '-' || vim_isdigit(**str)) /* parse "from" part of range */
|
||||
{
|
||||
vim_str2nr(*str, NULL, &len, FALSE, FALSE, &num, NULL, 0);
|
||||
vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0);
|
||||
*str += len;
|
||||
*num1 = (int)num;
|
||||
first = TRUE;
|
||||
|
@ -5944,7 +5944,7 @@ get_list_range(str, num1, num2)
|
|||
if (**str == ',') /* parse "to" part of range */
|
||||
{
|
||||
*str = skipwhite(*str + 1);
|
||||
vim_str2nr(*str, NULL, &len, FALSE, FALSE, &num, NULL, 0);
|
||||
vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0);
|
||||
if (len > 0)
|
||||
{
|
||||
*num2 = (int)num;
|
||||
|
|
|
@ -2780,7 +2780,7 @@ find_special_key(srcp, modp, keycode, keep_x_key)
|
|||
bp += 3; /* skip t_xx, xx may be '-' or '>' */
|
||||
else if (STRNICMP(bp, "char-", 5) == 0)
|
||||
{
|
||||
vim_str2nr(bp + 5, NULL, &l, TRUE, TRUE, NULL, NULL, 0);
|
||||
vim_str2nr(bp + 5, NULL, &l, STR2NR_ALL, NULL, NULL, 0);
|
||||
bp += l + 5;
|
||||
break;
|
||||
}
|
||||
|
@ -2812,7 +2812,7 @@ find_special_key(srcp, modp, keycode, keep_x_key)
|
|||
&& VIM_ISDIGIT(last_dash[6]))
|
||||
{
|
||||
/* <Char-123> or <Char-033> or <Char-0x33> */
|
||||
vim_str2nr(last_dash + 6, NULL, NULL, TRUE, TRUE, NULL, &n, 0);
|
||||
vim_str2nr(last_dash + 6, NULL, NULL, STR2NR_ALL, NULL, &n, 0);
|
||||
key = (int)n;
|
||||
}
|
||||
else
|
||||
|
|
82
src/ops.c
82
src/ops.c
|
@ -5379,7 +5379,7 @@ do_addsub(command, Prenum1, g_cmd)
|
|||
int col;
|
||||
char_u *buf1;
|
||||
char_u buf2[NUMBUFLEN];
|
||||
int hex; /* 'X' or 'x': hex; '0': octal */
|
||||
int pre; /* 'X'/'x': hex; '0': octal; 'B'/'b': bin */
|
||||
static int hexupper = FALSE; /* 0xABC */
|
||||
unsigned long n;
|
||||
unsigned long offset = 0; /* line offset for Ctrl_V mode */
|
||||
|
@ -5390,6 +5390,7 @@ do_addsub(command, Prenum1, g_cmd)
|
|||
int todel;
|
||||
int dohex;
|
||||
int dooct;
|
||||
int dobin;
|
||||
int doalp;
|
||||
int firstdigit;
|
||||
int subtract;
|
||||
|
@ -5403,9 +5404,13 @@ do_addsub(command, Prenum1, g_cmd)
|
|||
int did_change = FALSE;
|
||||
pos_T t = curwin->w_cursor;
|
||||
int maxlen = 0;
|
||||
int pos = 0;
|
||||
int bit = 0;
|
||||
int bits = sizeof(unsigned long) * 8;
|
||||
|
||||
dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL); /* "heX" */
|
||||
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" */
|
||||
|
||||
/*
|
||||
|
@ -5454,17 +5459,45 @@ do_addsub(command, Prenum1, g_cmd)
|
|||
ptr = ml_get_curline();
|
||||
RLADDSUBFIX(ptr);
|
||||
|
||||
if (dobin)
|
||||
while (col > 0 && vim_isbdigit(ptr[col]))
|
||||
--col;
|
||||
|
||||
if (dohex)
|
||||
while (col > 0 && vim_isxdigit(ptr[col]))
|
||||
--col;
|
||||
if ( dohex
|
||||
|
||||
if ( dobin
|
||||
&& dohex
|
||||
&& ! ((col > 0
|
||||
&& (ptr[col] == 'X'
|
||||
|| ptr[col] == 'x')
|
||||
&& ptr[col - 1] == '0'
|
||||
&& vim_isxdigit(ptr[col + 1]))))
|
||||
{
|
||||
|
||||
/* In case of binary/hexadecimal pattern overlap match, rescan */
|
||||
|
||||
col = curwin->w_cursor.col;
|
||||
|
||||
while (col > 0 && vim_isdigit(ptr[col]))
|
||||
col--;
|
||||
}
|
||||
|
||||
if (( dohex
|
||||
&& col > 0
|
||||
&& (ptr[col] == 'X'
|
||||
|| ptr[col] == 'x')
|
||||
&& ptr[col - 1] == '0'
|
||||
&& vim_isxdigit(ptr[col + 1]))
|
||||
&& vim_isxdigit(ptr[col + 1])) ||
|
||||
( dobin
|
||||
&& col > 0
|
||||
&& (ptr[col] == 'B'
|
||||
|| ptr[col] == 'b')
|
||||
&& ptr[col - 1] == '0'
|
||||
&& vim_isbdigit(ptr[col + 1])))
|
||||
{
|
||||
/* Found hexadecimal number, move to its start. */
|
||||
/* Found hexadecimal or binary number, move to its start. */
|
||||
--col;
|
||||
}
|
||||
else
|
||||
|
@ -5609,11 +5642,14 @@ do_addsub(command, Prenum1, g_cmd)
|
|||
: curwin->w_cursor.col - col + 1);
|
||||
}
|
||||
|
||||
vim_str2nr(ptr + col, &hex, &length, dooct, dohex, NULL, &n,
|
||||
maxlen);
|
||||
vim_str2nr(ptr + col, &pre, &length,
|
||||
0 + (dobin ? STR2NR_BIN : 0)
|
||||
+ (dooct ? STR2NR_OCT : 0)
|
||||
+ (dohex ? STR2NR_HEX : 0),
|
||||
NULL, &n, maxlen);
|
||||
|
||||
/* ignore leading '-' for hex and octal numbers */
|
||||
if (hex && negative)
|
||||
/* ignore leading '-' for hex and octal and bin numbers */
|
||||
if (pre && negative)
|
||||
{
|
||||
++col;
|
||||
--length;
|
||||
|
@ -5634,7 +5670,7 @@ do_addsub(command, Prenum1, g_cmd)
|
|||
n += (unsigned long)Prenum1;
|
||||
|
||||
/* handle wraparound for decimal numbers */
|
||||
if (!hex)
|
||||
if (!pre)
|
||||
{
|
||||
if (subtract)
|
||||
{
|
||||
|
@ -5706,25 +5742,37 @@ do_addsub(command, Prenum1, g_cmd)
|
|||
{
|
||||
*ptr++ = '-';
|
||||
}
|
||||
if (hex)
|
||||
if (pre)
|
||||
{
|
||||
*ptr++ = '0';
|
||||
--length;
|
||||
}
|
||||
if (hex == 'x' || hex == 'X')
|
||||
if (pre == 'b' || pre == 'B' ||
|
||||
pre == 'x' || pre == 'X')
|
||||
{
|
||||
*ptr++ = hex;
|
||||
*ptr++ = pre;
|
||||
--length;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the number characters in buf2[].
|
||||
*/
|
||||
if (hex == 0)
|
||||
if (pre == 'b' || pre == 'B')
|
||||
{
|
||||
/* leading zeros */
|
||||
for (bit = bits; bit > 0; bit--)
|
||||
if ((n >> (bit - 1)) & 0x1) break;
|
||||
|
||||
for (pos = 0; bit > 0; bit--)
|
||||
buf2[pos++] = ((n >> (bit - 1)) & 0x1) ? '1' : '0';
|
||||
|
||||
buf2[pos] = '\0';
|
||||
}
|
||||
else if (pre == 0)
|
||||
sprintf((char *)buf2, "%lu", n);
|
||||
else if (hex == '0')
|
||||
else if (pre == '0')
|
||||
sprintf((char *)buf2, "%lo", n);
|
||||
else if (hex && hexupper)
|
||||
else if (pre && hexupper)
|
||||
sprintf((char *)buf2, "%lX", n);
|
||||
else
|
||||
sprintf((char *)buf2, "%lx", n);
|
||||
|
@ -5736,7 +5784,7 @@ do_addsub(command, Prenum1, g_cmd)
|
|||
* Don't do this when
|
||||
* the result may look like an octal number.
|
||||
*/
|
||||
if (firstdigit == '0' && !(dooct && hex == 0))
|
||||
if (firstdigit == '0' && !(dooct && pre == 0))
|
||||
while (length-- > 0)
|
||||
*ptr++ = '0';
|
||||
*ptr = NUL;
|
||||
|
@ -6359,7 +6407,7 @@ get_reg_type(regname, reglen)
|
|||
#endif
|
||||
|
||||
if (regname != NUL && !valid_yank_reg(regname, FALSE))
|
||||
return MAUTO;
|
||||
return MAUTO;
|
||||
|
||||
get_yank_register(regname, FALSE);
|
||||
|
||||
|
|
|
@ -1940,7 +1940,7 @@ static struct vimoption
|
|||
{(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
|
||||
{"nrformats", "nf", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP,
|
||||
(char_u *)&p_nf, PV_NF,
|
||||
{(char_u *)"octal,hex", (char_u *)0L}
|
||||
{(char_u *)"bin,octal,hex", (char_u *)0L}
|
||||
SCRIPTID_INIT},
|
||||
{"number", "nu", P_BOOL|P_VI_DEF|P_RWIN,
|
||||
(char_u *)VAR_WIN, PV_NU,
|
||||
|
@ -3031,7 +3031,7 @@ static struct vimoption
|
|||
static char *(p_ambw_values[]) = {"single", "double", NULL};
|
||||
#endif
|
||||
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};
|
||||
#ifdef FEAT_CRYPT
|
||||
static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2", NULL};
|
||||
|
@ -4579,7 +4579,8 @@ do_set(arg, opt_flags)
|
|||
{
|
||||
/* Allow negative (for 'undolevels'), octal and
|
||||
* hex numbers. */
|
||||
vim_str2nr(arg, NULL, &i, TRUE, TRUE, &value, NULL, 0);
|
||||
vim_str2nr(arg, NULL, &i, STR2NR_ALL,
|
||||
&value, NULL, 0);
|
||||
if (arg[i] != NUL && !vim_iswhite(arg[i]))
|
||||
{
|
||||
errmsg = e_invarg;
|
||||
|
|
|
@ -36,11 +36,14 @@ void getvvcol __ARGS((win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, co
|
|||
void getvcols __ARGS((win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right));
|
||||
char_u *skipwhite __ARGS((char_u *q));
|
||||
char_u *skipdigits __ARGS((char_u *q));
|
||||
char_u *skipbin __ARGS((char_u *q));
|
||||
char_u *skiphex __ARGS((char_u *q));
|
||||
char_u *skiptobin __ARGS((char_u *q));
|
||||
char_u *skiptodigit __ARGS((char_u *q));
|
||||
char_u *skiptohex __ARGS((char_u *q));
|
||||
int vim_isdigit __ARGS((int c));
|
||||
int vim_isxdigit __ARGS((int c));
|
||||
int vim_isbdigit __ARGS((int c));
|
||||
int vim_islower __ARGS((int c));
|
||||
int vim_isupper __ARGS((int c));
|
||||
int vim_toupper __ARGS((int c));
|
||||
|
@ -49,7 +52,7 @@ char_u *skiptowhite __ARGS((char_u *p));
|
|||
char_u *skiptowhite_esc __ARGS((char_u *p));
|
||||
long getdigits __ARGS((char_u **pp));
|
||||
int vim_isblankline __ARGS((char_u *lbuf));
|
||||
void vim_str2nr __ARGS((char_u *start, int *hexp, int *len, int dooct, int dohex, long *nptr, unsigned long *unptr, int strlen));
|
||||
void vim_str2nr __ARGS((char_u *start, int *prep, int *len, int what, long *nptr, unsigned long *unptr, int maxlen));
|
||||
int hex2nr __ARGS((int c));
|
||||
int hexhex2nr __ARGS((char_u *p));
|
||||
int rem_backslash __ARGS((char_u *str));
|
||||
|
|
|
@ -1047,7 +1047,9 @@ spell_check(wp, ptr, attrp, capcol, docount)
|
|||
* julifeest". */
|
||||
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);
|
||||
else
|
||||
mi.mi_end = skipdigits(ptr);
|
||||
|
@ -15612,7 +15614,7 @@ ex_spelldump(eap)
|
|||
|
||||
/* enable spelling locally in the new window */
|
||||
set_option_value((char_u*)"spell", TRUE, (char_u*)"", OPT_LOCAL);
|
||||
set_option_value((char_u*)"spl", dummy, spl, OPT_LOCAL);
|
||||
set_option_value((char_u*)"spl", dummy, spl, OPT_LOCAL);
|
||||
vim_free(spl);
|
||||
|
||||
if (!bufempty() || !buf_valid(curbuf))
|
||||
|
|
|
@ -30,6 +30,8 @@ STARTTEST
|
|||
:/^t25:/+1,/^t26/-1sort/\d\d/rn
|
||||
:/^t26:/+1,/^t27/-1sort/\d\d/rx
|
||||
:/^t27:/+1,/^t28/-1sort no
|
||||
:/^t28:/+1,/^t29/-1sort b
|
||||
:/^t29:/+1,/^t30/-1sort b
|
||||
:/^t01:/,$wq! test.out
|
||||
ENDTEST
|
||||
|
||||
|
@ -494,7 +496,38 @@ c321d
|
|||
b322b
|
||||
b321
|
||||
b321b
|
||||
t28: binary
|
||||
|
||||
|
||||
t28: done
|
||||
0b111000
|
||||
0b101100
|
||||
0b101001
|
||||
0b101001
|
||||
0b101000
|
||||
0b000000
|
||||
0b001000
|
||||
0b010000
|
||||
0b101000
|
||||
0b100000
|
||||
0b101010
|
||||
0b100010
|
||||
0b100100
|
||||
0b100010
|
||||
t29: binary with leading characters
|
||||
|
||||
|
||||
0b100010
|
||||
0b010000
|
||||
0b101001
|
||||
b0b101100
|
||||
0b100010
|
||||
0b100100
|
||||
a0b001000
|
||||
0b101000
|
||||
0b101000
|
||||
a0b101001
|
||||
ab0b100000
|
||||
0b101010
|
||||
0b000000
|
||||
b0b111000
|
||||
t30: done
|
||||
|
|
|
@ -453,7 +453,38 @@ c321d
|
|||
b322b
|
||||
b321
|
||||
b321b
|
||||
t28: binary
|
||||
|
||||
|
||||
t28: done
|
||||
0b000000
|
||||
0b001000
|
||||
0b010000
|
||||
0b100000
|
||||
0b100010
|
||||
0b100010
|
||||
0b100100
|
||||
0b101000
|
||||
0b101000
|
||||
0b101001
|
||||
0b101001
|
||||
0b101010
|
||||
0b101100
|
||||
0b111000
|
||||
t29: binary with leading characters
|
||||
|
||||
|
||||
0b000000
|
||||
a0b001000
|
||||
0b010000
|
||||
ab0b100000
|
||||
0b100010
|
||||
0b100010
|
||||
0b100100
|
||||
0b101000
|
||||
0b101000
|
||||
0b101001
|
||||
a0b101001
|
||||
0b101010
|
||||
b0b101100
|
||||
b0b111000
|
||||
t30: done
|
||||
|
|
|
@ -104,6 +104,8 @@ gg:/^addstart/+1,/^addend/-1w! Xtest.latin1.add
|
|||
:"
|
||||
:" NOSLITSUGS
|
||||
:call TestOne('8', '8')
|
||||
:" Numbers
|
||||
:call TestOne('9', '9')
|
||||
:"
|
||||
:" clean up for valgrind
|
||||
:delfunc TestOne
|
||||
|
@ -636,4 +638,19 @@ bad: foobar barfoo
|
|||
badend
|
||||
|
||||
|
||||
Test Numbers
|
||||
|
||||
9affstart
|
||||
9affend
|
||||
|
||||
9dicstart
|
||||
1234
|
||||
foo
|
||||
bar
|
||||
9dicend
|
||||
|
||||
9good: 0b1011 0777 1234 0x01ff
|
||||
badend
|
||||
|
||||
|
||||
test output:
|
||||
|
|
|
@ -281,3 +281,9 @@ foobar
|
|||
['faabar', 'foo bar', 'bar']
|
||||
barfoo
|
||||
['bar foo', 'bar', 'foo']
|
||||
|
||||
test 9-9
|
||||
# file: Xtest.latin1.spl
|
||||
bar
|
||||
foo
|
||||
-------
|
||||
|
|
|
@ -286,6 +286,49 @@ Text:
|
|||
1) Ctrl-V f3 <ctrl-a>
|
||||
0x124456
|
||||
|
||||
22) Block increment on 0b0
|
||||
Text:
|
||||
0b1
|
||||
0b1
|
||||
Expected:
|
||||
1) Ctrl-A on visually block selected region (cursor at beginning):
|
||||
0b10
|
||||
0b10
|
||||
2) Ctrl-A on visually block selected region (cursor at end)
|
||||
0b10
|
||||
0b10
|
||||
|
||||
23) block-wise increment on part of binary
|
||||
Text:
|
||||
0b1001
|
||||
|
||||
Expected:
|
||||
1) Ctrl-V 5l <ctrl-a>
|
||||
0b1011
|
||||
|
||||
24) increment hexadecimal
|
||||
Text:
|
||||
0x0b1001
|
||||
|
||||
Expected:
|
||||
1) <ctrl-a>
|
||||
0x0b1002
|
||||
|
||||
25) increment binary with nrformats including alpha
|
||||
Text:
|
||||
0b1001a
|
||||
|
||||
Expected:
|
||||
1) <ctrl-a>
|
||||
0b1010a
|
||||
|
||||
26) increment binary with 64 bits
|
||||
Text:
|
||||
0b1111111111111111111111111111111111111111111111111111111111111110
|
||||
|
||||
Expected:
|
||||
1) <ctrl-a>
|
||||
0b1111111111111111111111111111111111111111111111111111111111111111
|
||||
|
||||
|
||||
STARTTEST
|
||||
|
@ -415,6 +458,38 @@ V3kg..
|
|||
:set nrformats&vim
|
||||
f3
|
||||
|
||||
:" Test 22
|
||||
:/^S22=/+,/^E22=/-y a
|
||||
:/^E22=/+put a
|
||||
kj$j:.+put a
|
||||
k$+
|
||||
|
||||
:" Test 23
|
||||
:/^S23=/+,/^E23=/-y a
|
||||
:/^E23=/+put a
|
||||
:set nrformats&vim
|
||||
4l
|
||||
|
||||
:" Test 24
|
||||
:/^S24=/+,/^E24=/-y a
|
||||
:/^E24=/+put a
|
||||
:set nrformats&vim
|
||||
$
|
||||
|
||||
:" Test 25
|
||||
:set nrformats+=alpha
|
||||
:/^S25=/+,/^E25=/-y a
|
||||
:/^E25=/+put a
|
||||
k$
|
||||
:set nrformats&vim
|
||||
|
||||
:" Test 26
|
||||
:set nrformats+=alpha
|
||||
:/^S26=/+,/^E26=/-y a
|
||||
:/^E26=/+put a
|
||||
k$
|
||||
:set nrformats&vim
|
||||
|
||||
:" Save the report
|
||||
:/^# Test 1/,$w! test.out
|
||||
:qa!
|
||||
|
@ -615,6 +690,45 @@ E21====
|
|||
|
||||
|
||||
|
||||
# Test 22
|
||||
S22====
|
||||
0b1
|
||||
0b1
|
||||
E22====
|
||||
|
||||
|
||||
|
||||
|
||||
# Test 23
|
||||
S23====
|
||||
0b1001
|
||||
E23====
|
||||
|
||||
|
||||
|
||||
|
||||
# Test 24
|
||||
S24====
|
||||
0x0b1001
|
||||
E24====
|
||||
|
||||
|
||||
|
||||
|
||||
# Test 25
|
||||
S25====
|
||||
0b1001a
|
||||
E25====
|
||||
|
||||
|
||||
|
||||
|
||||
# Test 26
|
||||
S26====
|
||||
0b1111111111111111111111111111111111111111111111111111111111111110
|
||||
E26====
|
||||
|
||||
|
||||
|
||||
ENDTEST
|
||||
|
||||
|
|
|
@ -288,6 +288,53 @@ E21====
|
|||
0x124456
|
||||
|
||||
|
||||
# Test 22
|
||||
S22====
|
||||
0b1
|
||||
0b1
|
||||
E22====
|
||||
|
||||
0b10
|
||||
0b10
|
||||
|
||||
0b10
|
||||
0b10
|
||||
|
||||
|
||||
# Test 23
|
||||
S23====
|
||||
0b1001
|
||||
E23====
|
||||
|
||||
0b1011
|
||||
|
||||
|
||||
|
||||
# Test 24
|
||||
S24====
|
||||
0x0b1001
|
||||
E24====
|
||||
|
||||
0x0b1002
|
||||
|
||||
|
||||
|
||||
# Test 25
|
||||
S25====
|
||||
0b1001a
|
||||
E25====
|
||||
|
||||
0b1010a
|
||||
|
||||
|
||||
|
||||
# Test 26
|
||||
S26====
|
||||
0b1111111111111111111111111111111111111111111111111111111111111110
|
||||
E26====
|
||||
|
||||
0b1111111111111111111111111111111111111111111111111111111111111111
|
||||
|
||||
|
||||
ENDTEST
|
||||
|
||||
|
|
|
@ -741,6 +741,8 @@ static char *(features[]) =
|
|||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1027,
|
||||
/**/
|
||||
1026,
|
||||
/**/
|
||||
|
|
10
src/vim.h
10
src/vim.h
|
@ -392,7 +392,15 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#define NUMBUFLEN 30 /* length of a buffer to store a number in ASCII */
|
||||
/* length of a buffer to store a number in ASCII (64 bits binary + NUL) */
|
||||
#define NUMBUFLEN 65
|
||||
|
||||
/* flags for vim_str2nr() */
|
||||
#define STR2NR_BIN 1
|
||||
#define STR2NR_OCT 2
|
||||
#define STR2NR_HEX 4
|
||||
#define STR2NR_ALL (STR2NR_BIN + STR2NR_OCT + STR2NR_HEX)
|
||||
#define STR2NR_FORCE 8 /* only when ONE of the above is used */
|
||||
|
||||
/*
|
||||
* Shorthand for unsigned variables. Many systems, but not all, have u_char
|
||||
|
|
Loading…
Add table
Reference in a new issue