aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/charset.c37
-rw-r--r--src/nvim/eval.c26
-rw-r--r--src/nvim/ex_cmds.c35
-rw-r--r--src/nvim/ex_getln.c4
-rw-r--r--src/nvim/keymap.c4
-rw-r--r--src/nvim/ops.c19
-rw-r--r--src/nvim/option.c2
-rw-r--r--src/nvim/spell.c4
-rw-r--r--src/nvim/testdir/test_increment.in114
-rw-r--r--src/nvim/testdir/test_increment.ok47
-rw-r--r--src/nvim/version.c2
-rw-r--r--src/nvim/vim.h10
12 files changed, 246 insertions, 58 deletions
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 02d4baaaef..9a0e1440cc 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -1767,31 +1767,26 @@ int vim_isblankline(char_u *lbuf)
/// 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.
+/// 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.
///
/// @param start
/// @param prep Returns type of number 0 = decimal, 'x' or 'X' is hex,
-// '0' = octal, 'b' or 'B' is bin
+/// '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 what Recognizes what number passed.
/// @param nptr Returns the signed result.
/// @param unptr Returns the unsigned result.
/// @param maxlen Max length of string to check.
-void vim_str2nr(char_u *start, int *prep, int *len,
- int dobin, int dooct, int dohex,
+void vim_str2nr(char_u *start, int *prep, int *len, int what,
long *nptr, unsigned long *unptr, int maxlen)
{
char_u *ptr = start;
int pre = 0; // default is decimal
- int negative = false;
+ bool negative = false;
unsigned long un = 0;
if (ptr[0] == '-') {
@@ -1804,23 +1799,23 @@ void vim_str2nr(char_u *start, int *prep, int *len,
&& (maxlen == 0 || maxlen > 1)) {
pre = ptr[1];
- if (dohex
+ if ((what & STR2NR_HEX)
&& ((pre == 'X') || (pre == 'x'))
&& ascii_isxdigit(ptr[2])
&& (maxlen == 0 || maxlen > 2)) {
// hexadecimal
ptr += 2;
- } else if (dobin
+ } else if ((what & STR2NR_BIN)
&& ((pre == 'B') || (pre == 'b'))
&& ascii_isbdigit(ptr[2])
&& (maxlen == 0 || maxlen > 2)) {
// binary
ptr += 2;
} else {
- // default is decimal
+ // decimal or octal, default is decimal
pre = 0;
- if (dooct) {
+ if (what & STR2NR_OCT) {
// Don't interpret "0", "08" or "0129" as octal.
for (int n = 1; ascii_isdigit(ptr[n]); ++n) {
if (ptr[n] > '7') {
@@ -1844,6 +1839,9 @@ void vim_str2nr(char_u *start, int *prep, int *len,
int n = 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++;
@@ -1851,7 +1849,7 @@ void vim_str2nr(char_u *start, int *prep, int *len,
break;
}
}
- } else if ((pre == '0') || (dooct > 1)) {
+ } else if ((pre == '0') || what == STR2NR_OCT + STR2NR_FORCE) {
// octal
while ('0' <= *ptr && *ptr <= '7') {
un = 8 * un + (unsigned long)(*ptr - '0');
@@ -1860,7 +1858,8 @@ void vim_str2nr(char_u *start, int *prep, int *len,
break;
}
}
- } else if ((pre == 'X') || (pre == 'x') || dohex > 1) {
+ } else if ((pre == 'X') || (pre == 'x')
+ || what == STR2NR_HEX + STR2NR_FORCE) {
// hex
if (pre != 0) {
n += 2; // skip over "0x"
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 52c22b19b9..b591c91147 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -1147,7 +1147,7 @@ int call_vim_function(
len = 0;
} else {
// Recognize a number argument, the others must be strings.
- vim_str2nr(argv[i], NULL, &len, true, 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;
@@ -4138,7 +4138,7 @@ static int eval7(
rettv->vval.v_float = f;
}
} else {
- vim_str2nr(*arg, NULL, &len, true, true, true, &n, NULL, 0);
+ vim_str2nr(*arg, NULL, &len, STR2NR_ALL, &n, NULL, 0);
*arg += len;
if (evaluate) {
rettv->v_type = VAR_NUMBER;
@@ -16037,6 +16037,7 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv)
int base = 10;
char_u *p;
long n;
+ int what;
if (argvars[1].v_type != VAR_UNKNOWN) {
base = get_tv_number(&argvars[1]);
@@ -16050,11 +16051,20 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv)
if (*p == '+') {
p = skipwhite(p + 1);
}
- vim_str2nr(p, NULL, NULL,
- base == 2 ? 2 : 0,
- 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;
}
@@ -18336,7 +18346,7 @@ long get_tv_number_chk(typval_T *varp, int *denote)
case VAR_STRING:
if (varp->vval.v_string != NULL) {
vim_str2nr(varp->vval.v_string, NULL, NULL,
- true, true, true, &n, NULL, 0);
+ STR2NR_ALL, &n, NULL, 0);
}
return n;
case VAR_LIST:
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 5cabb9b820..a517037431 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -342,27 +342,27 @@ void ex_sort(exarg_T *eap)
char_u *s;
char_u *s2;
char_u c; // temporary character storage
- int unique = false;
+ bool unique = false;
long deleted;
colnr_T start_col;
colnr_T end_col;
- int sort_bin; // sort on bin number
- int sort_oct; // sort on octal number
- int sort_hex; // sort on hex number
+ int sort_what = 0;
// Sorting one line is really quick!
if (count <= 1) {
return;
}
- if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL)
+ if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL) {
return;
+ }
sortbuf1 = NULL;
sortbuf2 = NULL;
regmatch.regprog = NULL;
sorti_T *nrs = xmalloc(count * sizeof(sorti_T));
- sort_abort = sort_ic = sort_rx = sort_nr = sort_bin = sort_oct = sort_hex = 0;
+ sort_abort = sort_ic = sort_rx = sort_nr = 0;
+ size_t format_found = 0;
for (p = eap->arg; *p != NUL; ++p) {
if (ascii_iswhite(*p)) {
@@ -372,12 +372,16 @@ void ex_sort(exarg_T *eap)
sort_rx = true;
} else if (*p == 'n') {
sort_nr = 2;
+ format_found++;
} else if (*p == 'b') {
- sort_bin = 2;
+ 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 == '"') {
@@ -415,13 +419,13 @@ void ex_sort(exarg_T *eap)
}
// Can only have one of 'n', 'b', 'o' and 'x'.
- if (sort_nr + sort_bin + sort_oct + sort_hex > 2) {
+ 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_bin + sort_oct + sort_hex;
+ sort_nr += sort_what;
// Make an array with all line numbers. This avoids having to copy all
// the lines into allocated memory.
@@ -457,21 +461,22 @@ void ex_sort(exarg_T *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_bin) {
+ } else if (sort_what & STR2NR_BIN) {
s = (char_u*) skiptobin((char*) p);
} else {
s = skiptodigit(p);
}
if (s > p && s[-1] == '-') {
- --s; // include preceding negative sign
+ // include preceding negative sign
+ s--;
}
if (*s == NUL) {
// empty line should sort before any number
nrs[lnum - eap->line1].start_col_nr = -MAXLNUM;
} else {
- vim_str2nr(s, NULL, NULL, sort_bin, sort_oct, sort_hex,
+ vim_str2nr(s, NULL, NULL, sort_what,
&nrs[lnum - eap->line1].start_col_nr, NULL, 0);
}
*s2 = c;
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index d47e2fa954..96bf2c78d2 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -4786,7 +4786,7 @@ int get_list_range(char_u **str, int *num1, int *num2)
*str = skipwhite(*str);
if (**str == '-' || ascii_isdigit(**str)) { // parse "from" part of range
- vim_str2nr(*str, NULL, &len, false, false, false, &num, NULL, 0);
+ vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0);
*str += len;
*num1 = (int)num;
first = true;
@@ -4794,7 +4794,7 @@ int get_list_range(char_u **str, int *num1, int *num2)
*str = skipwhite(*str);
if (**str == ',') { // parse "to" part of range
*str = skipwhite(*str + 1);
- vim_str2nr(*str, NULL, &len, false, false, false, &num, NULL, 0);
+ vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0);
if (len > 0) {
*num2 = (int)num;
*str = skipwhite(*str + len);
diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c
index 6aa42a9801..65c808eb06 100644
--- a/src/nvim/keymap.c
+++ b/src/nvim/keymap.c
@@ -574,7 +574,7 @@ int find_special_key(
if (bp[0] == 't' && bp[1] == '_' && bp[2] && bp[3]) {
bp += 3; // skip t_xx, xx may be '-' or '>'
} else if (STRNICMP(bp, "char-", 5) == 0) {
- vim_str2nr(bp + 5, NULL, &l, true, true, true, NULL, NULL, 0);
+ vim_str2nr(bp + 5, NULL, &l, STR2NR_ALL, NULL, NULL, 0);
bp += l + 5;
break;
}
@@ -600,7 +600,7 @@ int find_special_key(
if (STRNICMP(last_dash + 1, "char-", 5) == 0
&& ascii_isdigit(last_dash[6])) {
// <Char-123> or <Char-033> or <Char-0x33>
- vim_str2nr(last_dash + 6, NULL, NULL, true, true, true, NULL, &n, 0);
+ vim_str2nr(last_dash + 6, NULL, NULL, STR2NR_ALL, NULL, &n, 0);
key = (int)n;
} else {
/*
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index e88d1d611c..c8894d6a91 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -4219,10 +4219,10 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
int c;
int length = 0; // character length of the number
int todel;
- int dohex;
- int dooct;
- int dobin;
- int doalp;
+ bool dohex;
+ bool dooct;
+ bool dobin;
+ bool doalp;
int firstdigit;
bool subtract;
bool negative = false;
@@ -4443,7 +4443,10 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
}
}
- vim_str2nr(ptr + col, &pre, &length, dobin, dooct, dohex,
+ 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, octal and bin numbers
@@ -4540,8 +4543,10 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
size_t pos = 0;
// leading zeros
- for (bits = 8 * sizeof(unsigned long); bits > 0; bits--) {
- if ((n >> (bits - 1)) & 0x1) { break; }
+ for (bits = 8 * sizeof(n); bits > 0; bits--) {
+ if ((n >> (bits - 1)) & 0x1) {
+ break;
+ }
}
while (bits > 0) {
diff --git a/src/nvim/option.c b/src/nvim/option.c
index dd512d2dba..18269f4c18 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -1432,7 +1432,7 @@ do_set (
} else if (*arg == '-' || ascii_isdigit(*arg)) {
// Allow negative (for 'undolevels'), octal and
// hex numbers.
- vim_str2nr(arg, NULL, &i, true, true, true, &value, NULL, 0);
+ vim_str2nr(arg, NULL, &i, STR2NR_ALL, &value, NULL, 0);
if (arg[i] != NUL && !ascii_iswhite(arg[i])) {
errmsg = e_invarg;
goto skip;
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index b2028109be..cc7dc6210c 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -12910,8 +12910,8 @@ void ex_spelldump(exarg_T *eap)
do_cmdline_cmd("new");
// 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*)"spell", true, (char_u*)"", OPT_LOCAL);
+ set_option_value((char_u*)"spl", dummy, spl, OPT_LOCAL);
xfree(spl);
if (!bufempty() || !buf_valid(curbuf))
diff --git a/src/nvim/testdir/test_increment.in b/src/nvim/testdir/test_increment.in
index 2ae6b8a563..753951d40c 100644
--- a/src/nvim/testdir/test_increment.in
+++ b/src/nvim/testdir/test_increment.in
@@ -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
diff --git a/src/nvim/testdir/test_increment.ok b/src/nvim/testdir/test_increment.ok
index 15d0e9b50b..4d8fbb0ae1 100644
--- a/src/nvim/testdir/test_increment.ok
+++ b/src/nvim/testdir/test_increment.ok
@@ -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
diff --git a/src/nvim/version.c b/src/nvim/version.c
index ed58396329..c1a92ac0a8 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -107,7 +107,7 @@ static int included_patches[] = {
// 1030,
// 1029,
// 1028,
- // 1027,
+ 1027,
// 1026,
// 1025,
// 1024,
diff --git a/src/nvim/vim.h b/src/nvim/vim.h
index 2e20d48f90..5f9785a9a9 100644
--- a/src/nvim/vim.h
+++ b/src/nvim/vim.h
@@ -35,7 +35,15 @@ Error: configure did not run properly.Check auto/config.log.
#include "nvim/os/os_defs.h" /* bring lots of system header files */
-#define NUMBUFLEN 65 // 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
#define MAX_TYPENR 65535