diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/charset.c | 37 | ||||
-rw-r--r-- | src/nvim/eval.c | 26 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 35 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 4 | ||||
-rw-r--r-- | src/nvim/keymap.c | 4 | ||||
-rw-r--r-- | src/nvim/ops.c | 19 | ||||
-rw-r--r-- | src/nvim/option.c | 2 | ||||
-rw-r--r-- | src/nvim/spell.c | 4 | ||||
-rw-r--r-- | src/nvim/testdir/test_increment.in | 114 | ||||
-rw-r--r-- | src/nvim/testdir/test_increment.ok | 47 | ||||
-rw-r--r-- | src/nvim/version.c | 2 | ||||
-rw-r--r-- | src/nvim/vim.h | 10 |
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 |