aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2016-01-20 23:46:31 -0500
committerJustin M. Keyes <justinkz@gmail.com>2016-01-21 01:34:36 -0500
commit9eb6a4456491c1b4dec8c1ff07c4b33220c3bab2 (patch)
treee357cc3ea0bf85d9977f6f43ee8e77a75790480f /src
parent03d8adda8e5101538893d8b7ddf547273bb4a26e (diff)
parentf82e982bda49d15f19dbd72531a6c1125d863486 (diff)
downloadrneovim-9eb6a4456491c1b4dec8c1ff07c4b33220c3bab2.tar.gz
rneovim-9eb6a4456491c1b4dec8c1ff07c4b33220c3bab2.tar.bz2
rneovim-9eb6a4456491c1b4dec8c1ff07c4b33220c3bab2.zip
Merge #3916 "Add support for binary numbers".
Diffstat (limited to 'src')
-rw-r--r--src/nvim/ascii.h31
-rw-r--r--src/nvim/charset.c98
-rw-r--r--src/nvim/eval.c283
-rw-r--r--src/nvim/ex_cmds.c150
-rw-r--r--src/nvim/ex_getln.c31
-rw-r--r--src/nvim/keymap.c79
-rw-r--r--src/nvim/message.c141
-rw-r--r--src/nvim/ops.c273
-rw-r--r--src/nvim/option.c51
-rw-r--r--src/nvim/options.lua2
-rw-r--r--src/nvim/spell.c54
-rw-r--r--src/nvim/vim.h2
12 files changed, 694 insertions, 501 deletions
diff --git a/src/nvim/ascii.h b/src/nvim/ascii.h
index 2b3e94d5a0..44ff540b40 100644
--- a/src/nvim/ascii.h
+++ b/src/nvim/ascii.h
@@ -85,10 +85,25 @@
# define PATHSEPSTR "/"
#endif
-static inline bool ascii_iswhite(int) REAL_FATTR_ALWAYS_INLINE REAL_FATTR_CONST;
-static inline bool ascii_isdigit(int) REAL_FATTR_ALWAYS_INLINE REAL_FATTR_CONST;
-static inline bool ascii_isxdigit(int) REAL_FATTR_ALWAYS_INLINE REAL_FATTR_CONST;
-static inline bool ascii_isspace(int) REAL_FATTR_ALWAYS_INLINE REAL_FATTR_CONST;
+static inline bool ascii_iswhite(int)
+ REAL_FATTR_CONST
+ REAL_FATTR_ALWAYS_INLINE;
+
+static inline bool ascii_isdigit(int)
+ REAL_FATTR_CONST
+ REAL_FATTR_ALWAYS_INLINE;
+
+static inline bool ascii_isxdigit(int)
+ REAL_FATTR_CONST
+ REAL_FATTR_ALWAYS_INLINE;
+
+static inline bool ascii_isbdigit(int)
+ REAL_FATTR_CONST
+ REAL_FATTR_ALWAYS_INLINE;
+
+static inline bool ascii_isspace(int)
+ REAL_FATTR_CONST
+ REAL_FATTR_ALWAYS_INLINE;
/// Checks if `c` is a space or tab character.
///
@@ -122,6 +137,14 @@ static inline bool ascii_isxdigit(int c)
|| (c >= 'A' && c <= 'F');
}
+/// Checks if `c` is a binary digit, that is, 0-1.
+///
+/// @see {ascii_isdigit}
+static inline bool ascii_isbdigit(int c)
+{
+ return (c == '0' || c == '1');
+}
+
/// Checks if `c` is a white-space character, that is,
/// one of \f, \n, \r, \t, \v.
///
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index b93eafbf60..e0c9443511 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -1454,6 +1454,24 @@ char_u* skipdigits(char_u *q)
return p;
}
+/// skip over binary digits
+///
+/// @param q pointer to string
+///
+/// @return Pointer to the character after the skipped digits.
+const char* skipbin(const char *q)
+ FUNC_ATTR_PURE
+ FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_RET
+{
+ const char *p = q;
+ while (ascii_isbdigit(*p)) {
+ // skip to next non-digit
+ p++;
+ }
+ return p;
+}
+
/// skip over digits and hex characters
///
/// @param q
@@ -1485,6 +1503,24 @@ char_u* skiptodigit(char_u *q)
return p;
}
+/// skip to binary character (or NUL after the string)
+///
+/// @param q pointer to string
+///
+/// @return Pointer to the binary character or (NUL after the string).
+const char* skiptobin(const char *q)
+ FUNC_ATTR_PURE
+ FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_RET
+{
+ const char *p = q;
+ while (*p != NUL && !ascii_isbdigit(*p)) {
+ // skip to next digit
+ p++;
+ }
+ return p;
+}
+
/// skip to hex character (or NUL after the string)
///
/// @param q
@@ -1720,67 +1756,77 @@ int vim_isblankline(char_u *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 "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.
///
/// @param start
-/// @param hexp Returns type of number 0 = decimal, 'x' or 'X' is hex,
-// '0' = octal
+/// @param prep Returns type of number 0 = decimal, 'x' or 'X' is hex,
+// '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 nptr Returns the signed result.
/// @param unptr Returns the unsigned result.
-void vim_str2nr(char_u *start, int *hexp, int *len, int dooct, int dohex,
+void vim_str2nr(char_u *start, int *prep, int *len,
+ int dobin, int dooct, int dohex,
long *nptr, unsigned long *unptr)
{
char_u *ptr = start;
- int hex = 0; // default is decimal
- int negative = FALSE;
+ int pre = 0; // default is decimal
+ int negative = false;
unsigned long un = 0;
int n;
if (ptr[0] == '-') {
- negative = TRUE;
- ++ptr;
+ negative = true;
+ ptr++;
}
- // Recognize hex and octal.
+ // Recognize hex, octal, and bin.
if ((ptr[0] == '0') && (ptr[1] != '8') && (ptr[1] != '9')) {
- hex = ptr[1];
+ pre = ptr[1];
if (dohex
- && ((hex == 'X') || (hex == 'x'))
+ && ((pre == 'X') || (pre == 'x'))
&& ascii_isxdigit(ptr[2])) {
// hexadecimal
ptr += 2;
+ } else if (dobin
+ && ((pre == 'B') || (pre == 'b'))
+ && ascii_isbdigit(ptr[2])) {
+ // binary
+ ptr += 2;
} else {
// default is decimal
- hex = 0;
+ pre = 0;
if (dooct) {
// Don't interpret "0", "08" or "0129" as octal.
for (n = 1; ascii_isdigit(ptr[n]); ++n) {
if (ptr[n] > '7') {
// can't be octal
- hex = 0;
+ pre = 0;
break;
}
-
if (ptr[n] >= '0') {
// assume octal
- hex = '0';
+ pre = '0';
}
}
}
@@ -1788,14 +1834,26 @@ void vim_str2nr(char_u *start, int *hexp, int *len, int dooct, int dohex,
}
// Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
- if ((hex == '0') || (dooct > 1)) {
+ if ((pre == 'B') || (pre == 'b') || (dobin > 1)) {
+ // bin
+ if (pre != 0) {
+ n += 2; // skip over "0b"
+ }
+ while ('0' <= *ptr && *ptr <= '1') {
+ un = 2 * un + (unsigned long)(*ptr - '0');
+ ptr++;
+ }
+ } else if ((pre == '0') || (dooct > 1)) {
// octal
while ('0' <= *ptr && *ptr <= '7') {
un = 8 * un + (unsigned long)(*ptr - '0');
ptr++;
}
- } else if ((hex != 0) || (dohex > 1)) {
+ } else if (pre != 0 || dohex > 1) {
// hex
+ if (pre != 0) {
+ n += 2; // skip over "0x"
+ }
while (ascii_isxdigit(*ptr)) {
un = 16 * un + (unsigned long)hex2nr(*ptr);
ptr++;
@@ -1808,8 +1866,8 @@ void vim_str2nr(char_u *start, int *hexp, int *len, int dooct, int dohex,
}
}
- if (hexp != NULL) {
- *hexp = hex;
+ if (prep != NULL) {
+ *prep = pre;
}
if (len != NULL) {
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 8e8232b44d..a5a8671697 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -1113,19 +1113,17 @@ typval_T *eval_expr(char_u *arg, char_u **nextcmd)
}
-/*
- * Call some vimL function and return the result in "*rettv".
- * Uses argv[argc] for the function arguments. Only Number and String
- * arguments are currently supported.
- * Returns OK or FAIL.
- */
-int
-call_vim_function (
+// Call some vimL function and return the result in "*rettv".
+// Uses argv[argc] for the function arguments. Only Number and String
+// arguments are currently supported.
+//
+// Return OK or FAIL.
+int call_vim_function(
char_u *func,
int argc,
char_u **argv,
- int safe, /* use the sandbox */
- int str_arg_only, /* all arguments are strings */
+ int safe, // use the sandbox
+ int str_arg_only, // all arguments are strings
typval_T *rettv
)
{
@@ -1138,18 +1136,19 @@ call_vim_function (
typval_T *argvars = xmalloc((argc + 1) * sizeof(typval_T));
for (int i = 0; i < argc; i++) {
- /* Pass a NULL or empty argument as an empty string */
+ // Pass a NULL or empty argument as an empty string
if (argv[i] == NULL || *argv[i] == NUL) {
argvars[i].v_type = VAR_STRING;
argvars[i].vval.v_string = (char_u *)"";
continue;
}
- if (str_arg_only)
+ if (str_arg_only) {
len = 0;
- else
- /* Recognize a number argument, the others must be strings. */
- vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL);
+ } else {
+ // Recognize a number argument, the others must be strings.
+ vim_str2nr(argv[i], NULL, &len, true, true, true, &n, NULL);
+ }
if (len != 0 && len == (int)STRLEN(argv[i])) {
argvars[i].v_type = VAR_NUMBER;
argvars[i].vval.v_number = n;
@@ -1166,16 +1165,17 @@ call_vim_function (
rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */
ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum,
- &doesrange, TRUE, NULL);
+ curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+ &doesrange, true, NULL);
if (safe) {
--sandbox;
restore_funccal(save_funccalp);
}
xfree(argvars);
- if (ret == FAIL)
+ if (ret == FAIL) {
clear_tv(rettv);
+ }
return ret;
}
@@ -4025,38 +4025,35 @@ eval6 (
return OK;
}
-/*
- * Handle sixth level expression:
- * number number constant
- * "string" string constant
- * 'string' literal string constant
- * &option-name option value
- * @r register contents
- * identifier variable value
- * function() function call
- * $VAR environment variable
- * (expression) nested expression
- * [expr, expr] List
- * {key: val, key: val} Dictionary
- *
- * Also handle:
- * ! in front logical NOT
- * - in front unary minus
- * + in front unary plus (ignored)
- * trailing [] subscript in String or List
- * trailing .name entry in Dictionary
- *
- * "arg" must point to the first non-white of the expression.
- * "arg" is advanced to the next non-white after the recognized expression.
- *
- * Return OK or FAIL.
- */
-static int
-eval7 (
+// Handle sixth level expression:
+// number number constant
+// "string" string constant
+// 'string' literal string constant
+// &option-name option value
+// @r register contents
+// identifier variable value
+// function() function call
+// $VAR environment variable
+// (expression) nested expression
+// [expr, expr] List
+// {key: val, key: val} Dictionary
+//
+// Also handle:
+// ! in front logical NOT
+// - in front unary minus
+// + in front unary plus (ignored)
+// trailing [] subscript in String or List
+// trailing .name entry in Dictionary
+//
+// "arg" must point to the first non-white of the expression.
+// "arg" is advanced to the next non-white after the recognized expression.
+//
+// Return OK or FAIL.
+static int eval7(
char_u **arg,
typval_T *rettv,
int evaluate,
- int want_string /* after "." operator */
+ int want_string // after "." operator
)
{
long n;
@@ -4066,24 +4063,19 @@ eval7 (
int ret = OK;
char_u *alias;
- /*
- * Initialise variable so that clear_tv() can't mistake this for a
- * string and free a string that isn't there.
- */
+ // Initialise variable so that clear_tv() can't mistake this for a
+ // string and free a string that isn't there.
rettv->v_type = VAR_UNKNOWN;
- /*
- * Skip '!' and '-' characters. They are handled later.
- */
+ // Skip '!' and '-' characters. They are handled later.
start_leader = *arg;
- while (**arg == '!' || **arg == '-' || **arg == '+')
+ while (**arg == '!' || **arg == '-' || **arg == '+') {
*arg = skipwhite(*arg + 1);
+ }
end_leader = *arg;
switch (**arg) {
- /*
- * Number constant.
- */
+ // Number constant.
case '0':
case '1':
case '2':
@@ -4096,27 +4088,30 @@ eval7 (
case '9':
{
char_u *p = skipdigits(*arg + 1);
- int get_float = FALSE;
+ int get_float = false;
- /* We accept a float when the format matches
- * "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very
- * strict to avoid backwards compatibility problems.
- * Don't look for a float after the "." operator, so that
- * ":let vers = 1.2.3" doesn't fail. */
+ // We accept a float when the format matches
+ // "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very
+ // strict to avoid backwards compatibility problems.
+ // Don't look for a float after the "." operator, so that
+ // ":let vers = 1.2.3" doesn't fail.
if (!want_string && p[0] == '.' && ascii_isdigit(p[1])) {
- get_float = TRUE;
+ get_float = true;
p = skipdigits(p + 2);
if (*p == 'e' || *p == 'E') {
++p;
- if (*p == '-' || *p == '+')
+ if (*p == '-' || *p == '+') {
++p;
- if (!ascii_isdigit(*p))
- get_float = FALSE;
- else
+ }
+ if (!ascii_isdigit(*p)) {
+ get_float = false;
+ } else {
p = skipdigits(p + 1);
+ }
+ }
+ if (ASCII_ISALPHA(*p) || *p == '.') {
+ get_float = false;
}
- if (ASCII_ISALPHA(*p) || *p == '.')
- get_float = FALSE;
}
if (get_float) {
float_T f;
@@ -4127,7 +4122,7 @@ eval7 (
rettv->vval.v_float = f;
}
} else {
- vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL);
+ vim_str2nr(*arg, NULL, &len, true, true, true, &n, NULL);
*arg += len;
if (evaluate) {
rettv->v_type = VAR_NUMBER;
@@ -4137,62 +4132,47 @@ eval7 (
break;
}
- /*
- * String constant: "string".
- */
+ // String constant: "string".
case '"': ret = get_string_tv(arg, rettv, evaluate);
break;
- /*
- * Literal string constant: 'str''ing'.
- */
+ // Literal string constant: 'str''ing'.
case '\'': ret = get_lit_string_tv(arg, rettv, evaluate);
break;
- /*
- * List: [expr, expr]
- */
+ // List: [expr, expr]
case '[': ret = get_list_tv(arg, rettv, evaluate);
break;
- /*
- * Dictionary: {key: val, key: val}
- */
+ // Dictionary: {key: val, key: val}
case '{': ret = get_dict_tv(arg, rettv, evaluate);
break;
- /*
- * Option value: &name
- */
+ // Option value: &name
case '&': ret = get_option_tv(arg, rettv, evaluate);
break;
- /*
- * Environment variable: $VAR.
- */
+ // Environment variable: $VAR.
case '$': ret = get_env_tv(arg, rettv, evaluate);
break;
- /*
- * Register contents: @r.
- */
+ // Register contents: @r.
case '@': ++*arg;
if (evaluate) {
rettv->v_type = VAR_STRING;
rettv->vval.v_string = get_reg_contents(**arg, kGRegExprSrc);
}
- if (**arg != NUL)
+ if (**arg != NUL) {
++*arg;
+ }
break;
- /*
- * nested expression: (expression).
- */
+ // nested expression: (expression).
case '(': *arg = skipwhite(*arg + 1);
- ret = eval1(arg, rettv, evaluate); /* recursive! */
- if (**arg == ')')
+ ret = eval1(arg, rettv, evaluate); // recursive!
+ if (**arg == ')') {
++*arg;
- else if (ret == OK) {
+ } else if (ret == OK) {
EMSG(_("E110: Missing ')'"));
clear_tv(rettv);
ret = FAIL;
@@ -4204,71 +4184,72 @@ eval7 (
}
if (ret == NOTDONE) {
- /*
- * Must be a variable or function name.
- * Can also be a curly-braces kind of name: {expr}.
- */
+ // Must be a variable or function name.
+ // Can also be a curly-braces kind of name: {expr}.
s = *arg;
- len = get_name_len(arg, &alias, evaluate, TRUE);
- if (alias != NULL)
+ len = get_name_len(arg, &alias, evaluate, true);
+ if (alias != NULL) {
s = alias;
+ }
- if (len <= 0)
+ if (len <= 0) {
ret = FAIL;
- else {
- if (**arg == '(') { /* recursive! */
- /* If "s" is the name of a variable of type VAR_FUNC
- * use its contents. */
+ } else {
+ if (**arg == '(') { // recursive!
+ // If "s" is the name of a variable of type VAR_FUNC
+ // use its contents.
s = deref_func_name(s, &len, !evaluate);
- /* Invoke the function. */
+ // Invoke the function.
ret = get_func_tv(s, len, rettv, arg,
curwin->w_cursor.lnum, curwin->w_cursor.lnum,
&len, evaluate, NULL);
- /* If evaluate is FALSE rettv->v_type was not set in
- * get_func_tv, but it's needed in handle_subscript() to parse
- * what follows. So set it here. */
+ // If evaluate is false rettv->v_type was not set in
+ // get_func_tv, but it's needed in handle_subscript() to parse
+ // what follows. So set it here.
if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(') {
rettv->vval.v_string = empty_string;
rettv->v_type = VAR_FUNC;
}
- /* Stop the expression evaluation when immediately
- * aborting on error, or when an interrupt occurred or
- * an exception was thrown but not caught. */
+ // Stop the expression evaluation when immediately
+ // aborting on error, or when an interrupt occurred or
+ // an exception was thrown but not caught.
if (aborting()) {
- if (ret == OK)
+ if (ret == OK) {
clear_tv(rettv);
+ }
ret = FAIL;
}
- } else if (evaluate)
- ret = get_var_tv(s, len, rettv, TRUE, FALSE);
- else
+ } else if (evaluate) {
+ ret = get_var_tv(s, len, rettv, true, false);
+ } else {
ret = OK;
+ }
}
xfree(alias);
}
*arg = skipwhite(*arg);
- /* Handle following '[', '(' and '.' for expr[expr], expr.name,
- * expr(expr). */
- if (ret == OK)
- ret = handle_subscript(arg, rettv, evaluate, TRUE);
+ // Handle following '[', '(' and '.' for expr[expr], expr.name,
+ // expr(expr).
+ if (ret == OK) {
+ ret = handle_subscript(arg, rettv, evaluate, true);
+ }
- /*
- * Apply logical NOT and unary '-', from right to left, ignore '+'.
- */
+ // Apply logical NOT and unary '-', from right to left, ignore '+'.
if (ret == OK && evaluate && end_leader > start_leader) {
- int error = FALSE;
+ int error = false;
int val = 0;
float_T f = 0.0;
- if (rettv->v_type == VAR_FLOAT)
+ if (rettv->v_type == VAR_FLOAT) {
f = rettv->vval.v_float;
- else
+ } else {
val = get_tv_number_chk(rettv, &error);
+ }
if (error) {
clear_tv(rettv);
ret = FAIL;
@@ -4276,15 +4257,17 @@ eval7 (
while (end_leader > start_leader) {
--end_leader;
if (*end_leader == '!') {
- if (rettv->v_type == VAR_FLOAT)
+ if (rettv->v_type == VAR_FLOAT) {
f = !f;
- else
+ } else {
val = !val;
+ }
} else if (*end_leader == '-') {
- if (rettv->v_type == VAR_FLOAT)
+ if (rettv->v_type == VAR_FLOAT) {
f = -f;
- else
+ } else {
val = -val;
+ }
}
}
if (rettv->v_type == VAR_FLOAT) {
@@ -15998,9 +15981,7 @@ static void f_str2float(typval_T *argvars, typval_T *rettv)
rettv->v_type = VAR_FLOAT;
}
-/*
- * "str2nr()" function
- */
+// "str2nr()" function
static void f_str2nr(typval_T *argvars, typval_T *rettv)
{
int base = 10;
@@ -16009,16 +15990,21 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv)
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;
}
}
p = skipwhite(get_tv_string(&argvars[0]));
- if (*p == '+')
+ if (*p == '+') {
p = skipwhite(p + 1);
- vim_str2nr(p, NULL, NULL, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL);
+ }
+ vim_str2nr(p, NULL, NULL,
+ base == 2 ? 2 : 0,
+ base == 8 ? 2 : 0,
+ base == 16 ? 2 : 0,
+ &n, NULL);
rettv->vval.v_number = n;
}
@@ -18298,9 +18284,10 @@ long get_tv_number_chk(typval_T *varp, int *denote)
EMSG(_("E703: Using a Funcref as a Number"));
break;
case VAR_STRING:
- if (varp->vval.v_string != NULL)
+ if (varp->vval.v_string != NULL) {
vim_str2nr(varp->vval.v_string, NULL, NULL,
- TRUE, TRUE, &n, NULL);
+ true, true, true, &n, NULL);
+ }
return n;
case VAR_LIST:
EMSG(_("E745: Using a List as a Number"));
@@ -18312,10 +18299,12 @@ long get_tv_number_chk(typval_T *varp, int *denote)
EMSG2(_(e_intern2), "get_tv_number()");
break;
}
- if (denote == NULL) /* useful for values that must be unsigned */
+ if (denote == NULL) {
+ // useful for values that must be unsigned
n = -1;
- else
- *denote = TRUE;
+ } else {
+ *denote = true;
+ }
return n;
}
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 29d87d0fc1..407dded6af 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -329,9 +329,7 @@ static int sort_compare(const void *s1, const void *s2)
return result;
}
-/*
- * ":sort".
- */
+// ":sort".
void ex_sort(exarg_T *eap)
{
regmatch_T regmatch;
@@ -343,17 +341,19 @@ void ex_sort(exarg_T *eap)
char_u *p;
char_u *s;
char_u *s2;
- char_u c; /* temporary character storage */
- int unique = FALSE;
+ char_u c; // temporary character storage
+ int unique = false;
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_bin; // sort on bin number
+ int sort_oct; // sort on octal number
+ int sort_hex; // sort on hex number
- /* Sorting one line is really quick! */
- if (count <= 1)
+ // Sorting one line is really quick!
+ if (count <= 1) {
return;
+ }
if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL)
return;
@@ -362,47 +362,51 @@ void ex_sort(exarg_T *eap)
regmatch.regprog = NULL;
sorti_T *nrs = xmalloc(count * sizeof(sorti_T));
- sort_abort = sort_ic = sort_rx = sort_nr = sort_oct = sort_hex = 0;
+ sort_abort = sort_ic = sort_rx = sort_nr = sort_bin = sort_oct = sort_hex = 0;
for (p = eap->arg; *p != NUL; ++p) {
- if (ascii_iswhite(*p))
- ;
- else if (*p == 'i')
- sort_ic = TRUE;
- else if (*p == 'r')
- sort_rx = TRUE;
- else if (*p == 'n')
+ if (ascii_iswhite(*p)) {
+ } else if (*p == 'i') {
+ sort_ic = true;
+ } else if (*p == 'r') {
+ sort_rx = true;
+ } else if (*p == 'n') {
sort_nr = 2;
- else if (*p == 'o')
+ } else if (*p == 'b') {
+ sort_bin = 2;
+ } else if (*p == 'o') {
sort_oct = 2;
- else if (*p == 'x')
+ } else if (*p == 'x') {
sort_hex = 2;
- else if (*p == 'u')
- unique = TRUE;
- else if (*p == '"') /* comment start */
+ } else if (*p == 'u') {
+ unique = true;
+ } else if (*p == '"') {
+ // comment start
break;
- else if (check_nextcmd(p) != NULL) {
+ } else if (check_nextcmd(p) != NULL) {
eap->nextcmd = check_nextcmd(p);
break;
} else if (!ASCII_ISALPHA(*p) && regmatch.regprog == NULL) {
- s = skip_regexp(p + 1, *p, TRUE, NULL);
+ s = skip_regexp(p + 1, *p, true, NULL);
if (*s != *p) {
EMSG(_(e_invalpat));
goto sortend;
}
*s = NUL;
- /* Use last search pattern if sort pattern is empty. */
+ // Use last search pattern if sort pattern is empty.
if (s == p + 1) {
if (last_search_pat() == NULL) {
EMSG(_(e_noprevre));
goto sortend;
}
regmatch.regprog = vim_regcomp(last_search_pat(), RE_MAGIC);
- } else
+ } else {
regmatch.regprog = vim_regcomp(p + 1, RE_MAGIC);
- if (regmatch.regprog == NULL)
+ }
+ if (regmatch.regprog == NULL) {
goto sortend;
- p = s; /* continue after the regexp */
+ }
+ p = s; // continue after the regexp
regmatch.rm_ic = p_ic;
} else {
EMSG2(_(e_invarg2), p);
@@ -410,28 +414,27 @@ void ex_sort(exarg_T *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 (sort_nr + sort_bin + sort_oct + sort_hex > 2) {
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;
+ // From here on "sort_nr" is used as a flag for any number sorting.
+ sort_nr += sort_bin + sort_oct + sort_hex;
- /*
- * Make an array with all line numbers. This avoids having to copy all
- * the lines into allocated memory.
- * When sorting on strings "start_col_nr" is the offset in the line, for
- * numbers sorting it's the number to sort on. This means the pattern
- * matching and number conversion only has to be done once per line.
- * Also get the longest line length for allocating "sortbuf".
- */
+ // Make an array with all line numbers. This avoids having to copy all
+ // the lines into allocated memory.
+ // When sorting on strings "start_col_nr" is the offset in the line, for
+ // numbers sorting it's the number to sort on. This means the pattern
+ // matching and number conversion only has to be done once per line.
+ // Also get the longest line length for allocating "sortbuf".
for (lnum = eap->line1; lnum <= eap->line2; ++lnum) {
s = ml_get(lnum);
len = (int)STRLEN(s);
- if (maxlen < len)
+ if (maxlen < len) {
maxlen = len;
+ }
start_col = 0;
end_col = len;
@@ -439,34 +442,41 @@ void ex_sort(exarg_T *eap)
if (sort_rx) {
start_col = (colnr_T)(regmatch.startp[0] - s);
end_col = (colnr_T)(regmatch.endp[0] - s);
- } else
+ } else {
start_col = (colnr_T)(regmatch.endp[0] - s);
- } else if (regmatch.regprog != NULL)
+ }
+ } else if (regmatch.regprog != NULL) {
end_col = 0;
+ }
if (sort_nr) {
- /* Make sure vim_str2nr doesn't read any digits past the end
- * of the match, by temporarily terminating the string there */
+ // Make sure vim_str2nr doesn't read any digits past the end
+ // of the match, by temporarily terminating the string there
s2 = s + end_col;
c = *s2;
*s2 = NUL;
- /* Sorting on number: Store the number itself. */
+ // Sorting on number: Store the number itself.
p = s + start_col;
- if (sort_hex)
+ if (sort_hex) {
s = skiptohex(p);
- else
+ } else if (sort_bin) {
+ s = (char_u*) skiptobin((char*) p);
+ } else {
s = skiptodigit(p);
- if (s > p && s[-1] == '-')
- --s; /* include preceding negative sign */
- if (*s == NUL)
- /* empty line should sort before any number */
+ }
+ if (s > p && s[-1] == '-') {
+ --s; // include preceding negative sign
+ }
+ 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_oct, sort_hex,
- &nrs[lnum - eap->line1].start_col_nr, NULL);
+ } else {
+ vim_str2nr(s, NULL, NULL, sort_bin, sort_oct, sort_hex,
+ &nrs[lnum - eap->line1].start_col_nr, NULL);
+ }
*s2 = c;
} else {
- /* Store the column to sort at. */
+ // Store the column to sort at.
nrs[lnum - eap->line1].start_col_nr = start_col;
nrs[lnum - eap->line1].end_col_nr = end_col;
}
@@ -479,17 +489,17 @@ void ex_sort(exarg_T *eap)
goto sortend;
}
- /* Allocate a buffer that can hold the longest line. */
+ // Allocate a buffer that can hold the longest line.
sortbuf1 = xmalloc(maxlen + 1);
sortbuf2 = xmalloc(maxlen + 1);
- /* Sort the array of line numbers. Note: can't be interrupted! */
+ // Sort the array of line numbers. Note: can't be interrupted!
qsort((void *)nrs, count, sizeof(sorti_T), sort_compare);
if (sort_abort)
goto sortend;
- /* Insert the lines in the sorted order below the last one. */
+ // Insert the lines in the sorted order below the last one.
lnum = eap->line2;
for (i = 0; i < count; ++i) {
s = ml_get(nrs[eap->forceit ? count - i - 1 : i].lnum);
@@ -507,19 +517,22 @@ void ex_sort(exarg_T *eap)
goto sortend;
}
- /* delete the original lines if appending worked */
- if (i == count)
- for (i = 0; i < count; ++i)
- ml_delete(eap->line1, FALSE);
- else
+ // delete the original lines if appending worked
+ if (i == count) {
+ for (i = 0; i < count; ++i) {
+ ml_delete(eap->line1, false);
+ }
+ } else {
count = 0;
+ }
- /* Adjust marks for deleted (or added) lines and prepare for displaying. */
+ // Adjust marks for deleted (or added) lines and prepare for displaying.
deleted = (long)(count - (lnum - eap->line2));
- if (deleted > 0)
+ if (deleted > 0) {
mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted);
- else if (deleted < 0)
+ } else if (deleted < 0) {
mark_adjust(eap->line2, MAXLNUM, -deleted, 0L);
+ }
changed_lines(eap->line1, 0, eap->line2 + 1, -deleted);
curwin->w_cursor.lnum = eap->line1;
@@ -530,8 +543,9 @@ sortend:
xfree(sortbuf1);
xfree(sortbuf2);
vim_regfree(regmatch.regprog);
- if (got_int)
+ if (got_int) {
EMSG(_(e_interr));
+ }
}
/*
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index eca62da949..87a6bf8901 100644
--- a/