]> granicus.if.org Git - vim/commitdiff
patch 7.4.1027 v7.4.1027
authorBram Moolenaar <Bram@vim.org>
Sat, 2 Jan 2016 16:56:35 +0000 (17:56 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 2 Jan 2016 16:56:35 +0000 (17:56 +0100)
Problem:    No support for binary numbers.
Solution:   Add "bin" to nrformats. (Jason Schulz)

19 files changed:
runtime/doc/change.txt
runtime/doc/version7.txt
src/charset.c
src/eval.c
src/ex_cmds.c
src/ex_getln.c
src/misc2.c
src/ops.c
src/option.c
src/proto/charset.pro
src/spell.c
src/testdir/test57.in
src/testdir/test57.ok
src/testdir/test58.in
src/testdir/test58.ok
src/testdir/test_increment.in
src/testdir/test_increment.ok
src/version.c
src/vim.h

index d1fcb5d53c05916f6be546377ccd6ebd0ef3fc2d..6ccf93dfa32bb2f0e92dd25f679e9d564e5aa86a 100644 (file)
@@ -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
index 3e3e32b395f554e60a5fb9dfbd1b72bdace6d2f7..90b80ca9f0ead2b487c1ceef3b48f7f6288df5f8 100644 (file)
@@ -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
index a74bf0d5bf705a091cdb009f39f221e4fe4e4792..1000692cc1932ee11cbe13dfeb7fd113710b734e 100644 (file)
@@ -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)
index 1abb62059c94237815ed79206b57085c7643b66c..c613f4adbd6ea960264c98c801bdefe6443decf0 100644 (file)
@@ -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"));
index 9da5c0956ef6b94880cd0c26e22ff837b19e5fc6..1d0a3856c58737f81844d3df3b5e3121459850d5 100644 (file)
@@ -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
index 391946623e3194b4e3fb87d06627abf0670e7a23..ff058040eafac0a6be287c17d7f4cbcda0563b99 100644 (file)
@@ -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;
index f13a80e223f0d6c9d9eafaa1e88d1a4d6e518c75..9f8d7ad99d30109f3283873a59384d264faef177 100644 (file)
@@ -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
index c86d8de9413ed5a878db9ea94157db5f9322d975..31d7eb1108a006d50a905d6f35bc3b377ae7abae 100644 (file)
--- a/src/ops.c
+++ b/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);
 
index aca0f315fb6692f4c2fc48f65e995644a9ddb6b8..35732114480c3ba81d90e0c7688ec401238e01b0 100644 (file)
@@ -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;
index dd3b6f2a05532c3d5ab21bb5918c7c4338470822..22e43cd7aa97168eca69f2e73d9d8448ea87a441 100644 (file)
@@ -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));
index 5d9c0cceb09c2c27c21041c8f210456c7eae3c31..4db475c07a0360e5c897b155ff913c0b472ecb22 100644 (file)
@@ -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))
index 8d972e4a6888107646f916e4a38cbaa4e3bbeb44..0bb95adc34c9f5dcaefef898af4b33b38b1a0c1a 100644 (file)
@@ -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: done
-
+t28: binary
+
+
+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
index aa3d373183f721609991690dc3149f4ac511e0d7..2ac5e59e278a2d7a147465b08e2c312e6b55e7b0 100644 (file)
@@ -453,7 +453,38 @@ c321d
 b322b
 b321
 b321b
-
-
-t28: done
-
+t28: binary
+
+
+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
index cef1cfa1ba41655ac329bb5d97498d1a49ce5c5e..b99ee45f9d27ae8caf4b19ecf91a22a8232f3f3c 100644 (file)
@@ -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:
index ce05c733220b00796de14e4d5dfbd8309111c55e..dc37f0fd4ddaa1ead50999a5690ef00d4359a940 100644 (file)
@@ -281,3 +281,9 @@ foobar
 ['faabar', 'foo bar', 'bar']
 barfoo
 ['bar foo', 'bar', 'foo']
+
+test 9-9
+# file: Xtest.latin1.spl
+bar
+foo
+-------
index 2ae6b8a56395be276bd2eb8d84742aa30a9060f1..753951d40c390a0b0d675ac1faa8b979c95368af 100644 (file)
@@ -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\ 1..
 :set nrformats&vim
 \16f3\ 1
 
+:" Test 22
+:/^S22=/+,/^E22=/-y a
+:/^E22=/+put a
+k\16j$\ 1j:.+put a
+k$\16+\ 1
+
+:" Test 23
+:/^S23=/+,/^E23=/-y a
+:/^E23=/+put a
+:set nrformats&vim
+\164l\ 1
+
+:" Test 24
+:/^S24=/+,/^E24=/-y a
+:/^E24=/+put a
+:set nrformats&vim
+\16$\ 1
+
+:" Test 25
+:set nrformats+=alpha
+:/^S25=/+,/^E25=/-y a
+:/^E25=/+put a
+\16k$\ 1
+:set nrformats&vim
+
+:" Test 26
+:set nrformats+=alpha
+:/^S26=/+,/^E26=/-y a
+:/^E26=/+put a
+\16k$\ 1
+: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
 
index 15d0e9b50bbf43c4b0832338541e998accca920a..4d8fbb0ae19553aaabdde478c58916515943c0d6 100644 (file)
@@ -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
 
index e12ff71e7ff6f3fa84b0a0f0dd1985f2548b548b..6c373bf7e99a6e4e5789e7d9777463fb03467a07 100644 (file)
@@ -741,6 +741,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1027,
 /**/
     1026,
 /**/
index ac3a883edf78301d75dfe4c005df053f69f91f4b..1a176beaee7693b415bffba50fc4f70cdf136f6e 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
 # 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