@@ -1569,6 +1569,20 @@ skipdigits(q)
15691569}
15701570
15711571#if defined(FEAT_SYN_HL ) || defined(FEAT_SPELL ) || defined(PROTO )
1572+ /*
1573+ * skip over binary digits
1574+ */
1575+ char_u *
1576+ skipbin (q )
1577+ char_u * q ;
1578+ {
1579+ char_u * p = q ;
1580+
1581+ while (vim_isbdigit (* p )) /* skip to next non-digit */
1582+ ++ p ;
1583+ return p ;
1584+ }
1585+
15721586/*
15731587 * skip over digits and hex characters
15741588 */
@@ -1585,6 +1599,20 @@ skiphex(q)
15851599#endif
15861600
15871601#if defined(FEAT_EX_EXTRA ) || defined(PROTO )
1602+ /*
1603+ * skip to bin digit (or NUL after the string)
1604+ */
1605+ char_u *
1606+ skiptobin (q )
1607+ char_u * q ;
1608+ {
1609+ char_u * p = q ;
1610+
1611+ while (* p != NUL && !vim_isbdigit (* p )) /* skip to next digit */
1612+ ++ p ;
1613+ return p ;
1614+ }
1615+
15881616/*
15891617 * skip to digit (or NUL after the string)
15901618 */
@@ -1641,6 +1669,17 @@ vim_isxdigit(c)
16411669 || (c >= 'A' && c <= 'F' );
16421670}
16431671
1672+ /*
1673+ * Corollary of vim_isdigit and vim_isxdigit() that can handle
1674+ * characters > 0x100.
1675+ */
1676+ int
1677+ vim_isbdigit (c )
1678+ int c ;
1679+ {
1680+ return (c == '0' || c == '1' );
1681+ }
1682+
16441683#if defined(FEAT_MBYTE ) || defined(PROTO )
16451684/*
16461685 * Vim's own character class functions. These exist because many library
@@ -1822,35 +1861,37 @@ vim_isblankline(lbuf)
18221861
18231862/*
18241863 * Convert a string into a long and/or unsigned long, taking care of
1825- * hexadecimal and octal numbers. Accepts a '-' sign.
1826- * If "hexp " is not NULL, returns a flag to indicate the type of the number:
1864+ * hexadecimal, octal, and binary numbers. Accepts a '-' sign.
1865+ * If "prep " is not NULL, returns a flag to indicate the type of the number:
18271866 * 0 decimal
18281867 * '0' octal
1868+ * 'B' bin
1869+ * 'b' bin
18291870 * 'X' hex
18301871 * 'x' hex
18311872 * If "len" is not NULL, the length of the number in characters is returned.
18321873 * If "nptr" is not NULL, the signed result is returned in it.
18331874 * If "unptr" is not NULL, the unsigned result is returned in it.
1834- * If "dooct" is non-zero recognize octal numbers, when > 1 always assume
1835- * octal number.
1836- * If "dohex" is non-zero recognize hex numbers, when > 1 always assume
1837- * hex number .
1875+ * If "what" contains STR2NR_BIN recognize binary numbers
1876+ * If "what" contains STR2NR_OCT recognize octal numbers
1877+ * If "what" contains STR2NR_HEX recognize hex numbers
1878+ * If "what" contains STR2NR_FORCE always assume bin/oct/hex .
18381879 * If maxlen > 0, check at a maximum maxlen chars
18391880 */
18401881 void
1841- vim_str2nr (start , hexp , len , dooct , dohex , nptr , unptr , maxlen )
1882+ vim_str2nr (start , prep , len , what , nptr , unptr , maxlen )
18421883 char_u * start ;
1843- int * hexp ; /* return: type of number 0 = decimal, 'x'
1844- or 'X' is hex, '0' = octal */
1884+ int * prep ; /* return: type of number 0 = decimal, 'x'
1885+ or 'X' is hex, '0' = octal, 'b' or 'B'
1886+ is bin */
18451887 int * len ; /* return: detected length of number */
1846- int dooct ; /* recognize octal number */
1847- int dohex ; /* recognize hex number */
1888+ int what ; /* what numbers to recognize */
18481889 long * nptr ; /* return: signed result */
18491890 unsigned long * unptr ; /* return: unsigned result */
18501891 int maxlen ; /* max length of string to check */
18511892{
18521893 char_u * ptr = start ;
1853- int hex = 0 ; /* default is decimal */
1894+ int pre = 0 ; /* default is decimal */
18541895 int negative = FALSE;
18551896 unsigned long un = 0 ;
18561897 int n ;
@@ -1861,29 +1902,37 @@ vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr, maxlen)
18611902 ++ ptr ;
18621903 }
18631904
1864- /* Recognize hex and octal . */
1905+ /* Recognize hex, octal, and bin . */
18651906 if (ptr [0 ] == '0' && ptr [1 ] != '8' && ptr [1 ] != '9'
18661907 && (maxlen == 0 || maxlen > 1 ))
18671908 {
1868- hex = ptr [1 ];
1869- if (dohex && (hex == 'X' || hex == 'x' ) && vim_isxdigit (ptr [2 ])
1870- && (maxlen == 0 || maxlen > 2 ))
1871- ptr += 2 ; /* hexadecimal */
1909+ pre = ptr [1 ];
1910+ if ((what & STR2NR_HEX )
1911+ && (pre == 'X' || pre == 'x' ) && vim_isxdigit (ptr [2 ])
1912+ && (maxlen == 0 || maxlen > 2 ))
1913+ /* hexadecimal */
1914+ ptr += 2 ;
1915+ else if ((what & STR2NR_BIN )
1916+ && (pre == 'B' || pre == 'b' ) && vim_isbdigit (ptr [2 ])
1917+ && (maxlen == 0 || maxlen > 2 ))
1918+ /* binary */
1919+ ptr += 2 ;
18721920 else
18731921 {
1874- hex = 0 ; /* default is decimal */
1875- if (dooct )
1922+ /* decimal or octal, default is decimal */
1923+ pre = 0 ;
1924+ if (what & STR2NR_OCT )
18761925 {
18771926 /* Don't interpret "0", "08" or "0129" as octal. */
18781927 for (n = 1 ; VIM_ISDIGIT (ptr [n ]); ++ n )
18791928 {
18801929 if (ptr [n ] > '7' )
18811930 {
1882- hex = 0 ; /* can't be octal */
1931+ pre = 0 ; /* can't be octal */
18831932 break ;
18841933 }
18851934 if (ptr [n ] >= '0' )
1886- hex = '0' ; /* assume octal */
1935+ pre = '0' ; /* assume octal */
18871936 if (n == maxlen )
18881937 break ;
18891938 }
@@ -1892,10 +1941,23 @@ vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr, maxlen)
18921941 }
18931942
18941943 /*
1895- * Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
1896- */
1944+ * Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
1945+ */
18971946 n = 1 ;
1898- if (hex == '0' || dooct > 1 )
1947+ if (pre == 'B' || pre == 'b' || what == STR2NR_BIN + STR2NR_FORCE )
1948+ {
1949+ /* bin */
1950+ if (pre != 0 )
1951+ n += 2 ; /* skip over "0b" */
1952+ while ('0' <= * ptr && * ptr <= '1' )
1953+ {
1954+ un = 2 * un + (unsigned long )(* ptr - '0' );
1955+ ++ ptr ;
1956+ if (n ++ == maxlen )
1957+ break ;
1958+ }
1959+ }
1960+ else if (pre == '0' || what == STR2NR_OCT + STR2NR_FORCE )
18991961 {
19001962 /* octal */
19011963 while ('0' <= * ptr && * ptr <= '7' )
@@ -1906,10 +1968,10 @@ vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr, maxlen)
19061968 break ;
19071969 }
19081970 }
1909- else if (hex != 0 || dohex > 1 )
1971+ else if (pre != 0 || what == STR2NR_HEX + STR2NR_FORCE )
19101972 {
19111973 /* hex */
1912- if (hex != 0 )
1974+ if (pre != 0 )
19131975 n += 2 ; /* skip over "0x" */
19141976 while (vim_isxdigit (* ptr ))
19151977 {
@@ -1931,8 +1993,8 @@ vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr, maxlen)
19311993 }
19321994 }
19331995
1934- if (hexp != NULL )
1935- * hexp = hex ;
1996+ if (prep != NULL )
1997+ * prep = pre ;
19361998 if (len != NULL )
19371999 * len = (int )(ptr - start );
19382000 if (nptr != NULL )
0 commit comments