forked from aniani/vim
patch 7.4.1027
Problem: No support for binary numbers. Solution: Add "bin" to nrformats. (Jason Schulz)
This commit is contained in:
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)
|
||||
|
||||
Reference in New Issue
Block a user