diff options
Diffstat (limited to 'src')
317 files changed, 28533 insertions, 19641 deletions
diff --git a/src/cjson/fpconv.c b/src/cjson/fpconv.c new file mode 100644 index 0000000000..b2f7a214c2 --- /dev/null +++ b/src/cjson/fpconv.c @@ -0,0 +1,211 @@ +/* fpconv - Floating point conversion routines + * + * Copyright (c) 2011-2012 Mark Pulford <mark@kyne.com.au> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* JSON uses a '.' decimal separator. strtod() / sprintf() under C libraries + * with locale support will break when the decimal separator is a comma. + * + * fpconv_* will around these issues with a translation buffer if required. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <string.h> + +#include "fpconv.h" + +/* Workaround for MSVC */ +#ifdef _MSC_VER +#define inline __inline +#define snprintf sprintf_s +#endif + +/* Lua CJSON assumes the locale is the same for all threads within a + * process and doesn't change after initialisation. + * + * This avoids the need for per thread storage or expensive checks + * for call. */ +static char locale_decimal_point = '.'; + +/* In theory multibyte decimal_points are possible, but + * Lua CJSON only supports UTF-8 and known locales only have + * single byte decimal points ([.,]). + * + * localconv() may not be thread safe (=>crash), and nl_langinfo() is + * not supported on some platforms. Use sprintf() instead - if the + * locale does change, at least Lua CJSON won't crash. */ +static void fpconv_update_locale(void) +{ + char buf[8]; + + snprintf(buf, sizeof(buf), "%g", 0.5); + + /* Failing this test might imply the platform has a buggy dtoa + * implementation or wide characters */ + if (buf[0] != '0' || buf[2] != '5' || buf[3] != 0) { + fprintf(stderr, "Error: wide characters found or printf() bug."); + abort(); + } + + locale_decimal_point = buf[1]; +} + +/* Check for a valid number character: [-+0-9a-yA-Y.] + * Eg: -0.6e+5, infinity, 0xF0.F0pF0 + * + * Used to find the probable end of a number. It doesn't matter if + * invalid characters are counted - strtod() will find the valid + * number if it exists. The risk is that slightly more memory might + * be allocated before a parse error occurs. */ +static inline int valid_number_character(char ch) +{ + char lower_ch; + + if ('0' <= ch && ch <= '9') + return 1; + if (ch == '-' || ch == '+' || ch == '.') + return 1; + + /* Hex digits, exponent (e), base (p), "infinity",.. */ + lower_ch = ch | 0x20; + if ('a' <= lower_ch && lower_ch <= 'y') + return 1; + + return 0; +} + +/* Calculate the size of the buffer required for a strtod locale + * conversion. */ +static int strtod_buffer_size(const char *s) +{ + const char *p = s; + + while (valid_number_character(*p)) + p++; + + return p - s; +} + +/* Similar to strtod(), but must be passed the current locale's decimal point + * character. Guaranteed to be called at the start of any valid number in a string */ +double fpconv_strtod(const char *nptr, char **endptr) +{ + char localbuf[FPCONV_G_FMT_BUFSIZE]; + char *buf, *endbuf, *dp; + int buflen; + double value; + + /* System strtod() is fine when decimal point is '.' */ + if (locale_decimal_point == '.') + return strtod(nptr, endptr); + + buflen = strtod_buffer_size(nptr); + if (!buflen) { + /* No valid characters found, standard strtod() return */ + *endptr = (char *)nptr; + return 0; + } + + /* Duplicate number into buffer */ + if (buflen >= FPCONV_G_FMT_BUFSIZE) { + /* Handle unusually large numbers */ + buf = malloc(buflen + 1); + if (!buf) { + fprintf(stderr, "Out of memory"); + abort(); + } + } else { + /* This is the common case.. */ + buf = localbuf; + } + memcpy(buf, nptr, buflen); + buf[buflen] = 0; + + /* Update decimal point character if found */ + dp = strchr(buf, '.'); + if (dp) + *dp = locale_decimal_point; + + value = strtod(buf, &endbuf); + *endptr = (char *)&nptr[endbuf - buf]; + if (buflen >= FPCONV_G_FMT_BUFSIZE) + free(buf); + + return value; +} + +/* "fmt" must point to a buffer of at least 6 characters */ +static void set_number_format(char *fmt, int precision) +{ + int d1, d2, i; + + assert(1 <= precision && precision <= 16); + + /* Create printf format (%.14g) from precision */ + d1 = precision / 10; + d2 = precision % 10; + fmt[0] = '%'; + fmt[1] = '.'; + i = 2; + if (d1) { + fmt[i++] = '0' + d1; + } + fmt[i++] = '0' + d2; + fmt[i++] = 'g'; + fmt[i] = 0; +} + +/* Assumes there is always at least 32 characters available in the target buffer */ +int fpconv_g_fmt(char *str, double num, int precision) +{ + char buf[FPCONV_G_FMT_BUFSIZE]; + char fmt[6]; + int len; + char *b; + + set_number_format(fmt, precision); + + /* Pass through when decimal point character is dot. */ + if (locale_decimal_point == '.') + return snprintf(str, FPCONV_G_FMT_BUFSIZE, fmt, num); + + /* snprintf() to a buffer then translate for other decimal point characters */ + len = snprintf(buf, FPCONV_G_FMT_BUFSIZE, fmt, num); + + /* Copy into target location. Translate decimal point if required */ + b = buf; + do { + *str++ = (*b == locale_decimal_point ? '.' : *b); + } while(*b++); + + return len; +} + +void fpconv_init() +{ + fpconv_update_locale(); +} + +/* vi:ai et sw=4 ts=4: + */ diff --git a/src/cjson/fpconv.h b/src/cjson/fpconv.h new file mode 100644 index 0000000000..6ac97808b6 --- /dev/null +++ b/src/cjson/fpconv.h @@ -0,0 +1,22 @@ +/* Lua CJSON floating point conversion routines */ + +/* Buffer required to store the largest string representation of a double. + * + * Longest double printed with %.14g is 21 characters long: + * -1.7976931348623e+308 */ +# define FPCONV_G_FMT_BUFSIZE 32 + +#ifdef USE_INTERNAL_FPCONV +static inline void fpconv_init() +{ + /* Do nothing - not required */ +} +#else +extern void fpconv_init(void); +#endif + +extern int fpconv_g_fmt(char*, double, int); +extern double fpconv_strtod(const char*, char**); + +/* vi:ai et sw=4 ts=4: + */ diff --git a/src/cjson/lua_cjson.c b/src/cjson/lua_cjson.c new file mode 100644 index 0000000000..cf9e82c38e --- /dev/null +++ b/src/cjson/lua_cjson.c @@ -0,0 +1,1655 @@ +/* Lua CJSON - JSON support for Lua + * + * Copyright (c) 2010-2012 Mark Pulford <mark@kyne.com.au> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* Caveats: + * - JSON "null" values are represented as lightuserdata since Lua + * tables cannot contain "nil". Compare with cjson.null. + * - Invalid UTF-8 characters are not detected and will be passed + * untouched. If required, UTF-8 error checking should be done + * outside this library. + * - Javascript comments are not part of the JSON spec, and are not + * currently supported. + * + * Note: Decoding is slower than encoding. Lua spends significant + * time (30%) managing tables when parsing JSON since it is + * difficult to know object/array sizes ahead of time. + */ + +#include <assert.h> +#include <stdint.h> +#include <string.h> +#include <math.h> +#include <limits.h> +#include <lua.h> +#include <lauxlib.h> + +#include "nvim/lua/executor.h" + +#include "lua_cjson.h" +#include "strbuf.h" +#include "fpconv.h" + +#ifndef CJSON_MODNAME +#define CJSON_MODNAME "cjson" +#endif + +#ifndef CJSON_VERSION +#define CJSON_VERSION "2.1.0.9" +#endif + +#ifdef _MSC_VER +#define snprintf sprintf_s + +#ifndef isnan +#include <float.h> +#define isnan(x) _isnan(x) +#endif + +#endif + +/* Workaround for Solaris platforms missing isinf() */ +#if !defined(isinf) && (defined(USE_INTERNAL_ISINF) || defined(MISSING_ISINF)) +#define isinf(x) (!isnan(x) && isnan((x) - (x))) +#endif + +#define DEFAULT_SPARSE_CONVERT 0 +#define DEFAULT_SPARSE_RATIO 2 +#define DEFAULT_SPARSE_SAFE 10 +#define DEFAULT_ENCODE_MAX_DEPTH 1000 +#define DEFAULT_DECODE_MAX_DEPTH 1000 +#define DEFAULT_ENCODE_INVALID_NUMBERS 0 +#define DEFAULT_DECODE_INVALID_NUMBERS 1 +#define DEFAULT_ENCODE_KEEP_BUFFER 1 +#define DEFAULT_ENCODE_NUMBER_PRECISION 14 +#define DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT 0 +#define DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT 0 +#define DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH 1 + +#ifdef DISABLE_INVALID_NUMBERS +#undef DEFAULT_DECODE_INVALID_NUMBERS +#define DEFAULT_DECODE_INVALID_NUMBERS 0 +#endif + +#ifdef _MSC_VER +/* Microsoft C compiler lacks strncasecmp and strcasecmp. */ +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif + +#if LONG_MAX > ((1UL << 31) - 1) +#define json_lightudata_mask(ludata) \ + ((void *) ((uintptr_t) (ludata) & ((1UL << 47) - 1))) + +#else +#define json_lightudata_mask(ludata) (ludata) +#endif + +#if LUA_VERSION_NUM > 501 +#define lua_objlen(L,i) lua_rawlen(L, (i)) +#endif + +static const char * const *json_empty_array; +static const char * const *json_array; + +typedef enum { + T_OBJ_BEGIN, + T_OBJ_END, + T_ARR_BEGIN, + T_ARR_END, + T_STRING, + T_NUMBER, + T_BOOLEAN, + T_NULL, + T_COLON, + T_COMMA, + T_END, + T_WHITESPACE, + T_ERROR, + T_UNKNOWN +} json_token_type_t; + +static const char *json_token_type_name[] = { + "T_OBJ_BEGIN", + "T_OBJ_END", + "T_ARR_BEGIN", + "T_ARR_END", + "T_STRING", + "T_NUMBER", + "T_BOOLEAN", + "T_NULL", + "T_COLON", + "T_COMMA", + "T_END", + "T_WHITESPACE", + "T_ERROR", + "T_UNKNOWN", + NULL +}; + +typedef struct { + json_token_type_t ch2token[256]; + char escape2char[256]; /* Decoding */ + + /* encode_buf is only allocated and used when + * encode_keep_buffer is set */ + strbuf_t encode_buf; + + int encode_sparse_convert; + int encode_sparse_ratio; + int encode_sparse_safe; + int encode_max_depth; + int encode_invalid_numbers; /* 2 => Encode as "null" */ + int encode_number_precision; + int encode_keep_buffer; + int encode_empty_table_as_object; + int encode_escape_forward_slash; + + int decode_invalid_numbers; + int decode_max_depth; + int decode_array_with_array_mt; +} json_config_t; + +typedef struct { + /* convert null in json objects to lua nil instead of vim.NIL */ + int luanil_object; + /* convert null in json arrays to lua nil instead of vim.NIL */ + int luanil_array; +} json_options_t; + +typedef struct { + const char *data; + const char *ptr; + strbuf_t *tmp; /* Temporary storage for strings */ + json_config_t *cfg; + json_options_t *options; + int current_depth; +} json_parse_t; + +typedef struct { + json_token_type_t type; + int index; + union { + const char *string; + double number; + int boolean; + } value; + int string_len; +} json_token_t; + +static const char *char2escape[256] = { + "\\u0000", "\\u0001", "\\u0002", "\\u0003", + "\\u0004", "\\u0005", "\\u0006", "\\u0007", + "\\b", "\\t", "\\n", "\\u000b", + "\\f", "\\r", "\\u000e", "\\u000f", + "\\u0010", "\\u0011", "\\u0012", "\\u0013", + "\\u0014", "\\u0015", "\\u0016", "\\u0017", + "\\u0018", "\\u0019", "\\u001a", "\\u001b", + "\\u001c", "\\u001d", "\\u001e", "\\u001f", + NULL, NULL, "\\\"", NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\\/", + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, "\\\\", NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\\u007f", + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +/* ===== CONFIGURATION ===== */ + +static json_config_t *json_fetch_config(lua_State *l) +{ + json_config_t *cfg; + + cfg = lua_touserdata(l, lua_upvalueindex(1)); + if (!cfg) + luaL_error(l, "BUG: Unable to fetch CJSON configuration"); + + return cfg; +} + +/* Ensure the correct number of arguments have been provided. + * Pad with nil to allow other functions to simply check arg[i] + * to find whether an argument was provided */ +static json_config_t *json_arg_init(lua_State *l, int args) +{ + luaL_argcheck(l, lua_gettop(l) <= args, args + 1, + "found too many arguments"); + + while (lua_gettop(l) < args) + lua_pushnil(l); + + return json_fetch_config(l); +} + +/* Process integer options for configuration functions */ +static int json_integer_option(lua_State *l, int optindex, int *setting, + int min, int max) +{ + char errmsg[64]; + int value; + + if (!lua_isnil(l, optindex)) { + value = luaL_checkinteger(l, optindex); + snprintf(errmsg, sizeof(errmsg), "expected integer between %d and %d", min, max); + luaL_argcheck(l, min <= value && value <= max, 1, errmsg); + *setting = value; + } + + lua_pushinteger(l, *setting); + + return 1; +} + +/* Process enumerated arguments for a configuration function */ +static int json_enum_option(lua_State *l, int optindex, int *setting, + const char **options, int bool_true) +{ + static const char *bool_options[] = { "off", "on", NULL }; + + if (!options) { + options = bool_options; + bool_true = 1; + } + + if (!lua_isnil(l, optindex)) { + if (bool_true && lua_isboolean(l, optindex)) + *setting = lua_toboolean(l, optindex) * bool_true; + else + *setting = luaL_checkoption(l, optindex, NULL, options); + } + + if (bool_true && (*setting == 0 || *setting == bool_true)) + lua_pushboolean(l, *setting); + else + lua_pushstring(l, options[*setting]); + + return 1; +} + +/* Configures handling of extremely sparse arrays: + * convert: Convert extremely sparse arrays into objects? Otherwise error. + * ratio: 0: always allow sparse; 1: never allow sparse; >1: use ratio + * safe: Always use an array when the max index <= safe */ +static int json_cfg_encode_sparse_array(lua_State *l) +{ + json_config_t *cfg = json_arg_init(l, 3); + + json_enum_option(l, 1, &cfg->encode_sparse_convert, NULL, 1); + json_integer_option(l, 2, &cfg->encode_sparse_ratio, 0, INT_MAX); + json_integer_option(l, 3, &cfg->encode_sparse_safe, 0, INT_MAX); + + return 3; +} + +/* Configures the maximum number of nested arrays/objects allowed when + * encoding */ +static int json_cfg_encode_max_depth(lua_State *l) +{ + json_config_t *cfg = json_arg_init(l, 1); + + return json_integer_option(l, 1, &cfg->encode_max_depth, 1, INT_MAX); +} + +/* Configures the maximum number of nested arrays/objects allowed when + * encoding */ +static int json_cfg_decode_max_depth(lua_State *l) +{ + json_config_t *cfg = json_arg_init(l, 1); + + return json_integer_option(l, 1, &cfg->decode_max_depth, 1, INT_MAX); +} + +/* Configures number precision when converting doubles to text */ +static int json_cfg_encode_number_precision(lua_State *l) +{ + json_config_t *cfg = json_arg_init(l, 1); + + return json_integer_option(l, 1, &cfg->encode_number_precision, 1, 16); +} + +/* Configures how to treat empty table when encode lua table */ +static int json_cfg_encode_empty_table_as_object(lua_State *l) +{ + json_config_t *cfg = json_arg_init(l, 1); + + return json_enum_option(l, 1, &cfg->encode_empty_table_as_object, NULL, 1); +} + +/* Configures how to decode arrays */ +static int json_cfg_decode_array_with_array_mt(lua_State *l) +{ + json_config_t *cfg = json_arg_init(l, 1); + + json_enum_option(l, 1, &cfg->decode_array_with_array_mt, NULL, 1); + + return 1; +} + +/* Configures JSON encoding buffer persistence */ +static int json_cfg_encode_keep_buffer(lua_State *l) +{ + json_config_t *cfg = json_arg_init(l, 1); + int old_value; + + old_value = cfg->encode_keep_buffer; + + json_enum_option(l, 1, &cfg->encode_keep_buffer, NULL, 1); + + /* Init / free the buffer if the setting has changed */ + if (old_value ^ cfg->encode_keep_buffer) { + if (cfg->encode_keep_buffer) + strbuf_init(&cfg->encode_buf, 0); + else + strbuf_free(&cfg->encode_buf); + } + + return 1; +} + +#if defined(DISABLE_INVALID_NUMBERS) && !defined(USE_INTERNAL_FPCONV) +void json_verify_invalid_number_setting(lua_State *l, int *setting) +{ + if (*setting == 1) { + *setting = 0; + luaL_error(l, "Infinity, NaN, and/or hexadecimal numbers are not supported."); + } +} +#else +#define json_verify_invalid_number_setting(l, s) do { } while(0) +#endif + +static int json_cfg_encode_invalid_numbers(lua_State *l) +{ + static const char *options[] = { "off", "on", "null", NULL }; + json_config_t *cfg = json_arg_init(l, 1); + + json_enum_option(l, 1, &cfg->encode_invalid_numbers, options, 1); + + json_verify_invalid_number_setting(l, &cfg->encode_invalid_numbers); + + return 1; +} + +static int json_cfg_decode_invalid_numbers(lua_State *l) +{ + json_config_t *cfg = json_arg_init(l, 1); + + json_enum_option(l, 1, &cfg->decode_invalid_numbers, NULL, 1); + + json_verify_invalid_number_setting(l, &cfg->encode_invalid_numbers); + + return 1; +} + +static int json_cfg_encode_escape_forward_slash(lua_State *l) +{ + int ret; + json_config_t *cfg = json_arg_init(l, 1); + + ret = json_enum_option(l, 1, &cfg->encode_escape_forward_slash, NULL, 1); + if (cfg->encode_escape_forward_slash) { + char2escape['/'] = "\\/"; + } else { + char2escape['/'] = NULL; + } + return ret; +} + +static int json_destroy_config(lua_State *l) +{ + json_config_t *cfg; + + cfg = lua_touserdata(l, 1); + if (cfg) + strbuf_free(&cfg->encode_buf); + cfg = NULL; + + return 0; +} + +static void json_create_config(lua_State *l) +{ + json_config_t *cfg; + int i; + + cfg = lua_newuserdata(l, sizeof(*cfg)); + + /* Create GC method to clean up strbuf */ + lua_newtable(l); + lua_pushcfunction(l, json_destroy_config); + lua_setfield(l, -2, "__gc"); + lua_setmetatable(l, -2); + + cfg->encode_sparse_convert = DEFAULT_SPARSE_CONVERT; + cfg->encode_sparse_ratio = DEFAULT_SPARSE_RATIO; + cfg->encode_sparse_safe = DEFAULT_SPARSE_SAFE; + cfg->encode_max_depth = DEFAULT_ENCODE_MAX_DEPTH; + cfg->decode_max_depth = DEFAULT_DECODE_MAX_DEPTH; + cfg->encode_invalid_numbers = DEFAULT_ENCODE_INVALID_NUMBERS; + cfg->decode_invalid_numbers = DEFAULT_DECODE_INVALID_NUMBERS; + cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER; + cfg->encode_number_precision = DEFAULT_ENCODE_NUMBER_PRECISION; + cfg->encode_empty_table_as_object = DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT; + cfg->decode_array_with_array_mt = DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT; + cfg->encode_escape_forward_slash = DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH; + +#if DEFAULT_ENCODE_KEEP_BUFFER > 0 + strbuf_init(&cfg->encode_buf, 0); +#endif + + /* Decoding init */ + + /* Tag all characters as an error */ + for (i = 0; i < 256; i++) + cfg->ch2token[i] = T_ERROR; + + /* Set tokens that require no further processing */ + cfg->ch2token['{'] = T_OBJ_BEGIN; + cfg->ch2token['}'] = T_OBJ_END; + cfg->ch2token['['] = T_ARR_BEGIN; + cfg->ch2token[']'] = T_ARR_END; + cfg->ch2token[','] = T_COMMA; + cfg->ch2token[':'] = T_COLON; + cfg->ch2token['\0'] = T_END; + cfg->ch2token[' '] = T_WHITESPACE; + cfg->ch2token['\t'] = T_WHITESPACE; + cfg->ch2token['\n'] = T_WHITESPACE; + cfg->ch2token['\r'] = T_WHITESPACE; + + /* Update characters that require further processing */ + cfg->ch2token['f'] = T_UNKNOWN; /* false? */ + cfg->ch2token['i'] = T_UNKNOWN; /* inf, ininity? */ + cfg->ch2token['I'] = T_UNKNOWN; + cfg->ch2token['n'] = T_UNKNOWN; /* null, nan? */ + cfg->ch2token['N'] = T_UNKNOWN; + cfg->ch2token['t'] = T_UNKNOWN; /* true? */ + cfg->ch2token['"'] = T_UNKNOWN; /* string? */ + cfg->ch2token['+'] = T_UNKNOWN; /* number? */ + cfg->ch2token['-'] = T_UNKNOWN; + for (i = 0; i < 10; i++) + cfg->ch2token['0' + i] = T_UNKNOWN; + + /* Lookup table for parsing escape characters */ + for (i = 0; i < 256; i++) + cfg->escape2char[i] = 0; /* String error */ + cfg->escape2char['"'] = '"'; + cfg->escape2char['\\'] = '\\'; + cfg->escape2char['/'] = '/'; + cfg->escape2char['b'] = '\b'; + cfg->escape2char['t'] = '\t'; + cfg->escape2char['n'] = '\n'; + cfg->escape2char['f'] = '\f'; + cfg->escape2char['r'] = '\r'; + cfg->escape2char['u'] = 'u'; /* Unicode parsing required */ +} + +/* ===== ENCODING ===== */ + +static void json_encode_exception(lua_State *l, json_config_t *cfg, strbuf_t *json, int lindex, + const char *reason) +{ + if (!cfg->encode_keep_buffer) + strbuf_free(json); + luaL_error(l, "Cannot serialise %s: %s", + lua_typename(l, lua_type(l, lindex)), reason); +} + +/* json_append_string args: + * - lua_State + * - JSON strbuf + * - String (Lua stack index) + * + * Returns nothing. Doesn't remove string from Lua stack */ +static void json_append_string(lua_State *l, strbuf_t *json, int lindex) +{ + const char *escstr; + unsigned i; + const char *str; + size_t len; + + str = lua_tolstring(l, lindex, &len); + + /* Worst case is len * 6 (all unicode escapes). + * This buffer is reused constantly for small strings + * If there are any excess pages, they won't be hit anyway. + * This gains ~5% speedup. */ + strbuf_ensure_empty_length(json, len * 6 + 2); + + strbuf_append_char_unsafe(json, '\"'); + for (i = 0; i < len; i++) { + escstr = char2escape[(unsigned char)str[i]]; + if (escstr) + strbuf_append_string(json, escstr); + else + strbuf_append_char_unsafe(json, str[i]); + } + strbuf_append_char_unsafe(json, '\"'); +} + +/* Find the size of the array on the top of the Lua stack + * -1 object (not a pure array) + * >=0 elements in array + */ +static int lua_array_length(lua_State *l, json_config_t *cfg, strbuf_t *json) +{ + double k; + int max; + int items; + + max = 0; + items = 0; + + lua_pushnil(l); + /* table, startkey */ + while (lua_next(l, -2) != 0) { + /* table, key, value */ + if (lua_type(l, -2) == LUA_TNUMBER && + (k = lua_tonumber(l, -2))) { + /* Integer >= 1 ? */ + if (floor(k) == k && k >= 1) { + if (k > max) + max = k; + items++; + lua_pop(l, 1); + continue; + } + } + + /* Must not be an array (non integer key) */ + lua_pop(l, 2); + return -1; + } + + /* Encode excessively sparse arrays as objects (if enabled) */ + if (cfg->encode_sparse_ratio > 0 && + max > items * cfg->encode_sparse_ratio && + max > cfg->encode_sparse_safe) { + if (!cfg->encode_sparse_convert) + json_encode_exception(l, cfg, json, -1, "excessively sparse array"); + + return -1; + } + + return max; +} + +static void json_check_encode_depth(lua_State *l, json_config_t *cfg, + int current_depth, strbuf_t *json) +{ + /* Ensure there are enough slots free to traverse a table (key, + * value) and push a string for a potential error message. + * + * Unlike "decode", the key and value are still on the stack when + * lua_checkstack() is called. Hence an extra slot for luaL_error() + * below is required just in case the next check to lua_checkstack() + * fails. + * + * While this won't cause a crash due to the EXTRA_STACK reserve + * slots, it would still be an improper use of the API. */ + if (current_depth <= cfg->encode_max_depth && lua_checkstack(l, 3)) + return; + + if (!cfg->encode_keep_buffer) + strbuf_free(json); + + luaL_error(l, "Cannot serialise, excessive nesting (%d)", + current_depth); +} + +static void json_append_data(lua_State *l, json_config_t *cfg, + int current_depth, strbuf_t *json); + +/* json_append_array args: + * - lua_State + * - JSON strbuf + * - Size of passwd Lua array (top of stack) */ +static void json_append_array(lua_State *l, json_config_t *cfg, int current_depth, + strbuf_t *json, int array_length) +{ + int comma, i; + + strbuf_append_char(json, '['); + + comma = 0; + for (i = 1; i <= array_length; i++) { + if (comma) + strbuf_append_char(json, ','); + else + comma = 1; + + lua_rawgeti(l, -1, i); + json_append_data(l, cfg, current_depth, json); + lua_pop(l, 1); + } + + strbuf_append_char(json, ']'); +} + +static void json_append_number(lua_State *l, json_config_t *cfg, + strbuf_t *json, int lindex) +{ + double num = lua_tonumber(l, lindex); + int len; + + if (cfg->encode_invalid_numbers == 0) { + /* Prevent encoding invalid numbers */ + if (isinf(num) || isnan(num)) + json_encode_exception(l, cfg, json, lindex, + "must not be NaN or Infinity"); + } else if (cfg->encode_invalid_numbers == 1) { + /* Encode NaN/Infinity separately to ensure Javascript compatible + * values are used. */ + if (isnan(num)) { + strbuf_append_mem(json, "NaN", 3); + return; + } + if (isinf(num)) { + if (num < 0) + strbuf_append_mem(json, "-Infinity", 9); + else + strbuf_append_mem(json, "Infinity", 8); + return; + } + } else { + /* Encode invalid numbers as "null" */ + if (isinf(num) || isnan(num)) { + strbuf_append_mem(json, "null", 4); + return; + } + } + + strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE); + len = fpconv_g_fmt(strbuf_empty_ptr(json), num, cfg->encode_number_precision); + strbuf_extend_length(json, len); +} + +static void json_append_object(lua_State *l, json_config_t *cfg, + int current_depth, strbuf_t *json) +{ + int comma, keytype; + + /* Object */ + strbuf_append_char(json, '{'); + + lua_pushnil(l); + /* table, startkey */ + comma = 0; + while (lua_next(l, -2) != 0) { + if (comma) + strbuf_append_char(json, ','); + else + comma = 1; + + /* table, key, value */ + keytype = lua_type(l, -2); + if (keytype == LUA_TNUMBER) { + strbuf_append_char(json, '"'); + json_append_number(l, cfg, json, -2); + strbuf_append_mem(json, "\":", 2); + } else if (keytype == LUA_TSTRING) { + json_append_string(l, json, -2); + strbuf_append_char(json, ':'); + } else { + json_encode_exception(l, cfg, json, -2, + "table key must be a number or string"); + /* never returns */ + } + + /* table, key, value */ + json_append_data(l, cfg, current_depth, json); + lua_pop(l, 1); + /* table, key */ + } + + strbuf_append_char(json, '}'); +} + +/* Serialise Lua data into JSON string. */ +static void json_append_data(lua_State *l, json_config_t *cfg, + int current_depth, strbuf_t *json) +{ + int len; + int as_array = 0; + int as_empty_dict = 0; + int has_metatable; + + switch (lua_type(l, -1)) { + case LUA_TSTRING: + json_append_string(l, json, -1); + break; + case LUA_TNUMBER: + json_append_number(l, cfg, json, -1); + break; + case LUA_TBOOLEAN: + if (lua_toboolean(l, -1)) + strbuf_append_mem(json, "true", 4); + else + strbuf_append_mem(json, "false", 5); + break; + case LUA_TTABLE: + current_depth++; + json_check_encode_depth(l, cfg, current_depth, json); + + has_metatable = lua_getmetatable(l, -1); + + if (has_metatable) { + + nlua_pushref(l, nlua_empty_dict_ref); + if (lua_rawequal(l, -2, -1)) { + as_empty_dict = true; + } else { + lua_pop(l, 1); + lua_pushlightuserdata(l, json_lightudata_mask(&json_array)); + lua_rawget(l, LUA_REGISTRYINDEX); + as_array = lua_rawequal(l, -1, -2); + } + lua_pop(l, 2); + } + + if (as_array) { + len = lua_objlen(l, -1); + json_append_array(l, cfg, current_depth, json, len); + } else { + len = lua_array_length(l, cfg, json); + + if (len > 0 || (len == 0 && !cfg->encode_empty_table_as_object && !as_empty_dict)) { + json_append_array(l, cfg, current_depth, json, len); + } else { + if (has_metatable) { + lua_getmetatable(l, -1); + lua_pushlightuserdata(l, json_lightudata_mask( + &json_empty_array)); + lua_rawget(l, LUA_REGISTRYINDEX); + as_array = lua_rawequal(l, -1, -2); + lua_pop(l, 2); /* pop pointer + metatable */ + if (as_array) { + json_append_array(l, cfg, current_depth, json, 0); + break; + } + } + json_append_object(l, cfg, current_depth, json); + } + } + break; + case LUA_TNIL: + strbuf_append_mem(json, "null", 4); + break; + case LUA_TLIGHTUSERDATA: + if (lua_touserdata(l, -1) == &json_array) { + json_append_array(l, cfg, current_depth, json, 0); + } + break; + case LUA_TUSERDATA: + nlua_pushref(l, nlua_nil_ref); + bool is_nil = lua_rawequal(l, -2, -1); + lua_pop(l, 1); + if (is_nil) { + strbuf_append_mem(json, "null", 4); + break; + } else { + FALLTHROUGH; + } + default: + /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD, + * and LUA_TLIGHTUSERDATA) cannot be serialised */ + json_encode_exception(l, cfg, json, -1, "type not supported"); + /* never returns */ + } +} + +static int json_encode(lua_State *l) +{ + json_config_t *cfg = json_fetch_config(l); + strbuf_t local_encode_buf; + strbuf_t *encode_buf; + char *json; + int len; + + luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument"); + + if (!cfg->encode_keep_buffer) { + /* Use private buffer */ + encode_buf = &local_encode_buf; + strbuf_init(encode_buf, 0); + } else { + /* Reuse existing buffer */ + encode_buf = &cfg->encode_buf; + strbuf_reset(encode_buf); + } + + json_append_data(l, cfg, 0, encode_buf); + json = strbuf_string(encode_buf, &len); + + lua_pushlstring(l, json, len); + + if (!cfg->encode_keep_buffer) + strbuf_free(encode_buf); + + return 1; +} + +/* ===== DECODING ===== */ + +static void json_process_value(lua_State *l, json_parse_t *json, + json_token_t *token, bool use_luanil); + +static int hexdigit2int(char hex) +{ + if ('0' <= hex && hex <= '9') + return hex - '0'; + + /* Force lowercase */ + hex |= 0x20; + if ('a' <= hex && hex <= 'f') + return 10 + hex - 'a'; + + return -1; +} + +static int decode_hex4(const char *hex) +{ + int digit[4]; + int i; + + /* Convert ASCII hex digit to numeric digit + * Note: this returns an error for invalid hex digits, including + * NULL */ + for (i = 0; i < 4; i++) { + digit[i] = hexdigit2int(hex[i]); + if (digit[i] < 0) { + return -1; + } + } + + return (digit[0] << 12) + + (digit[1] << 8) + + (digit[2] << 4) + + digit[3]; +} + +/* Converts a Unicode codepoint to UTF-8. + * Returns UTF-8 string length, and up to 4 bytes in *utf8 */ +static int codepoint_to_utf8(char *utf8, int codepoint) +{ + /* 0xxxxxxx */ + if (codepoint <= 0x7F) { + utf8[0] = codepoint; + return 1; + } + + /* 110xxxxx 10xxxxxx */ + if (codepoint <= 0x7FF) { + utf8[0] = (codepoint >> 6) | 0xC0; + utf8[1] = (codepoint & 0x3F) | 0x80; + return 2; + } + + /* 1110xxxx 10xxxxxx 10xxxxxx */ + if (codepoint <= 0xFFFF) { + utf8[0] = (codepoint >> 12) | 0xE0; + utf8[1] = ((codepoint >> 6) & 0x3F) | 0x80; + utf8[2] = (codepoint & 0x3F) | 0x80; + return 3; + } + + /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (codepoint <= 0x1FFFFF) { + utf8[0] = (codepoint >> 18) | 0xF0; + utf8[1] = ((codepoint >> 12) & 0x3F) | 0x80; + utf8[2] = ((codepoint >> 6) & 0x3F) | 0x80; + utf8[3] = (codepoint & 0x3F) | 0x80; + return 4; + } + + return 0; +} + + +/* Called when index pointing to beginning of UTF-16 code escape: \uXXXX + * \u is guaranteed to exist, but the remaining hex characters may be + * missing. + * Translate to UTF-8 and append to temporary token string. + * Must advance index to the next character to be processed. + * Returns: 0 success + * -1 error + */ +static int json_append_unicode_escape(json_parse_t *json) +{ + char utf8[4]; /* Surrogate pairs require 4 UTF-8 bytes */ + int codepoint; + int surrogate_low; + int len; + int escape_len = 6; + + /* Fetch UTF-16 code unit */ + codepoint = decode_hex4(json->ptr + 2); + if (codepoint < 0) + return -1; + + /* UTF-16 surrogate pairs take the following 2 byte form: + * 11011 x yyyyyyyyyy + * When x = 0: y is the high 10 bits of the codepoint + * x = 1: y is the low 10 bits of the codepoint + * + * Check for a surrogate pair (high or low) */ + if ((codepoint & 0xF800) == 0xD800) { + /* Error if the 1st surrogate is not high */ + if (codepoint & 0x400) + return -1; + + /* Ensure the next code is a unicode escape */ + if (*(json->ptr + escape_len) != '\\' || + *(json->ptr + escape_len + 1) != 'u') { + return -1; + } + + /* Fetch the next codepoint */ + surrogate_low = decode_hex4(json->ptr + 2 + escape_len); + if (surrogate_low < 0) + return -1; + + /* Error if the 2nd code is not a low surrogate */ + if ((surrogate_low & 0xFC00) != 0xDC00) + return -1; + + /* Calculate Unicode codepoint */ + codepoint = (codepoint & 0x3FF) << 10; + surrogate_low &= 0x3FF; + codepoint = (codepoint | surrogate_low) + 0x10000; + escape_len = 12; + } + + /* Convert codepoint to UTF-8 */ + len = codepoint_to_utf8(utf8, codepoint); + if (!len) + return -1; + + /* Append bytes and advance parse index */ + strbuf_append_mem_unsafe(json->tmp, utf8, len); + json->ptr += escape_len; + + return 0; +} + +static void json_set_token_error(json_token_t *token, json_parse_t *json, + const char *errtype) +{ + token->type = T_ERROR; + token->index = json->ptr - json->data; + token->value.string = errtype; +} + +static void json_next_string_token(json_parse_t *json, json_token_t *token) +{ + char *escape2char = json->cfg->escape2char; + char ch; + + /* Caller must ensure a string is next */ + assert(*json->ptr == '"'); + + /* Skip " */ + json->ptr++; + + /* json->tmp is the temporary strbuf used to accumulate the + * decoded string value. + * json->tmp is sized to handle JSON containing only a string value. + */ + strbuf_reset(json->tmp); + + while ((ch = *json->ptr) != '"') { + if (!ch) { + /* Premature end of the string */ + json_set_token_error(token, json, "unexpected end of string"); + return; + } + + /* Handle escapes */ + if (ch == '\\') { + /* Fetch escape character */ + ch = *(json->ptr + 1); + + /* Translate escape code and append to tmp string */ + ch = escape2char[(unsigned char)ch]; + if (ch == 'u') { + if (json_append_unicode_escape(json) == 0) + continue; + + json_set_token_error(token, json, + "invalid unicode escape code"); + return; + } + if (!ch) { + json_set_token_error(token, json, "invalid escape code"); + return; + } + + /* Skip '\' */ + json->ptr++; + } + /* Append normal character or translated single character + * Unicode escapes are handled above */ + strbuf_append_char_unsafe(json->tmp, ch); + json->ptr++; + } + json->ptr++; /* Eat final quote (") */ + + strbuf_ensure_null(json->tmp); + + token->type = T_STRING; + token->value.string = strbuf_string(json->tmp, &token->string_len); +} + +/* JSON numbers should take the following form: + * -?(0|[1-9]|[1-9][0-9]+)(.[0-9]+)?([eE][-+]?[0-9]+)? + * + * json_next_number_token() uses strtod() which allows other forms: + * - numbers starting with '+' + * - NaN, -NaN, infinity, -infinity + * - hexadecimal numbers + * - numbers with leading zeros + * + * json_is_invalid_number() detects "numbers" which may pass strtod()'s + * error checking, but should not be allowed with strict JSON. + * + * json_is_invalid_number() may pass numbers which cause strtod() + * to generate an error. + */ +static int json_is_invalid_number(json_parse_t *json) +{ + const char *p = json->ptr; + + /* Reject numbers starting with + */ + if (*p == '+') + return 1; + + /* Skip minus sign if it exists */ + if (*p == '-') + p++; + + /* Reject numbers starting with 0x, or leading zeros */ + if (*p == '0') { + int ch2 = *(p + 1); + + if ((ch2 | 0x20) == 'x' || /* Hex */ + ('0' <= ch2 && ch2 <= '9')) /* Leading zero */ + return 1; + + return 0; + } else if (*p <= '9') { + return 0; /* Ordinary number */ + } + + /* Reject inf/nan */ + if (!strncasecmp(p, "inf", 3)) + return 1; + if (!strncasecmp(p, "nan", 3)) + return 1; + + /* Pass all other numbers which may still be invalid, but + * strtod() will catch them. */ + return 0; +} + +static void json_next_number_token(json_parse_t *json, json_token_t *token) +{ + char *endptr; + + token->type = T_NUMBER; + token->value.number = fpconv_strtod(json->ptr, &endptr); + if (json->ptr == endptr) + json_set_token_error(token, json, "invalid number"); + else + json->ptr = endptr; /* Skip the processed number */ + + return; +} + +/* Fills in the token struct. + * T_STRING will return a pointer to the json_parse_t temporary string + * T_ERROR will leave the json->ptr pointer at the error. + */ +static void json_next_token(json_parse_t *json, json_token_t *token) +{ + const json_token_type_t *ch2token = json->cfg->ch2token; + int ch; + + /* Eat whitespace. */ + while (1) { + ch = (unsigned char)*(json->ptr); + token->type = ch2token[ch]; + if (token->type != T_WHITESPACE) + break; + json->ptr++; + } + + /* Store location of new token. Required when throwing errors + * for unexpected tokens (syntax errors). */ + token->index = json->ptr - json->data; + + /* Don't advance the pointer for an error or the end */ + if (token->type == T_ERROR) { + json_set_token_error(token, json, "invalid token"); + return; + } + + if (token->type == T_END) { + return; + } + + /* Found a known single character token, advance index and return */ + if (token->type != T_UNKNOWN) { + json->ptr++; + return; + } + + /* Process characters which triggered T_UNKNOWN + * + * Must use strncmp() to match the front of the JSON string. + * JSON identifier must be lowercase. + * When strict_numbers if disabled, either case is allowed for + * Infinity/NaN (since we are no longer following the spec..) */ + if (ch == '"') { + json_next_string_token(json, token); + return; + } else if (ch == '-' || ('0' <= ch && ch <= '9')) { + if (!json->cfg->decode_invalid_numbers && json_is_invalid_number(json)) { + json_set_token_error(token, json, "invalid number"); + return; + } + json_next_number_token(json, token); + return; + } else if (!strncmp(json->ptr, "true", 4)) { + token->type = T_BOOLEAN; + token->value.boolean = 1; + json->ptr += 4; + return; + } else if (!strncmp(json->ptr, "false", 5)) { + token->type = T_BOOLEAN; + token->value.boolean = 0; + json->ptr += 5; + return; + } else if (!strncmp(json->ptr, "null", 4)) { + token->type = T_NULL; + json->ptr += 4; + return; + } else if (json->cfg->decode_invalid_numbers && + json_is_invalid_number(json)) { + /* When decode_invalid_numbers is enabled, only attempt to process + * numbers we know are invalid JSON (Inf, NaN, hex) + * This is required to generate an appropriate token error, + * otherwise all bad tokens will register as "invalid number" + */ + json_next_number_token(json, token); + return; + } + + /* Token starts with t/f/n but isn't recognised above. */ + json_set_token_error(token, json, "invalid token"); +} + +/* This function does not return. + * DO NOT CALL WITH DYNAMIC MEMORY ALLOCATED. + * The only supported exception is the temporary parser string + * json->tmp struct. + * json and token should exist on the stack somewhere. + * luaL_error() will long_jmp and release the stack */ +static void json_throw_parse_error(lua_State *l, json_parse_t *json, + const char *exp, json_token_t *token) +{ + const char *found; + + strbuf_free(json->tmp); + + if (token->type == T_ERROR) + found = token->value.string; + else + found = json_token_type_name[token->type]; + + /* Note: token->index is 0 based, display starting from 1 */ + luaL_error(l, "Expected %s but found %s at character %d", + exp, found, token->index + 1); +} + +static inline void json_decode_ascend(json_parse_t *json) +{ + json->current_depth--; +} + +static void json_decode_descend(lua_State *l, json_parse_t *json, int slots) +{ + json->current_depth++; + + if (json->current_depth <= json->cfg->decode_max_depth && + lua_checkstack(l, slots)) { + return; + } + + strbuf_free(json->tmp); + luaL_error(l, "Found too many nested data structures (%d) at character %d", + json->current_depth, json->ptr - json->data); +} + +static void json_parse_object_context(lua_State *l, json_parse_t *json) +{ + json_token_t token; + + /* 3 slots required: + * .., table, key, value */ + json_decode_descend(l, json, 3); + + lua_newtable(l); + + json_next_token(json, &token); + + /* Handle empty objects */ + if (token.type == T_OBJ_END) { + nlua_pushref(l, nlua_empty_dict_ref); \ + lua_setmetatable(l, -2); \ + json_decode_ascend(json); + return; + } + + while (1) { + if (token.type != T_STRING) + json_throw_parse_error(l, json, "object key string", &token); + + /* Push key */ + lua_pushlstring(l, token.value.string, token.string_len); + + json_next_token(json, &token); + if (token.type != T_COLON) + json_throw_parse_error(l, json, "colon", &token); + + /* Fetch value */ + json_next_token(json, &token); + json_process_value(l, json, &token, json->options->luanil_object); + + /* Set key = value */ + lua_rawset(l, -3); + + json_next_token(json, &token); + + if (token.type == T_OBJ_END) { + json_decode_ascend(json); + return; + } + + if (token.type != T_COMMA) + json_throw_parse_error(l, json, "comma or object end", &token); + + json_next_token(json, &token); + } +} + +/* Handle the array context */ +static void json_parse_array_context(lua_State *l, json_parse_t *json) +{ + json_token_t token; + int i; + + /* 2 slots required: + * .., table, value */ + json_decode_descend(l, json, 2); + + lua_newtable(l); + + /* set array_mt on the table at the top of the stack */ + if (json->cfg->decode_array_with_array_mt) { + lua_pushlightuserdata(l, json_lightudata_mask(&json_array)); + lua_rawget(l, LUA_REGISTRYINDEX); + lua_setmetatable(l, -2); + } + + json_next_token(json, &token); + + /* Handle empty arrays */ + if (token.type == T_ARR_END) { + json_decode_ascend(json); + return; + } + + for (i = 1; ; i++) { + json_process_value(l, json, &token, json->options->luanil_array); + lua_rawseti(l, -2, i); /* arr[i] = value */ + + json_next_token(json, &token); + + if (token.type == T_ARR_END) { + json_decode_ascend(json); + return; + } + + if (token.type != T_COMMA) + json_throw_parse_error(l, json, "comma or array end", &token); + + json_next_token(json, &token); + } +} + +/* Handle the "value" context */ +static void json_process_value(lua_State *l, json_parse_t *json, + json_token_t *token, bool use_luanil) +{ + switch (token->type) { + case T_STRING: + lua_pushlstring(l, token->value.string, token->string_len); + break;; + case T_NUMBER: + lua_pushnumber(l, token->value.number); + break;; + case T_BOOLEAN: + lua_pushboolean(l, token->value.boolean); + break;; + case T_OBJ_BEGIN: + json_parse_object_context(l, json); + break;; + case T_ARR_BEGIN: + json_parse_array_context(l, json); + break;; + case T_NULL: + if (use_luanil) { + lua_pushnil(l); + } else { + nlua_pushref(l, nlua_nil_ref); + } + break;; + default: + json_throw_parse_error(l, json, "value", token); + } +} + +static int json_decode(lua_State *l) +{ + json_parse_t json; + json_token_t token; + json_options_t options = { .luanil_object = false, .luanil_array = false }; + + + size_t json_len; + + switch (lua_gettop(l)) { + case 1: + break; + case 2: + luaL_checktype(l, 2, LUA_TTABLE); + lua_getfield(l, 2, "luanil"); + + /* We only handle the luanil option for now */ + if (lua_isnil(l, -1)) { + lua_pop(l, 1); + break; + } + + luaL_checktype(l, -1, LUA_TTABLE); + + lua_getfield(l, -1, "object"); + if (!lua_isnil(l, -1)) { + options.luanil_object = true; + } + lua_pop(l, 1); + + lua_getfield(l, -1, "array"); + if (!lua_isnil(l, -1)) { + options.luanil_array = true; + } + /* Also pop the luanil table */ + lua_pop(l, 2); + break; + default: + return luaL_error (l, "expected 1 or 2 arguments"); + } + + json.cfg = json_fetch_config(l); + json.data = luaL_checklstring(l, 1, &json_len); + json.options = &options; + json.current_depth = 0; + json.ptr = json.data; + + /* Detect Unicode other than UTF-8 (see RFC 4627, Sec 3) + * + * CJSON can support any simple data type, hence only the first + * character is guaranteed to be ASCII (at worst: '"'). This is + * still enough to detect whether the wrong encoding is in use. */ + if (json_len >= 2 && (!json.data[0] || !json.data[1])) + luaL_error(l, "JSON parser does not support UTF-16 or UTF-32"); + + /* Ensure the temporary buffer can hold the entire string. + * This means we no longer need to do length checks since the decoded + * string must be smaller than the entire json string */ + json.tmp = strbuf_new(json_len); + + json_next_token(&json, &token); + json_process_value(l, &json, &token, json.options->luanil_object); + + /* Ensure there is no more input left */ + json_next_token(&json, &token); + + if (token.type != T_END) + json_throw_parse_error(l, &json, "the end", &token); + + strbuf_free(json.tmp); + + return 1; +} + +/* ===== INITIALISATION ===== */ + +#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502 +/* Compatibility for Lua 5.1 and older LuaJIT. + * + * compat_luaL_setfuncs() is used to create a module table where the functions + * have json_config_t as their first upvalue. Code borrowed from Lua 5.2 + * source's luaL_setfuncs(). + */ +static void compat_luaL_setfuncs(lua_State *l, const luaL_Reg *reg, int nup) +{ + int i; + + luaL_checkstack(l, nup, "too many upvalues"); + for (; reg->name != NULL; reg++) { /* fill the table with given functions */ + for (i = 0; i < nup; i++) /* copy upvalues to the top */ + lua_pushvalue(l, -nup); + lua_pushcclosure(l, reg->func, nup); /* closure with those upvalues */ + lua_setfield(l, -(nup + 2), reg->name); + } + lua_pop(l, nup); /* remove upvalues */ +} +#else +#define compat_luaL_setfuncs(L, reg, nup) luaL_setfuncs(L, reg, nup) +#endif + +/* Call target function in protected mode with all supplied args. + * Assumes target function only returns a single non-nil value. + * Convert and return thrown errors as: nil, "error message" */ +static int json_protect_conversion(lua_State *l) +{ + int err; + + /* Deliberately throw an error for invalid arguments */ + luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument"); + + /* pcall() the function stored as upvalue(1) */ + lua_pushvalue(l, lua_upvalueindex(1)); + lua_insert(l, 1); + err = lua_pcall(l, 1, 1, 0); + if (!err) + return 1; + + if (err == LUA_ERRRUN) { + lua_pushnil(l); + lua_insert(l, -2); + return 2; + } + + /* Since we are not using a custom error handler, the only remaining + * errors are memory related */ + return luaL_error(l, "Memory allocation error in CJSON protected call"); +} + +/* Return cjson module table */ +int lua_cjson_new(lua_State *l) +{ + luaL_Reg reg[] = { + { "encode", json_encode }, + { "decode", json_decode }, + { "encode_empty_table_as_object", json_cfg_encode_empty_table_as_object }, + { "decode_array_with_array_mt", json_cfg_decode_array_with_array_mt }, + { "encode_sparse_array", json_cfg_encode_sparse_array }, + { "encode_max_depth", json_cfg_encode_max_depth }, + { "decode_max_depth", json_cfg_decode_max_depth }, + { "encode_number_precision", json_cfg_encode_number_precision }, + { "encode_keep_buffer", json_cfg_encode_keep_buffer }, + { "encode_invalid_numbers", json_cfg_encode_invalid_numbers }, + { "decode_invalid_numbers", json_cfg_decode_invalid_numbers }, + { "encode_escape_forward_slash", json_cfg_encode_escape_forward_slash }, + { "new", lua_cjson_new }, + { NULL, NULL } + }; + + /* Initialise number conversions */ + fpconv_init(); + + /* Test if array metatables are in registry */ + lua_pushlightuserdata(l, json_lightudata_mask(&json_empty_array)); + lua_rawget(l, LUA_REGISTRYINDEX); + if (lua_isnil(l, -1)) { + /* Create array metatables. + * + * If multiple calls to lua_cjson_new() are made, + * this prevents overriding the tables at the given + * registry's index with a new one. + */ + lua_pop(l, 1); + + /* empty_array_mt */ + lua_pushlightuserdata(l, json_lightudata_mask(&json_empty_array)); + lua_newtable(l); + lua_rawset(l, LUA_REGISTRYINDEX); + + /* array_mt */ + lua_pushlightuserdata(l, json_lightudata_mask(&json_array)); + lua_newtable(l); + lua_rawset(l, LUA_REGISTRYINDEX); + } + + /* cjson module table */ + lua_newtable(l); + + /* Register functions with config data as upvalue */ + json_create_config(l); + compat_luaL_setfuncs(l, reg, 1); + + /* Set cjson.null */ + nlua_pushref(l, nlua_nil_ref); + lua_setfield(l, -2, "null"); + + /* Set cjson.empty_array_mt */ + lua_pushlightuserdata(l, json_lightudata_mask(&json_empty_array)); + lua_rawget(l, LUA_REGISTRYINDEX); + lua_setfield(l, -2, "empty_array_mt"); + + /* Set cjson.array_mt */ + lua_pushlightuserdata(l, json_lightudata_mask(&json_array)); + lua_rawget(l, LUA_REGISTRYINDEX); + lua_setfield(l, -2, "array_mt"); + + /* Set cjson.empty_array */ + lua_pushlightuserdata(l, json_lightudata_mask(&json_array)); + lua_setfield(l, -2, "empty_array"); + + /* Set module name / version fields */ + lua_pushliteral(l, CJSON_MODNAME); + lua_setfield(l, -2, "_NAME"); + lua_pushliteral(l, CJSON_VERSION); + lua_setfield(l, -2, "_VERSION"); + + return 1; +} + +/* Return cjson.safe module table */ +static int lua_cjson_safe_new(lua_State *l) +{ + const char *func[] = { "decode", "encode", NULL }; + int i; + + lua_cjson_new(l); + + /* Fix new() method */ + lua_pushcfunction(l, lua_cjson_safe_new); + lua_setfield(l, -2, "new"); + + for (i = 0; func[i]; i++) { + lua_getfield(l, -1, func[i]); + lua_pushcclosure(l, json_protect_conversion, 1); + lua_setfield(l, -2, func[i]); + } + + return 1; +} + +int luaopen_cjson(lua_State *l) +{ + lua_cjson_new(l); + +#ifdef ENABLE_CJSON_GLOBAL + /* Register a global "cjson" table. */ + lua_pushvalue(l, -1); + lua_setglobal(l, CJSON_MODNAME); +#endif + + /* Return cjson table */ + return 1; +} + +int luaopen_cjson_safe(lua_State *l) +{ + lua_cjson_safe_new(l); + + /* Return cjson.safe table */ + return 1; +} + +/* vi:ai et sw=4 ts=4: + */ diff --git a/src/cjson/lua_cjson.h b/src/cjson/lua_cjson.h new file mode 100644 index 0000000000..3f70b679be --- /dev/null +++ b/src/cjson/lua_cjson.h @@ -0,0 +1,10 @@ +#ifndef CJSON_LUACJSON_H +#define CJSON_LUACJSON_H + +#include "lua.h" + +int lua_cjson_new(lua_State *l); +int luaopen_cjson(lua_State *l); +int luaopen_cjson_safe(lua_State *l); + +#endif // CJSON_LUACJSON_H diff --git a/src/cjson/strbuf.c b/src/cjson/strbuf.c new file mode 100644 index 0000000000..f0f7f4b9a3 --- /dev/null +++ b/src/cjson/strbuf.c @@ -0,0 +1,251 @@ +/* strbuf - String buffer routines + * + * Copyright (c) 2010-2012 Mark Pulford <mark@kyne.com.au> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> + +#include "strbuf.h" + +static void die(const char *fmt, ...) +{ + va_list arg; + + va_start(arg, fmt); + vfprintf(stderr, fmt, arg); + va_end(arg); + fprintf(stderr, "\n"); + + exit(-1); +} + +void strbuf_init(strbuf_t *s, int len) +{ + int size; + + if (len <= 0) + size = STRBUF_DEFAULT_SIZE; + else + size = len + 1; /* \0 terminator */ + + s->buf = NULL; + s->size = size; + s->length = 0; + s->increment = STRBUF_DEFAULT_INCREMENT; + s->dynamic = 0; + s->reallocs = 0; + s->debug = 0; + + s->buf = malloc(size); + if (!s->buf) + die("Out of memory"); + + strbuf_ensure_null(s); +} + +strbuf_t *strbuf_new(int len) +{ + strbuf_t *s; + + s = malloc(sizeof(strbuf_t)); + if (!s) + die("Out of memory"); + + strbuf_init(s, len); + + /* Dynamic strbuf allocation / deallocation */ + s->dynamic = 1; + + return s; +} + +void strbuf_set_increment(strbuf_t *s, int increment) +{ + /* Increment > 0: Linear buffer growth rate + * Increment < -1: Exponential buffer growth rate */ + if (increment == 0 || increment == -1) + die("BUG: Invalid string increment"); + + s->increment = increment; +} + +static inline void debug_stats(strbuf_t *s) +{ + if (s->debug) { + fprintf(stderr, "strbuf(%lx) reallocs: %d, length: %d, size: %d\n", + (long)s, s->reallocs, s->length, s->size); + } +} + +/* If strbuf_t has not been dynamically allocated, strbuf_free() can + * be called any number of times strbuf_init() */ +void strbuf_free(strbuf_t *s) +{ + debug_stats(s); + + if (s->buf) { + free(s->buf); + s->buf = NULL; + } + if (s->dynamic) + free(s); +} + +char *strbuf_free_to_string(strbuf_t *s, int *len) +{ + char *buf; + + debug_stats(s); + + strbuf_ensure_null(s); + + buf = s->buf; + if (len) + *len = s->length; + + if (s->dynamic) + free(s); + + return buf; +} + +static int calculate_new_size(strbuf_t *s, int len) +{ + int reqsize, newsize; + + if (len <= 0) + die("BUG: Invalid strbuf length requested"); + + /* Ensure there is room for optional NULL termination */ + reqsize = len + 1; + + /* If the user has requested to shrink the buffer, do it exactly */ + if (s->size > reqsize) + return reqsize; + + newsize = s->size; + if (s->increment < 0) { + /* Exponential sizing */ + while (newsize < reqsize) + newsize *= -s->increment; + } else { + /* Linear sizing */ + newsize = ((newsize + s->increment - 1) / s->increment) * s->increment; + } + + return newsize; +} + + +/* Ensure strbuf can handle a string length bytes long (ignoring NULL + * optional termination). */ +void strbuf_resize(strbuf_t *s, int len) +{ + int newsize; + + newsize = calculate_new_size(s, len); + + if (s->debug > 1) { + fprintf(stderr, "strbuf(%lx) resize: %d => %d\n", + (long)s, s->size, newsize); + } + + s->size = newsize; + s->buf = realloc(s->buf, s->size); + if (!s->buf) + die("Out of memory"); + s->reallocs++; +} + +void strbuf_append_string(strbuf_t *s, const char *str) +{ + int space, i; + + space = strbuf_empty_length(s); + + for (i = 0; str[i]; i++) { + if (space < 1) { + strbuf_resize(s, s->length + 1); + space = strbuf_empty_length(s); + } + + s->buf[s->length] = str[i]; + s->length++; + space--; + } +} + +/* strbuf_append_fmt() should only be used when an upper bound + * is known for the output string. */ +void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...) +{ + va_list arg; + int fmt_len; + + strbuf_ensure_empty_length(s, len); + + va_start(arg, fmt); + fmt_len = vsnprintf(s->buf + s->length, len, fmt, arg); + va_end(arg); + + if (fmt_len < 0) + die("BUG: Unable to convert number"); /* This should never happen.. */ + + s->length += fmt_len; +} + +/* strbuf_append_fmt_retry() can be used when the there is no known + * upper bound for the output string. */ +void strbuf_append_fmt_retry(strbuf_t *s, const char *fmt, ...) +{ + va_list arg; + int fmt_len, try; + int empty_len; + + /* If the first attempt to append fails, resize the buffer appropriately + * and try again */ + for (try = 0; ; try++) { + va_start(arg, fmt); + /* Append the new formatted string */ + /* fmt_len is the length of the string required, excluding the + * trailing NULL */ + empty_len = strbuf_empty_length(s); + /* Add 1 since there is also space to store the terminating NULL. */ + fmt_len = vsnprintf(s->buf + s->length, empty_len + 1, fmt, arg); + va_end(arg); + + if (fmt_len <= empty_len) + break; /* SUCCESS */ + if (try > 0) + die("BUG: length of formatted string changed"); + + strbuf_resize(s, s->length + fmt_len); + } + + s->length += fmt_len; +} + +/* vi:ai et sw=4 ts=4: + */ diff --git a/src/cjson/strbuf.h b/src/cjson/strbuf.h new file mode 100644 index 0000000000..5df0b7bea3 --- /dev/null +++ b/src/cjson/strbuf.h @@ -0,0 +1,159 @@ +/* strbuf - String buffer routines + * + * Copyright (c) 2010-2012 Mark Pulford <mark@kyne.com.au> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <stdlib.h> +#include <stdarg.h> + +/* Workaround for MSVC */ +#ifdef _MSC_VER +#define inline __inline +#endif + +/* Size: Total bytes allocated to *buf + * Length: String length, excluding optional NULL terminator. + * Increment: Allocation increments when resizing the string buffer. + * Dynamic: True if created via strbuf_new() + */ + +typedef struct { + char *buf; + int size; + int length; + int increment; + int dynamic; + int reallocs; + int debug; +} strbuf_t; + +#ifndef STRBUF_DEFAULT_SIZE +#define STRBUF_DEFAULT_SIZE 1023 +#endif +#ifndef STRBUF_DEFAULT_INCREMENT +#define STRBUF_DEFAULT_INCREMENT -2 +#endif + +/* Initialise */ +extern strbuf_t *strbuf_new(int len); +extern void strbuf_init(strbuf_t *s, int len); +extern void strbuf_set_increment(strbuf_t *s, int increment); + +/* Release */ +extern void strbuf_free(strbuf_t *s); +extern char *strbuf_free_to_string(strbuf_t *s, int *len); + +/* Management */ +extern void strbuf_resize(strbuf_t *s, int len); +static int strbuf_empty_length(strbuf_t *s); +static int strbuf_length(strbuf_t *s); +static char *strbuf_string(strbuf_t *s, int *len); +static void strbuf_ensure_empty_length(strbuf_t *s, int len); +static char *strbuf_empty_ptr(strbuf_t *s); +static void strbuf_extend_length(strbuf_t *s, int len); + +/* Update */ +extern void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...); +extern void strbuf_append_fmt_retry(strbuf_t *s, const char *format, ...); +static void strbuf_append_mem(strbuf_t *s, const char *c, int len); +extern void strbuf_append_string(strbuf_t *s, const char *str); +static void strbuf_append_char(strbuf_t *s, const char c); +static void strbuf_ensure_null(strbuf_t *s); + +/* Reset string for before use */ +static inline void strbuf_reset(strbuf_t *s) +{ + s->length = 0; +} + +static inline int strbuf_allocated(strbuf_t *s) +{ + return s->buf != NULL; +} + +/* Return bytes remaining in the string buffer + * Ensure there is space for a NULL terminator. */ +static inline int strbuf_empty_length(strbuf_t *s) +{ + return s->size - s->length - 1; +} + +static inline void strbuf_ensure_empty_length(strbuf_t *s, int len) +{ + if (len > strbuf_empty_length(s)) + strbuf_resize(s, s->length + len); +} + +static inline char *strbuf_empty_ptr(strbuf_t *s) +{ + return s->buf + s->length; +} + +static inline void strbuf_extend_length(strbuf_t *s, int len) +{ + s->length += len; +} + +static inline int strbuf_length(strbuf_t *s) +{ + return s->length; +} + +static inline void strbuf_append_char(strbuf_t *s, const char c) +{ + strbuf_ensure_empty_length(s, 1); + s->buf[s->length++] = c; +} + +static inline void strbuf_append_char_unsafe(strbuf_t *s, const char c) +{ + s->buf[s->length++] = c; +} + +static inline void strbuf_append_mem(strbuf_t *s, const char *c, int len) +{ + strbuf_ensure_empty_length(s, len); + memcpy(s->buf + s->length, c, len); + s->length += len; +} + +static inline void strbuf_append_mem_unsafe(strbuf_t *s, const char *c, int len) +{ + memcpy(s->buf + s->length, c, len); + s->length += len; +} + +static inline void strbuf_ensure_null(strbuf_t *s) +{ + s->buf[s->length] = 0; +} + +static inline char *strbuf_string(strbuf_t *s, int *len) +{ + if (len) + *len = s->length; + + return s->buf; +} + +/* vi:ai et sw=4 ts=4: + */ diff --git a/src/clint.py b/src/clint.py index e7d76366b0..4b7bf002e6 100755 --- a/src/clint.py +++ b/src/clint.py @@ -2544,6 +2544,7 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error): r'(?<!\bPMap)' r'(?<!\bArrayOf)' r'(?<!\bDictionaryOf)' + r'(?<!\bDict)' r'\((?:const )?(?:struct )?[a-zA-Z_]\w*(?: *\*(?:const)?)*\)' r' +' r'-?(?:\*+|&)?(?:\w+|\+\+|--|\()', cast_line) diff --git a/src/mpack/conv.c b/src/mpack/conv.c index 203b13fadb..6bd446ca49 100644 --- a/src/mpack/conv.c +++ b/src/mpack/conv.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + #include "conv.h" static int mpack_fits_single(double v); @@ -298,7 +301,6 @@ MPACK_API double mpack_unpack_number(mpack_token_t t) */ if (!hi) { assert(t.length <= 4); - hi = 0; lo = (~lo & (((mpack_uint32_t)1 << ((t.length * 8) - 1)) - 1)); } else { hi = ~hi; diff --git a/src/mpack/lmpack.c b/src/mpack/lmpack.c index 99207246c8..24d27fd17a 100644 --- a/src/mpack/lmpack.c +++ b/src/mpack/lmpack.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + /* * This module exports three classes, and each instance of those classes has its * own private registry for temporary reference storage(keeping state between @@ -201,14 +204,14 @@ static void lmpack_pushnil(lua_State *L) static mpack_uint32_t lmpack_objlen(lua_State *L, int *is_array) { size_t len, max; - int isarr, type; + int isarr; lua_Number n; #ifndef NDEBUG int top = lua_gettop(L); assert(top); #endif - if ((type = lua_type(L, -1)) != LUA_TTABLE) { + if ((lua_type(L, -1)) != LUA_TTABLE) { #if LUA_VERSION_NUM >= 502 len = lua_rawlen(L, -1); #elif LUA_VERSION_NUM == 501 @@ -442,7 +445,6 @@ static int lmpack_unpacker_unpack_str(lua_State *L, Unpacker *unpacker, if (rv == MPACK_NOMEM) { unpacker->parser = lmpack_grow_parser(unpacker->parser); if (!unpacker->parser) { - unpacker->unpacking = 0; return luaL_error(L, "failed to grow Unpacker capacity"); } } @@ -796,7 +798,6 @@ static int lmpack_packer_pack(lua_State *L) if (result == MPACK_NOMEM) { packer->parser = lmpack_grow_parser(packer->parser); if (!packer->parser) { - packer->packing = 0; return luaL_error(L, "Failed to grow Packer capacity"); } } diff --git a/src/mpack/mpack_core.c b/src/mpack/mpack_core.c index 0ad09bd46a..f8ca63b7a3 100644 --- a/src/mpack/mpack_core.c +++ b/src/mpack/mpack_core.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + #include <string.h> #include "mpack_core.h" diff --git a/src/mpack/object.c b/src/mpack/object.c index 0c7759ee51..e2d893bc88 100644 --- a/src/mpack/object.c +++ b/src/mpack/object.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + #include <string.h> #include "object.h" diff --git a/src/mpack/rpc.c b/src/mpack/rpc.c index 3b2b328065..2d251284ba 100644 --- a/src/mpack/rpc.c +++ b/src/mpack/rpc.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + #include <string.h> #include "rpc.h" diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 331ab16dd7..185d55daed 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -27,6 +27,7 @@ set(BINARY_LIB_DIR ${PROJECT_BINARY_DIR}/lib/nvim/) set(API_DISPATCH_GENERATOR ${GENERATOR_DIR}/gen_api_dispatch.lua) set(API_UI_EVENTS_GENERATOR ${GENERATOR_DIR}/gen_api_ui_events.lua) set(GENERATOR_C_GRAMMAR ${GENERATOR_DIR}/c_grammar.lua) +set(GENERATOR_HASHY ${GENERATOR_DIR}/hashy.lua) set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack) set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack) set(LUA_API_C_BINDINGS ${GENERATED_DIR}/lua_api_c_bindings.generated.c) @@ -42,12 +43,15 @@ set(GENERATED_UI_EVENTS_METADATA ${GENERATED_DIR}/api/private/ui_events_metadata set(GENERATED_EX_CMDS_ENUM ${GENERATED_INCLUDES_DIR}/ex_cmds_enum.generated.h) set(GENERATED_EX_CMDS_DEFS ${GENERATED_DIR}/ex_cmds_defs.generated.h) set(GENERATED_FUNCS ${GENERATED_DIR}/funcs.generated.h) +set(GENERATED_KEYSETS ${GENERATED_DIR}/keysets.generated.h) +set(GENERATED_KEYSETS_DEFS ${GENERATED_DIR}/keysets_defs.generated.h) set(GENERATED_EVENTS_ENUM ${GENERATED_INCLUDES_DIR}/auevents_enum.generated.h) set(GENERATED_EVENTS_NAMES_MAP ${GENERATED_DIR}/auevents_name_map.generated.h) set(GENERATED_OPTIONS ${GENERATED_DIR}/options.generated.h) set(EX_CMDS_GENERATOR ${GENERATOR_DIR}/gen_ex_cmds.lua) set(FUNCS_GENERATOR ${GENERATOR_DIR}/gen_eval.lua) set(EVENTS_GENERATOR ${GENERATOR_DIR}/gen_events.lua) +set(KEYSETS_GENERATOR ${GENERATOR_DIR}/gen_keysets.lua) set(OPTIONS_GENERATOR ${GENERATOR_DIR}/gen_options.lua) set(UNICODE_TABLES_GENERATOR ${GENERATOR_DIR}/gen_unicode_tables.lua) set(UNICODE_DIR ${PROJECT_SOURCE_DIR}/unicode) @@ -87,8 +91,8 @@ file(MAKE_DIRECTORY ${LINT_SUPPRESSES_ROOT}/src) file(GLOB NVIM_SOURCES *.c) file(GLOB NVIM_HEADERS *.h) -file(GLOB EXTERNAL_SOURCES ../xdiff/*.c ../mpack/*.c) -file(GLOB EXTERNAL_HEADERS ../xdiff/*.h ../mpack/*.h) +file(GLOB EXTERNAL_SOURCES ../xdiff/*.c ../mpack/*.c ../cjson/*.c) +file(GLOB EXTERNAL_HEADERS ../xdiff/*.h ../mpack/*.h ../cjson/*.h) foreach(subdir os @@ -171,7 +175,7 @@ foreach(sfile ${CONV_SOURCES}) message(FATAL_ERROR "${sfile} doesn't exist (it was added to CONV_SOURCES)") endif() endforeach() -# xdiff, mpack: inlined external project, we don't maintain it. #9306 +# xdiff, mpack, lua-cjson: inlined external project, we don't maintain it. #9306 list(APPEND CONV_SOURCES ${EXTERNAL_SOURCES}) if(NOT MSVC) @@ -227,8 +231,6 @@ endfunction() set(use_git_version 0) if(NVIM_VERSION_MEDIUM) message(STATUS "NVIM_VERSION_MEDIUM: ${NVIM_VERSION_MEDIUM}") -elseif(${CMAKE_VERSION} VERSION_LESS "3.2.0") - message(STATUS "Skipping version-string generation (requires CMake 3.2.0+)") elseif(EXISTS ${PROJECT_SOURCE_DIR}/.git) find_program(GIT_EXECUTABLE git) if(GIT_EXECUTABLE) @@ -261,6 +263,7 @@ foreach(sfile ${NVIM_SOURCES} "${GENERATED_UI_EVENTS_CALL}" "${GENERATED_UI_EVENTS_REMOTE}" "${GENERATED_UI_EVENTS_BRIDGE}" + "${GENERATED_KEYSETS}" ) get_filename_component(full_d ${sfile} PATH) file(RELATIVE_PATH d "${CMAKE_CURRENT_LIST_DIR}" "${full_d}") @@ -364,12 +367,14 @@ add_custom_command( list(APPEND NVIM_GENERATED_FOR_HEADERS "${GENERATED_EX_CMDS_ENUM}" "${GENERATED_EVENTS_ENUM}" + "${GENERATED_KEYSETS_DEFS}" ) list(APPEND NVIM_GENERATED_FOR_SOURCES "${GENERATED_API_DISPATCH}" "${GENERATED_EX_CMDS_DEFS}" "${GENERATED_EVENTS_NAMES_MAP}" + "${GENERATED_KEYSETS}" "${GENERATED_OPTIONS}" "${GENERATED_UNICODE_TABLES}" "${VIM_MODULE_FILE}" @@ -404,6 +409,12 @@ add_custom_command(OUTPUT ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP} DEPENDS ${EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/auevents.lua ) +add_custom_command(OUTPUT ${GENERATED_KEYSETS} ${GENERATED_KEYSETS_DEFS} + COMMAND ${LUA_PRG} ${KEYSETS_GENERATOR} + ${CMAKE_CURRENT_LIST_DIR} ${LUA_SHARED_MODULE_SOURCE} ${GENERATED_KEYSETS} ${GENERATED_KEYSETS_DEFS} + DEPENDS ${KEYSETS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/api/keysets.lua ${GENERATOR_HASHY} +) + add_custom_command(OUTPUT ${GENERATED_OPTIONS} COMMAND ${LUA_PRG} ${OPTIONS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR} ${GENERATED_OPTIONS} diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 8973f8fef6..31d44c68bf 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -418,7 +418,7 @@ void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integ try_start(); aco_save_T aco; - aucmd_prepbuf(&aco, (buf_T *)buf); + aucmd_prepbuf(&aco, buf); if (!MODIFIABLE(buf)) { api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'"); @@ -624,7 +624,8 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In if (replacement.size == 1) { firstlen += last_part_len; } - char *first = xmallocz(firstlen), *last = NULL; + char *first = xmallocz(firstlen); + char *last = NULL; memcpy(first, str_at_start, (size_t)start_col); memcpy(first+start_col, first_item.data, first_item.size); memchrsub(first+start_col, NUL, NL, first_item.size); @@ -637,7 +638,7 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In memcpy(last+last_item.size, str_at_end+end_col, last_part_len); } - char **lines = (new_len != 0) ? xcalloc(new_len, sizeof(char *)) : NULL; + char **lines = xcalloc(new_len, sizeof(char *)); lines[0] = first; new_byte += (bcount_t)(first_item.size); for (size_t i = 1; i < new_len-1; i++) { @@ -656,7 +657,7 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In try_start(); aco_save_T aco; - aucmd_prepbuf(&aco, (buf_T *)buf); + aucmd_prepbuf(&aco, buf); if (!MODIFIABLE(buf)) { api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'"); @@ -858,7 +859,7 @@ ArrayOf(Dictionary) nvim_buf_get_keymap(Buffer buffer, String mode, Error *err) /// @see |nvim_set_keymap()| /// /// @param buffer Buffer handle, or 0 for current buffer -void nvim_buf_set_keymap(Buffer buffer, String mode, String lhs, String rhs, Dictionary opts, +void nvim_buf_set_keymap(Buffer buffer, String mode, String lhs, String rhs, Dict(keymap) *opts, Error *err) FUNC_API_SINCE(6) { @@ -874,8 +875,7 @@ void nvim_buf_del_keymap(Buffer buffer, String mode, String lhs, Error *err) FUNC_API_SINCE(6) { String rhs = { .data = "", .size = 0 }; - Dictionary opts = ARRAY_DICT_INIT; - modify_keymap(buffer, true, mode, lhs, rhs, opts, err); + modify_keymap(buffer, true, mode, lhs, rhs, NULL, err); } /// Gets a map of buffer-local |user-commands|. @@ -885,22 +885,13 @@ void nvim_buf_del_keymap(Buffer buffer, String mode, String lhs, Error *err) /// @param[out] err Error details, if any. /// /// @returns Map of maps describing commands. -Dictionary nvim_buf_get_commands(Buffer buffer, Dictionary opts, Error *err) +Dictionary nvim_buf_get_commands(Buffer buffer, Dict(get_commands) *opts, Error *err) FUNC_API_SINCE(4) { bool global = (buffer == -1); - bool builtin = false; - - for (size_t i = 0; i < opts.size; i++) { - String k = opts.items[i].key; - Object v = opts.items[i].value; - if (!strequal("builtin", k.data)) { - api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data); - return (Dictionary)ARRAY_DICT_INIT; - } - if (strequal("builtin", k.data)) { - builtin = v.data.boolean; - } + bool builtin = api_object_to_bool(opts->builtin, "builtin", false, err); + if (ERROR_SET(err)) { + return (Dictionary)ARRAY_DICT_INIT; } if (global) { @@ -1118,14 +1109,96 @@ Boolean nvim_buf_is_valid(Buffer buffer) return ret; } -/// Return a tuple (row,col) representing the position of the named mark. +/// Deletes a named mark in the buffer. See |mark-motions|. +/// +/// @note only deletes marks set in the buffer, if the mark is not set +/// in the buffer it will return false. +/// @param buffer Buffer to set the mark on +/// @param name Mark name +/// @return true if the mark was deleted, else false. +/// @see |nvim_buf_set_mark()| +/// @see |nvim_del_mark()| +Boolean nvim_buf_del_mark(Buffer buffer, String name, Error *err) + FUNC_API_SINCE(8) +{ + bool res = false; + buf_T *buf = find_buffer_by_handle(buffer, err); + + if (!buf) { + return res; + } + + if (name.size != 1) { + api_set_error(err, kErrorTypeValidation, + "Mark name must be a single character"); + return res; + } + + pos_T *pos = getmark_buf(buf, *name.data, false); + + // pos point to NULL when there's no mark with name + if (pos == NULL) { + api_set_error(err, kErrorTypeValidation, "Invalid mark name: '%c'", + *name.data); + return res; + } + + // pos->lnum is 0 when the mark is not valid in the buffer, or is not set. + if (pos->lnum != 0) { + // since the mark belongs to the buffer delete it. + res = set_mark(buf, name, 0, 0, err); + } + + return res; +} + +/// Sets a named mark in the given buffer, all marks are allowed +/// file/uppercase, visual, last change, etc. See |mark-motions|. +/// +/// Marks are (1,0)-indexed. |api-indexing| +/// +/// @note Passing 0 as line deletes the mark +/// +/// @param buffer Buffer to set the mark on +/// @param name Mark name +/// @param line Line number +/// @param col Column/row number +/// @return true if the mark was set, else false. +/// @see |nvim_buf_del_mark()| +/// @see |nvim_buf_get_mark()| +Boolean nvim_buf_set_mark(Buffer buffer, String name, Integer line, Integer col, Error *err) + FUNC_API_SINCE(8) +{ + bool res = false; + buf_T *buf = find_buffer_by_handle(buffer, err); + + if (!buf) { + return res; + } + + if (name.size != 1) { + api_set_error(err, kErrorTypeValidation, + "Mark name must be a single character"); + return res; + } + + res = set_mark(buf, name, line, col, err); + + return res; +} + +/// Returns a tuple (row,col) representing the position of the named mark. See +/// |mark-motions|. /// /// Marks are (1,0)-indexed. |api-indexing| /// /// @param buffer Buffer handle, or 0 for current buffer /// @param name Mark name /// @param[out] err Error details, if any -/// @return (row, col) tuple +/// @return (row, col) tuple, (0, 0) if the mark is not set, or is an +/// uppercase/file mark set in another buffer. +/// @see |nvim_buf_set_mark()| +/// @see |nvim_buf_del_mark()| ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) FUNC_API_SINCE(1) { @@ -1267,7 +1340,7 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, if (extmark.row < 0) { return rv; } - return extmark_to_array(extmark, false, (bool)details); + return extmark_to_array(extmark, false, details); } /// Gets extmarks in "traversal order" from a |charwise| region defined by @@ -1415,6 +1488,10 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e /// - end_col : ending col of the mark, 0-based exclusive. /// - hl_group : name of the highlight group used to highlight /// this mark. +/// - hl_eol : when true, for a multiline highlight covering the +/// EOL of a line, continue the highlight for the rest +/// of the screen line (just like for diff and +/// cursorline highlight). /// - virt_text : virtual text to link to this mark. /// A list of [text, highlight] tuples, each representing a /// text chunk with specified highlight. `highlight` element @@ -1442,10 +1519,28 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e /// default /// - "combine": combine with background text color /// - "blend": blend with background text color. -/// - hl_eol : when true, for a multiline highlight covering the -/// EOL of a line, continue the highlight for the rest -/// of the screen line (just like for diff and -/// cursorline highlight). +/// +/// - virt_lines : virtual lines to add next to this mark +/// This should be an array over lines, where each line in +/// turn is an array over [text, highlight] tuples. In +/// general, buffer and window options do not affect the +/// display of the text. In particular 'wrap' +/// and 'linebreak' options do not take effect, so +/// the number of extra screen lines will always match +/// the size of the array. However the 'tabstop' buffer +/// option is still used for hard tabs. By default lines are +/// placed below the buffer line containing the mark. +/// +/// Note: currently virtual lines are limited to one block +/// per buffer. Thus setting a new mark disables any previous +/// `virt_lines` decoration. However plugins should not rely +/// on this behaviour, as this limitation is planned to be +/// removed. +/// +/// - virt_lines_above: place virtual lines above instead. +/// - virt_lines_leftcol: Place extmarks in the leftmost +/// column of the window, bypassing +/// sign and number columns. /// /// - ephemeral : for use with |nvim_set_decoration_provider| /// callbacks. The mark will only be used for the current @@ -1463,193 +1558,189 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e /// @param[out] err Error details, if any /// @return Id of the created/updated extmark Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer col, - Dictionary opts, Error *err) + Dict(set_extmark) *opts, Error *err) FUNC_API_SINCE(7) { + Decoration decor = DECORATION_INIT; + buf_T *buf = find_buffer_by_handle(buffer, err); if (!buf) { - return 0; + goto error; } if (!ns_initialized((uint64_t)ns_id)) { api_set_error(err, kErrorTypeValidation, "Invalid ns_id"); - return 0; + goto error; } - bool ephemeral = false; - uint64_t id = 0; + if (opts->id.type == kObjectTypeInteger && opts->id.data.integer > 0) { + id = (uint64_t)opts->id.data.integer; + } else if (HAS_KEY(opts->id)) { + api_set_error(err, kErrorTypeValidation, "id is not a positive integer"); + goto error; + } + int line2 = -1; - Decoration decor = DECORATION_INIT; + if (opts->end_line.type == kObjectTypeInteger) { + Integer val = opts->end_line.data.integer; + if (val < 0 || val > buf->b_ml.ml_line_count) { + api_set_error(err, kErrorTypeValidation, "end_line value outside range"); + goto error; + } else { + line2 = (int)val; + } + } else if (HAS_KEY(opts->end_line)) { + api_set_error(err, kErrorTypeValidation, "end_line is not an integer"); + goto error; + } + colnr_T col2 = -1; + if (opts->end_col.type == kObjectTypeInteger) { + Integer val = opts->end_col.data.integer; + if (val < 0 || val > MAXCOL) { + api_set_error(err, kErrorTypeValidation, "end_col value outside range"); + goto error; + } else { + col2 = (int)val; + } + } else if (HAS_KEY(opts->end_col)) { + api_set_error(err, kErrorTypeValidation, "end_col is not an integer"); + goto error; + } - bool right_gravity = true; - bool end_right_gravity = false; - bool end_gravity_set = false; + if (HAS_KEY(opts->hl_group)) { + decor.hl_id = object_to_hl_id(opts->hl_group, "hl_group", err); + if (ERROR_SET(err)) { + goto error; + } + } - for (size_t i = 0; i < opts.size; i++) { - String k = opts.items[i].key; - Object *v = &opts.items[i].value; - if (strequal("id", k.data)) { - if (v->type != kObjectTypeInteger || v->data.integer <= 0) { - api_set_error(err, kErrorTypeValidation, - "id is not a positive integer"); - goto error; - } + if (opts->virt_text.type == kObjectTypeArray) { + decor.virt_text = parse_virt_text(opts->virt_text.data.array, err, + &decor.virt_text_width); + if (ERROR_SET(err)) { + goto error; + } + } else if (HAS_KEY(opts->virt_text)) { + api_set_error(err, kErrorTypeValidation, "virt_text is not an Array"); + goto error; + } + + if (opts->virt_text_pos.type == kObjectTypeString) { + String str = opts->virt_text_pos.data.string; + if (strequal("eol", str.data)) { + decor.virt_text_pos = kVTEndOfLine; + } else if (strequal("overlay", str.data)) { + decor.virt_text_pos = kVTOverlay; + } else if (strequal("right_align", str.data)) { + decor.virt_text_pos = kVTRightAlign; + } else { + api_set_error(err, kErrorTypeValidation, "virt_text_pos: invalid value"); + goto error; + } + } else if (HAS_KEY(opts->virt_text_pos)) { + api_set_error(err, kErrorTypeValidation, "virt_text_pos is not a String"); + goto error; + } - id = (uint64_t)v->data.integer; - } else if (strequal("end_line", k.data)) { - if (v->type != kObjectTypeInteger) { - api_set_error(err, kErrorTypeValidation, - "end_line is not an integer"); - goto error; - } - if (v->data.integer < 0 || v->data.integer > buf->b_ml.ml_line_count) { - api_set_error(err, kErrorTypeValidation, - "end_line value outside range"); - goto error; - } + if (opts->virt_text_win_col.type == kObjectTypeInteger) { + decor.col = (int)opts->virt_text_win_col.data.integer; + decor.virt_text_pos = kVTWinCol; + } else if (HAS_KEY(opts->virt_text_win_col)) { + api_set_error(err, kErrorTypeValidation, + "virt_text_win_col is not a Number of the correct size"); + goto error; + } - line2 = (int)v->data.integer; - } else if (strequal("end_col", k.data)) { - if (v->type != kObjectTypeInteger) { - api_set_error(err, kErrorTypeValidation, - "end_col is not an integer"); - goto error; - } - if (v->data.integer < 0 || v->data.integer > MAXCOL) { - api_set_error(err, kErrorTypeValidation, - "end_col value outside range"); - goto error; - } +#define OPTION_TO_BOOL(target, name, val) \ + target = api_object_to_bool(opts-> name, #name, val, err); \ + if (ERROR_SET(err)) { \ + goto error; \ + } - col2 = (colnr_T)v->data.integer; - } else if (strequal("hl_group", k.data)) { - String hl_group; - switch (v->type) { - case kObjectTypeString: - hl_group = v->data.string; - decor.hl_id = syn_check_group((char_u *)(hl_group.data), - (int)hl_group.size); - break; - case kObjectTypeInteger: - decor.hl_id = (int)v->data.integer; - break; - default: - api_set_error(err, kErrorTypeValidation, - "hl_group is not valid."); - goto error; - } - } else if (strequal("virt_text", k.data)) { - if (v->type != kObjectTypeArray) { - api_set_error(err, kErrorTypeValidation, - "virt_text is not an Array"); - goto error; - } - decor.virt_text = parse_virt_text(v->data.array, err, - &decor.virt_text_width); - if (ERROR_SET(err)) { - goto error; - } - } else if (strequal("virt_text_pos", k.data)) { - if (v->type != kObjectTypeString) { - api_set_error(err, kErrorTypeValidation, - "virt_text_pos is not a String"); - goto error; - } - String str = v->data.string; - if (strequal("eol", str.data)) { - decor.virt_text_pos = kVTEndOfLine; - } else if (strequal("overlay", str.data)) { - decor.virt_text_pos = kVTOverlay; - } else if (strequal("right_align", str.data)) { - decor.virt_text_pos = kVTRightAlign; - } else { - api_set_error(err, kErrorTypeValidation, - "virt_text_pos: invalid value"); - goto error; - } - } else if (strequal("virt_text_win_col", k.data)) { - if (v->type != kObjectTypeInteger) { - api_set_error(err, kErrorTypeValidation, - "virt_text_win_col is not a Number of the correct size"); - goto error; - } + OPTION_TO_BOOL(decor.virt_text_hide, virt_text_hide, false); + OPTION_TO_BOOL(decor.hl_eol, hl_eol, false); - decor.col = (int)v->data.integer; - decor.virt_text_pos = kVTWinCol; - } else if (strequal("virt_text_hide", k.data)) { - decor.virt_text_hide = api_object_to_bool(*v, - "virt_text_hide", false, err); - if (ERROR_SET(err)) { - goto error; - } - } else if (strequal("hl_eol", k.data)) { - decor.hl_eol = api_object_to_bool(*v, "hl_eol", false, err); - if (ERROR_SET(err)) { - goto error; - } - } else if (strequal("hl_mode", k.data)) { - if (v->type != kObjectTypeString) { - api_set_error(err, kErrorTypeValidation, - "hl_mode is not a String"); - goto error; - } - String str = v->data.string; - if (strequal("replace", str.data)) { - decor.hl_mode = kHlModeReplace; - } else if (strequal("combine", str.data)) { - decor.hl_mode = kHlModeCombine; - } else if (strequal("blend", str.data)) { - decor.hl_mode = kHlModeBlend; - } else { - api_set_error(err, kErrorTypeValidation, - "virt_text_pos: invalid value"); + if (opts->hl_mode.type == kObjectTypeString) { + String str = opts->hl_mode.data.string; + if (strequal("replace", str.data)) { + decor.hl_mode = kHlModeReplace; + } else if (strequal("combine", str.data)) { + decor.hl_mode = kHlModeCombine; + } else if (strequal("blend", str.data)) { + decor.hl_mode = kHlModeBlend; + } else { + api_set_error(err, kErrorTypeValidation, + "virt_text_pos: invalid value"); + goto error; + } + } else if (HAS_KEY(opts->hl_mode)) { + api_set_error(err, kErrorTypeValidation, "hl_mode is not a String"); + goto error; + } + + VirtLines virt_lines = KV_INITIAL_VALUE; + bool virt_lines_above = false; + bool virt_lines_leftcol = false; + + if (opts->virt_lines.type == kObjectTypeArray) { + Array a = opts->virt_lines.data.array; + for (size_t j = 0; j < a.size; j++) { + if (a.items[j].type != kObjectTypeArray) { + api_set_error(err, kErrorTypeValidation, "virt_text_line item is not an Array"); goto error; } - } else if (strequal("ephemeral", k.data)) { - ephemeral = api_object_to_bool(*v, "ephemeral", false, err); + int dummig; + VirtText jtem = parse_virt_text(a.items[j].data.array, err, &dummig); + kv_push(virt_lines, jtem); if (ERROR_SET(err)) { goto error; } - } else if (strequal("priority", k.data)) { - if (v->type != kObjectTypeInteger) { - api_set_error(err, kErrorTypeValidation, - "priority is not a Number of the correct size"); - goto error; - } + } + } else if (HAS_KEY(opts->virt_lines)) { + api_set_error(err, kErrorTypeValidation, "virt_lines is not an Array"); + goto error; + } - if (v->data.integer < 0 || v->data.integer > UINT16_MAX) { - api_set_error(err, kErrorTypeValidation, - "priority is not a valid value"); - goto error; - } - decor.priority = (DecorPriority)v->data.integer; - } else if (strequal("right_gravity", k.data)) { - if (v->type != kObjectTypeBoolean) { - api_set_error(err, kErrorTypeValidation, - "right_gravity must be a boolean"); - goto error; - } - right_gravity = v->data.boolean; - } else if (strequal("end_right_gravity", k.data)) { - if (v->type != kObjectTypeBoolean) { - api_set_error(err, kErrorTypeValidation, - "end_right_gravity must be a boolean"); - goto error; - } - end_right_gravity = v->data.boolean; - end_gravity_set = true; - } else { - api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data); + OPTION_TO_BOOL(virt_lines_above, virt_lines_above, false); + OPTION_TO_BOOL(virt_lines_leftcol, virt_lines_leftcol, false); + + if (opts->priority.type == kObjectTypeInteger) { + Integer val = opts->priority.data.integer; + + if (val < 0 || val > UINT16_MAX) { + api_set_error(err, kErrorTypeValidation, "priority is not a valid value"); goto error; } + decor.priority = (DecorPriority)val; + } else if (HAS_KEY(opts->priority)) { + api_set_error(err, kErrorTypeValidation, "priority is not a Number of the correct size"); + goto error; + } + + bool right_gravity = true; + OPTION_TO_BOOL(right_gravity, right_gravity, true); + + // Only error out if they try to set end_right_gravity without + // setting end_col or end_line + if (line2 == -1 && col2 == -1 && HAS_KEY(opts->end_right_gravity)) { + api_set_error(err, kErrorTypeValidation, + "cannot set end_right_gravity without setting end_line or end_col"); + goto error; } + bool end_right_gravity = false; + OPTION_TO_BOOL(end_right_gravity, end_right_gravity, false); + size_t len = 0; + + bool ephemeral = false; + OPTION_TO_BOOL(ephemeral, ephemeral, false); + if (line < 0 || line > buf->b_ml.ml_line_count) { api_set_error(err, kErrorTypeValidation, "line value outside range"); - return 0; + goto error; } else if (line < buf->b_ml.ml_line_count) { len = ephemeral ? MAXCOL : STRLEN(ml_get_buf(buf, (linenr_T)line+1, false)); } @@ -1658,16 +1749,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer col = (Integer)len; } else if (col < -1 || col > (Integer)len) { api_set_error(err, kErrorTypeValidation, "col value outside range"); - return 0; - } - - - // Only error out if they try to set end_right_gravity without - // setting end_col or end_line - if (line2 == -1 && col2 == -1 && end_gravity_set) { - api_set_error(err, kErrorTypeValidation, - "cannot set end_right_gravity " - "without setting end_line or end_col"); + goto error; } if (col2 >= 0) { @@ -1688,15 +1770,6 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer col2 = 0; } - if (decor.virt_text_pos == kVTRightAlign) { - decor.col = 0; - for (size_t i = 0; i < kv_size(decor.virt_text); i++) { - decor.col - += (int)mb_string2cells((char_u *)kv_A(decor.virt_text, i).text); - } - } - - Decoration *d = NULL; if (ephemeral) { @@ -1721,9 +1794,23 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer goto error; } - id = extmark_set(buf, (uint64_t)ns_id, id, (int)line, (colnr_T)col, - line2, col2, d, right_gravity, - end_right_gravity, kExtmarkNoUndo); + if (kv_size(virt_lines) && buf->b_virt_line_mark) { + mtpos_t pos = marktree_lookup(buf->b_marktree, buf->b_virt_line_mark, NULL); + clear_virt_lines(buf, pos.row); // handles pos.row == -1 + } + + uint64_t mark = extmark_set(buf, (uint64_t)ns_id, &id, (int)line, (colnr_T)col, + line2, col2, d, right_gravity, + end_right_gravity, kExtmarkNoUndo); + + if (kv_size(virt_lines)) { + buf->b_virt_lines = virt_lines; + buf->b_virt_line_mark = mark; + buf->b_virt_line_pos = -1; + buf->b_virt_line_above = virt_lines_above; + buf->b_virt_line_leftcol = virt_lines_leftcol; + redraw_buf_line_later(buf, MIN(buf->b_ml.ml_line_count, line+1+(virt_lines_above?0:1))); + } } return (Integer)id; @@ -1816,7 +1903,7 @@ Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, In int hl_id = 0; if (hl_group.size > 0) { - hl_id = syn_check_group((char_u *)hl_group.data, (int)hl_group.size); + hl_id = syn_check_group(hl_group.data, (int)hl_group.size); } else { return ns_id; } @@ -1827,7 +1914,7 @@ Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, In end_line++; } - extmark_set(buf, ns, 0, + extmark_set(buf, ns, NULL, (int)line, (colnr_T)col_start, end_line, (colnr_T)col_end, decor_hl(hl_id), true, false, kExtmarkNoUndo); @@ -1895,7 +1982,7 @@ Object nvim_buf_call(Buffer buffer, LuaRef fun, Error *err) } try_start(); aco_save_T aco; - aucmd_prepbuf(&aco, (buf_T *)buf); + aucmd_prepbuf(&aco, buf); Array args = ARRAY_DICT_INIT; Object res = nlua_call_ref(fun, NULL, args, true, err); diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index 21b9db85c0..907d09e5b7 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -150,7 +150,7 @@ Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, A decor->virt_text = virt_text; decor->virt_text_width = width; - extmark_set(buf, ns_id, 0, (int)line, 0, -1, -1, decor, true, + extmark_set(buf, ns_id, NULL, (int)line, 0, -1, -1, decor, true, false, kExtmarkNoUndo); return src_id; } @@ -165,6 +165,7 @@ Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, A /// @param lines Array of lines /// @param[out] err Error details, if any void buffer_insert(Buffer buffer, Integer lnum, ArrayOf(String) lines, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { // "lnum" will be the index of the line after inserting, // no matter if it is negative or not @@ -184,6 +185,7 @@ void buffer_insert(Buffer buffer, Integer lnum, ArrayOf(String) lines, Error *er /// @param[out] err Error details, if any /// @return Line string String buffer_get_line(Buffer buffer, Integer index, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { String rv = { .size = 0 }; @@ -212,6 +214,7 @@ String buffer_get_line(Buffer buffer, Integer index, Error *err) /// @param line Contents of the new line /// @param[out] err Error details, if any void buffer_set_line(Buffer buffer, Integer index, String line, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { Object l = STRING_OBJ(line); Array array = { .items = &l, .size = 1 }; @@ -230,6 +233,7 @@ void buffer_set_line(Buffer buffer, Integer index, String line, Error *err) /// @param index line index /// @param[out] err Error details, if any void buffer_del_line(Buffer buffer, Integer index, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { Array array = ARRAY_DICT_INIT; index = convert_index(index); @@ -255,6 +259,7 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer, Boolean include_start, Boolean include_end, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { start = convert_index(start) + !include_start; end = convert_index(end) + include_end; @@ -278,6 +283,7 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer, /// @param[out] err Error details, if any void buffer_set_line_slice(Buffer buffer, Integer start, Integer end, Boolean include_start, Boolean include_end, ArrayOf(String) replacement, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { start = convert_index(start) + !include_start; end = convert_index(end) + include_end; @@ -298,6 +304,7 @@ void buffer_set_line_slice(Buffer buffer, Integer start, Integer end, Boolean in /// @warning It may return nil if there was no previous value /// or if previous value was `v:null`. Object buffer_set_var(Buffer buffer, String name, Object value, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -317,6 +324,7 @@ Object buffer_set_var(Buffer buffer, String name, Object value, Error *err) /// @param[out] err Error details, if any /// @return Old value Object buffer_del_var(Buffer buffer, String name, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -340,6 +348,7 @@ Object buffer_del_var(Buffer buffer, String name, Error *err) /// @warning It may return nil if there was no previous value /// or if previous value was `v:null`. Object window_set_var(Window window, String name, Object value, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { win_T *win = find_window_by_handle(window, err); @@ -359,6 +368,7 @@ Object window_set_var(Window window, String name, Object value, Error *err) /// @param[out] err Error details, if any /// @return Old value Object window_del_var(Window window, String name, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { win_T *win = find_window_by_handle(window, err); @@ -382,6 +392,7 @@ Object window_del_var(Window window, String name, Error *err) /// @warning It may return nil if there was no previous value /// or if previous value was `v:null`. Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { tabpage_T *tab = find_tab_by_handle(tabpage, err); @@ -401,6 +412,7 @@ Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err) /// @param[out] err Error details, if any /// @return Old value Object tabpage_del_var(Tabpage tabpage, String name, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { tabpage_T *tab = find_tab_by_handle(tabpage, err); @@ -417,6 +429,7 @@ Object tabpage_del_var(Tabpage tabpage, String name, Error *err) /// OR if previous value was `v:null`. /// @return Old value or nil if there was no previous value. Object vim_set_var(String name, Object value, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { return dict_set_var(&globvardict, name, value, false, true, err); } @@ -424,6 +437,7 @@ Object vim_set_var(String name, Object value, Error *err) /// @deprecated /// @see nvim_del_var Object vim_del_var(String name, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { return dict_set_var(&globvardict, name, NIL, true, true, err); } diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua new file mode 100644 index 0000000000..144c252687 --- /dev/null +++ b/src/nvim/api/keysets.lua @@ -0,0 +1,62 @@ +return { + context = { + "types"; + }; + set_extmark = { + "id"; + "end_line"; + "end_col"; + "hl_group"; + "virt_text"; + "virt_text_pos"; + "virt_text_win_col"; + "virt_text_hide"; + "hl_eol"; + "hl_mode"; + "ephemeral"; + "priority"; + "right_gravity"; + "end_right_gravity"; + "virt_lines"; + "virt_lines_above"; + "virt_lines_leftcol"; + }; + keymap = { + "noremap"; + "nowait"; + "silent"; + "script"; + "expr"; + "unique"; + }; + get_commands = { + "builtin"; + }; + float_config = { + "row"; + "col"; + "width"; + "height"; + "anchor"; + "relative"; + "win"; + "bufpos"; + "external"; + "focusable"; + "zindex"; + "border"; + "style"; + "noautocmd"; + }; + runtime = { + "is_lua"; + }; + eval_statusline = { + "winid"; + "maxwidth"; + "fillchar"; + "highlights"; + "use_tabline"; + }; +} + diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index f0d48bf145..663d1e16b5 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -1,15 +1,15 @@ #ifndef NVIM_API_PRIVATE_DEFS_H #define NVIM_API_PRIVATE_DEFS_H -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include <string.h> #include "nvim/func_attr.h" #include "nvim/types.h" -#define ARRAY_DICT_INIT {.size = 0, .capacity = 0, .items = NULL} -#define STRING_INIT {.data = NULL, .size = 0} +#define ARRAY_DICT_INIT { .size = 0, .capacity = 0, .items = NULL } +#define STRING_INIT { .data = NULL, .size = 0 } #define OBJECT_INIT { .type = kObjectTypeNil } #define ERROR_INIT { .type = kErrorTypeNone, .msg = NULL } #define REMOTE_TYPE(type) typedef handle_T type @@ -19,6 +19,7 @@ #ifdef INCLUDE_GENERATED_DECLARATIONS # define ArrayOf(...) Array # define DictionaryOf(...) Dictionary +# define Dict(name) KeyDict_##name #endif // Basic types @@ -129,5 +130,14 @@ struct key_value_pair { Object value; }; +typedef Object *(*field_hash)(void *retval, const char *str, size_t len); +typedef struct { + char *str; + size_t ptr_off; +} KeySetLink; + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "keysets_defs.generated.h" +#endif #endif // NVIM_API_PRIVATE_DEFS_H diff --git a/src/nvim/api/private/dispatch.c b/src/nvim/api/private/dispatch.c index 38ce7ca78c..519bf8ff14 100644 --- a/src/nvim/api/private/dispatch.c +++ b/src/nvim/api/private/dispatch.c @@ -14,6 +14,7 @@ #include "nvim/api/tabpage.h" #include "nvim/api/ui.h" #include "nvim/api/vim.h" +#include "nvim/api/win_config.h" #include "nvim/api/window.h" #include "nvim/log.h" #include "nvim/map.h" @@ -45,5 +46,5 @@ MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name, size_t na } #ifdef INCLUDE_GENERATED_DECLARATIONS -#include "api/private/dispatch_wrappers.generated.h" +# include "api/private/dispatch_wrappers.generated.h" #endif diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 541793e528..f1259c8a18 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -4,6 +4,7 @@ #include <assert.h> #include <inttypes.h> #include <stdbool.h> +#include <stddef.h> #include <stdlib.h> #include <string.h> @@ -24,6 +25,7 @@ #include "nvim/lua/executor.h" #include "nvim/map.h" #include "nvim/map_defs.h" +#include "nvim/mark.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/msgpack_rpc/helpers.h" @@ -395,7 +397,7 @@ void set_option_to(uint64_t channel_id, void *to, int type, String name, Object return; } - stringval = (char *)value.data.string.data; + stringval = value.data.string.data; } const sctx_T save_current_sctx = current_sctx; @@ -814,15 +816,8 @@ Array string_to_array(const String input, bool crlf) /// buffer, or -1 to signify global behavior ("all buffers") /// @param is_unmap When true, removes the mapping that matches {lhs}. void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String rhs, - Dictionary opts, Error *err) + Dict(keymap) *opts, Error *err) { - char *err_msg = NULL; // the error message to report, if any - char *err_arg = NULL; // argument for the error message format string - ErrorType err_type = kErrorTypeNone; - - char_u *lhs_buf = NULL; - char_u *rhs_buf = NULL; - bool global = (buffer == -1); if (global) { buffer = 0; @@ -833,10 +828,21 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String return; } - MapArguments parsed_args; - memset(&parsed_args, 0, sizeof(parsed_args)); - if (parse_keymap_opts(opts, &parsed_args, err)) { - goto fail_and_free; + MapArguments parsed_args = MAP_ARGUMENTS_INIT; + if (opts) { +#define KEY_TO_BOOL(name) \ + parsed_args. name = api_object_to_bool(opts-> name, #name, false, err); \ + if (ERROR_SET(err)) { \ + goto fail_and_free; \ + } + + KEY_TO_BOOL(nowait); + KEY_TO_BOOL(noremap); + KEY_TO_BOOL(silent); + KEY_TO_BOOL(script); + KEY_TO_BOOL(expr); + KEY_TO_BOOL(unique); +#undef KEY_TO_BOOL } parsed_args.buffer = !global; @@ -845,17 +851,13 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String CPO_TO_CPO_FLAGS, &parsed_args); if (parsed_args.lhs_len > MAXMAPLEN) { - err_msg = "LHS exceeds maximum map length: %s"; - err_arg = lhs.data; - err_type = kErrorTypeValidation; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, "LHS exceeds maximum map length: %s", lhs.data); + goto fail_and_free; } if (mode.size > 1) { - err_msg = "Shortname is too long: %s"; - err_arg = mode.data; - err_type = kErrorTypeValidation; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, "Shortname is too long: %s", mode.data); + goto fail_and_free; } int mode_val; // integer value of the mapping mode, to be passed to do_map() char_u *p = (char_u *)((mode.size) ? mode.data : "m"); @@ -867,18 +869,14 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String && mode.size > 0) { // get_map_mode() treats unrecognized mode shortnames as ":map". // This is an error unless the given shortname was empty string "". - err_msg = "Invalid mode shortname: \"%s\""; - err_arg = (char *)p; - err_type = kErrorTypeValidation; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, "Invalid mode shortname: \"%s\"", (char *)p); + goto fail_and_free; } } if (parsed_args.lhs_len == 0) { - err_msg = "Invalid (empty) LHS"; - err_arg = ""; - err_type = kErrorTypeValidation; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, "Invalid (empty) LHS"); + goto fail_and_free; } bool is_noremap = parsed_args.noremap; @@ -891,16 +889,13 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String // the given RHS was nonempty and not a <Nop>, but was parsed as if it // were empty? assert(false && "Failed to parse nonempty RHS!"); - err_msg = "Parsing of nonempty RHS failed: %s"; - err_arg = rhs.data; - err_type = kErrorTypeException; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, "Parsing of nonempty RHS failed: %s", rhs.data); + goto fail_and_free; } } else if (is_unmap && parsed_args.rhs_len) { - err_msg = "Gave nonempty RHS in unmap command: %s"; - err_arg = (char *)parsed_args.rhs; - err_type = kErrorTypeValidation; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, + "Gave nonempty RHS in unmap command: %s", parsed_args.rhs); + goto fail_and_free; } // buf_do_map() reads noremap/unmap as its own argument. @@ -929,113 +924,12 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String goto fail_and_free; } // switch - xfree(lhs_buf); - xfree(rhs_buf); - xfree(parsed_args.rhs); - xfree(parsed_args.orig_rhs); - - return; - -fail_with_message: - api_set_error(err, err_type, err_msg, err_arg); - fail_and_free: - xfree(lhs_buf); - xfree(rhs_buf); xfree(parsed_args.rhs); xfree(parsed_args.orig_rhs); return; } -/// Read in the given opts, setting corresponding flags in `out`. -/// -/// @param opts A dictionary passed to @ref nvim_set_keymap or -/// @ref nvim_buf_set_keymap. -/// @param[out] out MapArguments object in which to set parsed -/// |:map-arguments| flags. -/// @param[out] err Error details, if any. -/// -/// @returns Zero on success, nonzero on failure. -Integer parse_keymap_opts(Dictionary opts, MapArguments *out, Error *err) -{ - char *err_msg = NULL; // the error message to report, if any - char *err_arg = NULL; // argument for the error message format string - ErrorType err_type = kErrorTypeNone; - - out->buffer = false; - out->nowait = false; - out->silent = false; - out->script = false; - out->expr = false; - out->unique = false; - - for (size_t i = 0; i < opts.size; i++) { - KeyValuePair *key_and_val = &opts.items[i]; - char *optname = key_and_val->key.data; - - if (key_and_val->value.type != kObjectTypeBoolean) { - err_msg = "Gave non-boolean value for an opt: %s"; - err_arg = optname; - err_type = kErrorTypeValidation; - goto fail_with_message; - } - - bool was_valid_opt = false; - switch (optname[0]) { - // note: strncmp up to and including the null terminator, so that - // "nowaitFoobar" won't match against "nowait" - - // don't recognize 'buffer' as a key; user shouldn't provide <buffer> - // when calling nvim_set_keymap or nvim_buf_set_keymap, since it can be - // inferred from which function they called - case 'n': - if (STRNCMP(optname, "noremap", 8) == 0) { - was_valid_opt = true; - out->noremap = key_and_val->value.data.boolean; - } else if (STRNCMP(optname, "nowait", 7) == 0) { - was_valid_opt = true; - out->nowait = key_and_val->value.data.boolean; - } - break; - case 's': - if (STRNCMP(optname, "silent", 7) == 0) { - was_valid_opt = true; - out->silent = key_and_val->value.data.boolean; - } else if (STRNCMP(optname, "script", 7) == 0) { - was_valid_opt = true; - out->script = key_and_val->value.data.boolean; - } - break; - case 'e': - if (STRNCMP(optname, "expr", 5) == 0) { - was_valid_opt = true; - out->expr = key_and_val->value.data.boolean; - } - break; - case 'u': - if (STRNCMP(optname, "unique", 7) == 0) { - was_valid_opt = true; - out->unique = key_and_val->value.data.boolean; - } - break; - default: - break; - } // switch - if (!was_valid_opt) { - err_msg = "Invalid key: %s"; - err_arg = optname; - err_type = kErrorTypeValidation; - goto fail_with_message; - } - } // for - - return 0; - -fail_with_message: - api_set_error(err, err_type, err_msg, err_arg); - return 1; -} - /// Collects `n` buffer lines into array `l`, optionally replacing newlines /// with NUL. /// @@ -1413,8 +1307,10 @@ static void set_option_value_for(char *key, int numval, char *stringval, int opt switch (opt_type) { case SREQ_WIN: - if (switch_win(&save_curwin, &save_curtab, (win_T *)from, - win_find_tabpage((win_T *)from), false) == FAIL) { + if (switch_win_noblock(&save_curwin, &save_curtab, (win_T *)from, + win_find_tabpage((win_T *)from), true) + == FAIL) { + restore_win_noblock(save_curwin, save_curtab, true); if (try_end(err)) { return; } @@ -1424,7 +1320,7 @@ static void set_option_value_for(char *key, int numval, char *stringval, int opt return; } set_option_value_err(key, numval, stringval, opt_flags, err); - restore_win(save_curwin, save_curtab, true); + restore_win_noblock(save_curwin, save_curtab, true); break; case SREQ_BUF: aucmd_prepbuf(&aco, (buf_T *)from); @@ -1625,7 +1521,7 @@ VirtText parse_virt_text(Array chunks, Error *err, int *width) } } - char *text = transstr(str.size > 0 ? str.data : ""); // allocates + char *text = transstr(str.size > 0 ? str.data : "", false); // allocates w += (int)mb_string2cells((char_u *)text); kv_push(virt_text, ((VirtTextChunk){ .text = text, .hl_id = hl_id })); @@ -1663,7 +1559,7 @@ int object_to_hl_id(Object obj, const char *what, Error *err) { if (obj.type == kObjectTypeString) { String str = obj.data.string; - return str.size ? syn_check_group((char_u *)str.data, (int)str.size) : 0; + return str.size ? syn_check_group(str.data, (int)str.size) : 0; } else if (obj.type == kObjectTypeInteger) { return MAX((int)obj.data.integer, 0); } else { @@ -1697,7 +1593,7 @@ HlMessage parse_hl_msg(Array chunks, Error *err) String hl = chunk.items[1].data.string; if (hl.size > 0) { // TODO(bfredl): use object_to_hl_id and allow integer - int hl_id = syn_check_group((char_u *)hl.data, (int)hl.size); + int hl_id = syn_check_group(hl.data, (int)hl.size); attr = hl_id > 0 ? syn_id2attr(hl_id) : 0; } } @@ -1723,367 +1619,77 @@ const char *describe_ns(NS ns_id) return "(UNKNOWN PLUGIN)"; } -static bool parse_float_anchor(String anchor, FloatAnchor *out) +bool api_dict_to_keydict(void *rv, field_hash hashy, Dictionary dict, Error *err) { - if (anchor.size == 0) { - *out = (FloatAnchor)0; - } - char *str = anchor.data; - if (striequal(str, "NW")) { - *out = 0; // NW is the default - } else if (striequal(str, "NE")) { - *out = kFloatAnchorEast; - } else if (striequal(str, "SW")) { - *out = kFloatAnchorSouth; - } else if (striequal(str, "SE")) { - *out = kFloatAnchorSouth | kFloatAnchorEast; - } else { - return false; - } - return true; -} + for (size_t i = 0; i < dict.size; i++) { + String k = dict.items[i].key; + Object *field = hashy(rv, k.data, k.size); + if (!field) { + api_set_error(err, kErrorTypeValidation, "Invalid key: '%.*s'", (int)k.size, k.data); + return false; + } -static bool parse_float_relative(String relative, FloatRelative *out) -{ - char *str = relative.data; - if (striequal(str, "editor")) { - *out = kFloatRelativeEditor; - } else if (striequal(str, "win")) { - *out = kFloatRelativeWindow; - } else if (striequal(str, "cursor")) { - *out = kFloatRelativeCursor; - } else { - return false; + *field = dict.items[i].value; } + return true; } -static bool parse_float_bufpos(Array bufpos, lpos_T *out) +void api_free_keydict(void *dict, KeySetLink *table) { - if (bufpos.size != 2 - || bufpos.items[0].type != kObjectTypeInteger - || bufpos.items[1].type != kObjectTypeInteger) { - return false; + for (size_t i = 0; table[i].str; i++) { + api_free_object(*(Object *)((char *)dict + table[i].ptr_off)); } - out->lnum = bufpos.items[0].data.integer; - out->col = (colnr_T)bufpos.items[1].data.integer; - return true; } -static void parse_border_style(Object style, FloatConfig *fconfig, Error *err) +/// Set a named mark +/// buffer and mark name must be validated already +/// @param buffer Buffer to set the mark on +/// @param name Mark name +/// @param line Line number +/// @param col Column/row number +/// @return true if the mark was set, else false +bool set_mark(buf_T *buf, String name, Integer line, Integer col, Error *err) { - struct { - const char *name; - schar_T chars[8]; - bool shadow_color; - } defaults[] = { - { "double", { "╔", "═", "╗", "║", "╝", "═", "╚", "║" }, false }, - { "single", { "┌", "─", "┐", "│", "┘", "─", "└", "│" }, false }, - { "shadow", { "", "", " ", " ", " ", " ", " ", "" }, true }, - { "rounded", { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, false }, - { "solid", { " ", " ", " ", " ", " ", " ", " ", " " }, false }, - { NULL, { { NUL } }, false }, - }; - - schar_T *chars = fconfig->border_chars; - int *hl_ids = fconfig->border_hl_ids; - - fconfig->border = true; - - if (style.type == kObjectTypeArray) { - Array arr = style.data.array; - size_t size = arr.size; - if (!size || size > 8 || (size & (size-1))) { - api_set_error(err, kErrorTypeValidation, - "invalid number of border chars"); - return; - } - for (size_t i = 0; i < size; i++) { - Object iytem = arr.items[i]; - String string; - int hl_id = 0; - if (iytem.type == kObjectTypeArray) { - Array iarr = iytem.data.array; - if (!iarr.size || iarr.size > 2) { - api_set_error(err, kErrorTypeValidation, "invalid border char"); - return; - } - if (iarr.items[0].type != kObjectTypeString) { - api_set_error(err, kErrorTypeValidation, "invalid border char"); - return; - } - string = iarr.items[0].data.string; - if (iarr.size == 2) { - hl_id = object_to_hl_id(iarr.items[1], "border char highlight", err); - if (ERROR_SET(err)) { - return; - } - } - } else if (iytem.type == kObjectTypeString) { - string = iytem.data.string; - } else { - api_set_error(err, kErrorTypeValidation, "invalid border char"); - return; - } - if (string.size - && mb_string2cells_len((char_u *)string.data, string.size) > 1) { - api_set_error(err, kErrorTypeValidation, - "border chars must be one cell"); - return; - } - size_t len = MIN(string.size, sizeof(*chars)-1); - if (len) { - memcpy(chars[i], string.data, len); - } - chars[i][len] = NUL; - hl_ids[i] = hl_id; - } - while (size < 8) { - memcpy(chars+size, chars, sizeof(*chars) * size); - memcpy(hl_ids+size, hl_ids, sizeof(*hl_ids) * size); - size <<= 1; - } - if ((chars[7][0] && chars[1][0] && !chars[0][0]) - || (chars[1][0] && chars[3][0] && !chars[2][0]) - || (chars[3][0] && chars[5][0] && !chars[4][0]) - || (chars[5][0] && chars[7][0] && !chars[6][0])) { - api_set_error(err, kErrorTypeValidation, - "corner between used edges must be specified"); - } - } else if (style.type == kObjectTypeString) { - String str = style.data.string; - if (str.size == 0 || strequal(str.data, "none")) { - fconfig->border = false; - return; + buf = buf == NULL ? curbuf : buf; + // If line == 0 the marks is being deleted + bool res = false; + bool deleting = false; + if (line == 0) { + col = 0; + deleting = true; + } else { + if (col > MAXCOL) { + api_set_error(err, kErrorTypeValidation, "Column value outside range"); + return res; } - for (size_t i = 0; defaults[i].name; i++) { - if (strequal(str.data, defaults[i].name)) { - memcpy(chars, defaults[i].chars, sizeof(defaults[i].chars)); - memset(hl_ids, 0, 8 * sizeof(*hl_ids)); - if (defaults[i].shadow_color) { - int hl_blend = SYN_GROUP_STATIC("FloatShadow"); - int hl_through = SYN_GROUP_STATIC("FloatShadowThrough"); - hl_ids[2] = hl_through; - hl_ids[3] = hl_blend; - hl_ids[4] = hl_blend; - hl_ids[5] = hl_blend; - hl_ids[6] = hl_through; - } - return; - } + if (line < 1 || line > buf->b_ml.ml_line_count) { + api_set_error(err, kErrorTypeValidation, "Line value outside range"); + return res; } - api_set_error(err, kErrorTypeValidation, - "invalid border style \"%s\"", str.data); } -} - -bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf, bool new_win, - Error *err) -{ - // TODO(bfredl): use a get/has_key interface instead and get rid of extra - // flags - bool has_row = false, has_col = false, has_relative = false; - bool has_external = false, has_window = false; - bool has_width = false, has_height = false; - bool has_bufpos = false; - - for (size_t i = 0; i < config.size; i++) { - char *key = config.items[i].key.data; - Object val = config.items[i].value; - if (!strcmp(key, "row")) { - has_row = true; - if (val.type == kObjectTypeInteger) { - fconfig->row = (double)val.data.integer; - } else if (val.type == kObjectTypeFloat) { - fconfig->row = val.data.floating; - } else { - api_set_error(err, kErrorTypeValidation, - "'row' key must be Integer or Float"); - return false; - } - } else if (!strcmp(key, "col")) { - has_col = true; - if (val.type == kObjectTypeInteger) { - fconfig->col = (double)val.data.integer; - } else if (val.type == kObjectTypeFloat) { - fconfig->col = val.data.floating; - } else { - api_set_error(err, kErrorTypeValidation, - "'col' key must be Integer or Float"); - return false; - } - } else if (strequal(key, "width")) { - has_width = true; - if (val.type == kObjectTypeInteger && val.data.integer > 0) { - fconfig->width = (int)val.data.integer; - } else { - api_set_error(err, kErrorTypeValidation, - "'width' key must be a positive Integer"); - return false; - } - } else if (strequal(key, "height")) { - has_height = true; - if (val.type == kObjectTypeInteger && val.data.integer > 0) { - fconfig->height = (int)val.data.integer; - } else { - api_set_error(err, kErrorTypeValidation, - "'height' key must be a positive Integer"); - return false; - } - } else if (!strcmp(key, "anchor")) { - if (val.type != kObjectTypeString) { - api_set_error(err, kErrorTypeValidation, - "'anchor' key must be String"); - return false; - } - if (!parse_float_anchor(val.data.string, &fconfig->anchor)) { - api_set_error(err, kErrorTypeValidation, - "Invalid value of 'anchor' key"); - return false; - } - } else if (!strcmp(key, "relative")) { - if (val.type != kObjectTypeString) { - api_set_error(err, kErrorTypeValidation, - "'relative' key must be String"); - return false; - } - // ignore empty string, to match nvim_win_get_config - if (val.data.string.size > 0) { - has_relative = true; - if (!parse_float_relative(val.data.string, &fconfig->relative)) { - api_set_error(err, kErrorTypeValidation, - "Invalid value of 'relative' key"); - return false; - } - } - } else if (!strcmp(key, "win")) { - has_window = true; - if (val.type != kObjectTypeInteger - && val.type != kObjectTypeWindow) { - api_set_error(err, kErrorTypeValidation, - "'win' key must be Integer or Window"); - return false; - } - fconfig->window = (Window)val.data.integer; - } else if (!strcmp(key, "bufpos")) { - if (val.type != kObjectTypeArray) { - api_set_error(err, kErrorTypeValidation, - "'bufpos' key must be Array"); - return false; - } - if (!parse_float_bufpos(val.data.array, &fconfig->bufpos)) { - api_set_error(err, kErrorTypeValidation, - "Invalid value of 'bufpos' key"); - return false; - } - has_bufpos = true; - } else if (!strcmp(key, "external")) { - has_external = fconfig->external - = api_object_to_bool(val, "'external' key", false, err); - if (ERROR_SET(err)) { - return false; - } - } else if (!strcmp(key, "focusable")) { - fconfig->focusable - = api_object_to_bool(val, "'focusable' key", true, err); - if (ERROR_SET(err)) { - return false; - } - } else if (strequal(key, "zindex")) { - if (val.type == kObjectTypeInteger && val.data.integer > 0) { - fconfig->zindex = (int)val.data.integer; - } else { - api_set_error(err, kErrorTypeValidation, - "'zindex' key must be a positive Integer"); - return false; - } - } else if (!strcmp(key, "border")) { - parse_border_style(val, fconfig, err); - if (ERROR_SET(err)) { - return false; - } - } else if (!strcmp(key, "style")) { - if (val.type != kObjectTypeString) { - api_set_error(err, kErrorTypeValidation, - "'style' key must be String"); - return false; - } - if (val.data.string.data[0] == NUL) { - fconfig->style = kWinStyleUnused; - } else if (striequal(val.data.string.data, "minimal")) { - fconfig->style = kWinStyleMinimal; - } else { - api_set_error(err, kErrorTypeValidation, - "Invalid value of 'style' key"); - } - } else if (strequal(key, "noautocmd") && new_win) { - fconfig->noautocmd - = api_object_to_bool(val, "'noautocmd' key", false, err); - if (ERROR_SET(err)) { - return false; - } + pos_T pos = { line, (int)col, (int)col }; + res = setmark_pos(*name.data, &pos, buf->handle); + if (!res) { + if (deleting) { + api_set_error(err, kErrorTypeException, + "Failed to delete named mark: %c", *name.data); } else { - api_set_error(err, kErrorTypeValidation, - "Invalid key '%s'", key); - return false; - } - } - - if (has_window && !(has_relative - && fconfig->relative == kFloatRelativeWindow)) { - api_set_error(err, kErrorTypeValidation, - "'win' key is only valid with relative='win'"); - return false; - } - - if ((has_relative && fconfig->relative == kFloatRelativeWindow) - && (!has_window || fconfig->window == 0)) { - fconfig->window = curwin->handle; - } - - if (has_window && !has_bufpos) { - fconfig->bufpos.lnum = -1; - } - - if (has_bufpos) { - if (!has_row) { - fconfig->row = (fconfig->anchor & kFloatAnchorSouth) ? 0 : 1; - has_row = true; - } - if (!has_col) { - fconfig->col = 0; - has_col = true; + api_set_error(err, kErrorTypeException, + "Failed to set named mark: %c", *name.data); } } + return res; +} - if (has_relative && has_external) { - api_set_error(err, kErrorTypeValidation, - "Only one of 'relative' and 'external' must be used"); - return false; - } else if (!reconf && !has_relative && !has_external) { - api_set_error(err, kErrorTypeValidation, - "One of 'relative' and 'external' must be used"); - return false; - } else if (has_relative) { - fconfig->external = false; - } - - if (!reconf && !(has_height && has_width)) { - api_set_error(err, kErrorTypeValidation, - "Must specify 'width' and 'height'"); - return false; - } - - if (fconfig->external && !ui_has(kUIMultigrid)) { - api_set_error(err, kErrorTypeValidation, - "UI doesn't support external windows"); - return false; - } - - if (has_relative != has_row || has_row != has_col) { - api_set_error(err, kErrorTypeValidation, - "'relative' requires 'row'/'col' or 'bufpos'"); - return false; +/// Get default statusline highlight for window +const char *get_default_stl_hl(win_T *wp) +{ + if (wp == NULL) { + return "TabLineFill"; + } else if (wp == curwin) { + return "StatusLine"; + } else { + return "StatusLineNC"; } - return true; } diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index ecce6afa26..08d2c8d90c 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -4,12 +4,12 @@ #include <stdbool.h> #include "nvim/api/private/defs.h" -#include "nvim/vim.h" -#include "nvim/getchar.h" -#include "nvim/memory.h" #include "nvim/decoration.h" #include "nvim/ex_eval.h" +#include "nvim/getchar.h" #include "nvim/lib/kvec.h" +#include "nvim/memory.h" +#include "nvim/vim.h" #define OBJECT_OBJ(o) o @@ -59,6 +59,9 @@ #define NIL ((Object)OBJECT_INIT) #define NULL_STRING ((String)STRING_INIT) +// currently treat key=vim.NIL as if the key was missing +#define HAS_KEY(o) ((o).type != kObjectTypeNil) + #define PUT(dict, k, v) \ kv_push(dict, ((KeyValuePair) { .key = cstr_to_string(k), .value = v })) @@ -73,7 +76,7 @@ name.size = fixsize; \ name.items = name##__items; \ -#define STATIC_CSTR_AS_STRING(s) ((String) {.data = s, .size = sizeof(s) - 1}) +#define STATIC_CSTR_AS_STRING(s) ((String) { .data = s, .size = sizeof(s) - 1 }) /// Create a new String instance, putting data in allocated memory /// @@ -134,10 +137,13 @@ typedef struct { msg_list = &private_msg_list; \ private_msg_list = NULL; \ code \ - msg_list = saved_msg_list; /* Restore the exception context. */ \ + msg_list = saved_msg_list; /* Restore the exception context. */ \ } while (0) #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/private/helpers.h.generated.h" +# include "keysets.h.generated.h" #endif + + #endif // NVIM_API_PRIVATE_HELPERS_H diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 9b200dcba2..d86aecc318 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -40,7 +40,6 @@ typedef struct { static PMap(uint64_t) connected_uis = MAP_INIT; void remote_ui_disconnect(uint64_t channel_id) - FUNC_API_NOEXPORT { UI *ui = pmap_get(uint64_t)(&connected_uis, channel_id); if (!ui) { @@ -57,7 +56,6 @@ void remote_ui_disconnect(uint64_t channel_id) /// Wait until ui has connected on stdio channel. void remote_ui_wait_for_attach(void) - FUNC_API_NOEXPORT { Channel *channel = find_channel(CHAN_STDIO); if (!channel) { @@ -172,6 +170,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictiona /// @deprecated void ui_attach(uint64_t channel_id, Integer width, Integer height, Boolean enable_rgb, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { Dictionary opts = ARRAY_DICT_INIT; PUT(opts, "rgb", BOOLEAN_OBJ(enable_rgb)); diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 3be45d0cf7..b5cc02e761 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -17,6 +17,7 @@ #include "nvim/api/window.h" #include "nvim/ascii.h" #include "nvim/buffer.h" +#include "nvim/buffer_defs.h" #include "nvim/context.h" #include "nvim/decoration.h" #include "nvim/edit.h" @@ -59,7 +60,6 @@ #endif void api_vim_free_all_mem(void) - FUNC_API_NOEXPORT { String name; handle_T id; @@ -196,7 +196,7 @@ Dictionary nvim_get_hl_by_id(Integer hl_id, Boolean rgb, Error *err) Integer nvim_get_hl_id_by_name(String name) FUNC_API_SINCE(7) { - return syn_check_group((const char_u *)name.data, (int)name.size); + return syn_check_group(name.data, (int)name.size); } Dictionary nvim__get_hl_defs(Integer ns_id, Error *err) @@ -228,7 +228,7 @@ Dictionary nvim__get_hl_defs(Integer ns_id, Error *err) void nvim_set_hl(Integer ns_id, String name, Dictionary val, Error *err) FUNC_API_SINCE(7) { - int hl_id = syn_check_group( (char_u *)(name.data), (int)name.size); + int hl_id = syn_check_group(name.data, (int)name.size); int link_id = -1; HlAttrs attrs = dict2hlattrs(val, true, &link_id, err); @@ -264,7 +264,6 @@ void nvim__set_hl_ns(Integer ns_id, Error *err) } static void on_redraw_event(void **argv) - FUNC_API_NOEXPORT { redraw_all_later(NOT_VALID); } @@ -714,7 +713,7 @@ Object nvim_call_dict_function(Object dict, String fn, Array args, Error *err) } fn = (String) { .data = (char *)di->di_tv.vval.v_string, - .size = strlen((char *)di->di_tv.vval.v_string), + .size = STRLEN(di->di_tv.vval.v_string), }; } @@ -758,6 +757,11 @@ ArrayOf(String) nvim_list_runtime_paths(Error *err) return nvim_get_runtime_file(NULL_STRING, true, err); } +Array nvim__runtime_inspect(void) +{ + return runtime_inspect(); +} + /// Find files in runtime directories /// /// 'name' can contain wildcards. For example @@ -796,6 +800,25 @@ String nvim__get_lib_dir(void) return cstr_as_string(get_lib_dir()); } +/// Find files in runtime directories +/// +/// @param pat pattern of files to search for +/// @param all whether to return all matches or only the first +/// @param options +/// is_lua: only search lua subdirs +/// @return list of absolute paths to the found files +ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, Error *err) + FUNC_API_SINCE(8) + FUNC_API_FAST +{ + bool is_lua = api_object_to_bool(opts->is_lua, "is_lua", false, err); + if (ERROR_SET(err)) { + return (Array)ARRAY_DICT_INIT; + } + return runtime_get_named(is_lua, pat, all); +} + + /// Changes the global working directory. /// /// @param dir Directory path @@ -1221,14 +1244,20 @@ fail: /// buffer in a configured window before calling this. For instance, for a /// floating display, first create an empty buffer using |nvim_create_buf()|, /// then display it using |nvim_open_win()|, and then call this function. -/// Then |nvim_chan_send()| cal be called immediately to process sequences +/// Then |nvim_chan_send()| can be called immediately to process sequences /// in a virtual terminal having the intended size. /// /// @param buffer the buffer to use (expected to be empty) -/// @param opts Optional parameters. Reserved for future use. +/// @param opts Optional parameters. +/// - on_input: lua callback for input sent, i e keypresses in terminal +/// mode. Note: keypresses are sent raw as they would be to the pty +/// master end. For instance, a carriage return is sent +/// as a "\r", not as a "\n". |textlock| applies. It is possible +/// to call |nvim_chan_send| directly in the callback however. +/// ["input", term, bufnr, data] /// @param[out] err Error details, if any /// @return Channel id, or 0 on error -Integer nvim_open_term(Buffer buffer, Dictionary opts, Error *err) +Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err) FUNC_API_SINCE(7) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -1236,13 +1265,27 @@ Integer nvim_open_term(Buffer buffer, Dictionary opts, Error *err) return 0; } - if (opts.size > 0) { - api_set_error(err, kErrorTypeValidation, "opts dict isn't empty"); - return 0; + LuaRef cb = LUA_NOREF; + for (size_t i = 0; i < opts.size; i++) { + String k = opts.items[i].key; + Object *v = &opts.items[i].value; + if (strequal("on_input", k.data)) { + if (v->type != kObjectTypeLuaRef) { + api_set_error(err, kErrorTypeValidation, + "%s is not a function", "on_input"); + return 0; + } + cb = v->data.luaref; + v->data.luaref = LUA_NOREF; + break; + } else { + api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data); + } } TerminalOptions topts; Channel *chan = channel_alloc(kChannelStreamInternal); + chan->stream.internal.cb = cb; topts.data = chan; // NB: overridden in terminal_check_size if a window is already // displaying the buffer @@ -1260,7 +1303,18 @@ Integer nvim_open_term(Buffer buffer, Dictionary opts, Error *err) static void term_write(char *buf, size_t size, void *data) { - // TODO(bfredl): lua callback + Channel *chan = data; + LuaRef cb = chan->stream.internal.cb; + if (cb == LUA_NOREF) { + return; + } + FIXED_TEMP_ARRAY(args, 3); + args.items[0] = INTEGER_OBJ((Integer)chan->id); + args.items[1] = BUFFER_OBJ(terminal_buf(chan->term)); + args.items[2] = STRING_OBJ(((String){ .data = buf, .size = size })); + textlock++; + nlua_call_ref(cb, "input", args, false, NULL); + textlock--; } static void term_resize(uint16_t width, uint16_t height, void *data) @@ -1305,153 +1359,6 @@ void nvim_chan_send(Integer chan, String data, Error *err) } } -/// Open a new window. -/// -/// Currently this is used to open floating and external windows. -/// Floats are windows that are drawn above the split layout, at some anchor -/// position in some other window. Floats can be drawn internally or by external -/// GUI with the |ui-multigrid| extension. External windows are only supported -/// with multigrid GUIs, and are displayed as separate top-level windows. -/// -/// For a general overview of floats, see |api-floatwin|. -/// -/// Exactly one of `external` and `relative` must be specified. The `width` and -/// `height` of the new window must be specified. -/// -/// With relative=editor (row=0,col=0) refers to the top-left corner of the -/// screen-grid and (row=Lines-1,col=Columns-1) refers to the bottom-right -/// corner. Fractional values are allowed, but the builtin implementation -/// (used by non-multigrid UIs) will always round down to nearest integer. -/// -/// Out-of-bounds values, and configurations that make the float not fit inside -/// the main editor, are allowed. The builtin implementation truncates values -/// so floats are fully within the main screen grid. External GUIs -/// could let floats hover outside of the main window like a tooltip, but -/// this should not be used to specify arbitrary WM screen positions. -/// -/// Example (Lua): window-relative float -/// <pre> -/// vim.api.nvim_open_win(0, false, -/// {relative='win', row=3, col=3, width=12, height=3}) -/// </pre> -/// -/// Example (Lua): buffer-relative float (travels as buffer is scrolled) -/// <pre> -/// vim.api.nvim_open_win(0, false, -/// {relative='win', width=12, height=3, bufpos={100,10}}) -/// </pre> -/// -/// @param buffer Buffer to display, or 0 for current buffer -/// @param enter Enter the window (make it the current window) -/// @param config Map defining the window configuration. Keys: -/// - `relative`: Sets the window layout to "floating", placed at (row,col) -/// coordinates relative to: -/// - "editor" The global editor grid -/// - "win" Window given by the `win` field, or current window. -/// - "cursor" Cursor position in current window. -/// - `win`: |window-ID| for relative="win". -/// - `anchor`: Decides which corner of the float to place at (row,col): -/// - "NW" northwest (default) -/// - "NE" northeast -/// - "SW" southwest -/// - "SE" southeast -/// - `width`: Window width (in character cells). Minimum of 1. -/// - `height`: Window height (in character cells). Minimum of 1. -/// - `bufpos`: Places float relative to buffer text (only when -/// relative="win"). Takes a tuple of zero-indexed [line, column]. -/// `row` and `col` if given are applied relative to this -/// position, else they default to `row=1` and `col=0` -/// (thus like a tooltip near the buffer text). -/// - `row`: Row position in units of "screen cell height", may be fractional. -/// - `col`: Column position in units of "screen cell width", may be -/// fractional. -/// - `focusable`: Enable focus by user actions (wincmds, mouse events). -/// Defaults to true. Non-focusable windows can be entered by -/// |nvim_set_current_win()|. -/// - `external`: GUI should display the window as an external -/// top-level window. Currently accepts no other positioning -/// configuration together with this. -/// - `zindex`: Stacking order. floats with higher `zindex` go on top on -/// floats with lower indices. Must be larger than zero. The -/// following screen elements have hard-coded z-indices: -/// - 100: insert completion popupmenu -/// - 200: message scrollback -/// - 250: cmdline completion popupmenu (when wildoptions+=pum) -/// The default value for floats are 50. In general, values below 100 are -/// recommended, unless there is a good reason to overshadow builtin -/// elements. -/// - `style`: Configure the appearance of the window. Currently only takes -/// one non-empty value: -/// - "minimal" Nvim will display the window with many UI options -/// disabled. This is useful when displaying a temporary -/// float where the text should not be edited. Disables -/// 'number', 'relativenumber', 'cursorline', 'cursorcolumn', -/// 'foldcolumn', 'spell' and 'list' options. 'signcolumn' -/// is changed to `auto` and 'colorcolumn' is cleared. The -/// end-of-buffer region is hidden by setting `eob` flag of -/// 'fillchars' to a space char, and clearing the -/// |EndOfBuffer| region in 'winhighlight'. -/// - `border`: Style of (optional) window border. This can either be a string -/// or an array. The string values are -/// - "none": No border (default). -/// - "single": A single line box. -/// - "double": A double line box. -/// - "rounded": Like "single", but with rounded corners ("╭" etc.). -/// - "solid": Adds padding by a single whitespace cell. -/// - "shadow": A drop shadow effect by blending with the background. -/// - If it is an array, it should have a length of eight or any divisor of -/// eight. The array will specifify the eight chars building up the border -/// in a clockwise fashion starting with the top-left corner. As an -/// example, the double box style could be specified as -/// [ "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" ]. -/// If the number of chars are less than eight, they will be repeated. Thus -/// an ASCII border could be specified as -/// [ "/", "-", "\\", "|" ], -/// or all chars the same as -/// [ "x" ]. -/// An empty string can be used to turn off a specific border, for instance, -/// [ "", "", "", ">", "", "", "", "<" ] -/// will only make vertical borders but not horizontal ones. -/// By default, `FloatBorder` highlight is used, which links to `VertSplit` -/// when not defined. It could also be specified by character: -/// [ {"+", "MyCorner"}, {"x", "MyBorder"} ]. -/// - `noautocmd`: If true then no buffer-related autocommand events such as -/// |BufEnter|, |BufLeave| or |BufWinEnter| may fire from -/// calling this function. -/// -/// @param[out] err Error details, if any -/// -/// @return Window handle, or 0 on error -Window nvim_open_win(Buffer buffer, Boolean enter, Dictionary config, Error *err) - FUNC_API_SINCE(6) - FUNC_API_CHECK_TEXTLOCK -{ - FloatConfig fconfig = FLOAT_CONFIG_INIT; - if (!parse_float_config(config, &fconfig, false, true, err)) { - return 0; - } - win_T *wp = win_new_float(NULL, fconfig, err); - if (!wp) { - return 0; - } - if (enter) { - win_enter(wp, false); - } - if (!win_valid(wp)) { - api_set_error(err, kErrorTypeException, "Window was closed immediately"); - return 0; - } - if (buffer > 0) { - win_set_buf(wp->handle, buffer, fconfig.noautocmd, err); - } - - if (fconfig.style == kWinStyleMinimal) { - win_set_minimal_style(wp); - didset_window_options(wp); - } - return wp->handle; -} - /// Gets the current list of tabpage handles. /// /// @return List of tabpage handles @@ -1507,7 +1414,7 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err) } } -/// Creates a new *namespace*, or gets an existing one. +/// Creates a new \*namespace\* or gets an existing one. /// /// Namespaces are used for buffer highlights and virtual text, see /// |nvim_buf_add_highlight()| and |nvim_buf_set_extmark()|. @@ -1758,24 +1665,15 @@ Dictionary nvim_get_color_map(void) /// @param[out] err Error details, if any /// /// @return map of global |context|. -Dictionary nvim_get_context(Dictionary opts, Error *err) +Dictionary nvim_get_context(Dict(context) *opts, Error *err) FUNC_API_SINCE(6) { Array types = ARRAY_DICT_INIT; - for (size_t i = 0; i < opts.size; i++) { - String k = opts.items[i].key; - Object v = opts.items[i].value; - if (strequal("types", k.data)) { - if (v.type != kObjectTypeArray) { - api_set_error(err, kErrorTypeValidation, "invalid value for key: %s", - k.data); - return (Dictionary)ARRAY_DICT_INIT; - } - types = v.data.array; - } else { - api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data); - return (Dictionary)ARRAY_DICT_INIT; - } + if (opts->types.type == kObjectTypeArray) { + types = opts->types.data.array; + } else if (opts->types.type != kObjectTypeNil) { + api_set_error(err, kErrorTypeValidation, "invalid value for key: types"); + return (Dictionary)ARRAY_DICT_INIT; } int int_types = types.size > 0 ? 0 : kCtxAll; @@ -1885,7 +1783,7 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode) /// as keys excluding |<buffer>| but including |noremap|. /// Values are Booleans. Unknown key is an error. /// @param[out] err Error details, if any. -void nvim_set_keymap(String mode, String lhs, String rhs, Dictionary opts, Error *err) +void nvim_set_keymap(String mode, String lhs, String rhs, Dict(keymap) *opts, Error *err) FUNC_API_SINCE(6) { modify_keymap(-1, false, mode, lhs, rhs, opts, err); @@ -1911,7 +1809,7 @@ void nvim_del_keymap(String mode, String lhs, Error *err) /// @param[out] err Error details, if any. /// /// @returns Map of maps describing commands. -Dictionary nvim_get_commands(Dictionary opts, Error *err) +Dictionary nvim_get_commands(Dict(get_commands) *opts, Error *err) FUNC_API_SINCE(4) { return nvim_buf_get_commands(-1, opts, err); @@ -2937,3 +2835,266 @@ void nvim_set_decoration_provider(Integer ns_id, DictionaryOf(LuaRef) opts, Erro error: decor_provider_clear(p); } + +/// Deletes a uppercase/file named mark. See |mark-motions|. +/// +/// @note fails with error if a lowercase or buffer local named mark is used. +/// @param name Mark name +/// @return true if the mark was deleted, else false. +/// @see |nvim_buf_del_mark()| +/// @see |nvim_get_mark()| +Boolean nvim_del_mark(String name, Error *err) + FUNC_API_SINCE(8) +{ + bool res = false; + if (name.size != 1) { + api_set_error(err, kErrorTypeValidation, + "Mark name must be a single character"); + return res; + } + // Only allow file/uppercase marks + // TODO(muniter): Refactor this ASCII_ISUPPER macro to a proper function + if (ASCII_ISUPPER(*name.data) || ascii_isdigit(*name.data)) { + res = set_mark(NULL, name, 0, 0, err); + } else { + api_set_error(err, kErrorTypeValidation, + "Only file/uppercase marks allowed, invalid mark name: '%c'", + *name.data); + } + return res; +} + +/// Return a tuple (row, col, buffer, buffername) representing the position of +/// the uppercase/file named mark. See |mark-motions|. +/// +/// Marks are (1,0)-indexed. |api-indexing| +/// +/// @note fails with error if a lowercase or buffer local named mark is used. +/// @param name Mark name +/// @return 4-tuple (row, col, buffer, buffername), (0, 0, 0, '') if the mark is +/// not set. +/// @see |nvim_buf_set_mark()| +/// @see |nvim_del_mark()| +Array nvim_get_mark(String name, Error *err) + FUNC_API_SINCE(8) +{ + Array rv = ARRAY_DICT_INIT; + + if (name.size != 1) { + api_set_error(err, kErrorTypeValidation, + "Mark name must be a single character"); + return rv; + } else if (!(ASCII_ISUPPER(*name.data) || ascii_isdigit(*name.data))) { + api_set_error(err, kErrorTypeValidation, + "Only file/uppercase marks allowed, invalid mark name: '%c'", + *name.data); + return rv; + } + + xfmark_T mark = get_global_mark(*name.data); + pos_T pos = mark.fmark.mark; + bool allocated = false; + int bufnr; + char *filename; + + // Marks are from an open buffer it fnum is non zero + if (mark.fmark.fnum != 0) { + bufnr = mark.fmark.fnum; + filename = (char *)buflist_nr2name(bufnr, true, true); + allocated = true; + // Marks comes from shada + } else { + filename = (char *)mark.fname; + bufnr = 0; + } + + bool exists = filename != NULL; + Integer row; + Integer col; + + if (!exists || pos.lnum <= 0) { + if (allocated) { + xfree(filename); + allocated = false; + } + filename = ""; + bufnr = 0; + row = 0; + col = 0; + } else { + row = pos.lnum; + col = pos.col; + } + + ADD(rv, INTEGER_OBJ(row)); + ADD(rv, INTEGER_OBJ(col)); + ADD(rv, INTEGER_OBJ(bufnr)); + ADD(rv, STRING_OBJ(cstr_to_string(filename))); + + if (allocated) { + xfree(filename); + } + + return rv; +} + +/// Evaluates statusline string. +/// +/// @param str Statusline string (see 'statusline'). +/// @param opts Optional parameters. +/// - winid: (number) |window-ID| of the window to use as context for statusline. +/// - maxwidth: (number) Maximum width of statusline. +/// - fillchar: (string) Character to fill blank spaces in the statusline (see +/// 'fillchars'). +/// - highlights: (boolean) Return highlight information. +/// - use_tabline: (boolean) Evaluate tabline instead of statusline. When |TRUE|, {winid} +/// is ignored. +/// +/// @param[out] err Error details, if any. +/// @return Dictionary containing statusline information, with these keys: +/// - str: (string) Characters that will be displayed on the statusline. +/// - width: (number) Display width of the statusline. +/// - highlights: Array containing highlight information of the statusline. Only included when +/// the "highlights" key in {opts} is |TRUE|. Each element of the array is a +/// |Dictionary| with these keys: +/// - start: (number) Byte index (0-based) of first character that uses the highlight. +/// - group: (string) Name of highlight group. +Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error *err) + FUNC_API_SINCE(8) FUNC_API_FAST +{ + Dictionary result = ARRAY_DICT_INIT; + + int maxwidth; + char fillchar = 0; + Window window = 0; + bool use_tabline = false; + bool highlights = false; + + if (HAS_KEY(opts->winid)) { + if (opts->winid.type != kObjectTypeInteger) { + api_set_error(err, kErrorTypeValidation, "winid must be an integer"); + return result; + } + + window = (Window)opts->winid.data.integer; + } + + if (HAS_KEY(opts->fillchar)) { + if (opts->fillchar.type != kObjectTypeString || opts->fillchar.data.string.size > 1) { + api_set_error(err, kErrorTypeValidation, "fillchar must be an ASCII character"); + return result; + } + + fillchar = opts->fillchar.data.string.data[0]; + } + + if (HAS_KEY(opts->highlights)) { + highlights = api_object_to_bool(opts->highlights, "highlights", false, err); + + if (ERROR_SET(err)) { + return result; + } + } + + if (HAS_KEY(opts->use_tabline)) { + use_tabline = api_object_to_bool(opts->use_tabline, "use_tabline", false, err); + + if (ERROR_SET(err)) { + return result; + } + } + + win_T *wp, *ewp; + + if (use_tabline) { + wp = NULL; + ewp = curwin; + fillchar = ' '; + } else { + wp = find_window_by_handle(window, err); + ewp = wp; + + if (fillchar == 0) { + int attr; + fillchar = (char)fillchar_status(&attr, wp); + } + } + + if (HAS_KEY(opts->maxwidth)) { + if (opts->maxwidth.type != kObjectTypeInteger) { + api_set_error(err, kErrorTypeValidation, "maxwidth must be an integer"); + return result; + } + + maxwidth = (int)opts->maxwidth.data.integer; + } else { + maxwidth = use_tabline ? Columns : wp->w_width; + } + + char buf[MAXPATHL]; + stl_hlrec_t *hltab; + stl_hlrec_t **hltab_ptr = highlights ? &hltab : NULL; + + // Temporarily reset 'cursorbind' to prevent side effects from moving the cursor away and back. + int p_crb_save = ewp->w_p_crb; + ewp->w_p_crb = false; + + int width = build_stl_str_hl( + ewp, + (char_u *)buf, + sizeof(buf), + (char_u *)str.data, + false, + (char_u)fillchar, + maxwidth, + hltab_ptr, + NULL); + + PUT(result, "width", INTEGER_OBJ(width)); + + // Restore original value of 'cursorbind' + ewp->w_p_crb = p_crb_save; + + if (highlights) { + Array hl_values = ARRAY_DICT_INIT; + const char *grpname; + char user_group[6]; + + // If first character doesn't have a defined highlight, + // add the default highlight at the beginning of the highlight list + if (hltab->start == NULL || ((char *)hltab->start - buf) != 0) { + Dictionary hl_info = ARRAY_DICT_INIT; + grpname = get_default_stl_hl(wp); + + PUT(hl_info, "start", INTEGER_OBJ(0)); + PUT(hl_info, "group", CSTR_TO_OBJ(grpname)); + + ADD(hl_values, DICTIONARY_OBJ(hl_info)); + } + + for (stl_hlrec_t *sp = hltab; sp->start != NULL; sp++) { + Dictionary hl_info = ARRAY_DICT_INIT; + + PUT(hl_info, "start", INTEGER_OBJ((char *)sp->start - buf)); + + if (sp->userhl == 0) { + grpname = get_default_stl_hl(wp); + } else if (sp->userhl < 0) { + grpname = (char *)syn_id2name(-sp->userhl); + } else { + snprintf(user_group, sizeof(user_group), "User%d", sp->userhl); + grpname = user_group; + } + + PUT(hl_info, "group", CSTR_TO_OBJ(grpname)); + + ADD(hl_values, DICTIONARY_OBJ(hl_info)); + } + + PUT(result, "highlights", ARRAY_OBJ(hl_values)); + } + + PUT(result, "str", CSTR_TO_OBJ((char *)buf)); + + return result; +} diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c new file mode 100644 index 0000000000..ceb7f71423 --- /dev/null +++ b/src/nvim/api/win_config.c @@ -0,0 +1,639 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + +#include <assert.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#include "nvim/api/private/defs.h" +#include "nvim/api/private/helpers.h" +#include "nvim/api/win_config.h" +#include "nvim/ascii.h" +#include "nvim/option.h" +#include "nvim/screen.h" +#include "nvim/strings.h" +#include "nvim/syntax.h" +#include "nvim/ui.h" +#include "nvim/window.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "api/win_config.c.generated.h" +#endif + + +/// Open a new window. +/// +/// Currently this is used to open floating and external windows. +/// Floats are windows that are drawn above the split layout, at some anchor +/// position in some other window. Floats can be drawn internally or by external +/// GUI with the |ui-multigrid| extension. External windows are only supported +/// with multigrid GUIs, and are displayed as separate top-level windows. +/// +/// For a general overview of floats, see |api-floatwin|. +/// +/// Exactly one of `external` and `relative` must be specified. The `width` and +/// `height` of the new window must be specified. +/// +/// With relative=editor (row=0,col=0) refers to the top-left corner of the +/// screen-grid and (row=Lines-1,col=Columns-1) refers to the bottom-right +/// corner. Fractional values are allowed, but the builtin implementation +/// (used by non-multigrid UIs) will always round down to nearest integer. +/// +/// Out-of-bounds values, and configurations that make the float not fit inside +/// the main editor, are allowed. The builtin implementation truncates values +/// so floats are fully within the main screen grid. External GUIs +/// could let floats hover outside of the main window like a tooltip, but +/// this should not be used to specify arbitrary WM screen positions. +/// +/// Example (Lua): window-relative float +/// <pre> +/// vim.api.nvim_open_win(0, false, +/// {relative='win', row=3, col=3, width=12, height=3}) +/// </pre> +/// +/// Example (Lua): buffer-relative float (travels as buffer is scrolled) +/// <pre> +/// vim.api.nvim_open_win(0, false, +/// {relative='win', width=12, height=3, bufpos={100,10}}) +/// </pre> +/// +/// @param buffer Buffer to display, or 0 for current buffer +/// @param enter Enter the window (make it the current window) +/// @param config Map defining the window configuration. Keys: +/// - relative: Sets the window layout to "floating", placed at (row,col) +/// coordinates relative to: +/// - "editor" The global editor grid +/// - "win" Window given by the `win` field, or current window. +/// - "cursor" Cursor position in current window. +/// - win: |window-ID| for relative="win". +/// - anchor: Decides which corner of the float to place at (row,col): +/// - "NW" northwest (default) +/// - "NE" northeast +/// - "SW" southwest +/// - "SE" southeast +/// - width: Window width (in character cells). Minimum of 1. +/// - height: Window height (in character cells). Minimum of 1. +/// - bufpos: Places float relative to buffer text (only when +/// relative="win"). Takes a tuple of zero-indexed [line, column]. +/// `row` and `col` if given are applied relative to this +/// position, else they default to: +/// - `row=1` and `col=0` if `anchor` is "NW" or "NE" +/// - `row=0` and `col=0` if `anchor` is "SW" or "SE" +/// (thus like a tooltip near the buffer text). +/// - row: Row position in units of "screen cell height", may be fractional. +/// - col: Column position in units of "screen cell width", may be +/// fractional. +/// - focusable: Enable focus by user actions (wincmds, mouse events). +/// Defaults to true. Non-focusable windows can be entered by +/// |nvim_set_current_win()|. +/// - external: GUI should display the window as an external +/// top-level window. Currently accepts no other positioning +/// configuration together with this. +/// - zindex: Stacking order. floats with higher `zindex` go on top on +/// floats with lower indices. Must be larger than zero. The +/// following screen elements have hard-coded z-indices: +/// - 100: insert completion popupmenu +/// - 200: message scrollback +/// - 250: cmdline completion popupmenu (when wildoptions+=pum) +/// The default value for floats are 50. In general, values below 100 are +/// recommended, unless there is a good reason to overshadow builtin +/// elements. +/// - style: Configure the appearance of the window. Currently only takes +/// one non-empty value: +/// - "minimal" Nvim will display the window with many UI options +/// disabled. This is useful when displaying a temporary +/// float where the text should not be edited. Disables +/// 'number', 'relativenumber', 'cursorline', 'cursorcolumn', +/// 'foldcolumn', 'spell' and 'list' options. 'signcolumn' +/// is changed to `auto` and 'colorcolumn' is cleared. The +/// end-of-buffer region is hidden by setting `eob` flag of +/// 'fillchars' to a space char, and clearing the +/// |EndOfBuffer| region in 'winhighlight'. +/// - border: Style of (optional) window border. This can either be a string +/// or an array. The string values are +/// - "none": No border (default). +/// - "single": A single line box. +/// - "double": A double line box. +/// - "rounded": Like "single", but with rounded corners ("╭" etc.). +/// - "solid": Adds padding by a single whitespace cell. +/// - "shadow": A drop shadow effect by blending with the background. +/// - If it is an array, it should have a length of eight or any divisor of +/// eight. The array will specifify the eight chars building up the border +/// in a clockwise fashion starting with the top-left corner. As an +/// example, the double box style could be specified as +/// [ "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" ]. +/// If the number of chars are less than eight, they will be repeated. Thus +/// an ASCII border could be specified as +/// [ "/", "-", "\\", "|" ], +/// or all chars the same as +/// [ "x" ]. +/// An empty string can be used to turn off a specific border, for instance, +/// [ "", "", "", ">", "", "", "", "<" ] +/// will only make vertical borders but not horizontal ones. +/// By default, `FloatBorder` highlight is used, which links to `VertSplit` +/// when not defined. It could also be specified by character: +/// [ {"+", "MyCorner"}, {"x", "MyBorder"} ]. +/// - noautocmd: If true then no buffer-related autocommand events such as +/// |BufEnter|, |BufLeave| or |BufWinEnter| may fire from +/// calling this function. +/// +/// @param[out] err Error details, if any +/// +/// @return Window handle, or 0 on error +Window nvim_open_win(Buffer buffer, Boolean enter, Dict(float_config) *config, Error *err) + FUNC_API_SINCE(6) + FUNC_API_CHECK_TEXTLOCK +{ + FloatConfig fconfig = FLOAT_CONFIG_INIT; + if (!parse_float_config(config, &fconfig, false, true, err)) { + return 0; + } + win_T *wp = win_new_float(NULL, fconfig, err); + if (!wp) { + return 0; + } + if (enter) { + win_enter(wp, false); + } + // autocmds in win_enter or win_set_buf below may close the window + if (win_valid(wp) && buffer > 0) { + win_set_buf(wp->handle, buffer, fconfig.noautocmd, err); + } + if (!win_valid(wp)) { + api_set_error(err, kErrorTypeException, "Window was closed immediately"); + return 0; + } + + if (fconfig.style == kWinStyleMinimal) { + win_set_minimal_style(wp); + didset_window_options(wp); + } + return wp->handle; +} + +/// Configures window layout. Currently only for floating and external windows +/// (including changing a split window to those layouts). +/// +/// When reconfiguring a floating window, absent option keys will not be +/// changed. `row`/`col` and `relative` must be reconfigured together. +/// +/// @see |nvim_open_win()| +/// +/// @param window Window handle, or 0 for current window +/// @param config Map defining the window configuration, +/// see |nvim_open_win()| +/// @param[out] err Error details, if any +void nvim_win_set_config(Window window, Dict(float_config) *config, Error *err) + FUNC_API_SINCE(6) +{ + win_T *win = find_window_by_handle(window, err); + if (!win) { + return; + } + bool new_float = !win->w_floating; + // reuse old values, if not overridden + FloatConfig fconfig = new_float ? FLOAT_CONFIG_INIT : win->w_float_config; + + if (!parse_float_config(config, &fconfig, !new_float, false, err)) { + return; + } + if (new_float) { + if (!win_new_float(win, fconfig, err)) { + return; + } + redraw_later(win, NOT_VALID); + } else { + win_config_float(win, fconfig); + win->w_pos_changed = true; + } + if (fconfig.style == kWinStyleMinimal) { + win_set_minimal_style(win); + didset_window_options(win); + } +} + +/// Gets window configuration. +/// +/// The returned value may be given to |nvim_open_win()|. +/// +/// `relative` is empty for normal windows. +/// +/// @param window Window handle, or 0 for current window +/// @param[out] err Error details, if any +/// @return Map defining the window configuration, see |nvim_open_win()| +Dictionary nvim_win_get_config(Window window, Error *err) + FUNC_API_SINCE(6) +{ + Dictionary rv = ARRAY_DICT_INIT; + + win_T *wp = find_window_by_handle(window, err); + if (!wp) { + return rv; + } + + FloatConfig *config = &wp->w_float_config; + + PUT(rv, "focusable", BOOLEAN_OBJ(config->focusable)); + PUT(rv, "external", BOOLEAN_OBJ(config->external)); + + if (wp->w_floating) { + PUT(rv, "width", INTEGER_OBJ(config->width)); + PUT(rv, "height", INTEGER_OBJ(config->height)); + if (!config->external) { + if (config->relative == kFloatRelativeWindow) { + PUT(rv, "win", INTEGER_OBJ(config->window)); + if (config->bufpos.lnum >= 0) { + Array pos = ARRAY_DICT_INIT; + ADD(pos, INTEGER_OBJ(config->bufpos.lnum)); + ADD(pos, INTEGER_OBJ(config->bufpos.col)); + PUT(rv, "bufpos", ARRAY_OBJ(pos)); + } + } + PUT(rv, "anchor", STRING_OBJ(cstr_to_string(float_anchor_str[config->anchor]))); + PUT(rv, "row", FLOAT_OBJ(config->row)); + PUT(rv, "col", FLOAT_OBJ(config->col)); + PUT(rv, "zindex", INTEGER_OBJ(config->zindex)); + } + if (config->border) { + Array border = ARRAY_DICT_INIT; + for (size_t i = 0; i < 8; i++) { + Array tuple = ARRAY_DICT_INIT; + + String s = cstrn_to_string((const char *)config->border_chars[i], sizeof(schar_T)); + + int hi_id = config->border_hl_ids[i]; + char_u *hi_name = syn_id2name(hi_id); + if (hi_name[0]) { + ADD(tuple, STRING_OBJ(s)); + ADD(tuple, STRING_OBJ(cstr_to_string((const char *)hi_name))); + ADD(border, ARRAY_OBJ(tuple)); + } else { + ADD(border, STRING_OBJ(s)); + } + } + PUT(rv, "border", ARRAY_OBJ(border)); + } + } + + const char *rel = (wp->w_floating && !config->external + ? float_relative_str[config->relative] : ""); + PUT(rv, "relative", STRING_OBJ(cstr_to_string(rel))); + + return rv; +} + +static bool parse_float_anchor(String anchor, FloatAnchor *out) +{ + if (anchor.size == 0) { + *out = (FloatAnchor)0; + } + char *str = anchor.data; + if (striequal(str, "NW")) { + *out = 0; // NW is the default + } else if (striequal(str, "NE")) { + *out = kFloatAnchorEast; + } else if (striequal(str, "SW")) { + *out = kFloatAnchorSouth; + } else if (striequal(str, "SE")) { + *out = kFloatAnchorSouth | kFloatAnchorEast; + } else { + return false; + } + return true; +} + +static bool parse_float_relative(String relative, FloatRelative *out) +{ + char *str = relative.data; + if (striequal(str, "editor")) { + *out = kFloatRelativeEditor; + } else if (striequal(str, "win")) { + *out = kFloatRelativeWindow; + } else if (striequal(str, "cursor")) { + *out = kFloatRelativeCursor; + } else { + return false; + } + return true; +} + +static bool parse_float_bufpos(Array bufpos, lpos_T *out) +{ + if (bufpos.size != 2 + || bufpos.items[0].type != kObjectTypeInteger + || bufpos.items[1].type != kObjectTypeInteger) { + return false; + } + out->lnum = bufpos.items[0].data.integer; + out->col = (colnr_T)bufpos.items[1].data.integer; + return true; +} + +static void parse_border_style(Object style, FloatConfig *fconfig, Error *err) +{ + struct { + const char *name; + schar_T chars[8]; + bool shadow_color; + } defaults[] = { + { "double", { "╔", "═", "╗", "║", "╝", "═", "╚", "║" }, false }, + { "single", { "┌", "─", "┐", "│", "┘", "─", "└", "│" }, false }, + { "shadow", { "", "", " ", " ", " ", " ", " ", "" }, true }, + { "rounded", { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, false }, + { "solid", { " ", " ", " ", " ", " ", " ", " ", " " }, false }, + { NULL, { { NUL } }, false }, + }; + + schar_T *chars = fconfig->border_chars; + int *hl_ids = fconfig->border_hl_ids; + + fconfig->border = true; + + if (style.type == kObjectTypeArray) { + Array arr = style.data.array; + size_t size = arr.size; + if (!size || size > 8 || (size & (size-1))) { + api_set_error(err, kErrorTypeValidation, + "invalid number of border chars"); + return; + } + for (size_t i = 0; i < size; i++) { + Object iytem = arr.items[i]; + String string; + int hl_id = 0; + if (iytem.type == kObjectTypeArray) { + Array iarr = iytem.data.array; + if (!iarr.size || iarr.size > 2) { + api_set_error(err, kErrorTypeValidation, "invalid border char"); + return; + } + if (iarr.items[0].type != kObjectTypeString) { + api_set_error(err, kErrorTypeValidation, "invalid border char"); + return; + } + string = iarr.items[0].data.string; + if (iarr.size == 2) { + hl_id = object_to_hl_id(iarr.items[1], "border char highlight", err); + if (ERROR_SET(err)) { + return; + } + } + } else if (iytem.type == kObjectTypeString) { + string = iytem.data.string; + } else { + api_set_error(err, kErrorTypeValidation, "invalid border char"); + return; + } + if (string.size + && mb_string2cells_len((char_u *)string.data, string.size) > 1) { + api_set_error(err, kErrorTypeValidation, + "border chars must be one cell"); + return; + } + size_t len = MIN(string.size, sizeof(*chars)-1); + if (len) { + memcpy(chars[i], string.data, len); + } + chars[i][len] = NUL; + hl_ids[i] = hl_id; + } + while (size < 8) { + memcpy(chars+size, chars, sizeof(*chars) * size); + memcpy(hl_ids+size, hl_ids, sizeof(*hl_ids) * size); + size <<= 1; + } + if ((chars[7][0] && chars[1][0] && !chars[0][0]) + || (chars[1][0] && chars[3][0] && !chars[2][0]) + || (chars[3][0] && chars[5][0] && !chars[4][0]) + || (chars[5][0] && chars[7][0] && !chars[6][0])) { + api_set_error(err, kErrorTypeValidation, + "corner between used edges must be specified"); + } + } else if (style.type == kObjectTypeString) { + String str = style.data.string; + if (str.size == 0 || strequal(str.data, "none")) { + fconfig->border = false; + return; + } + for (size_t i = 0; defaults[i].name; i++) { + if (strequal(str.data, defaults[i].name)) { + memcpy(chars, defaults[i].chars, sizeof(defaults[i].chars)); + memset(hl_ids, 0, 8 * sizeof(*hl_ids)); + if (defaults[i].shadow_color) { + int hl_blend = SYN_GROUP_STATIC("FloatShadow"); + int hl_through = SYN_GROUP_STATIC("FloatShadowThrough"); + hl_ids[2] = hl_through; + hl_ids[3] = hl_blend; + hl_ids[4] = hl_blend; + hl_ids[5] = hl_blend; + hl_ids[6] = hl_through; + } + return; + } + } + api_set_error(err, kErrorTypeValidation, + "invalid border style \"%s\"", str.data); + } +} + +static bool parse_float_config(Dict(float_config) *config, FloatConfig *fconfig, bool reconf, + bool new_win, Error *err) +{ + bool has_relative = false, relative_is_win = false; + if (config->relative.type == kObjectTypeString) { + // ignore empty string, to match nvim_win_get_config + if (config->relative.data.string.size > 0) { + if (!parse_float_relative(config->relative.data.string, &fconfig->relative)) { + api_set_error(err, kErrorTypeValidation, "Invalid value of 'relative' key"); + return false; + } + + if (!(HAS_KEY(config->row) && HAS_KEY(config->col)) && !HAS_KEY(config->bufpos)) { + api_set_error(err, kErrorTypeValidation, + "'relative' requires 'row'/'col' or 'bufpos'"); + return false; + } + + has_relative = true; + fconfig->external = false; + if (fconfig->relative == kFloatRelativeWindow) { + relative_is_win = true; + fconfig->bufpos.lnum = -1; + } + } + } else if (HAS_KEY(config->relative)) { + api_set_error(err, kErrorTypeValidation, "'relative' key must be String"); + return false; + } + + if (config->anchor.type == kObjectTypeString) { + if (!parse_float_anchor(config->anchor.data.string, &fconfig->anchor)) { + api_set_error(err, kErrorTypeValidation, "Invalid value of 'anchor' key"); + return false; + } + } else if (HAS_KEY(config->anchor)) { + api_set_error(err, kErrorTypeValidation, "'anchor' key must be String"); + return false; + } + + if (HAS_KEY(config->row)) { + if (!has_relative) { + api_set_error(err, kErrorTypeValidation, "non-float cannot have 'row'"); + return false; + } else if (config->row.type == kObjectTypeInteger) { + fconfig->row = (double)config->row.data.integer; + } else if (config->row.type == kObjectTypeFloat) { + fconfig->row = config->row.data.floating; + } else { + api_set_error(err, kErrorTypeValidation, + "'row' key must be Integer or Float"); + return false; + } + } + + if (HAS_KEY(config->col)) { + if (!has_relative) { + api_set_error(err, kErrorTypeValidation, "non-float cannot have 'col'"); + return false; + } else if (config->col.type == kObjectTypeInteger) { + fconfig->col = (double)config->col.data.integer; + } else if (config->col.type == kObjectTypeFloat) { + fconfig->col = config->col.data.floating; + } else { + api_set_error(err, kErrorTypeValidation, + "'col' key must be Integer or Float"); + return false; + } + } + + if (HAS_KEY(config->bufpos)) { + if (!has_relative) { + api_set_error(err, kErrorTypeValidation, "non-float cannot have 'bufpos'"); + return false; + } else if (config->bufpos.type == kObjectTypeArray) { + if (!parse_float_bufpos(config->bufpos.data.array, &fconfig->bufpos)) { + api_set_error(err, kErrorTypeValidation, "Invalid value of 'bufpos' key"); + return false; + } + + if (!HAS_KEY(config->row)) { + fconfig->row = (fconfig->anchor & kFloatAnchorSouth) ? 0 : 1; + } + if (!HAS_KEY(config->col)) { + fconfig->col = 0; + } + } else { + api_set_error(err, kErrorTypeValidation, "'bufpos' key must be Array"); + return false; + } + } + + if (config->width.type == kObjectTypeInteger && config->width.data.integer > 0) { + fconfig->width = (int)config->width.data.integer; + } else if (HAS_KEY(config->width)) { + api_set_error(err, kErrorTypeValidation, "'width' key must be a positive Integer"); + return false; + } else if (!reconf) { + api_set_error(err, kErrorTypeValidation, "Must specify 'width'"); + return false; + } + + if (config->height.type == kObjectTypeInteger && config->height.data.integer > 0) { + fconfig->height = (int)config->height.data.integer; + } else if (HAS_KEY(config->height)) { + api_set_error(err, kErrorTypeValidation, "'height' key must be a positive Integer"); + return false; + } else if (!reconf) { + api_set_error(err, kErrorTypeValidation, "Must specify 'height'"); + return false; + } + + if (relative_is_win) { + fconfig->window = curwin->handle; + if (config->win.type == kObjectTypeInteger || config->win.type == kObjectTypeWindow) { + if (config->win.data.integer > 0) { + fconfig->window = (Window)config->win.data.integer; + } + } else if (HAS_KEY(config->win)) { + api_set_error(err, kErrorTypeValidation, "'win' key must be Integer or Window"); + return false; + } + } else { + if (HAS_KEY(config->win)) { + api_set_error(err, kErrorTypeValidation, "'win' key is only valid with relative='win'"); + return false; + } + } + + if (HAS_KEY(config->external)) { + fconfig->external = api_object_to_bool(config->external, "'external' key", false, err); + if (ERROR_SET(err)) { + return false; + } + if (has_relative && fconfig->external) { + api_set_error(err, kErrorTypeValidation, + "Only one of 'relative' and 'external' must be used"); + return false; + } + if (fconfig->external && !ui_has(kUIMultigrid)) { + api_set_error(err, kErrorTypeValidation, + "UI doesn't support external windows"); + return false; + } + } + + if (!reconf && (!has_relative && !fconfig->external)) { + api_set_error(err, kErrorTypeValidation, + "One of 'relative' and 'external' must be used"); + return false; + } + + + if (HAS_KEY(config->focusable)) { + fconfig->focusable = api_object_to_bool(config->focusable, "'focusable' key", false, err); + if (ERROR_SET(err)) { + return false; + } + } + + if (config->zindex.type == kObjectTypeInteger && config->zindex.data.integer > 0) { + fconfig->zindex = (int)config->zindex.data.integer; + } else if (HAS_KEY(config->zindex)) { + api_set_error(err, kErrorTypeValidation, "'zindex' key must be a positive Integer"); + return false; + } + + if (HAS_KEY(config->border)) { + parse_border_style(config->border, fconfig, err); + if (ERROR_SET(err)) { + return false; + } + } + + if (config->style.type == kObjectTypeString) { + if (config->style.data.string.data[0] == NUL) { + fconfig->style = kWinStyleUnused; + } else if (striequal(config->style.data.string.data, "minimal")) { + fconfig->style = kWinStyleMinimal; + } else { + api_set_error(err, kErrorTypeValidation, "Invalid value of 'style' key"); + } + } else if (HAS_KEY(config->style)) { + api_set_error(err, kErrorTypeValidation, "'style' key must be String"); + return false; + } + + if (HAS_KEY(config->noautocmd)) { + if (!new_win) { + api_set_error(err, kErrorTypeValidation, "Invalid key: 'noautocmd'"); + return false; + } + fconfig->noautocmd = api_object_to_bool(config->noautocmd, "'noautocmd' key", false, err); + if (ERROR_SET(err)) { + return false; + } + } + + return true; +} diff --git a/src/nvim/api/win_config.h b/src/nvim/api/win_config.h new file mode 100644 index 0000000000..9271c35f23 --- /dev/null +++ b/src/nvim/api/win_config.h @@ -0,0 +1,11 @@ +#ifndef NVIM_API_WIN_CONFIG_H +#define NVIM_API_WIN_CONFIG_H + +#include <stdint.h> + +#include "nvim/api/private/defs.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "api/win_config.h.generated.h" +#endif +#endif // NVIM_API_WIN_CONFIG_H diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index 99ba297111..6e68c057dc 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -373,117 +373,6 @@ Boolean nvim_win_is_valid(Window window) } -/// Configures window layout. Currently only for floating and external windows -/// (including changing a split window to those layouts). -/// -/// When reconfiguring a floating window, absent option keys will not be -/// changed. `row`/`col` and `relative` must be reconfigured together. -/// -/// @see |nvim_open_win()| -/// -/// @param window Window handle, or 0 for current window -/// @param config Map defining the window configuration, -/// see |nvim_open_win()| -/// @param[out] err Error details, if any -void nvim_win_set_config(Window window, Dictionary config, Error *err) - FUNC_API_SINCE(6) -{ - win_T *win = find_window_by_handle(window, err); - if (!win) { - return; - } - bool new_float = !win->w_floating; - // reuse old values, if not overridden - FloatConfig fconfig = new_float ? FLOAT_CONFIG_INIT : win->w_float_config; - - if (!parse_float_config(config, &fconfig, !new_float, false, err)) { - return; - } - if (new_float) { - if (!win_new_float(win, fconfig, err)) { - return; - } - redraw_later(win, NOT_VALID); - } else { - win_config_float(win, fconfig); - win->w_pos_changed = true; - } - if (fconfig.style == kWinStyleMinimal) { - win_set_minimal_style(win); - didset_window_options(win); - } -} - -/// Gets window configuration. -/// -/// The returned value may be given to |nvim_open_win()|. -/// -/// `relative` is empty for normal windows. -/// -/// @param window Window handle, or 0 for current window -/// @param[out] err Error details, if any -/// @return Map defining the window configuration, see |nvim_open_win()| -Dictionary nvim_win_get_config(Window window, Error *err) - FUNC_API_SINCE(6) -{ - Dictionary rv = ARRAY_DICT_INIT; - - win_T *wp = find_window_by_handle(window, err); - if (!wp) { - return rv; - } - - FloatConfig *config = &wp->w_float_config; - - PUT(rv, "focusable", BOOLEAN_OBJ(config->focusable)); - PUT(rv, "external", BOOLEAN_OBJ(config->external)); - - if (wp->w_floating) { - PUT(rv, "width", INTEGER_OBJ(config->width)); - PUT(rv, "height", INTEGER_OBJ(config->height)); - if (!config->external) { - if (config->relative == kFloatRelativeWindow) { - PUT(rv, "win", INTEGER_OBJ(config->window)); - if (config->bufpos.lnum >= 0) { - Array pos = ARRAY_DICT_INIT; - ADD(pos, INTEGER_OBJ(config->bufpos.lnum)); - ADD(pos, INTEGER_OBJ(config->bufpos.col)); - PUT(rv, "bufpos", ARRAY_OBJ(pos)); - } - } - PUT(rv, "anchor", STRING_OBJ(cstr_to_string(float_anchor_str[config->anchor]))); - PUT(rv, "row", FLOAT_OBJ(config->row)); - PUT(rv, "col", FLOAT_OBJ(config->col)); - PUT(rv, "zindex", INTEGER_OBJ(config->zindex)); - } - if (config->border) { - Array border = ARRAY_DICT_INIT; - for (size_t i = 0; i < 8; i++) { - Array tuple = ARRAY_DICT_INIT; - - String s = cstrn_to_string((const char *)config->border_chars[i], sizeof(schar_T)); - - int hi_id = config->border_hl_ids[i]; - char_u *hi_name = syn_id2name(hi_id); - if (hi_name[0]) { - ADD(tuple, STRING_OBJ(s)); - ADD(tuple, STRING_OBJ(cstr_to_string((const char *)hi_name))); - ADD(border, ARRAY_OBJ(tuple)); - } else { - ADD(border, STRING_OBJ(s)); - } - } - PUT(rv, "border", ARRAY_OBJ(border)); - } - } - - const char *rel = (wp->w_floating && !config->external - ? float_relative_str[config->relative] : ""); - PUT(rv, "relative", STRING_OBJ(cstr_to_string(rel))); - - return rv; -} - /// Closes the window and hide the buffer it contains (like |:hide| with a /// |window-ID|). /// diff --git a/src/nvim/arabic.h b/src/nvim/arabic.h index 7ea728ed47..eaab463777 100644 --- a/src/nvim/arabic.h +++ b/src/nvim/arabic.h @@ -6,8 +6,8 @@ /// Whether c belongs to the range of Arabic characters that might be shaped. static inline bool arabic_char(int c) { - // return c >= a_HAMZA && c <= a_MINI_ALEF; - return c >= 0x0621 && c <= 0x0670; + // return c >= a_HAMZA && c <= a_MINI_ALEF; + return c >= 0x0621 && c <= 0x0670; } #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/ascii.h b/src/nvim/ascii.h index 7b5e82cd3f..44ed94d2fc 100644 --- a/src/nvim/ascii.h +++ b/src/nvim/ascii.h @@ -3,8 +3,8 @@ #include <stdbool.h> -#include "nvim/macros.h" #include "nvim/func_attr.h" +#include "nvim/macros.h" #include "nvim/os/os_defs.h" // Definitions of various common control characters. diff --git a/src/nvim/assert.h b/src/nvim/assert.h index 1361879876..fc1a4be164 100644 --- a/src/nvim/assert.h +++ b/src/nvim/assert.h @@ -49,11 +49,11 @@ #define STATIC_ASSERT_PRAGMA_START #define STATIC_ASSERT_PRAGMA_END #define STATIC_ASSERT(cond, msg) \ - do { \ - STATIC_ASSERT_PRAGMA_START \ - STATIC_ASSERT_STATEMENT(cond, msg); \ - STATIC_ASSERT_PRAGMA_END \ - } while (0) + do { \ + STATIC_ASSERT_PRAGMA_START \ + STATIC_ASSERT_STATEMENT(cond, msg); \ + STATIC_ASSERT_PRAGMA_END \ + } while (0) // the easiest case, when the mode is C11 (generic compiler) or Clang // advertises explicit support for c_static_assert, meaning it won't warn. @@ -68,19 +68,19 @@ # undef STATIC_ASSERT_PRAGMA_START -#if __GNUC__ >= 6 -# define STATIC_ASSERT_PRAGMA_START \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wpedantic\"") -#else -# define STATIC_ASSERT_PRAGMA_START \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-pedantic\"") -#endif +# if __GNUC__ >= 6 +# define STATIC_ASSERT_PRAGMA_START \ + _Pragma("GCC diagnostic push")\ + _Pragma("GCC diagnostic ignored \"-Wpedantic\"") +# else +# define STATIC_ASSERT_PRAGMA_START \ + _Pragma("GCC diagnostic push")\ + _Pragma("GCC diagnostic ignored \"-pedantic\"") +# endif # undef STATIC_ASSERT_PRAGMA_END # define STATIC_ASSERT_PRAGMA_END \ - _Pragma("GCC diagnostic pop") + _Pragma("GCC diagnostic pop") // the same goes for clang in C99 mode, but we suppress a different warning #elif defined(__clang__) && __has_extension(c_static_assert) @@ -89,12 +89,12 @@ # undef STATIC_ASSERT_PRAGMA_START # define STATIC_ASSERT_PRAGMA_START \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wc11-extensions\"") + _Pragma("clang diagnostic push")\ + _Pragma("clang diagnostic ignored \"-Wc11-extensions\"") # undef STATIC_ASSERT_PRAGMA_END # define STATIC_ASSERT_PRAGMA_END \ - _Pragma("clang diagnostic pop") + _Pragma("clang diagnostic pop") // TODO(aktau): verify that this works, don't have MSVC on hand. #elif _MSC_VER >= 1600 @@ -113,14 +113,14 @@ // These can't be used after statements in c89. #ifdef __COUNTER__ # define STATIC_ASSERT_EXPR(e, m) \ - ((enum { ASSERT_CONCAT(static_assert_, __COUNTER__) = 1/(!!(e)) }) 0) + ((enum { ASSERT_CONCAT(static_assert_, __COUNTER__) = 1/(!!(e)) }) 0) #else // This can't be used twice on the same line so ensure if using in headers // that the headers are not included twice (by wrapping in #ifndef...#endif) // Note it doesn't cause an issue when used on same line of separate modules // compiled with gcc -combine -fwhole-program. # define STATIC_ASSERT_EXPR(e, m) \ - ((enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }) 0) + ((enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }) 0) #endif /// @def STRICT_ADD diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 4c502b53d4..d991b88131 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -24,8 +24,8 @@ #include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -#include "auevents_name_map.generated.h" -#include "autocmd.c.generated.h" +# include "auevents_name_map.generated.h" +# include "autocmd.c.generated.h" #endif // @@ -199,7 +199,7 @@ static void au_cleanup(void) } // Loop over all events. - for (event = (event_T)0; (int)event < (int)NUM_EVENTS; + for (event = (event_T)0; (int)event < NUM_EVENTS; event = (event_T)((int)event + 1)) { // Loop over all autocommand patterns. prev_ap = &(first_autopat[(int)event]); @@ -266,7 +266,7 @@ void aubuflocal_remove(buf_T *buf) } // invalidate buflocals looping through events - for (event = (event_T)0; (int)event < (int)NUM_EVENTS; + for (event = (event_T)0; (int)event < NUM_EVENTS; event = (event_T)((int)event + 1)) { // loop over all autocommand patterns for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) { @@ -321,7 +321,7 @@ static void au_del_group(char_u *name) AutoPat *ap; int in_use = false; - for (event = (event_T)0; (int)event < (int)NUM_EVENTS; + for (event = (event_T)0; (int)event < NUM_EVENTS; event = (event_T)((int)event + 1)) { for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) { if (ap->group == i && ap->pat != NULL) { @@ -475,7 +475,7 @@ static char_u *find_end_event(char_u *arg, int have_group) pat = arg + 1; } else { for (pat = arg; *pat && *pat != '|' && !ascii_iswhite(*pat); pat = p) { - if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS) { + if ((int)event_name2nr(pat, &p) >= NUM_EVENTS) { if (have_group) { EMSG2(_("E216: No such event: %s"), pat); } else { @@ -701,7 +701,7 @@ void do_autocmd(char_u *arg_in, int forceit) if (!forceit && *cmd != NUL) { EMSG(_(e_cannot_define_autocommands_for_all_events)); } else { - for (event_T event = (event_T)0; event < (int)NUM_EVENTS; + for (event_T event = (event_T)0; event < NUM_EVENTS; event = (event_T)(event + 1)) { if (do_autocmd_event(event, pat, once, nested, cmd, forceit, group) == FAIL) { @@ -956,10 +956,11 @@ static int do_autocmd_event(event_T event, char_u *pat, bool once, int nested, c return OK; } -// Implementation of ":doautocmd [group] event [fname]". -// Return OK for success, FAIL for failure; -int do_doautocmd(char_u *arg, bool do_msg, // give message for no matching autocmds? - bool *did_something) +/// Implementation of ":doautocmd [group] event [fname]". +/// Return OK for success, FAIL for failure; +/// +/// @param do_msg give message for no matching autocmds? +int do_doautocmd(char_u *arg, bool do_msg, bool *did_something) { char_u *fname; int nothing_done = true; @@ -1916,8 +1917,8 @@ char_u *get_augroup_name(expand_T *xp, int idx) return (char_u *)AUGROUP_NAME(idx); } -char_u *set_context_in_autocmd(expand_T *xp, char_u *arg, int doautocmd // true for :doauto*, false for :autocmd - ) +/// @param doautocmd true for :doauto*, false for :autocmd +char_u *set_context_in_autocmd(expand_T *xp, char_u *arg, int doautocmd) { char_u *p; int group; diff --git a/src/nvim/autocmd.h b/src/nvim/autocmd.h index 1c0f88f08f..ac12e2acf3 100644 --- a/src/nvim/autocmd.h +++ b/src/nvim/autocmd.h @@ -17,22 +17,22 @@ typedef struct { } aco_save_T; typedef struct AutoCmd { - char_u *cmd; // Command to be executed (NULL when - // command has been removed) + char_u *cmd; // Command to be executed (NULL when + // command has been removed) bool once; // "One shot": removed after execution bool nested; // If autocommands nest here bool last; // last command in list sctx_T script_ctx; // script context where defined - struct AutoCmd *next; // Next AutoCmd in list + struct AutoCmd *next; // Next AutoCmd in list } AutoCmd; typedef struct AutoPat { - struct AutoPat *next; // next AutoPat in AutoPat list; MUST - // be the first entry - char_u *pat; // pattern as typed (NULL when pattern - // has been removed) - regprog_T *reg_prog; // compiled regprog for pattern - AutoCmd *cmds; // list of commands to do + struct AutoPat *next; // next AutoPat in AutoPat list; MUST + // be the first entry + char_u *pat; // pattern as typed (NULL when pattern + // has been removed) + regprog_T *reg_prog; // compiled regprog for pattern + AutoCmd *cmds; // list of commands to do int group; // group ID int patlen; // strlen() of pat int buflocal_nr; // !=0 for buffer-local AutoPat @@ -48,16 +48,16 @@ typedef struct AutoPat { /// Struct used to keep status while executing autocommands for an event. /// typedef struct AutoPatCmd { - AutoPat *curpat; // next AutoPat to examine - AutoCmd *nextcmd; // next AutoCmd to execute + AutoPat *curpat; // next AutoPat to examine + AutoCmd *nextcmd; // next AutoCmd to execute int group; // group being used - char_u *fname; // fname to match with - char_u *sfname; // sfname to match with - char_u *tail; // tail of fname + char_u *fname; // fname to match with + char_u *sfname; // sfname to match with + char_u *tail; // tail of fname event_T event; // current event int arg_bufnr; // initially equal to <abuf>, set to zero when // buf is deleted - struct AutoPatCmd *next; // chain of active apc-s for auto-invalidation + struct AutoPatCmd *next; // chain of active apc-s for auto-invalidation } AutoPatCmd; diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 1893bdba0c..826a197454 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -65,6 +65,7 @@ #include "nvim/os/time.h" #include "nvim/os_unix.h" #include "nvim/path.h" +#include "nvim/plines.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" #include "nvim/screen.h" @@ -98,13 +99,15 @@ typedef enum { kBffInitChangedtick = 2, } BufFreeFlags; -// Read data from buffer for retrying. -static int read_buffer(int read_stdin, // read file from stdin, otherwise fifo - exarg_T *eap, // for forced 'ff' and 'fenc' or NULL - int flags) // extra flags for readfile() +/// Read data from buffer for retrying. +/// +/// @param read_stdin read file from stdin, otherwise fifo +/// @param eap for forced 'ff' and 'fenc' or NULL +/// @param flags extra flags for readfile() +static int read_buffer(int read_stdin, exarg_T *eap, int flags) { - int retval = OK; - linenr_T line_count; + int retval = OK; + linenr_T line_count; // // Read from the buffer which the text is already filled in and append at @@ -114,7 +117,7 @@ static int read_buffer(int read_stdin, // read file from stdin, otherwis line_count = curbuf->b_ml.ml_line_count; retval = readfile(read_stdin ? NULL : curbuf->b_ffname, read_stdin ? NULL : curbuf->b_fname, - (linenr_T)line_count, (linenr_T)0, (linenr_T)MAXLNUM, eap, + line_count, (linenr_T)0, (linenr_T)MAXLNUM, eap, flags | READ_BUFFER); if (retval == OK) { // Delete the binary lines. @@ -146,16 +149,18 @@ static int read_buffer(int read_stdin, // read file from stdin, otherwis return retval; } -// Open current buffer, that is: open the memfile and read the file into -// memory. -// Return FAIL for failure, OK otherwise. -int open_buffer(int read_stdin, // read file from stdin - exarg_T *eap, // for forced 'ff' and 'fenc' or NULL - int flags // extra flags for readfile() - ) +/// Open current buffer, that is: open the memfile and read the file into +/// memory. +/// +/// @param read_stdin read file from stdin +/// @param eap for forced 'ff' and 'fenc' or NULL +/// @param flags extra flags for readfile() +/// +/// @return FAIL for failure, OK otherwise. +int open_buffer(int read_stdin, exarg_T *eap, int flags) { int retval = OK; - bufref_T old_curbuf; + bufref_T old_curbuf; long old_tw = curbuf->b_p_tw; int read_fifo = false; @@ -521,8 +526,8 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last) diff_buf_delete(buf); // Clear 'diff' for hidden buffer. } - /* Return when a window is displaying the buffer or when it's not - * unloaded. */ + // Return when a window is displaying the buffer or when it's not + // unloaded. if (buf->b_nwindows > 0 || !unload_buf) { return false; } @@ -588,9 +593,6 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last) buf->b_nwindows--; } - // Change directories when the 'acd' option is set. - do_autochdir(); - // Disable buffer-updates for the current buffer. // No need to check `unload_buf`: in that case the function returned above. buf_updates_unload(buf, false); @@ -816,6 +818,7 @@ static void free_buffer_stuff(buf_T *buf, int free_flags) uc_clear(&buf->b_ucmds); // clear local user commands buf_delete_signs(buf, (char_u *)"*"); // delete any signs extmark_free_all(buf); // delete any extmarks + clear_virt_lines(buf, -1); map_clear_int(buf, MAP_ALL_MODES, true, false); // clear local mappings map_clear_int(buf, MAP_ALL_MODES, true, true); // clear local abbrevs XFREE_CLEAR(buf->b_start_fenc); @@ -939,23 +942,22 @@ void handle_swap_exists(bufref_T *old_curbuf) swap_exists_action = SEA_NONE; // -V519 } -/* - * do_bufdel() - delete or unload buffer(s) - * - * addr_count == 0: ":bdel" - delete current buffer - * addr_count == 1: ":N bdel" or ":bdel N [N ..]" - first delete - * buffer "end_bnr", then any other arguments. - * addr_count == 2: ":N,N bdel" - delete buffers in range - * - * command can be DOBUF_UNLOAD (":bunload"), DOBUF_WIPE (":bwipeout") or - * DOBUF_DEL (":bdel") - * - * Returns error message or NULL - */ -char_u *do_bufdel(int command, char_u *arg, // pointer to extra arguments - int addr_count, int start_bnr, // first buffer number in a range - int end_bnr, // buffer nr or last buffer nr in a range - int forceit) +/// do_bufdel() - delete or unload buffer(s) +/// +/// addr_count == 0: ":bdel" - delete current buffer +/// addr_count == 1: ":N bdel" or ":bdel N [N ..]" - first delete +/// buffer "end_bnr", then any other arguments. +/// addr_count == 2: ":N,N bdel" - delete buffers in range +/// +/// command can be DOBUF_UNLOAD (":bunload"), DOBUF_WIPE (":bwipeout") or +/// DOBUF_DEL (":bdel") +/// +/// @param arg pointer to extra arguments +/// @param start_bnr first buffer number in a range +/// @param end_bnr buffer nr or last buffer nr in a range +/// +/// @return error message or NULL +char_u *do_bufdel(int command, char_u *arg, int addr_count, int start_bnr, int end_bnr, int forceit) { int do_current = 0; // delete current buffer? int deleted = 0; // number of buffers deleted @@ -1097,26 +1099,26 @@ static int empty_curbuf(int close_others, int forceit, int action) return retval; } -/* - * Implementation of the commands for the buffer list. - * - * action == DOBUF_GOTO go to specified buffer - * action == DOBUF_SPLIT split window and go to specified buffer - * action == DOBUF_UNLOAD unload specified buffer(s) - * action == DOBUF_DEL delete specified buffer(s) from buffer list - * action == DOBUF_WIPE delete specified buffer(s) really - * - * start == DOBUF_CURRENT go to "count" buffer from current buffer - * start == DOBUF_FIRST go to "count" buffer from first buffer - * start == DOBUF_LAST go to "count" buffer from last buffer - * start == DOBUF_MOD go to "count" modified buffer from current buffer - * - * Return FAIL or OK. - */ -int do_buffer(int action, int start, int dir, // FORWARD or BACKWARD - int count, // buffer number or number of buffers - int forceit // true for :...! - ) + +/// Implementation of the commands for the buffer list. +/// +/// action == DOBUF_GOTO go to specified buffer +/// action == DOBUF_SPLIT split window and go to specified buffer +/// action == DOBUF_UNLOAD unload specified buffer(s) +/// action == DOBUF_DEL delete specified buffer(s) from buffer list +/// action == DOBUF_WIPE delete specified buffer(s) really +/// +/// start == DOBUF_CURRENT go to "count" buffer from current buffer +/// start == DOBUF_FIRST go to "count" buffer from first buffer +/// start == DOBUF_LAST go to "count" buffer from last buffer +/// start == DOBUF_MOD go to "count" modified buffer from current buffer +/// +/// @param dir FORWARD or BACKWARD +/// @param count buffer number or number of buffers +/// @param forceit true for :...! +/// +/// @return FAIL or OK. +int do_buffer(int action, int start, int dir, int count, int forceit) { buf_T *buf; buf_T *bp; @@ -1586,8 +1588,8 @@ void enter_buffer(buf_T *buf) apply_autocmds(EVENT_BUFWINENTER, NULL, NULL, false, curbuf); } - /* If autocommands did not change the cursor position, restore cursor lnum - * and possibly cursor col. */ + // If autocommands did not change the cursor position, restore cursor lnum + // and possibly cursor col. if (curwin->w_cursor.lnum == 1 && inindent(0)) { buflist_getfpos(); } @@ -1623,7 +1625,7 @@ void do_autochdir(void) if (p_acd) { if (starting == 0 && curbuf->b_ffname != NULL - && vim_chdirfile(curbuf->b_ffname) == OK) { + && vim_chdirfile(curbuf->b_ffname, kCdCauseAuto) == OK) { post_chdir(kCdScopeGlobal, false); shorten_fnames(true); } @@ -1749,8 +1751,8 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl if ((flags & BLN_CURBUF) && curbuf_reusable()) { assert(curbuf != NULL); buf = curbuf; - /* It's like this buffer is deleted. Watch out for autocommands that - * change curbuf! If that happens, allocate a new buffer anyway. */ + // It's like this buffer is deleted. Watch out for autocommands that + // change curbuf! If that happens, allocate a new buffer anyway. if (curbuf->b_p_bl) { apply_autocmds(EVENT_BUFDELETE, NULL, NULL, false, curbuf); } @@ -2154,11 +2156,13 @@ static buf_T *buflist_findname_file_id(char_u *ffname, FileID *file_id, bool fil /// Find file in buffer list by a regexp pattern. /// Return fnum of the found buffer. /// Return < 0 for error. -int buflist_findpat(const char_u *pattern, const char_u *pattern_end, // pointer to first char after pattern - bool unlisted, // find unlisted buffers - bool diffmode, // find diff-mode buffers only - bool curtab_only // find buffers in current tab only - ) +/// +/// @param pattern_end pointer to first char after pattern +/// @param unlisted find unlisted buffers +/// @param diffmode find diff-mode buffers only +/// @param curtab_only find buffers in current tab only +int buflist_findpat(const char_u *pattern, const char_u *pattern_end, bool unlisted, bool diffmode, + bool curtab_only) FUNC_ATTR_NONNULL_ARG(1) { int match = -1; @@ -2250,8 +2254,8 @@ int buflist_findpat(const char_u *pattern, const char_u *pattern_end, // pointe } } - /* Only search for unlisted buffers if there was no match with - * a listed buffer. */ + // Only search for unlisted buffers if there was no match with + // a listed buffer. if (!unlisted || !find_listed || match != -1) { break; } @@ -2466,14 +2470,14 @@ buf_T *buflist_findnr(int nr) return handle_get_buffer((handle_T)nr); } -/* - * Get name of file 'n' in the buffer list. - * When the file has no name an empty string is returned. - * home_replace() is used to shorten the file name (used for marks). - * Returns a pointer to allocated memory, of NULL when failed. - */ -char_u *buflist_nr2name(int n, int fullname, int helptail // for help buffers return tail only - ) +/// Get name of file 'n' in the buffer list. +/// When the file has no name an empty string is returned. +/// home_replace() is used to shorten the file name (used for marks). +/// +/// @param helptail for help buffers return tail only +/// +/// @return a pointer to allocated memory, of NULL when failed. +char_u *buflist_nr2name(int n, int fullname, int helptail) { buf_T *buf; @@ -2546,8 +2550,6 @@ void buflist_setfpos(buf_T *const buf, win_T *const win, linenr_T lnum, colnr_T if (wip->wi_next) { wip->wi_next->wi_prev = wip; } - - return; } @@ -2706,21 +2708,21 @@ void buflist_list(exarg_T *eap) const bool job_running = buf->terminal && terminal_running(buf->terminal); // skip unspecified buffers - if ((!buf->b_p_bl && !eap->forceit && !strchr((char *)eap->arg, 'u')) - || (strchr((char *)eap->arg, 'u') && buf->b_p_bl) - || (strchr((char *)eap->arg, '+') + if ((!buf->b_p_bl && !eap->forceit && !vim_strchr(eap->arg, 'u')) + || (vim_strchr(eap->arg, 'u') && buf->b_p_bl) + || (vim_strchr(eap->arg, '+') && ((buf->b_flags & BF_READERR) || !bufIsChanged(buf))) - || (strchr((char *)eap->arg, 'a') + || (vim_strchr(eap->arg, 'a') && (buf->b_ml.ml_mfp == NULL || buf->b_nwindows == 0)) - || (strchr((char *)eap->arg, 'h') + || (vim_strchr(eap->arg, 'h') && (buf->b_ml.ml_mfp == NULL || buf->b_nwindows != 0)) - || (strchr((char *)eap->arg, 'R') && (!is_terminal || !job_running)) - || (strchr((char *)eap->arg, 'F') && (!is_terminal || job_running)) - || (strchr((char *)eap->arg, '-') && buf->b_p_ma) - || (strchr((char *)eap->arg, '=') && !buf->b_p_ro) - || (strchr((char *)eap->arg, 'x') && !(buf->b_flags & BF_READERR)) - || (strchr((char *)eap->arg, '%') && buf != curbuf) - || (strchr((char *)eap->arg, '#') + || (vim_strchr(eap->arg, 'R') && (!is_terminal || !job_running)) + || (vim_strchr(eap->arg, 'F') && (!is_terminal || job_running)) + || (vim_strchr(eap->arg, '-') && buf->b_p_ma) + || (vim_strchr(eap->arg, '=') && !buf->b_p_ro) + || (vim_strchr(eap->arg, 'x') && !(buf->b_flags & BF_READERR)) + || (vim_strchr(eap->arg, '%') && buf != curbuf) + || (vim_strchr(eap->arg, '#') && (buf == curbuf || curwin->w_alt_fnum != buf->b_fnum))) { continue; } @@ -2800,13 +2802,14 @@ int buflist_name_nr(int fnum, char_u **fname, linenr_T *lnum) return OK; } -// Set the file name for "buf" to "ffname_arg", short file name to -// "sfname_arg". -// The file name with the full path is also remembered, for when :cd is used. -// Returns FAIL for failure (file name already in use by other buffer) -// OK otherwise. -int setfname(buf_T *buf, char_u *ffname_arg, char_u *sfname_arg, bool message // give message when buffer already exists - ) +/// Set the file name for "buf" to "ffname_arg", short file name to +/// "sfname_arg". +/// The file name with the full path is also remembered, for when :cd is used. +/// +/// @param message give message when buffer already exists +/// +/// @return FAIL for failure (file name already in use by other buffer) OK otherwise. +int setfname(buf_T *buf, char_u *ffname_arg, char_u *sfname_arg, bool message) { char_u *ffname = ffname_arg; char_u *sfname = sfname_arg; @@ -2887,8 +2890,8 @@ void buf_set_name(int fnum, char_u *name) xfree(buf->b_ffname); buf->b_ffname = vim_strsave(name); buf->b_sfname = NULL; - /* Allocate ffname and expand into full path. Also resolves .lnk - * files on Win32. */ + // Allocate ffname and expand into full path. Also resolves .lnk + // files on Win32. fname_expand(buf, &buf->b_ffname, &buf->b_sfname); buf->b_fname = buf->b_sfname; } @@ -2934,12 +2937,11 @@ buf_T *setaltfname(char_u *ffname, char_u *sfname, linenr_T lnum) return buf; } -/* - * Get alternate file name for current window. - * Return NULL if there isn't any, and give error message if requested. - */ -char_u * getaltfname(bool errmsg // give error message - ) +/// Get alternate file name for current window. +/// Return NULL if there isn't any, and give error message if requested. +/// +/// @param errmsg give error message +char_u *getaltfname(bool errmsg) { char_u *fname; linenr_T dummy; @@ -3078,11 +3080,10 @@ static bool buf_same_file_id(buf_T *buf, FileID *file_id) return buf->file_id_valid && os_fileid_equal(&(buf->file_id), file_id); } -/* - * Print info about the current buffer. - */ -void fileinfo(int fullname, // when non-zero print full path - int shorthelp, int dont_truncate) +/// Print info about the current buffer. +/// +/// @param fullname when non-zero print full path +void fileinfo(int fullname, int shorthelp, int dont_truncate) { char_u *name; int n; @@ -3112,12 +3113,13 @@ void fileinfo(int fullname, // when non-zero print full path (size_t)(IOSIZE - (p - buffer)), true); } + bool dontwrite = bt_dontwrite(curbuf); vim_snprintf_add((char *)buffer, IOSIZE, "\"%s%s%s%s%s%s", curbufIsChanged() ? (shortmess(SHM_MOD) ? " [+]" : _(" [Modified]")) : " ", - (curbuf->b_flags & BF_NOTEDITED) && !bt_dontwrite(curbuf) + (curbuf->b_flags & BF_NOTEDITED) && !dontwrite ? _("[Not edited]") : "", - (curbuf->b_flags & BF_NEW) && !bt_dontwrite(curbuf) + (curbuf->b_flags & BF_NEW) && !dontwrite ? new_file_message() : "", (curbuf->b_flags & BF_READERR) ? _("[Read errors]") : "", @@ -3161,8 +3163,8 @@ void fileinfo(int fullname, // when non-zero print full path (void)append_arg_number(curwin, buffer, IOSIZE, !shortmess(SHM_FILE)); if (dont_truncate) { - /* Temporarily set msg_scroll to avoid the message being truncated. - * First call msg_start() to get the message in the right place. */ + // Temporarily set msg_scroll to avoid the message being truncated. + // First call msg_start() to get the message in the right place. msg_start(); n = msg_scroll; msg_scroll = true; @@ -3230,7 +3232,7 @@ void maketitle(void) int use_sandbox = false; int save_called_emsg = called_emsg; - use_sandbox = was_set_insecurely(curwin, (char_u *)"titlestring", 0); + use_sandbox = was_set_insecurely(curwin, "titlestring", 0); called_emsg = false; build_stl_str_hl(curwin, (char_u *)buf, sizeof(buf), p_titlestring, use_sandbox, @@ -3257,7 +3259,7 @@ void maketitle(void) buf_p += MIN(size, SPACE_FOR_FNAME); } else { buf_p += transstr_buf((const char *)path_tail(curbuf->b_fname), - buf_p, SPACE_FOR_FNAME + 1); + buf_p, SPACE_FOR_FNAME + 1, true); } switch (bufIsChanged(curbuf) @@ -3306,7 +3308,7 @@ void maketitle(void) // room for the server name. When there is no room (very long // file name) use (...). if ((size_t)(buf_p - buf) < SPACE_FOR_DIR) { - char *const tbuf = transstr(buf_p); + char *const tbuf = transstr(buf_p, true); const size_t free_space = SPACE_FOR_DIR - (size_t)(buf_p - buf) + 1; const size_t dir_len = xstrlcpy(buf_p, tbuf, free_space); buf_p += MIN(dir_len, free_space - 1); @@ -3348,7 +3350,7 @@ void maketitle(void) int use_sandbox = false; int save_called_emsg = called_emsg; - use_sandbox = was_set_insecurely(curwin, (char_u *)"iconstring", 0); + use_sandbox = was_set_insecurely(curwin, "iconstring", 0); called_emsg = false; build_stl_str_hl(curwin, icon_str, sizeof(buf), p_iconstring, use_sandbox, @@ -3422,14 +3424,14 @@ void resettitle(void) ui_flush(); } -# if defined(EXITFREE) +#if defined(EXITFREE) void free_titles(void) { xfree(lasttitle); xfree(lasticon); } -# endif +#endif /// Enumeration specifying the valid numeric bases that can /// be used when printing numbers in the status line. @@ -4652,7 +4654,7 @@ void get_rel_pos(win_T *wp, char_u *buf, int buflen) long below; // number of lines below window above = wp->w_topline - 1; - above += diff_check_fill(wp, wp->w_topline) - wp->w_topfill; + above += win_get_fill(wp, wp->w_topline) - wp->w_topfill; if (wp->w_topline == 1 && wp->w_topfill >= 1) { // All buffer lines are displayed and there is an indication // of filler lines, that can be considered seeing all lines. @@ -4750,12 +4752,11 @@ char_u *alist_name(aentry_T *aep) return bp->b_fname; } -/* - * do_arg_all(): Open up to 'count' windows, one for each argument. - */ -void do_arg_all(int count, int forceit, // hide buffers in current windows - int keep_tabs // keep current tabs, for ":tab drop file" - ) +/// do_arg_all(): Open up to 'count' windows, one for each argument. +/// +/// @param forceit hide buffers in current windows +/// @param keep_tabs keep current tabs, for ":tab drop file" +void do_arg_all(int count, int forceit, int keep_tabs) { char_u *opened; // Array of weight for which args are open: // 0: not opened @@ -5229,8 +5230,8 @@ void do_modelines(int flags) return; } - /* Disallow recursive entry here. Can happen when executing a modeline - * triggers an autocommand, which reloads modelines with a ":do". */ + // Disallow recursive entry here. Can happen when executing a modeline + // triggers an autocommand, which reloads modelines with a ":do". if (entered) { return; } @@ -5253,12 +5254,11 @@ void do_modelines(int flags) entered--; } -/* - * chk_modeline() - check a single line for a mode string - * Return FAIL if an error encountered. - */ -static int chk_modeline(linenr_T lnum, int flags // Same as for do_modelines(). - ) +/// chk_modeline() - check a single line for a mode string +/// Return FAIL if an error encountered. +/// +/// @param flags Same as for do_modelines(). +static int chk_modeline(linenr_T lnum, int flags) { char_u *s; char_u *e; @@ -5630,13 +5630,12 @@ bool buf_contents_changed(buf_T *buf) return differ; } -/* - * Wipe out a buffer and decrement the last buffer number if it was used for - * this buffer. Call this to wipe out a temp buffer that does not contain any - * marks. - */ -void wipe_buffer(buf_T *buf, bool aucmd // When true trigger autocommands. - ) +/// Wipe out a buffer and decrement the last buffer number if it was used for +/// this buffer. Call this to wipe out a temp buffer that does not contain any +/// marks. +/// +/// @param aucmd When true trigger autocommands. +void wipe_buffer(buf_T *buf, bool aucmd) { if (!aucmd) { // Don't trigger BufDelete autocommands here. diff --git a/src/nvim/buffer.h b/src/nvim/buffer.h index 02a2ac36f7..0484c8550d 100644 --- a/src/nvim/buffer.h +++ b/src/nvim/buffer.h @@ -1,21 +1,21 @@ #ifndef NVIM_BUFFER_H #define NVIM_BUFFER_H -#include "nvim/vim.h" -#include "nvim/window.h" -#include "nvim/pos.h" // for linenr_T +#include "nvim/eval.h" #include "nvim/ex_cmds_defs.h" // for exarg_T -#include "nvim/screen.h" // for StlClickRecord #include "nvim/func_attr.h" -#include "nvim/eval.h" #include "nvim/macros.h" #include "nvim/memline.h" +#include "nvim/pos.h" // for linenr_T +#include "nvim/screen.h" // for StlClickRecord +#include "nvim/vim.h" +#include "nvim/window.h" // Values for buflist_getfile() enum getf_values { - GETF_SETMARK = 0x01, // set pcmark before jumping - GETF_ALT = 0x02, // jumping to alternate file (not buf num) - GETF_SWITCH = 0x04, // respect 'switchbuf' settings when jumping + GETF_SETMARK = 0x01, // set pcmark before jumping + GETF_ALT = 0x02, // jumping to alternate file (not buf num) + GETF_SWITCH = 0x04, // respect 'switchbuf' settings when jumping }; // Return values of getfile() @@ -41,26 +41,26 @@ enum bln_values { // Values for action argument for do_buffer() enum dobuf_action_values { - DOBUF_GOTO = 0, // go to specified buffer - DOBUF_SPLIT = 1, // split window and go to specified buffer - DOBUF_UNLOAD = 2, // unload specified buffer(s) - DOBUF_DEL = 3, // delete specified buffer(s) from buflist - DOBUF_WIPE = 4, // delete specified buffer(s) really + DOBUF_GOTO = 0, // go to specified buffer + DOBUF_SPLIT = 1, // split window and go to specified buffer + DOBUF_UNLOAD = 2, // unload specified buffer(s) + DOBUF_DEL = 3, // delete specified buffer(s) from buflist + DOBUF_WIPE = 4, // delete specified buffer(s) really }; // Values for start argument for do_buffer() enum dobuf_start_values { - DOBUF_CURRENT = 0, // "count" buffer from current buffer - DOBUF_FIRST = 1, // "count" buffer from first buffer - DOBUF_LAST = 2, // "count" buffer from last buffer - DOBUF_MOD = 3, // "count" mod. buffer from current buffer + DOBUF_CURRENT = 0, // "count" buffer from current buffer + DOBUF_FIRST = 1, // "count" buffer from first buffer + DOBUF_LAST = 2, // "count" buffer from last buffer + DOBUF_MOD = 3, // "count" mod. buffer from current buffer }; // flags for buf_freeall() enum bfa_values { - BFA_DEL = 1, // buffer is going to be deleted - BFA_WIPE = 2, // buffer is going to be wiped out - BFA_KEEP_UNDO = 4, // do not free undo information + BFA_DEL = 1, // buffer is going to be deleted + BFA_WIPE = 2, // buffer is going to be wiped out + BFA_KEEP_UNDO = 4, // do not free undo information }; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -75,14 +75,12 @@ static inline void buf_set_changedtick(buf_T *const buf, /// /// @param[out] buf Buffer to set changedtick in. /// @param[in] changedtick New value. -static inline void buf_set_changedtick(buf_T *const buf, - const varnumber_T changedtick) +static inline void buf_set_changedtick(buf_T *const buf, const varnumber_T changedtick) { typval_T old_val = buf->changedtick_di.di_tv; #ifndef NDEBUG - dictitem_T *const changedtick_di = tv_dict_find( - buf->b_vars, S_LEN("changedtick")); + dictitem_T *const changedtick_di = tv_dict_find(buf->b_vars, S_LEN("changedtick")); assert(changedtick_di != NULL); assert(changedtick_di->di_tv.v_type == VAR_NUMBER); assert(changedtick_di->di_tv.v_lock == VAR_FIXED); @@ -132,7 +130,7 @@ static inline void buf_inc_changedtick(buf_T *const buf) static inline bool buf_is_empty(buf_T *buf) { return buf->b_ml.ml_line_count == 1 - && *ml_get_buf(buf, (linenr_T)1, false) == '\0'; + && *ml_get_buf(buf, (linenr_T)1, false) == '\0'; } #endif // NVIM_BUFFER_H diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index ba2bcd7223..19b0a3c5c6 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -6,14 +6,14 @@ // for FILE #include <stdio.h> -typedef struct file_buffer buf_T; // Forward declaration +typedef struct file_buffer buf_T; // Forward declaration // Reference to a buffer that stores the value of buf_free_count. // bufref_valid() only needs to check "buf" when the count differs. typedef struct { buf_T *br_buf; - int br_fnum; - int br_buf_free_count; + int br_fnum; + int br_buf_free_count; } bufref_T; // for garray_T @@ -111,16 +111,15 @@ typedef uint16_t disptick_T; // display tick type // for synstate_T (needs reg_extmatch_T, win_T, buf_T) #include "nvim/syntax_defs.h" // for sign_entry_T -#include "nvim/sign_defs.h" - #include "nvim/os/fs_defs.h" // for FileID +#include "nvim/sign_defs.h" #include "nvim/terminal.h" // for Terminal /* * The taggy struct is used to store the information about a :tag command. */ typedef struct taggy { - char_u *tagname; // tag name + char_u *tagname; // tag name fmark_T fmark; // cursor position BEFORE ":tag" int cur_match; // match number int cur_fnum; // buffer number used for cur_match @@ -161,45 +160,45 @@ typedef struct */ typedef struct { int wo_arab; -# define w_p_arab w_onebuf_opt.wo_arab // 'arabic' +#define w_p_arab w_onebuf_opt.wo_arab // 'arabic' int wo_bri; -# define w_p_bri w_onebuf_opt.wo_bri // 'breakindent' +#define w_p_bri w_onebuf_opt.wo_bri // 'breakindent' char_u *wo_briopt; -# define w_p_briopt w_onebuf_opt.wo_briopt // 'breakindentopt' +#define w_p_briopt w_onebuf_opt.wo_briopt // 'breakindentopt' int wo_diff; -# define w_p_diff w_onebuf_opt.wo_diff // 'diff' +#define w_p_diff w_onebuf_opt.wo_diff // 'diff' char_u *wo_fdc; -# define w_p_fdc w_onebuf_opt.wo_fdc // 'foldcolumn' +#define w_p_fdc w_onebuf_opt.wo_fdc // 'foldcolumn' char_u *wo_fdc_save; -# define w_p_fdc_save w_onebuf_opt.wo_fdc_save // 'fdc' saved for diff mode +#define w_p_fdc_save w_onebuf_opt.wo_fdc_save // 'fdc' saved for diff mode int wo_fen; -# define w_p_fen w_onebuf_opt.wo_fen // 'foldenable' +#define w_p_fen w_onebuf_opt.wo_fen // 'foldenable' int wo_fen_save; // 'foldenable' saved for diff mode -# define w_p_fen_save w_onebuf_opt.wo_fen_save - char_u *wo_fdi; -# define w_p_fdi w_onebuf_opt.wo_fdi // 'foldignore' +#define w_p_fen_save w_onebuf_opt.wo_fen_save + char_u *wo_fdi; +#define w_p_fdi w_onebuf_opt.wo_fdi // 'foldignore' long wo_fdl; -# define w_p_fdl w_onebuf_opt.wo_fdl // 'foldlevel' +#define w_p_fdl w_onebuf_opt.wo_fdl // 'foldlevel' int wo_fdl_save; // 'foldlevel' state saved for diff mode -# define w_p_fdl_save w_onebuf_opt.wo_fdl_save - char_u *wo_fdm; -# define w_p_fdm w_onebuf_opt.wo_fdm // 'foldmethod' - char_u *wo_fdm_save; -# define w_p_fdm_save w_onebuf_opt.wo_fdm_save // 'fdm' saved for diff mode +#define w_p_fdl_save w_onebuf_opt.wo_fdl_save + char_u *wo_fdm; +#define w_p_fdm w_onebuf_opt.wo_fdm // 'foldmethod' + char_u *wo_fdm_save; +#define w_p_fdm_save w_onebuf_opt.wo_fdm_save // 'fdm' saved for diff mode long wo_fml; -# define w_p_fml w_onebuf_opt.wo_fml // 'foldminlines' +#define w_p_fml w_onebuf_opt.wo_fml // 'foldminlines' long wo_fdn; -# define w_p_fdn w_onebuf_opt.wo_fdn // 'foldnestmax' - char_u *wo_fde; -# define w_p_fde w_onebuf_opt.wo_fde // 'foldexpr' - char_u *wo_fdt; -# define w_p_fdt w_onebuf_opt.wo_fdt // 'foldtext' - char_u *wo_fmr; -# define w_p_fmr w_onebuf_opt.wo_fmr // 'foldmarker' +#define w_p_fdn w_onebuf_opt.wo_fdn // 'foldnestmax' + char_u *wo_fde; +#define w_p_fde w_onebuf_opt.wo_fde // 'foldexpr' + char_u *wo_fdt; +#define w_p_fdt w_onebuf_opt.wo_fdt // 'foldtext' + char_u *wo_fmr; +#define w_p_fmr w_onebuf_opt.wo_fmr // 'foldmarker' int wo_lbr; -# define w_p_lbr w_onebuf_opt.wo_lbr // 'linebreak' +#define w_p_lbr w_onebuf_opt.wo_lbr // 'linebreak' int wo_list; #define w_p_list w_onebuf_opt.wo_list // 'list' int wo_nu; @@ -207,64 +206,64 @@ typedef struct { int wo_rnu; #define w_p_rnu w_onebuf_opt.wo_rnu // 'relativenumber' long wo_nuw; -# define w_p_nuw w_onebuf_opt.wo_nuw // 'numberwidth' +#define w_p_nuw w_onebuf_opt.wo_nuw // 'numberwidth' int wo_wfh; -# define w_p_wfh w_onebuf_opt.wo_wfh // 'winfixheight' +#define w_p_wfh w_onebuf_opt.wo_wfh // 'winfixheight' int wo_wfw; -# define w_p_wfw w_onebuf_opt.wo_wfw // 'winfixwidth' +#define w_p_wfw w_onebuf_opt.wo_wfw // 'winfixwidth' int wo_pvw; -# define w_p_pvw w_onebuf_opt.wo_pvw // 'previewwindow' +#define w_p_pvw w_onebuf_opt.wo_pvw // 'previewwindow' int wo_rl; -# define w_p_rl w_onebuf_opt.wo_rl // 'rightleft' - char_u *wo_rlc; -# define w_p_rlc w_onebuf_opt.wo_rlc // 'rightleftcmd' +#define w_p_rl w_onebuf_opt.wo_rl // 'rightleft' + char_u *wo_rlc; +#define w_p_rlc w_onebuf_opt.wo_rlc // 'rightleftcmd' long wo_scr; #define w_p_scr w_onebuf_opt.wo_scr // 'scroll' int wo_spell; -# define w_p_spell w_onebuf_opt.wo_spell // 'spell' +#define w_p_spell w_onebuf_opt.wo_spell // 'spell' int wo_cuc; -# define w_p_cuc w_onebuf_opt.wo_cuc // 'cursorcolumn' +#define w_p_cuc w_onebuf_opt.wo_cuc // 'cursorcolumn' int wo_cul; -# define w_p_cul w_onebuf_opt.wo_cul // 'cursorline' - char_u *wo_culopt; -# define w_p_culopt w_onebuf_opt.wo_culopt // 'cursorlineopt' - char_u *wo_cc; -# define w_p_cc w_onebuf_opt.wo_cc // 'colorcolumn' - char_u *wo_sbr; -# define w_p_sbr w_onebuf_opt.wo_sbr // 'showbreak' - char_u *wo_stl; +#define w_p_cul w_onebuf_opt.wo_cul // 'cursorline' + char_u *wo_culopt; +#define w_p_culopt w_onebuf_opt.wo_culopt // 'cursorlineopt' + char_u *wo_cc; +#define w_p_cc w_onebuf_opt.wo_cc // 'colorcolumn' + char_u *wo_sbr; +#define w_p_sbr w_onebuf_opt.wo_sbr // 'showbreak' + char_u *wo_stl; #define w_p_stl w_onebuf_opt.wo_stl // 'statusline' int wo_scb; -# define w_p_scb w_onebuf_opt.wo_scb // 'scrollbind' +#define w_p_scb w_onebuf_opt.wo_scb // 'scrollbind' int wo_diff_saved; // options were saved for starting diff mode -# define w_p_diff_saved w_onebuf_opt.wo_diff_saved +#define w_p_diff_saved w_onebuf_opt.wo_diff_saved int wo_scb_save; // 'scrollbind' saved for diff mode -# define w_p_scb_save w_onebuf_opt.wo_scb_save +#define w_p_scb_save w_onebuf_opt.wo_scb_save int wo_wrap; #define w_p_wrap w_onebuf_opt.wo_wrap // 'wrap' int wo_wrap_save; // 'wrap' state saved for diff mode -# define w_p_wrap_save w_onebuf_opt.wo_wrap_save - char_u *wo_cocu; // 'concealcursor' -# define w_p_cocu w_onebuf_opt.wo_cocu +#define w_p_wrap_save w_onebuf_opt.wo_wrap_save + char_u *wo_cocu; // 'concealcursor' +#define w_p_cocu w_onebuf_opt.wo_cocu long wo_cole; // 'conceallevel' -# define w_p_cole w_onebuf_opt.wo_cole +#define w_p_cole w_onebuf_opt.wo_cole int wo_crb; -# define w_p_crb w_onebuf_opt.wo_crb // 'cursorbind' +#define w_p_crb w_onebuf_opt.wo_crb // 'cursorbind' int wo_crb_save; // 'cursorbind' state saved for diff mode -# define w_p_crb_save w_onebuf_opt.wo_crb_save +#define w_p_crb_save w_onebuf_opt.wo_crb_save char_u *wo_scl; -# define w_p_scl w_onebuf_opt.wo_scl // 'signcolumn' +#define w_p_scl w_onebuf_opt.wo_scl // 'signcolumn' char_u *wo_winhl; -# define w_p_winhl w_onebuf_opt.wo_winhl // 'winhighlight' +#define w_p_winhl w_onebuf_opt.wo_winhl // 'winhighlight' char_u *wo_fcs; -# define w_p_fcs w_onebuf_opt.wo_fcs // 'fillchars' +#define w_p_fcs w_onebuf_opt.wo_fcs // 'fillchars' char_u *wo_lcs; -# define w_p_lcs w_onebuf_opt.wo_lcs // 'listchars' +#define w_p_lcs w_onebuf_opt.wo_lcs // 'listchars' long wo_winbl; -# define w_p_winbl w_onebuf_opt.wo_winbl // 'winblend' +#define w_p_winbl w_onebuf_opt.wo_winbl // 'winblend' LastSet wo_script_ctx[WV_COUNT]; // SCTXs for window-local options -# define w_p_script_ctx w_onebuf_opt.wo_script_ctx +#define w_p_script_ctx w_onebuf_opt.wo_script_ctx } winopt_T; /* @@ -278,9 +277,9 @@ typedef struct { * most-recently-used order. */ struct wininfo_S { - wininfo_T *wi_next; // next entry or NULL for last entry - wininfo_T *wi_prev; // previous entry or NULL for first entry - win_T *wi_win; // pointer to window that did set wi_fpos + wininfo_T *wi_next; // next entry or NULL for last entry + wininfo_T *wi_prev; // previous entry or NULL for first entry + win_T *wi_win; // pointer to window that did set wi_fpos pos_T wi_fpos; // last cursor position in the file bool wi_optset; // true when wi_opt has useful values winopt_T wi_opt; // local window options @@ -306,11 +305,11 @@ typedef struct arglist { // // TODO(Felipe): move aentry_T to another header typedef struct argentry { - char_u *ae_fname; // file name as specified + char_u *ae_fname; // file name as specified int ae_fnum; // buffer number with expanded file name } aentry_T; -# define ALIST(win) (win)->w_alist +#define ALIST(win) (win)->w_alist #define GARGLIST ((aentry_T *)global_alist.al_ga.ga_data) #define ARGLIST ((aentry_T *)ALIST(curwin)->al_ga.ga_data) #define WARGLIST(wp) ((aentry_T *)ALIST(wp)->al_ga.ga_data) @@ -323,8 +322,8 @@ typedef struct argentry { * Used for the typeahead buffer: typebuf. */ typedef struct { - char_u *tb_buf; // buffer for typed characters - char_u *tb_noremap; // mapping flags for characters in tb_buf[] + char_u *tb_buf; // buffer for typed characters + char_u *tb_noremap; // mapping flags for characters in tb_buf[] int tb_buflen; // size of tb_buf[] int tb_off; // current position in tb_buf[] int tb_len; // number of valid bytes in tb_buf[] @@ -350,10 +349,10 @@ typedef struct { */ typedef struct mapblock mapblock_T; struct mapblock { - mapblock_T *m_next; // next mapblock in list - char_u *m_keys; // mapped from, lhs - char_u *m_str; // mapped to, rhs - char_u *m_orig_str; // rhs as entered by the user + mapblock_T *m_next; // next mapblock in list + char_u *m_keys; // mapped from, lhs + char_u *m_str; // mapped to, rhs + char_u *m_orig_str; // rhs as entered by the user int m_keylen; // strlen(m_keys) int m_mode; // valid mode int m_noremap; // if non-zero no re-mapping for m_str @@ -366,7 +365,7 @@ struct mapblock { /// Used for highlighting in the status line. typedef struct stl_hlrec stl_hlrec_t; struct stl_hlrec { - char_u *start; + char_u *start; int userhl; // 0: no HL, 1-9: User HL, < 0 for syn ID }; @@ -403,7 +402,7 @@ struct stl_item { #define SYNFLD_MINIMUM 1 // use lowest local minimum level on line // avoid #ifdefs for when b_spell is not available -# define B_SPELL(buf) ((buf)->b_spell) +#define B_SPELL(buf) ((buf)->b_spell) typedef struct qf_info_S qf_info_T; @@ -440,8 +439,8 @@ typedef struct { long b_syn_sync_minlines; // minimal sync lines offset long b_syn_sync_maxlines; // maximal sync lines offset long b_syn_sync_linebreaks; // offset for multi-line pattern - char_u *b_syn_linecont_pat; // line continuation pattern - regprog_T *b_syn_linecont_prog; // line continuation program + char_u *b_syn_linecont_pat; // line continuation pattern + regprog_T *b_syn_linecont_prog; // line continuation program syn_time_T b_syn_linecont_time; int b_syn_linecont_ic; // ignore-case flag for above int b_syn_topgrp; // for ":syntax include" @@ -460,10 +459,10 @@ typedef struct { // b_sst_freecount number of free entries in b_sst_array[] // b_sst_check_lnum entries after this lnum need to be checked for // validity (MAXLNUM means no check needed) - synstate_T *b_sst_array; + synstate_T *b_sst_array; int b_sst_len; - synstate_T *b_sst_first; - synstate_T *b_sst_firstfree; + synstate_T *b_sst_first; + synstate_T *b_sst_firstfree; int b_sst_freecount; linenr_T b_sst_check_lnum; disptick_T b_sst_lasttick; // last display tick @@ -471,12 +470,12 @@ typedef struct { // for spell checking garray_T b_langp; // list of pointers to slang_T, see spell.c bool b_spell_ismw[256]; // flags: is midword char - char_u *b_spell_ismw_mb; // multi-byte midword chars - char_u *b_p_spc; // 'spellcapcheck' - regprog_T *b_cap_prog; // program for 'spellcapcheck' - char_u *b_p_spf; // 'spellfile' - char_u *b_p_spl; // 'spelllang' - char_u *b_p_spo; // 'spelloptions' + char_u *b_spell_ismw_mb; // multi-byte midword chars + char_u *b_p_spc; // 'spellcapcheck' + regprog_T *b_cap_prog; // program for 'spellcapcheck' + char_u *b_p_spf; // 'spellfile' + char_u *b_p_spl; // 'spelllang' + char_u *b_p_spo; // 'spelloptions' int b_cjk; // all CJK letters as OK char_u b_syn_chartab[32]; // syntax iskeyword option char_u *b_syn_isk; // iskeyword option @@ -521,8 +520,8 @@ struct file_buffer { memline_T b_ml; // associated memline (also contains line count - buf_T *b_next; // links in list of buffers - buf_T *b_prev; + buf_T *b_next; // links in list of buffers + buf_T *b_prev; int b_nwindows; // nr of windows open on this buffer @@ -538,11 +537,11 @@ struct file_buffer { // b_fname is the same as b_sfname, unless ":cd" has been done, // then it is the same as b_ffname (NULL for no name). // - char_u *b_ffname; // full path file name, allocated - char_u *b_sfname; // short file name, allocated, may be equal to - // b_ffname - char_u *b_fname; // current file name, points to b_ffname or - // b_sfname + char_u *b_ffname; // full path file name, allocated + char_u *b_sfname; // short file name, allocated, may be equal to + // b_ffname + char_u *b_fname; // current file name, points to b_ffname or + // b_sfname bool file_id_valid; FileID file_id; @@ -577,7 +576,7 @@ struct file_buffer { // change long b_mod_xlines; // number of extra buffer lines inserted; // negative when lines were deleted - wininfo_T *b_wininfo; // list of last used info for each window + wininfo_T *b_wininfo; // list of last used info for each window int b_mod_tick_syn; // last display tick syntax was updated int b_mod_tick_decor; // last display tick decoration providers // where invoked @@ -614,10 +613,10 @@ struct file_buffer { uint64_t b_chartab[4]; // Table used for mappings local to a buffer. - mapblock_T *(b_maphash[MAX_MAPHASH]); + mapblock_T *(b_maphash[MAX_MAPHASH]); // First abbreviation local to a buffer. - mapblock_T *b_first_abbr; + mapblock_T *b_first_abbr; // User commands local to the buffer. garray_T b_ucmds; /* @@ -632,10 +631,10 @@ struct file_buffer { /* * The following only used in undo.c. */ - u_header_T *b_u_oldhead; // pointer to oldest header - u_header_T *b_u_newhead; // pointer to newest header; may not be valid - // if b_u_curhead is not NULL - u_header_T *b_u_curhead; // pointer to current header + u_header_T *b_u_oldhead; // pointer to oldest header + u_header_T *b_u_newhead; // pointer to newest header; may not be valid + // if b_u_curhead is not NULL + u_header_T *b_u_curhead; // pointer to current header int b_u_numhead; // current number of headers bool b_u_synced; // entry lists are synced long b_u_seq_last; // last used undo sequence number @@ -647,7 +646,7 @@ struct file_buffer { /* * variables for "U" command in undo.c */ - char_u *b_u_line_ptr; // saved line for "U" command + char_u *b_u_line_ptr; // saved line for "U" command linenr_T b_u_line_lnum; // line number of line in u_line colnr_T b_u_line_colnr; // optional column number @@ -659,11 +658,11 @@ struct file_buffer { #define B_IMODE_USE_INSERT -1 // Use b_p_iminsert value for search #define B_IMODE_NONE 0 // Input via none #define B_IMODE_LMAP 1 // Input via langmap -# define B_IMODE_LAST 1 +#define B_IMODE_LAST 1 int16_t b_kmap_state; // using "lmap" mappings -# define KEYMAP_INIT 1 // 'keymap' was set, call keymap_init() -# define KEYMAP_LOADED 2 // 'keymap' mappings have been loaded +#define KEYMAP_INIT 1 // 'keymap' was set, call keymap_init() +#define KEYMAP_LOADED 2 // 'keymap' mappings have been loaded garray_T b_kmap_ga; // the keymap table /* @@ -818,7 +817,7 @@ struct file_buffer { int b_start_eol; // last line had eol when it was read int b_start_ffc; // first char of 'ff' when edit started - char_u *b_start_fenc; // 'fileencoding' when edit started or NULL + char_u *b_start_fenc; // 'fileencoding' when edit started or NULL int b_bad_char; // "++bad=" argument when edit started or 0 int b_start_bomb; // 'bomb' when it was read @@ -868,6 +867,12 @@ struct file_buffer { Map(uint64_t, ExtmarkItem) b_extmark_index[1]; Map(uint64_t, ExtmarkNs) b_extmark_ns[1]; // extmark namespaces + VirtLines b_virt_lines; + uint64_t b_virt_line_mark; + int b_virt_line_pos; + bool b_virt_line_above; + bool b_virt_line_leftcol; + // array of channel_id:s which have asked to receive updates for this // buffer. kvec_t(uint64_t) update_channels; @@ -895,7 +900,7 @@ struct file_buffer { /* * Stuff for diff mode. */ -# define DB_COUNT 8 // up to four buffers can be diff'ed +#define DB_COUNT 8 // up to four buffers can be diff'ed /* * Each diffblock defines where a block of lines starts in each of the buffers @@ -913,14 +918,14 @@ struct file_buffer { */ typedef struct diffblock_S diff_T; struct diffblock_S { - diff_T *df_next; + diff_T *df_next; linenr_T df_lnum[DB_COUNT]; // line number in buffer linenr_T df_count[DB_COUNT]; // nr of inserted/changed lines }; #define SNAP_HELP_IDX 0 -# define SNAP_AUCMD_IDX 1 -# define SNAP_COUNT 2 +#define SNAP_AUCMD_IDX 1 +#define SNAP_COUNT 2 /// Tab pages point to the top frame of each tab page. /// Note: Most values are NOT valid for the current tab page! Use "curwin", @@ -929,25 +934,26 @@ struct diffblock_S { typedef struct tabpage_S tabpage_T; struct tabpage_S { handle_T handle; - tabpage_T *tp_next; ///< next tabpage or NULL - frame_T *tp_topframe; ///< topframe for the windows - win_T *tp_curwin; ///< current window in this Tab page - win_T *tp_prevwin; ///< previous window in this Tab page - win_T *tp_firstwin; ///< first window in this Tab page - win_T *tp_lastwin; ///< last window in this Tab page + tabpage_T *tp_next; ///< next tabpage or NULL + frame_T *tp_topframe; ///< topframe for the windows + win_T *tp_curwin; ///< current window in this Tab page + win_T *tp_prevwin; ///< previous window in this Tab page + win_T *tp_firstwin; ///< first window in this Tab page + win_T *tp_lastwin; ///< last window in this Tab page long tp_old_Rows; ///< Rows when Tab page was left long tp_old_Columns; ///< Columns when Tab page was left long tp_ch_used; ///< value of 'cmdheight' when frame size ///< was set - diff_T *tp_first_diff; - buf_T *(tp_diffbuf[DB_COUNT]); + diff_T *tp_first_diff; + buf_T *(tp_diffbuf[DB_COUNT]); int tp_diff_invalid; ///< list of diffs is outdated int tp_diff_update; ///< update diffs before redrawing - frame_T *(tp_snapshot[SNAP_COUNT]); ///< window layout snapshots + frame_T *(tp_snapshot[SNAP_COUNT]); ///< window layout snapshots ScopeDictDictItem tp_winvar; ///< Variable for "t:" Dictionary. - dict_T *tp_vars; ///< Internal variables, local to tab page. - char_u *tp_localdir; ///< Absolute path of local cwd or NULL. + dict_T *tp_vars; ///< Internal variables, local to tab page. + char_u *tp_localdir; ///< Absolute path of local cwd or NULL. + char_u *tp_prevdir; ///< Previous directory. }; /* @@ -980,14 +986,14 @@ struct frame_S { int fr_newwidth; // new width used in win_equal_rec() int fr_height; int fr_newheight; // new height used in win_equal_rec() - frame_T *fr_parent; // containing frame or NULL - frame_T *fr_next; // frame right or below in same parent, NULL - // for last - frame_T *fr_prev; // frame left or above in same parent, NULL - // for first + frame_T *fr_parent; // containing frame or NULL + frame_T *fr_next; // frame right or below in same parent, NULL + // for last + frame_T *fr_prev; // frame left or above in same parent, NULL + // for first // fr_child and fr_win are mutually exclusive - frame_T *fr_child; // first contained frame - win_T *fr_win; // window that fills this frame + frame_T *fr_child; // first contained frame + win_T *fr_win; // window that fills this frame }; #define FR_LEAF 0 // frame is a leaf @@ -1003,7 +1009,7 @@ struct frame_S { typedef struct { regmmatch_T rm; // points to the regexp program; contains last found // match (may continue in next line) - buf_T *buf; // the buffer to search for a match + buf_T *buf; // the buffer to search for a match linenr_T lnum; // the line to search for a match int attr; // attributes to be used for a match int attr_cur; // attributes currently active in win_line() @@ -1020,9 +1026,9 @@ typedef struct { /// Same as lpos_T, but with additional field len. typedef struct { - linenr_T lnum; ///< line number - colnr_T col; ///< column number - int len; ///< length: 0 - to the end of line + linenr_T lnum; ///< line number + colnr_T col; ///< column number + int len; ///< length: 0 - to the end of line } llpos_T; /// posmatch_T provides an array for storing match items for matchaddpos() @@ -1030,10 +1036,10 @@ typedef struct typedef struct posmatch posmatch_T; struct posmatch { - llpos_T pos[MAXPOSMATCH]; ///< array of positions - int cur; ///< internal position counter - linenr_T toplnum; ///< top buffer line - linenr_T botlnum; ///< bottom buffer line + llpos_T pos[MAXPOSMATCH]; ///< array of positions + int cur; ///< internal position counter + linenr_T toplnum; ///< top buffer line + linenr_T botlnum; ///< bottom buffer line }; /* @@ -1138,20 +1144,20 @@ typedef struct VimMenu vimmenu_T; struct VimMenu { int modes; ///< Which modes is this menu visible for int enabled; ///< for which modes the menu is enabled - char_u *name; ///< Name of menu, possibly translated - char_u *dname; ///< Displayed Name ("name" without '&') - char_u *en_name; ///< "name" untranslated, NULL when - ///< was not translated - char_u *en_dname; ///< NULL when "dname" untranslated + char_u *name; ///< Name of menu, possibly translated + char_u *dname; ///< Displayed Name ("name" without '&') + char_u *en_name; ///< "name" untranslated, NULL when + ///< was not translated + char_u *en_dname; ///< NULL when "dname" untranslated int mnemonic; ///< mnemonic key (after '&') - char_u *actext; ///< accelerator text (after TAB) + char_u *actext; ///< accelerator text (after TAB) long priority; ///< Menu order priority - char_u *strings[MENU_MODES]; ///< Mapped string for each mode + char_u *strings[MENU_MODES]; ///< Mapped string for each mode int noremap[MENU_MODES]; ///< A \ref REMAP_VALUES flag for each mode bool silent[MENU_MODES]; ///< A silent flag for each mode - vimmenu_T *children; ///< Children of sub-menu - vimmenu_T *parent; ///< Parent of menu - vimmenu_T *next; ///< Next item in menu + vimmenu_T *children; ///< Children of sub-menu + vimmenu_T *parent; ///< Parent of menu + vimmenu_T *next; ///< Next item in menu }; /// Structure which contains all information that belongs to a window. @@ -1160,10 +1166,10 @@ struct VimMenu { struct window_S { handle_T handle; ///< unique identifier for the window - buf_T *w_buffer; ///< buffer we are a window into (used - ///< often, keep it the first item!) + buf_T *w_buffer; ///< buffer we are a window into (used + ///< often, keep it the first item!) - synblock_T *w_s; ///< for :ownsyntax + synblock_T *w_s; ///< for :ownsyntax int w_hl_id_normal; ///< 'winhighlight' normal id int w_hl_attr_normal; ///< 'winhighlight' normal final attrs @@ -1173,12 +1179,12 @@ struct window_S { int w_hl_needs_update; ///< attrs need to be recalculated - win_T *w_prev; ///< link to previous window - win_T *w_next; ///< link to next window + win_T *w_prev; ///< link to previous window + win_T *w_next; ///< link to next window bool w_closing; ///< window is being closed, don't let /// autocommands close it too. - frame_T *w_frame; ///< frame containing this window + frame_T *w_frame; ///< frame containing this window pos_T w_cursor; ///< cursor position in buffer @@ -1339,7 +1345,7 @@ struct window_S { * This is used for efficient redrawing. */ int w_lines_valid; // number of valid entries - wline_T *w_lines; + wline_T *w_lines; garray_T w_folds; // array of nested folds bool w_fold_manual; // when true: some folds are opened/closed @@ -1371,13 +1377,13 @@ struct window_S { int w_alt_fnum; // alternate file (for # and CTRL-^) - alist_T *w_alist; // pointer to arglist for this window + alist_T *w_alist; // pointer to arglist for this window int w_arg_idx; // current index in argument list (can be // out of range!) int w_arg_idx_invalid; // editing another file than w_arg_idx - char_u *w_localdir; /* absolute path of local directory or - NULL */ + char_u *w_localdir; // absolute path of local directory or NULL + char_u *w_prevdir; // previous directory // Options local to a window. // They are local because they influence the layout of the window or // depend on the window layout. @@ -1390,10 +1396,10 @@ struct window_S { uint32_t w_p_stl_flags; // flags for 'statusline' uint32_t w_p_fde_flags; // flags for 'foldexpr' uint32_t w_p_fdt_flags; // flags for 'foldtext' - int *w_p_cc_cols; // array of columns to highlight or NULL - char_u w_p_culopt_flags; // flags for cursorline highlighting - long w_p_siso; // 'sidescrolloff' local value - long w_p_so; // 'scrolloff' local value + int *w_p_cc_cols; // array of columns to highlight or NULL + char_u w_p_culopt_flags; // flags for cursorline highlighting + long w_p_siso; // 'sidescrolloff' local value + long w_p_so; // 'scrolloff' local value int w_briopt_min; // minimum width for breakindent int w_briopt_shift; // additional shift for breakindent @@ -1457,10 +1463,10 @@ struct window_S { * was computed. */ int w_nrwidth_width; // nr of chars to print line count. - qf_info_T *w_llist; // Location list for this window + qf_info_T *w_llist; // Location list for this window // Location list reference used in the location list window. // In a non-location list window, w_llist_ref is NULL. - qf_info_T *w_llist_ref; + qf_info_T *w_llist_ref; }; static inline int win_hl_attr(win_T *wp, int hlf) @@ -1470,6 +1476,6 @@ static inline int win_hl_attr(win_T *wp, int hlf) /// Macros defined in Vim, but not in Neovim #define CHANGEDTICK(buf) \ - (=== Include buffer.h & use buf_(get|set|inc)_changedtick ===) + (=== Include buffer.h & use buf_(get|set|inc) _changedtick ===) #endif // NVIM_BUFFER_DEFS_H diff --git a/src/nvim/change.c b/src/nvim/change.c index ccceb0e320..2450c56838 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -413,7 +413,11 @@ void deleted_lines(linenr_T lnum, long count) /// be triggered to display the cursor. void deleted_lines_mark(linenr_T lnum, long count) { - mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, -count, + // if we deleted the entire buffer, we need to implicity add a new empty line + bool made_empty = (count > 0) && curbuf->b_ml.ml_flags & ML_EMPTY; + + mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, + -count + (made_empty?1:0), kExtmarkUndo); changed_lines(lnum, 0, lnum + count, -count, true); } @@ -461,15 +465,15 @@ void changed_lines_buf(buf_T *buf, linenr_T lnum, linenr_T lnume, long xtra) /// When only inserting lines, "lnum" and "lnume" are equal. /// Takes care of calling changed() and updating b_mod_*. /// Careful: may trigger autocommands that reload the buffer. -void changed_lines(linenr_T lnum, // first line with change - colnr_T col, // column in first line with change - linenr_T lnume, // line below last changed line - long xtra, // number of extra lines (negative when deleting) - bool do_buf_event // some callers like undo/redo call changed_lines() - // and then increment changedtick *again*. This flag - // allows these callers to send the nvim_buf_lines_event - // events after they're done modifying changedtick. - ) +/// +/// @param lnum first line with change +/// @param col column in first line with change +/// @param lnume line below last changed line +/// @param xtra number of extra lines (negative when deleting) +/// @param do_buf_event some callers like undo/redo call changed_lines() and +/// then increment changedtick *again*. This flag allows these callers to send +/// the nvim_buf_lines_event events after they're done modifying changedtick. +void changed_lines(linenr_T lnum, colnr_T col, linenr_T lnume, long xtra, bool do_buf_event) { changed_lines_buf(curbuf, lnum, lnume, xtra); @@ -625,7 +629,7 @@ void ins_char_bytes(char_u *buf, size_t charlen) // Copy bytes before the cursor. if (col > 0) { - memmove(newp, oldp, (size_t)col); + memmove(newp, oldp, col); } // Copy bytes after the changed character(s). @@ -950,9 +954,10 @@ int copy_indent(int size, char_u *src) /// "second_line_indent": indent for after ^^D in Insert mode or if flag /// OPENLINE_COM_LIST /// +/// @param dir FORWARD or BACKWARD +/// /// @return true on success, false on failure -int open_line(int dir, // FORWARD or BACKWARD - int flags, int second_line_indent) +int open_line(int dir, int flags, int second_line_indent) { char_u *next_line = NULL; // copy of the next line char_u *p_extra = NULL; // what goes to next line diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 30243a3102..313eefd562 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -8,6 +8,7 @@ #include "nvim/eval/encode.h" #include "nvim/event/socket.h" #include "nvim/fileio.h" +#include "nvim/lua/executor.h" #include "nvim/msgpack_rpc/channel.h" #include "nvim/msgpack_rpc/server.h" #include "nvim/os/shell.h" @@ -87,7 +88,7 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error) break; case kChannelStreamProc: - proc = (Process *)&chan->stream.proc; + proc = &chan->stream.proc; if (part == kChannelPartStdin || close_main) { stream_may_close(&proc->in); } @@ -136,6 +137,8 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error) *error = (const char *)e_invstream; return false; } + api_free_luaref(chan->stream.internal.cb); + chan->stream.internal.cb = LUA_NOREF; break; default: @@ -335,7 +338,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader chan->stream.uv = libuv_process_init(&main_loop, chan); } - Process *proc = (Process *)&chan->stream.proc; + Process *proc = &chan->stream.proc; proc->argv = argv; proc->cb = channel_process_exit_cb; proc->events = chan->events; @@ -420,6 +423,7 @@ uint64_t channel_connect(bool tcp, const char *address, bool rpc, CallbackReader // Create a loopback channel. This avoids deadlock if nvim connects to // its own named pipe. channel = channel_alloc(kChannelStreamInternal); + channel->stream.internal.cb = LUA_NOREF; rpc_start(channel); goto end; } diff --git a/src/nvim/channel.h b/src/nvim/channel.h index 9bc0df3615..8d14f465c1 100644 --- a/src/nvim/channel.h +++ b/src/nvim/channel.h @@ -1,13 +1,13 @@ #ifndef NVIM_CHANNEL_H #define NVIM_CHANNEL_H -#include "nvim/main.h" -#include "nvim/event/socket.h" -#include "nvim/event/process.h" -#include "nvim/os/pty_process.h" -#include "nvim/event/libuv_process.h" #include "nvim/eval/typval.h" +#include "nvim/event/libuv_process.h" +#include "nvim/event/process.h" +#include "nvim/event/socket.h" +#include "nvim/main.h" #include "nvim/msgpack_rpc/channel_defs.h" +#include "nvim/os/pty_process.h" #define CHAN_STDIO 1 #define CHAN_STDERR 2 @@ -43,6 +43,10 @@ typedef struct { } StderrState; typedef struct { + LuaRef cb; +} InternalState; + +typedef struct { Callback cb; dict_T *self; garray_T buffer; @@ -74,6 +78,7 @@ struct Channel { Stream socket; StdioPair stdio; StderrState err; + InternalState internal; } stream; bool is_rpc; @@ -105,18 +110,18 @@ static inline Stream *channel_instream(Channel *chan) FUNC_ATTR_NONNULL_ALL { switch (chan->streamtype) { - case kChannelStreamProc: - return &chan->stream.proc.in; + case kChannelStreamProc: + return &chan->stream.proc.in; - case kChannelStreamSocket: - return &chan->stream.socket; + case kChannelStreamSocket: + return &chan->stream.socket; - case kChannelStreamStdio: - return &chan->stream.stdio.out; + case kChannelStreamStdio: + return &chan->stream.stdio.out; - case kChannelStreamInternal: - case kChannelStreamStderr: - abort(); + case kChannelStreamInternal: + case kChannelStreamStderr: + abort(); } abort(); } @@ -125,18 +130,18 @@ static inline Stream *channel_outstream(Channel *chan) FUNC_ATTR_NONNULL_ALL { switch (chan->streamtype) { - case kChannelStreamProc: - return &chan->stream.proc.out; + case kChannelStreamProc: + return &chan->stream.proc.out; - case kChannelStreamSocket: - return &chan->stream.socket; + case kChannelStreamSocket: + return &chan->stream.socket; - case kChannelStreamStdio: - return &chan->stream.stdio.in; + case kChannelStreamStdio: + return &chan->stream.stdio.in; - case kChannelStreamInternal: - case kChannelStreamStderr: - abort(); + case kChannelStreamInternal: + case kChannelStreamStderr: + abort(); } abort(); } diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 21e04128dc..d2f95ad81c 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -310,7 +310,7 @@ void trans_characters(char_u *buf, int bufsize) /// /// @return number of bytes needed to hold a translation of `s`, NUL byte not /// included. -size_t transstr_len(const char *const s) +size_t transstr_len(const char *const s, bool untab) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE { const char *p = s; @@ -331,6 +331,9 @@ size_t transstr_len(const char *const s) } } p += l; + } else if (*p == TAB && !untab) { + len += 1; + p++; } else { const int b2c_l = byte2cells((uint8_t)(*p++)); // Illegal byte sequence may occupy up to 4 characters. @@ -346,9 +349,10 @@ size_t transstr_len(const char *const s) /// @param[out] buf Buffer to which result should be saved. /// @param[in] len Buffer length. Resulting string may not occupy more then /// len - 1 bytes (one for trailing NUL byte). +/// @param[in] untab remove tab characters /// /// @return length of the resulting string, without the NUL byte. -size_t transstr_buf(const char *const s, char *const buf, const size_t len) +size_t transstr_buf(const char *const s, char *const buf, const size_t len, bool untab) FUNC_ATTR_NONNULL_ALL { const char *p = s; @@ -379,6 +383,8 @@ size_t transstr_buf(const char *const s, char *const buf, const size_t len) } } p += l; + } else if (*p == TAB && !untab) { + *buf_p++ = *p++; } else { const char *const tb = (const char *)transchar_byte((uint8_t)(*p++)); const size_t tb_len = strlen(tb); @@ -401,14 +407,14 @@ size_t transstr_buf(const char *const s, char *const buf, const size_t len) /// @param[in] s String to replace characters from. /// /// @return [allocated] translated string -char *transstr(const char *const s) +char *transstr(const char *const s, bool untab) FUNC_ATTR_NONNULL_RET { // Compute the length of the result, taking account of unprintable // multi-byte characters. - const size_t len = transstr_len((const char *)s) + 1; + const size_t len = transstr_len(s, untab) + 1; char *const buf = xmalloc(len); - transstr_buf(s, buf, len); + transstr_buf(s, buf, len, untab); return buf; } @@ -417,7 +423,7 @@ char *transstr(const char *const s) /// /// When "buf" is NULL, return an allocated string. /// Otherwise, put the result in buf, limited by buflen, and return buf. -char_u * str_foldcase(char_u *str, int orglen, char_u *buf, int buflen) +char_u *str_foldcase(char_u *str, int orglen, char_u *buf, int buflen) FUNC_ATTR_NONNULL_RET { garray_T ga; @@ -1209,7 +1215,7 @@ char_u *skipdigits(const char_u *q) /// @param q pointer to string /// /// @return Pointer to the character after the skipped digits. -const char * skipbin(const char *q) +const char *skipbin(const char *q) FUNC_ATTR_PURE FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET @@ -1228,7 +1234,7 @@ const char * skipbin(const char *q) /// /// @return Pointer to the character after the skipped digits and hex /// characters. -char_u * skiphex(char_u *q) +char_u *skiphex(char_u *q) { char_u *p = q; while (ascii_isxdigit(*p)) { @@ -1243,7 +1249,7 @@ char_u * skiphex(char_u *q) /// @param q /// /// @return Pointer to the digit or (NUL after the string). -char_u * skiptodigit(char_u *q) +char_u *skiptodigit(char_u *q) { char_u *p = q; while (*p != NUL && !ascii_isdigit(*p)) { @@ -1258,7 +1264,7 @@ char_u * skiptodigit(char_u *q) /// @param q pointer to string /// /// @return Pointer to the binary character or (NUL after the string). -const char * skiptobin(const char *q) +const char *skiptobin(const char *q) FUNC_ATTR_PURE FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET @@ -1276,7 +1282,7 @@ const char * skiptobin(const char *q) /// @param q /// /// @return Pointer to the hex character or (NUL after the string). -char_u * skiptohex(char_u *q) +char_u *skiptohex(char_u *q) { char_u *p = q; while (*p != NUL && !ascii_isxdigit(*p)) { @@ -1305,7 +1311,7 @@ char_u *skiptowhite(const char_u *p) /// @param p /// /// @return Pointer to the next whitespace character. -char_u * skiptowhite_esc(char_u *p) { +char_u *skiptowhite_esc(char_u *p) { while (*p != ' ' && *p != '\t' && *p != NUL) { if (((*p == '\\') || (*p == Ctrl_V)) && (*(p + 1) != NUL)) { ++p; diff --git a/src/nvim/charset.h b/src/nvim/charset.h index 2fef4d78a2..47d89717e8 100644 --- a/src/nvim/charset.h +++ b/src/nvim/charset.h @@ -1,11 +1,11 @@ #ifndef NVIM_CHARSET_H #define NVIM_CHARSET_H -#include "nvim/types.h" -#include "nvim/pos.h" #include "nvim/buffer_defs.h" #include "nvim/eval/typval.h" #include "nvim/option_defs.h" +#include "nvim/pos.h" +#include "nvim/types.h" /// Return the folded-case equivalent of the given character /// @@ -13,7 +13,7 @@ /// /// @return Folded variant. #define CH_FOLD(c) \ - utf_fold((sizeof(c) == sizeof(char)) \ + utf_fold((sizeof(c) == sizeof(char)) \ ?((int)(uint8_t)(c)) \ :((int)(c))) diff --git a/src/nvim/context.h b/src/nvim/context.h index 7edd63ced2..c2deca12c9 100644 --- a/src/nvim/context.h +++ b/src/nvim/context.h @@ -2,6 +2,7 @@ #define NVIM_CONTEXT_H #include <msgpack.h> + #include "nvim/api/private/defs.h" #include "nvim/lib/kvec.h" diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c index 2eced03c03..e334fd166e 100644 --- a/src/nvim/cursor.c +++ b/src/nvim/cursor.c @@ -93,10 +93,10 @@ int coladvance(colnr_T wcol) return rc; } -static int coladvance2(pos_T *pos, bool addspaces, // change the text to achieve our goal? - bool finetune, // change char offset for the exact column - colnr_T wcol_arg // column to move to (can be negative) - ) +/// @param addspaces change the text to achieve our goal? +/// @param finetune change char offset for the exact column +/// @param wcol_arg column to move to (can be negative) +static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_arg) { colnr_T wcol = wcol_arg; int idx; diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c index 128bc480da..18cade1052 100644 --- a/src/nvim/cursor_shape.c +++ b/src/nvim/cursor_shape.c @@ -230,12 +230,11 @@ char_u *parse_shape_opt(int what) slashp = vim_strchr(p, '/'); if (slashp != NULL && slashp < endp) { // "group/langmap_group" - i = syn_check_group(p, (int)(slashp - p)); + i = syn_check_group((char *)p, (int)(slashp - p)); p = slashp + 1; } if (round == 2) { - shape_table[idx].id = syn_check_group(p, - (int)(endp - p)); + shape_table[idx].id = syn_check_group((char *)p, (int)(endp - p)); shape_table[idx].id_lm = shape_table[idx].id; if (slashp != NULL && slashp < endp) { shape_table[idx].id = i; diff --git a/src/nvim/cursor_shape.h b/src/nvim/cursor_shape.h index a23fa6836d..06eaa431a0 100644 --- a/src/nvim/cursor_shape.h +++ b/src/nvim/cursor_shape.h @@ -1,36 +1,36 @@ #ifndef NVIM_CURSOR_SHAPE_H #define NVIM_CURSOR_SHAPE_H -#include "nvim/types.h" #include "nvim/api/private/defs.h" +#include "nvim/types.h" /// struct to store values from 'guicursor' and 'mouseshape' /// Indexes in shape_table[] typedef enum { -SHAPE_IDX_N = 0, ///< Normal mode -SHAPE_IDX_V = 1, ///< Visual mode -SHAPE_IDX_I = 2, ///< Insert mode -SHAPE_IDX_R = 3, ///< Replace mode -SHAPE_IDX_C = 4, ///< Command line Normal mode -SHAPE_IDX_CI = 5, ///< Command line Insert mode -SHAPE_IDX_CR = 6, ///< Command line Replace mode -SHAPE_IDX_O = 7, ///< Operator-pending mode -SHAPE_IDX_VE = 8, ///< Visual mode with 'selection' exclusive -SHAPE_IDX_CLINE = 9, ///< On command line -SHAPE_IDX_STATUS = 10, ///< On status line -SHAPE_IDX_SDRAG = 11, ///< dragging a status line -SHAPE_IDX_VSEP = 12, ///< On vertical separator line -SHAPE_IDX_VDRAG = 13, ///< dragging a vertical separator line -SHAPE_IDX_MORE = 14, ///< Hit-return or More -SHAPE_IDX_MOREL = 15, ///< Hit-return or More in last line -SHAPE_IDX_SM = 16, ///< showing matching paren -SHAPE_IDX_COUNT = 17 + SHAPE_IDX_N = 0, ///< Normal mode + SHAPE_IDX_V = 1, ///< Visual mode + SHAPE_IDX_I = 2, ///< Insert mode + SHAPE_IDX_R = 3, ///< Replace mode + SHAPE_IDX_C = 4, ///< Command line Normal mode + SHAPE_IDX_CI = 5, ///< Command line Insert mode + SHAPE_IDX_CR = 6, ///< Command line Replace mode + SHAPE_IDX_O = 7, ///< Operator-pending mode + SHAPE_IDX_VE = 8, ///< Visual mode with 'selection' exclusive + SHAPE_IDX_CLINE = 9, ///< On command line + SHAPE_IDX_STATUS = 10, ///< On status line + SHAPE_IDX_SDRAG = 11, ///< dragging a status line + SHAPE_IDX_VSEP = 12, ///< On vertical separator line + SHAPE_IDX_VDRAG = 13, ///< dragging a vertical separator line + SHAPE_IDX_MORE = 14, ///< Hit-return or More + SHAPE_IDX_MOREL = 15, ///< Hit-return or More in last line + SHAPE_IDX_SM = 16, ///< showing matching paren + SHAPE_IDX_COUNT = 17 } ModeShape; typedef enum { -SHAPE_BLOCK = 0, ///< block cursor -SHAPE_HOR = 1, ///< horizontal bar cursor -SHAPE_VER = 2 ///< vertical bar cursor + SHAPE_BLOCK = 0, ///< block cursor + SHAPE_HOR = 1, ///< horizontal bar cursor + SHAPE_VER = 2 ///< vertical bar cursor } CursorShape; #define MSHAPE_NUMBERED 1000 // offset for shapes identified by number diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c index 73665009ff..aeaf2555b1 100644 --- a/src/nvim/debugger.c +++ b/src/nvim/debugger.c @@ -60,9 +60,9 @@ void do_debug(char_u *cmd) int save_ignore_script = 0; int save_ex_normal_busy; int n; - char_u *cmdline = NULL; - char_u *p; - char *tail = NULL; + char_u *cmdline = NULL; + char_u *p; + char *tail = NULL; static int last_cmd = 0; #define CMD_CONT 1 #define CMD_NEXT 2 @@ -145,13 +145,16 @@ void do_debug(char_u *cmd) p = skipwhite(cmdline); if (*p != NUL) { switch (*p) { - case 'c': last_cmd = CMD_CONT; + case 'c': + last_cmd = CMD_CONT; tail = "ont"; break; - case 'n': last_cmd = CMD_NEXT; + case 'n': + last_cmd = CMD_NEXT; tail = "ext"; break; - case 's': last_cmd = CMD_STEP; + case 's': + last_cmd = CMD_STEP; tail = "tep"; break; case 'f': @@ -164,10 +167,12 @@ void do_debug(char_u *cmd) tail = "inish"; } break; - case 'q': last_cmd = CMD_QUIT; + case 'q': + last_cmd = CMD_QUIT; tail = "uit"; break; - case 'i': last_cmd = CMD_INTERRUPT; + case 'i': + last_cmd = CMD_INTERRUPT; tail = "nterrupt"; break; case 'b': @@ -190,7 +195,8 @@ void do_debug(char_u *cmd) last_cmd = CMD_DOWN; tail = "own"; break; - default: last_cmd = 0; + default: + last_cmd = 0; } if (last_cmd != 0) { // Check that the tail matches. @@ -366,7 +372,7 @@ void ex_debug(exarg_T *eap) debug_break_level = debug_break_level_save; } -static char_u *debug_breakpoint_name = NULL; +static char_u *debug_breakpoint_name = NULL; static linenr_T debug_breakpoint_lnum; /// When debugging or a breakpoint is set on a skipped command, no debug prompt @@ -375,7 +381,7 @@ static linenr_T debug_breakpoint_lnum; /// a skipped command decides itself that a debug prompt should be displayed, it /// can do so by calling dbg_check_skipped(). static int debug_skipped; -static char_u *debug_skipped_name; +static char_u *debug_skipped_name; /// Go to debug mode when a breakpoint was encountered or "ex_nesting_level" is /// at or below the break level. But only when the line is actually @@ -384,7 +390,7 @@ static char_u *debug_skipped_name; /// Called from do_one_cmd() before executing a command. void dbg_check_breakpoint(exarg_T *eap) { - char_u *p; + char *p; debug_skipped = false; if (debug_breakpoint_name != NULL) { @@ -392,10 +398,10 @@ void dbg_check_breakpoint(exarg_T *eap) // replace K_SNR with "<SNR>" if (debug_breakpoint_name[0] == K_SPECIAL && debug_breakpoint_name[1] == KS_EXTRA - && debug_breakpoint_name[2] == (int)KE_SNR) { - p = (char_u *)"<SNR>"; + && debug_breakpoint_name[2] == KE_SNR) { + p = "<SNR>"; } else { - p = (char_u *)""; + p = ""; } smsg(_("Breakpoint in \"%s%s\" line %" PRId64), p, @@ -474,8 +480,8 @@ static typval_T *eval_expr_no_emsg(struct debuggy *const bp) /// @param gap either &dbg_breakp or &prof_ga static int dbg_parsearg(char_u *arg, garray_T *gap) { - char_u *p = arg; - char_u *q; + char_u *p = arg; + char_u *q; struct debuggy *bp; bool here = false; @@ -559,7 +565,7 @@ static int dbg_parsearg(char_u *arg, garray_T *gap) void ex_breakadd(exarg_T *eap) { struct debuggy *bp; - garray_T *gap; + garray_T *gap; gap = &dbg_breakp; if (eap->cmdidx == CMD_profile) { @@ -614,7 +620,7 @@ void ex_breakdel(exarg_T *eap) int todel = -1; bool del_all = false; linenr_T best_lnum = 0; - garray_T *gap; + garray_T *gap; gap = &dbg_breakp; if (eap->cmdidx == CMD_profdel) { @@ -712,12 +718,11 @@ void ex_breaklist(exarg_T *eap) /// Find a breakpoint for a function or sourced file. /// Returns line number at which to break; zero when no matching breakpoint. -linenr_T -dbg_find_breakpoint( - bool file, // true for a file, false for a function - char_u *fname, // file or function name - linenr_T after // after this line number -) +/// +/// @param file true for a file, false for a function +/// @param fname file or function name +/// @param after after this line number +linenr_T dbg_find_breakpoint(bool file, char_u *fname, linenr_T after) { return debuggy_find(file, fname, after, &dbg_breakp, NULL); } @@ -734,18 +739,17 @@ bool has_profiling(bool file, char_u *fname, bool *fp) } /// Common code for dbg_find_breakpoint() and has_profiling(). -static linenr_T -debuggy_find( - bool file, // true for a file, false for a function - char_u *fname, // file or function name - linenr_T after, // after this line number - garray_T *gap, // either &dbg_breakp or &prof_ga - bool *fp // if not NULL: return forceit -) +/// +/// @param file true for a file, false for a function +/// @param fname file or function name +/// @param after after this line number +/// @param gap either &dbg_breakp or &prof_ga +/// @param fp if not NULL: return forceit +static linenr_T debuggy_find(bool file, char_u *fname, linenr_T after, garray_T *gap, bool *fp) { struct debuggy *bp; linenr_T lnum = 0; - char_u *name = fname; + char_u *name = fname; int prev_got_int; // Return quickly when there are no breakpoints. diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 5168ed6d0f..4e80528c74 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -1,13 +1,13 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com -#include "nvim/vim.h" -#include "nvim/lua/executor.h" -#include "nvim/extmark.h" #include "nvim/decoration.h" +#include "nvim/extmark.h" +#include "nvim/highlight.h" +#include "nvim/lua/executor.h" #include "nvim/screen.h" #include "nvim/syntax.h" -#include "nvim/highlight.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "decoration.c.generated.h" @@ -28,11 +28,7 @@ static PMap(uint64_t) hl_decors; /// @param pos_start Cursor position to start the highlighting at /// @param pos_end Cursor position to end the highlighting at /// @param offset Move the whole highlighting this many columns to the right -void bufhl_add_hl_pos_offset(buf_T *buf, - int src_id, - int hl_id, - lpos_T pos_start, - lpos_T pos_end, +void bufhl_add_hl_pos_offset(buf_T *buf, int src_id, int hl_id, lpos_T pos_start, lpos_T pos_end, colnr_T offset) { colnr_T hl_start = 0; @@ -41,7 +37,7 @@ void bufhl_add_hl_pos_offset(buf_T *buf, decor->priority = DECOR_PRIORITY_BASE; // TODO(bfredl): if decoration had blocky mode, we could avoid this loop - for (linenr_T lnum = pos_start.lnum; lnum <= pos_end.lnum; lnum ++) { + for (linenr_T lnum = pos_start.lnum; lnum <= pos_end.lnum; lnum++) { int end_off = 0; if (pos_start.lnum < lnum && lnum < pos_end.lnum) { // TODO(bfredl): This is quite ad-hoc, but the space between |num| and @@ -63,7 +59,7 @@ void bufhl_add_hl_pos_offset(buf_T *buf, hl_start = pos_start.col + offset; hl_end = pos_end.col + offset; } - (void)extmark_set(buf, (uint64_t)src_id, 0, + (void)extmark_set(buf, (uint64_t)src_id, NULL, (int)lnum-1, hl_start, (int)lnum-1+end_off, hl_end, decor, true, false, kExtmarkNoUndo); } @@ -172,7 +168,7 @@ bool decor_redraw_start(buf_T *buf, int top_row, DecorState *state) ExtmarkItem *item = map_ref(uint64_t, ExtmarkItem)(buf->b_extmark_index, start_id, false); if (!item || !item->decor) { - // TODO(bfredl): dedicated flag for being a decoration? + // TODO(bfredl): dedicated flag for being a decoration? goto next_mark; } Decoration *decor = item->decor; @@ -217,14 +213,14 @@ bool decor_redraw_line(buf_T *buf, int row, DecorState *state) return true; // TODO(bfredl): be more precise } -static void decor_add(DecorState *state, int start_row, int start_col, - int end_row, int end_col, Decoration *decor, bool owned) +static void decor_add(DecorState *state, int start_row, int start_col, int end_row, int end_col, + Decoration *decor, bool owned) { int attr_id = decor->hl_id > 0 ? syn_id2attr(decor->hl_id) : 0; DecorRange range = { start_row, start_col, end_row, end_col, *decor, attr_id, - kv_size(decor->virt_text) && owned, -1 }; + kv_size(decor->virt_text) && owned, -1 }; kv_pushp(state->active); size_t index; @@ -238,8 +234,7 @@ static void decor_add(DecorState *state, int start_row, int start_col, kv_A(state->active, index) = range; } -int decor_redraw_col(buf_T *buf, int col, int win_col, bool hidden, - DecorState *state) +int decor_redraw_col(buf_T *buf, int col, int win_col, bool hidden, DecorState *state) { if (col <= state->col_until) { return state->current; @@ -257,7 +252,7 @@ int decor_redraw_col(buf_T *buf, int col, int win_col, bool hidden, } if ((mark.id&MARKTREE_END_FLAG)) { - // TODO(bfredl): check decoration flag + // TODO(bfredl): check decoration flag goto next_mark; } mtpos_t endpos = marktree_lookup(buf->b_marktree, @@ -266,7 +261,7 @@ int decor_redraw_col(buf_T *buf, int col, int win_col, bool hidden, ExtmarkItem *item = map_ref(uint64_t, ExtmarkItem)(buf->b_extmark_index, mark.id, false); if (!item || !item->decor) { - // TODO(bfredl): dedicated flag for being a decoration? + // TODO(bfredl): dedicated flag for being a decoration? goto next_mark; } Decoration *decor = item->decor; @@ -355,8 +350,7 @@ bool decor_redraw_eol(buf_T *buf, DecorState *state, int *eol_attr, int eol_col) return has_virttext; } -void decor_add_ephemeral(int start_row, int start_col, int end_row, int end_col, - Decoration *decor) +void decor_add_ephemeral(int start_row, int start_col, int end_row, int end_col, Decoration *decor) { if (end_row == -1) { end_row = start_row; @@ -418,3 +412,35 @@ void decor_free_all_mem(void) } kv_destroy(decor_providers); } + + +int decor_virtual_lines(win_T *wp, linenr_T lnum) +{ + buf_T *buf = wp->w_buffer; + if (!buf->b_virt_line_mark) { + return 0; + } + if (buf->b_virt_line_pos < 0) { + mtpos_t pos = marktree_lookup(buf->b_marktree, buf->b_virt_line_mark, NULL); + if (pos.row < 0) { + buf->b_virt_line_mark = 0; + } + buf->b_virt_line_pos = pos.row + (buf->b_virt_line_above ? 0 : 1); + } + + return (lnum-1 == buf->b_virt_line_pos) ? (int)kv_size(buf->b_virt_lines) : 0; +} + +void clear_virt_lines(buf_T *buf, int row) +{ + if (row > -1) { + redraw_buf_line_later(buf, MIN(buf->b_ml.ml_line_count, + row+1+(buf->b_virt_line_above?0:1))); + } + for (size_t i = 0; i < kv_size(buf->b_virt_lines); i++) { + clear_virttext(&kv_A(buf->b_virt_lines, i)); + } + kv_destroy(buf->b_virt_lines); // re-initializes + buf->b_virt_line_pos = -1; + buf->b_virt_line_mark = 0; +} diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h index 28dabeeada..e44fbab0a5 100644 --- a/src/nvim/decoration.h +++ b/src/nvim/decoration.h @@ -1,20 +1,12 @@ #ifndef NVIM_DECORATION_H #define NVIM_DECORATION_H -#include "nvim/pos.h" #include "nvim/buffer_defs.h" #include "nvim/extmark_defs.h" +#include "nvim/pos.h" // actual Decoration data is in extmark_defs.h -typedef struct { - char *text; - int hl_id; -} VirtTextChunk; - -typedef kvec_t(VirtTextChunk) VirtText; -#define VIRTTEXT_EMPTY ((VirtText)KV_INITIAL_VALUE) - typedef uint16_t DecorPriority; #define DECOR_PRIORITY_BASE 0x1000 @@ -90,9 +82,9 @@ EXTERN DecorState decor_state INIT(= { 0 }); EXTERN bool provider_active INIT(= false); #define DECORATION_PROVIDER_INIT(ns_id) (DecorProvider) \ - { ns_id, false, LUA_NOREF, LUA_NOREF, \ - LUA_NOREF, LUA_NOREF, LUA_NOREF, \ - LUA_NOREF, -1 } + { ns_id, false, LUA_NOREF, LUA_NOREF, \ + LUA_NOREF, LUA_NOREF, LUA_NOREF, \ + LUA_NOREF, -1 } #ifdef INCLUDE_GENERATED_DECLARATIONS # include "decoration.h.generated.h" diff --git a/src/nvim/diff.c b/src/nvim/diff.c index fd5b2c6599..80b8920a7f 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -13,14 +13,12 @@ #include <inttypes.h> #include <stdbool.h> -#include "nvim/vim.h" -#include "xdiff/xdiff.h" #include "nvim/ascii.h" -#include "nvim/diff.h" #include "nvim/buffer.h" #include "nvim/change.h" #include "nvim/charset.h" #include "nvim/cursor.h" +#include "nvim/diff.h" #include "nvim/eval.h" #include "nvim/ex_cmds.h" #include "nvim/ex_docmd.h" @@ -29,19 +27,21 @@ #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" +#include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/memory.h" #include "nvim/move.h" #include "nvim/normal.h" #include "nvim/option.h" +#include "nvim/os/os.h" +#include "nvim/os/shell.h" #include "nvim/path.h" #include "nvim/screen.h" #include "nvim/strings.h" #include "nvim/undo.h" +#include "nvim/vim.h" #include "nvim/window.h" -#include "nvim/os/os.h" -#include "nvim/os/shell.h" +#include "xdiff/xdiff.h" static int diff_busy = false; // using diff structs, don't change them static bool diff_need_update = false; // ex_diffupdate needs to be called @@ -72,22 +72,22 @@ static TriState diff_a_works = kNone; // used for diff input typedef struct { - char_u *din_fname; // used for external diff - mmfile_t din_mmfile; // used for internal diff + char_u *din_fname; // used for external diff + mmfile_t din_mmfile; // used for internal diff } diffin_T; // used for diff result typedef struct { - char_u *dout_fname; // used for external diff - garray_T dout_ga; // used for internal diff + char_u *dout_fname; // used for external diff + garray_T dout_ga; // used for internal diff } diffout_T; // two diff inputs and one result typedef struct { - diffin_T dio_orig; // original file input - diffin_T dio_new; // new file input - diffout_T dio_diff; // diff result - int dio_internal; // using internal diff + diffin_T dio_orig; // original file input + diffin_T dio_new; // new file input + diffout_T dio_diff; // diff result + int dio_internal; // using internal diff } diffio_T; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -119,7 +119,6 @@ void diff_buf_delete(buf_T *buf) /// @param win void diff_buf_adjust(win_T *win) { - if (!win->w_p_diff) { // When there is no window showing a diff for this buffer, remove // it from the diffs. @@ -242,8 +241,7 @@ void diff_invalidate(buf_T *buf) /// @param line2 /// @param amount /// @param amount_after -void diff_mark_adjust(linenr_T line1, linenr_T line2, long amount, - long amount_after) +void diff_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) { // Handle all tab pages that use the current buffer in a diff. FOR_ALL_TABS(tp) { @@ -267,8 +265,8 @@ void diff_mark_adjust(linenr_T line1, linenr_T line2, long amount, /// @param line2 /// @param amount /// @amount_after -static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, - linenr_T line2, long amount, long amount_after) +static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, linenr_T line2, long amount, + long amount_after) { if (diff_internal()) { // Will update diffs before redrawing. Set _invalid to update the @@ -299,7 +297,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, diff_T *dp = tp->tp_first_diff; linenr_T last; - linenr_T lnum_deleted = line1; // lnum of remaining deletion + linenr_T lnum_deleted = line1; // lnum of remaining deletion int n; int off; for (;;) { @@ -323,8 +321,8 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, dnext->df_lnum[i] = line1; } else { dnext->df_lnum[i] = line1 - + (dprev->df_lnum[i] + dprev->df_count[i]) - - (dprev->df_lnum[idx] + dprev->df_count[idx]); + + (dprev->df_lnum[i] + dprev->df_count[i]) + - (dprev->df_lnum[idx] + dprev->df_count[idx]); } dnext->df_count[i] = deleted; } @@ -393,7 +391,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, off = 0; if (last < line2) { - // 2. delete at end of of diff + // 2. delete at end of diff dp->df_count[idx] -= last - lnum_deleted + 1; if ((dp->df_next != NULL) @@ -509,7 +507,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, /// @param dp /// /// @return The new diff block. -static diff_T* diff_alloc_new(tabpage_T *tp, diff_T *dprev, diff_T *dp) +static diff_T *diff_alloc_new(tabpage_T *tp, diff_T *dprev, diff_T *dp) { diff_T *dnew = xmalloc(sizeof(*dnew)); @@ -704,10 +702,10 @@ static void clear_diffout(diffout_T *dout) /// @return FAIL for failure. static int diff_write_buffer(buf_T *buf, diffin_T *din) { - linenr_T lnum; - char_u *s; - long len = 0; - char_u *ptr; + linenr_T lnum; + char_u *s; + long len = 0; + char_u *ptr; // xdiff requires one big block of memory with all the text. for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) { @@ -734,7 +732,7 @@ static int diff_write_buffer(buf_T *buf, diffin_T *din) for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) { for (s = ml_get_buf(buf, lnum, false); *s != NUL; ) { if (diff_flags & DIFF_ICASE) { - char_u cbuf[MB_MAXBYTES + 1]; + char_u cbuf[MB_MAXBYTES + 1]; // xdiff doesn't support ignoring case, fold-case the text. int c = PTR2CHAR(s); @@ -789,12 +787,10 @@ static int diff_write(buf_T *buf, diffin_T *din) /// @param dio /// @param idx_orig /// @param eap can be NULL -static void diff_try_update(diffio_T *dio, - int idx_orig, - exarg_T *eap) +static void diff_try_update(diffio_T *dio, int idx_orig, exarg_T *eap) { buf_T *buf; - int idx_new; + int idx_new; if (dio->dio_internal) { ga_init(&dio->dio_diff.dout_ga, sizeof(char *), 1000); @@ -932,7 +928,7 @@ void ex_diffupdate(exarg_T *eap) } // Only use the internal method if it did not fail for one of the buffers. - diffio_T diffio; + diffio_T diffio; memset(&diffio, 0, sizeof(diffio)); diffio.dio_internal = diff_internal() && !diff_internal_failed(); @@ -1048,9 +1044,9 @@ static int check_external_diff(diffio_T *diffio) /// static int diff_file_internal(diffio_T *diffio) { - xpparam_t param; - xdemitconf_t emit_cfg; - xdemitcb_t emit_cb; + xpparam_t param; + xdemitconf_t emit_cfg; + xdemitcb_t emit_cb; memset(¶m, 0, sizeof(param)); memset(&emit_cfg, 0, sizeof(emit_cfg)); @@ -1090,9 +1086,9 @@ static int diff_file_internal(diffio_T *diffio) /// @return OK or FAIL static int diff_file(diffio_T *dio) { - char *tmp_orig = (char *)dio->dio_orig.din_fname; - char *tmp_new = (char *)dio->dio_new.din_fname; - char *tmp_diff = (char *)dio->dio_diff.dout_fname; + char *tmp_orig = (char *)dio->dio_orig.din_fname; + char *tmp_new = (char *)dio->dio_new.din_fname; + char *tmp_diff = (char *)dio->dio_diff.dout_fname; if (*p_dex != NUL) { // Use 'diffexpr' to generate the diff file. eval_diff(tmp_orig, tmp_new, tmp_diff); @@ -1114,7 +1110,7 @@ static int diff_file(diffio_T *dio) // Build the diff command and execute it. Always use -a, binary // differences are of no use. Ignore errors, diff returns // non-zero when differences have been found. - vim_snprintf((char *)cmd, len, "diff %s%s%s%s%s%s%s%s %s", + vim_snprintf(cmd, len, "diff %s%s%s%s%s%s%s%s %s", diff_a_works == kFalse ? "" : "-a ", "", (diff_flags & DIFF_IWHITE) ? "-b " : "", @@ -1123,9 +1119,9 @@ static int diff_file(diffio_T *dio) (diff_flags & DIFF_IBLANK) ? "-B " : "", (diff_flags & DIFF_ICASE) ? "-i " : "", tmp_orig, tmp_new); - append_redir(cmd, len, (char *) p_srr, tmp_diff); + append_redir(cmd, len, (char *)p_srr, tmp_diff); block_autocmds(); // Avoid ShellCmdPost stuff - (void)call_shell((char_u *) cmd, + (void)call_shell((char_u *)cmd, kShellOptFilter | kShellOptSilent | kShellOptDoOut, NULL); unblock_autocmds(); @@ -1171,8 +1167,8 @@ void ex_diffpatch(exarg_T *eap) #ifdef UNIX // Get the absolute path of the patchfile, changing directory below. fullname = FullName_save((char *)eap->arg, false); - esc_name = vim_strsave_shellescape( - (fullname != NULL ? (char_u *)fullname : eap->arg), true, true); + esc_name = + vim_strsave_shellescape((fullname != NULL ? (char_u *)fullname : eap->arg), true, true); #else esc_name = vim_strsave_shellescape(eap->arg, true, true); #endif @@ -1324,8 +1320,8 @@ void ex_diffsplit(exarg_T *eap) if (bufref_valid(&old_curbuf)) { // Move the cursor position to that of the old window. - curwin->w_cursor.lnum = diff_get_corresponding_line( - old_curbuf.br_buf, old_curwin->w_cursor.lnum); + curwin->w_cursor.lnum = diff_get_corresponding_line(old_curbuf.br_buf, + old_curwin->w_cursor.lnum); } } // Now that lines are folded scroll to show the cursor at the same @@ -1344,15 +1340,15 @@ void ex_diffthis(exarg_T *eap) static void set_diff_option(win_T *wp, int value) { - win_T *old_curwin = curwin; - - curwin = wp; - curbuf = curwin->w_buffer; - curbuf->b_ro_locked++; - set_option_value("diff", (long)value, NULL, OPT_LOCAL); - curbuf->b_ro_locked--; - curwin = old_curwin; - curbuf = curwin->w_buffer; + win_T *old_curwin = curwin; + + curwin = wp; + curbuf = curwin->w_buffer; + curbuf->b_ro_locked++; + set_option_value("diff", (long)value, NULL, OPT_LOCAL); + curbuf->b_ro_locked--; + curwin = old_curwin; + curbuf = curwin->w_buffer; } @@ -1724,8 +1720,7 @@ static void diff_read(int idx_orig, int idx_new, diffout_T *dout) /// @param dp /// @param idx_orig /// @param idx_new -static void diff_copy_entry(diff_T *dprev, diff_T *dp, int idx_orig, - int idx_new) +static void diff_copy_entry(diff_T *dprev, diff_T *dp, int idx_orig, int idx_new) { long off; @@ -1769,7 +1764,7 @@ void diff_clear(tabpage_T *tp) /// @return diff status. int diff_check(win_T *wp, linenr_T lnum) { - int idx; // index in tp_diffbuf[] for this buffer + int idx; // index in tp_diffbuf[] for this buffer diff_T *dp; int maxcount; int i; @@ -1912,8 +1907,7 @@ static bool diff_equal_entry(diff_T *dp, int idx1, int idx2) // Compare the characters at "p1" and "p2". If they are equal (possibly // ignoring case) return true and set "len" to the number of bytes. -static bool diff_equal_char(const char_u *const p1, const char_u *const p2, - int *const len) +static bool diff_equal_char(const char_u *const p1, const char_u *const p2, int *const len) { const int l = utfc_ptr2len(p1); @@ -1991,26 +1985,6 @@ static int diff_cmp(char_u *s1, char_u *s2) return 0; } -/// Return the number of filler lines above "lnum". -/// -/// @param wp -/// @param lnum -/// -/// @return Number of filler lines above lnum -int diff_check_fill(win_T *wp, linenr_T lnum) -{ - // be quick when there are no filler lines - if (!(diff_flags & DIFF_FILLER)) { - return 0; - } - int n = diff_check(wp, lnum); - - if (n <= 0) { - return 0; - } - return n; -} - /// Set the topline of "towin" to match the position in "fromwin", so that they /// show the same diff'ed lines. /// @@ -2036,6 +2010,7 @@ void diff_set_topline(win_T *fromwin, win_T *towin) } towin->w_topfill = 0; + // search for a change that includes "lnum" in the list of diffblocks. for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next) { if (lnum <= dp->df_lnum[fromidx] + dp->df_count[fromidx]) { @@ -2261,6 +2236,13 @@ bool diffopt_closeoff(void) return (diff_flags & DIFF_CLOSE_OFF) != 0; } +// Return true if 'diffopt' contains "filler". +bool diffopt_filler(void) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT +{ + return (diff_flags & DIFF_FILLER) != 0; +} + /// Find the difference within a changed line. /// /// @param wp window whose current buffer to check @@ -2537,7 +2519,7 @@ void ex_diffgetput(exarg_T *eap) if ((curtab->tp_diffbuf[i] != curbuf) && (curtab->tp_diffbuf[i] != NULL) && ((eap->cmdidx != CMD_diffput) - || MODIFIABLE(curtab->tp_diffbuf[i]))) { + || MODIFIABLE(curtab->tp_diffbuf[i]))) { EMSG(_("E101: More than two buffers in diff mode, don't know " "which one to use")); return; @@ -2958,7 +2940,7 @@ static linenr_T diff_get_corresponding_line_int(buf_T *buf1, linenr_T lnum1) return curwin->w_cursor.lnum; } baseline = (dp->df_lnum[idx1] + dp->df_count[idx1]) - - (dp->df_lnum[idx2] + dp->df_count[idx2]); + - (dp->df_lnum[idx2] + dp->df_count[idx2]); } // If we get here then the cursor is after the last diff @@ -3035,15 +3017,12 @@ linenr_T diff_lnum_win(linenr_T lnum, win_T *wp) /// Handle an ED style diff line. /// Return FAIL if the line does not contain diff info. /// -static int parse_diff_ed(char_u *line, - linenr_T *lnum_orig, - long *count_orig, - linenr_T *lnum_new, - long *count_new) +static int parse_diff_ed(char_u *line, linenr_T *lnum_orig, long *count_orig, linenr_T *lnum_new, + long *count_new) { char_u *p; - long f1, l1, f2, l2; - int difftype; + long f1, l1, f2, l2; + int difftype; // The line must be one of three formats: // change: {first}[,{last}]c{first}[,{last}] @@ -3093,14 +3072,11 @@ static int parse_diff_ed(char_u *line, /// Parses unified diff with zero(!) context lines. /// Return FAIL if there is no diff information in "line". /// -static int parse_diff_unified(char_u *line, - linenr_T *lnum_orig, - long *count_orig, - linenr_T *lnum_new, - long *count_new) +static int parse_diff_unified(char_u *line, linenr_T *lnum_orig, long *count_orig, + linenr_T *lnum_new, long *count_new) { char_u *p; - long oldline, oldcount, newline, newcount; + long oldline, oldcount, newline, newcount; // Parse unified diff hunk header: // @@ -oldline,oldcount +newline,newcount @@ @@ -3153,7 +3129,7 @@ static int parse_diff_unified(char_u *line, static int xdiff_out(void *priv, mmbuffer_t *mb, int nbuf) { diffout_T *dout = (diffout_T *)priv; - char_u *p; + char_u *p; // The header line always comes by itself, text lines in at least two // parts. We drop the text part. diff --git a/src/nvim/diff.h b/src/nvim/diff.h index 99a60381bd..53fc5aa077 100644 --- a/src/nvim/diff.h +++ b/src/nvim/diff.h @@ -1,8 +1,8 @@ #ifndef NVIM_DIFF_H #define NVIM_DIFF_H -#include "nvim/pos.h" #include "nvim/ex_cmds_defs.h" +#include "nvim/pos.h" // Value set from 'diffopt'. EXTERN int diff_context INIT(= 6); // context for folds diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c index 07e484c178..0fa6ebcd94 100644 --- a/src/nvim/digraph.c +++ b/src/nvim/digraph.c @@ -6,26 +6,26 @@ /// code for digraphs #include <assert.h> -#include <stdbool.h> #include <inttypes.h> +#include <stdbool.h> -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/digraph.h" #include "nvim/charset.h" +#include "nvim/digraph.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" +#include "nvim/garray.h" #include "nvim/getchar.h" -#include "nvim/misc1.h" #include "nvim/mbyte.h" -#include "nvim/message.h" #include "nvim/memory.h" -#include "nvim/garray.h" +#include "nvim/message.h" +#include "nvim/misc1.h" #include "nvim/normal.h" +#include "nvim/os/input.h" #include "nvim/screen.h" #include "nvim/strings.h" -#include "nvim/os/input.h" +#include "nvim/vim.h" typedef int result_T; @@ -40,7 +40,7 @@ typedef struct digraph { # include "digraph.c.generated.h" #endif // digraphs added by the user -static garray_T user_digraphs = {0, 0, (int)sizeof(digr_T), 10, NULL}; +static garray_T user_digraphs = { 0, 0, (int)sizeof(digr_T), 10, NULL }; /// Note: Characters marked with XX are not included literally, because some /// compilers cannot handle them (Amiga SAS/C is the most picky one). @@ -49,7 +49,7 @@ static digr_T digraphdefault[] = // digraphs for Unicode from RFC1345 // (also work for ISO-8859-1 aka latin1) { - { 'N', 'U', 0x0a }, // LF for NUL + { 'N', 'U', 0x0a }, // LF for NUL { 'S', 'H', 0x01 }, { 'S', 'X', 0x02 }, { 'E', 'X', 0x03 }, @@ -1452,12 +1452,12 @@ static digr_T digraphdefault[] = /// @return The digraph. int do_digraph(int c) { - static int backspaced; // character before K_BS + static int backspaced; // character before K_BS static int lastchar; // last typed character if (c == -1) { // init values backspaced = -1; - } else if (p_dg) { + } else if (p_dg) { if (backspaced >= 0) { c = getdigraph(backspaced, c, false); } @@ -1557,7 +1557,7 @@ static int getexactdigraph(int char1, int char2, bool meta_char) // Search user digraphs first. digr_T *dp = (digr_T *)user_digraphs.ga_data; for (int i = 0; i < user_digraphs.ga_len; ++i) { - if (((int) dp->char1 == char1) && ((int) dp->char2 == char2)) { + if (((int)dp->char1 == char1) && ((int)dp->char2 == char2)) { retval = dp->result; break; } @@ -1569,7 +1569,7 @@ static int getexactdigraph(int char1, int char2, bool meta_char) dp = digraphdefault; for (int i = 0; dp->char1 != 0; ++i) { - if (((int) dp->char1 == char1) && ((int) dp->char2 == char2)) { + if (((int)dp->char1 == char1) && ((int)dp->char2 == char2)) { retval = dp->result; break; } @@ -1821,7 +1821,7 @@ typedef struct { /// @return NULL if OK, an error message for failure. This only needs to be /// used when setting the option, not later when the value has already /// been checked. -char_u* keymap_init(void) +char_u *keymap_init(void) { curbuf->b_kmap_state &= ~KEYMAP_INIT; @@ -1843,12 +1843,12 @@ char_u* keymap_init(void) vim_snprintf(buf, buflen, "keymap/%s_%s.vim", curbuf->b_p_keymap, p_enc); - if (source_runtime((char_u *)buf, 0) == FAIL) { + if (source_runtime(buf, 0) == FAIL) { // try finding "keymap/'keymap'.vim" in 'runtimepath' vim_snprintf(buf, buflen, "keymap/%s.vim", curbuf->b_p_keymap); - if (source_runtime((char_u *)buf, 0) == FAIL) { + if (source_runtime(buf, 0) == FAIL) { xfree(buf); return (char_u *)N_("E544: Keymap file not found"); } diff --git a/src/nvim/digraph.h b/src/nvim/digraph.h index 1b73ccaf3f..71330ae9b1 100644 --- a/src/nvim/digraph.h +++ b/src/nvim/digraph.h @@ -1,8 +1,8 @@ #ifndef NVIM_DIGRAPH_H #define NVIM_DIGRAPH_H -#include "nvim/types.h" #include "nvim/ex_cmds_defs.h" +#include "nvim/types.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "digraph.h.generated.h" diff --git a/src/nvim/edit.c b/src/nvim/edit.c index aeab1cdad4..b3a08971e9 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -116,7 +116,7 @@ static char *ctrl_x_msgs[] = static char *ctrl_x_mode_names[] = { "keyword", "ctrl_x", - "unknown", // CTRL_X_SCROLL + "scroll", "whole_line", "files", "tags", @@ -147,7 +147,7 @@ struct compl_S { compl_T *cp_prev; char_u *cp_str; // matched text char_u *(cp_text[CPT_COUNT]); // text for the menu - typval_T cp_user_data; + typval_T cp_user_data; char_u *cp_fname; // file containing the match, allocated when // cp_flags has CP_FREE_FNAME int cp_flags; // CP_ values @@ -3327,9 +3327,9 @@ void get_complete_info(list_T *what_list, dict_T *retdict) } // Return Insert completion mode name string -static char_u * ins_compl_mode(void) +static char_u *ins_compl_mode(void) { - if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET || compl_started) { + if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET || ctrl_x_mode == CTRL_X_SCROLL || compl_started) { return (char_u *)ctrl_x_mode_names[ctrl_x_mode & ~CTRL_X_WANT_IDENT]; } return (char_u *)""; @@ -3344,12 +3344,10 @@ static char_u * ins_compl_mode(void) */ static int ins_compl_bs(void) { - char_u *line; - char_u *p; - - line = get_cursor_line_ptr(); - p = line + curwin->w_cursor.col; + char_u *line = get_cursor_line_ptr(); + char_u *p = line + curwin->w_cursor.col; MB_PTR_BACK(line, p); + ptrdiff_t p_off = p - line; // Stop completion when the whole word was deleted. For Omni completion // allow the word to be deleted, we won't match everything. @@ -3369,8 +3367,12 @@ static int ins_compl_bs(void) ins_compl_restart(); } + // ins_compl_restart() calls update_screen(0) which may invalidate the pointer + // TODO(bfredl): get rid of random update_screen() calls deep inside completion logic + line = get_cursor_line_ptr(); + xfree(compl_leader); - compl_leader = vim_strnsave(line + compl_col, (int)(p - line) - compl_col); + compl_leader = vim_strnsave(line + compl_col, (int)p_off - compl_col); ins_compl_new_leader(); if (compl_shown_match != NULL) { // Make sure current match is not a hidden item. @@ -5121,7 +5123,7 @@ static int ins_complete(int c, bool enable_pum) ))) { prefix = (char_u *)""; } - STRCPY((char *)compl_pattern, prefix); + STRCPY(compl_pattern, prefix); (void)quote_meta(compl_pattern + STRLEN(prefix), line + compl_col, compl_length); } else if (--startcol < 0 @@ -5150,13 +5152,13 @@ static int ins_complete(int c, bool enable_pum) * xmalloc(7) is enough -- Acevedo */ compl_pattern = xmalloc(7); - STRCPY((char *)compl_pattern, "\\<"); + STRCPY(compl_pattern, "\\<"); (void)quote_meta(compl_pattern + 2, line + compl_col, 1); - STRCAT((char *)compl_pattern, "\\k"); + STRCAT(compl_pattern, "\\k"); } else { compl_pattern = xmalloc(quote_meta(NULL, line + compl_col, compl_length) + 2); - STRCPY((char *)compl_pattern, "\\<"); + STRCPY(compl_pattern, "\\<"); (void)quote_meta(compl_pattern + 2, line + compl_col, compl_length); } @@ -5679,7 +5681,7 @@ static void insert_special(int c, int allow_modmask, int ctrlv) * stop and defer processing to the "normal" mechanism. * '0' and '^' are special, because they can be followed by CTRL-D. */ -# define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL || (c) == '0' || (c) == '^') +#define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL || (c) == '0' || (c) == '^') #define WHITECHAR(cc) ( \ ascii_iswhite(cc) \ @@ -6214,8 +6216,8 @@ static void internal_format(int textwidth, int second_indent, int flags, int for open_line(FORWARD, OPENLINE_DELSPACES + OPENLINE_MARKFIX + (fo_white_par ? OPENLINE_KEEPTRAIL : 0) + (do_comments ? OPENLINE_DO_COM : 0) - + ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0) - , ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent)); + + ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0), + ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent)); if (!(flags & INSCHAR_COM_LIST)) { old_indent = 0; } diff --git a/src/nvim/edit.h b/src/nvim/edit.h index ef5dce738a..894e23ee9f 100644 --- a/src/nvim/edit.h +++ b/src/nvim/edit.h @@ -24,27 +24,27 @@ typedef enum { typedef int (*IndentGetter)(void); -/* Values for in_cinkeys() */ +// Values for in_cinkeys() #define KEY_OPEN_FORW 0x101 #define KEY_OPEN_BACK 0x102 -#define KEY_COMPLETE 0x103 /* end of completion */ - -/* Values for change_indent() */ -#define INDENT_SET 1 /* set indent */ -#define INDENT_INC 2 /* increase indent */ -#define INDENT_DEC 3 /* decrease indent */ - -/* flags for beginline() */ -#define BL_WHITE 1 /* cursor on first non-white in the line */ -#define BL_SOL 2 /* use 'sol' option */ -#define BL_FIX 4 /* don't leave cursor on a NUL */ - -/* flags for insertchar() */ -#define INSCHAR_FORMAT 1 /* force formatting */ -#define INSCHAR_DO_COM 2 /* format comments */ -#define INSCHAR_CTRLV 4 /* char typed just after CTRL-V */ -#define INSCHAR_NO_FEX 8 /* don't use 'formatexpr' */ -#define INSCHAR_COM_LIST 16 /* format comments with list/2nd line indent */ +#define KEY_COMPLETE 0x103 // end of completion + +// Values for change_indent() +#define INDENT_SET 1 // set indent +#define INDENT_INC 2 // increase indent +#define INDENT_DEC 3 // decrease indent + +// flags for beginline() +#define BL_WHITE 1 // cursor on first non-white in the line +#define BL_SOL 2 // use 'sol' option +#define BL_FIX 4 // don't leave cursor on a NUL + +// flags for insertchar() +#define INSCHAR_FORMAT 1 // force formatting +#define INSCHAR_DO_COM 2 // format comments +#define INSCHAR_CTRLV 4 // char typed just after CTRL-V +#define INSCHAR_NO_FEX 8 // don't use 'formatexpr' +#define INSCHAR_COM_LIST 16 // format comments with list/2nd line indent #ifdef INCLUDE_GENERATED_DECLARATIONS # include "edit.h.generated.h" diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 2736e9a14f..e6a3901dcf 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -20,12 +20,12 @@ #include "nvim/charset.h" #include "nvim/cursor.h" #include "nvim/edit.h" -#include "nvim/eval/userfunc.h" #include "nvim/eval.h" #include "nvim/eval/encode.h" #include "nvim/eval/executor.h" #include "nvim/eval/gc.h" #include "nvim/eval/typval.h" +#include "nvim/eval/userfunc.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" @@ -66,7 +66,7 @@ static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); static char *e_illvar = N_("E461: Illegal variable name: %s"); static char *e_cannot_mod = N_("E995: Cannot modify existing variable"); static char *e_nowhitespace - = N_("E274: No white space allowed before parenthesis"); + = N_("E274: No white space allowed before parenthesis"); static char *e_invalwindow = N_("E957: Invalid window number"); static char *e_lock_unlock = N_("E940: Cannot lock or unlock variable %s"); static char *e_write2 = N_("E80: Error while writing: %s"); @@ -97,7 +97,7 @@ typedef struct { dict_T sv_dict; } scriptvar_T; -static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL}; +static garray_T ga_scripts = { 0, 0, sizeof(scriptvar_T *), 4, NULL }; #define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1]) #define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab) @@ -113,7 +113,7 @@ typedef struct { int fi_semicolon; // TRUE if ending in '; var]' int fi_varcount; // nr of variables in the list listwatch_T fi_lw; // keep an eye on the item used. - list_T *fi_list; // list being used + list_T *fi_list; // list being used int fi_bi; // index of blob blob_T *fi_blob; // blob being used } forinfo_T; @@ -139,7 +139,7 @@ typedef struct { // The reason to use this table anyway is for very quick access to the // variables with the VV_ defines. static struct vimvar { - char *vv_name; ///< Name of the variable, without v:. + char *vv_name; ///< Name of the variable, without v:. TV_DICTITEM_STRUCT(17) vv_di; ///< Value and name for key (max 16 chars). char vv_flags; ///< Flags: #VV_COMPAT, #VV_RO, #VV_RO_SBX. } vimvars[] = @@ -334,7 +334,7 @@ void eval_init(void) { vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; - struct vimvar *p; + struct vimvar *p; init_var_dict(&globvardict, &globvars_var, VAR_DEF_SCOPE); init_var_dict(&vimvardict, &vimvars_var, VAR_SCOPE); @@ -346,12 +346,13 @@ void eval_init(void) p = &vimvars[i]; assert(STRLEN(p->vv_name) <= 16); STRCPY(p->vv_di.di_key, p->vv_name); - if (p->vv_flags & VV_RO) + if (p->vv_flags & VV_RO) { p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; - else if (p->vv_flags & VV_RO_SBX) + } else if (p->vv_flags & VV_RO_SBX) { p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; - else + } else { p->vv_di.di_flags = DI_FLAGS_FIX; + } // add to v: scope dict, unless the value is not always available if (p->vv_type != VAR_UNKNOWN) { @@ -424,7 +425,7 @@ void eval_init(void) #if defined(EXITFREE) void eval_clear(void) { - struct vimvar *p; + struct vimvar *p; for (size_t i = 0; i < ARRAY_SIZE(vimvars); i++) { p = &vimvars[i]; @@ -451,10 +452,12 @@ void eval_clear(void) /* Script-local variables. First clear all the variables and in a second * loop free the scriptvar_T, because a variable in one script might hold * a reference to the whole scope of another script. */ - for (int i = 1; i <= ga_scripts.ga_len; ++i) + for (int i = 1; i <= ga_scripts.ga_len; ++i) { vars_clear(&SCRIPT_VARS(i)); - for (int i = 1; i <= ga_scripts.ga_len; ++i) + } + for (int i = 1; i <= ga_scripts.ga_len; ++i) { xfree(SCRIPT_SV(i)); + } ga_clear(&ga_scripts); // unreferenced lists and dicts @@ -481,20 +484,16 @@ void set_internal_string_var(const char *name, char_u *value) set_var(name, strlen(name), &tv, true); } -static lval_T *redir_lval = NULL; +static lval_T *redir_lval = NULL; static garray_T redir_ga; // Only valid when redir_lval is not NULL. static char_u *redir_endp = NULL; -static char_u *redir_varname = NULL; +static char_u *redir_varname = NULL; -/* - * Start recording command output to a variable - * Returns OK if successfully completed the setup. FAIL otherwise. - */ -int -var_redir_start( - char_u *name, - int append // append to an existing variable -) +/// Start recording command output to a variable +/// Returns OK if successfully completed the setup. FAIL otherwise. +/// +/// @param append append to an existing variable +int var_redir_start(char_u *name, int append) { int save_emsg; int err; @@ -515,8 +514,8 @@ var_redir_start( ga_init(&redir_ga, (int)sizeof(char), 500); // Parse the variable name (can be a dict or list entry). - redir_endp = (char_u *)get_lval(redir_varname, NULL, redir_lval, false, false, - 0, FNE_CHECK_START); + redir_endp = get_lval(redir_varname, NULL, redir_lval, false, false, + 0, FNE_CHECK_START); if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) { clear_lval(redir_lval); @@ -567,8 +566,9 @@ void var_redir_str(char_u *value, int value_len) { int len; - if (redir_lval == NULL) + if (redir_lval == NULL) { return; + } if (value_len == -1) { len = (int)STRLEN(value); // Append the entire string @@ -597,8 +597,8 @@ void var_redir_stop(void) tv.vval.v_string = redir_ga.ga_data; // Call get_lval() again, if it's inside a Dict or List it may // have changed. - redir_endp = (char_u *)get_lval(redir_varname, NULL, redir_lval, - false, false, 0, FNE_CHECK_START); + redir_endp = get_lval(redir_varname, NULL, redir_lval, + false, false, 0, FNE_CHECK_START); if (redir_endp != NULL && redir_lval->ll_name != NULL) { set_var_lval(redir_lval, redir_endp, &tv, false, false, "."); } @@ -655,8 +655,7 @@ int eval_printexpr(const char *const fname, const char *const args) return OK; } -void eval_diff(const char *const origfile, const char *const newfile, - const char *const outfile) +void eval_diff(const char *const origfile, const char *const newfile, const char *const outfile) { bool err = false; @@ -669,8 +668,7 @@ void eval_diff(const char *const origfile, const char *const newfile, set_vim_var_string(VV_FNAME_OUT, NULL, -1); } -void eval_patch(const char *const origfile, const char *const difffile, - const char *const outfile) +void eval_patch(const char *const origfile, const char *const difffile, const char *const outfile) { bool err = false; @@ -683,18 +681,13 @@ void eval_patch(const char *const origfile, const char *const difffile, set_vim_var_string(VV_FNAME_OUT, NULL, -1); } -/* - * Top level evaluation function, returning a boolean. - * Sets "error" to TRUE if there was an error. - * Return TRUE or FALSE. - */ -int -eval_to_bool( - char_u *arg, - bool *error, - char_u **nextcmd, - int skip // only parse, don't execute -) +/// Top level evaluation function, returning a boolean. +/// Sets "error" to TRUE if there was an error. +/// +/// @param skip only parse, don't execute +/// +/// @return TRUE or FALSE. +int eval_to_bool(char_u *arg, bool *error, char_u **nextcmd, int skip) { typval_T tv; bool retval = false; @@ -741,8 +734,7 @@ static int eval1_emsg(char_u **arg, typval_T *rettv, bool evaluate) return ret; } -int eval_expr_typval(const typval_T *expr, typval_T *argv, - int argc, typval_T *rettv) +int eval_expr_typval(const typval_T *expr, typval_T *argv, int argc, typval_T *rettv) FUNC_ATTR_NONNULL_ARG(1, 2, 4) { funcexe_T funcexe = FUNCEXE_INIT; @@ -811,8 +803,7 @@ bool eval_expr_to_bool(const typval_T *expr, bool *error) /// /// @return [allocated] string result of evaluation or NULL in case of error or /// when skipping. -char *eval_to_string_skip(const char *arg, const char **nextcmd, - const bool skip) +char *eval_to_string_skip(const char *arg, const char **nextcmd, const bool skip) FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT { typval_T tv; @@ -890,7 +881,7 @@ char_u *eval_to_string(char_u *arg, char_u **nextcmd, bool convert) */ char_u *eval_to_string_safe(char_u *arg, char_u **nextcmd, int use_sandbox) { - char_u *retval; + char_u *retval; funccal_entry_T funccal_entry; save_funccal(&funccal_entry); @@ -916,7 +907,7 @@ varnumber_T eval_to_number(char_u *expr) { typval_T rettv; varnumber_T retval; - char_u *p = skipwhite(expr); + char_u *p = skipwhite(expr); ++emsg_off; @@ -951,8 +942,9 @@ typval_T *eval_expr(char_u *arg) void prepare_vimvar(int idx, typval_T *save_tv) { *save_tv = vimvars[idx].vv_tv; - if (vimvars[idx].vv_type == VAR_UNKNOWN) + if (vimvars[idx].vv_type == VAR_UNKNOWN) { hash_add(&vimvarht, vimvars[idx].vv_di.di_key); + } } /* @@ -961,7 +953,7 @@ void prepare_vimvar(int idx, typval_T *save_tv) */ void restore_vimvar(int idx, typval_T *save_tv) { - hashitem_T *hi; + hashitem_T *hi; vimvars[idx].vv_tv = *save_tv; if (vimvars[idx].vv_type == VAR_UNKNOWN) { @@ -994,15 +986,16 @@ list_T *eval_spell_expr(char_u *badword, char_u *expr) { typval_T save_val; typval_T rettv; - list_T *list = NULL; - char_u *p = skipwhite(expr); + list_T *list = NULL; + char_u *p = skipwhite(expr); // Set "v:val" to the bad word. prepare_vimvar(VV_VAL, &save_val); vimvars[VV_VAL].vv_type = VAR_STRING; vimvars[VV_VAL].vv_str = badword; - if (p_verbose == 0) + if (p_verbose == 0) { ++emsg_off; + } if (eval1(&p, &rettv, true) == OK) { if (rettv.v_type != VAR_LIST) { @@ -1012,8 +1005,9 @@ list_T *eval_spell_expr(char_u *badword, char_u *expr) } } - if (p_verbose == 0) + if (p_verbose == 0) { --emsg_off; + } restore_vimvar(VV_VAL, &save_val); return list; @@ -1052,12 +1046,7 @@ int get_spellword(list_T *const list, const char **ret_word) // should have type VAR_UNKNOWN. // // Return OK or FAIL. -int call_vim_function( - const char_u *func, - int argc, - typval_T *argv, - typval_T *rettv -) +int call_vim_function(const char_u *func, int argc, typval_T *argv, typval_T *rettv) FUNC_ATTR_NONNULL_ALL { int ret; @@ -1096,8 +1085,7 @@ fail: /// @param[in] argv Array with typval_T arguments. /// /// @return -1 when calling function fails, result of function otherwise. -varnumber_T call_func_retnr(const char_u *func, int argc, - typval_T *argv) +varnumber_T call_func_retnr(const char_u *func, int argc, typval_T *argv) FUNC_ATTR_NONNULL_ALL { typval_T rettv; @@ -1118,8 +1106,7 @@ varnumber_T call_func_retnr(const char_u *func, int argc, /// /// @return [allocated] NULL when calling function fails, allocated string /// otherwise. -char *call_func_retstr(const char *const func, int argc, - typval_T *argv) +char *call_func_retstr(const char *const func, int argc, typval_T *argv) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC { typval_T rettv; @@ -1159,14 +1146,12 @@ void *call_func_retlist(const char_u *func, int argc, typval_T *argv) return rettv.vval.v_list; } -/* - * Prepare profiling for entering a child or something else that is not - * counted for the script/function itself. - * Should always be called in pair with prof_child_exit(). - */ -void prof_child_enter( - proftime_T *tm // place to store waittime -) +/// Prepare profiling for entering a child or something else that is not +/// counted for the script/function itself. +/// Should always be called in pair with prof_child_exit(). +/// +/// @param tm place to store waittime +void prof_child_enter(proftime_T *tm) { funccall_T *fc = get_current_funccal(); @@ -1177,13 +1162,11 @@ void prof_child_enter( script_prof_save(tm); } -/* - * Take care of time spent in a child. - * Should always be called after prof_child_enter(). - */ -void prof_child_exit( - proftime_T *tm // where waittime was stored -) +/// Take care of time spent in a child. +/// Should always be called after prof_child_enter(). +/// +/// @param tm where waittime was stored +void prof_child_exit(proftime_T *tm) { funccall_T *fc = get_current_funccal(); @@ -1208,11 +1191,12 @@ int eval_foldexpr(char_u *arg, int *cp) { typval_T tv; varnumber_T retval; - int use_sandbox = was_set_insecurely(curwin, (char_u *)"foldexpr", OPT_LOCAL); + int use_sandbox = was_set_insecurely(curwin, "foldexpr", OPT_LOCAL); ++emsg_off; - if (use_sandbox) + if (use_sandbox) { ++sandbox; + } ++textlock; *cp = NUL; if (eval0(arg, &tv, NULL, true) == FAIL) { @@ -1235,8 +1219,9 @@ int eval_foldexpr(char_u *arg, int *cp) tv_clear(&tv); } --emsg_off; - if (use_sandbox) + if (use_sandbox) { --sandbox; + } --textlock; return (int)retval; @@ -1262,8 +1247,7 @@ void ex_const(exarg_T *eap) // marker, then the leading indentation before the lines (matching the // indentation in the 'cmd' line) is stripped. // Returns a List with {lines} or NULL. -static list_T * -heredoc_get(exarg_T *eap, char_u *cmd) +static list_T *heredoc_get(exarg_T *eap, char_u *cmd) { char_u *marker; char_u *p; @@ -1327,29 +1311,29 @@ heredoc_get(exarg_T *eap, char_u *cmd) // marker if (marker_indent_len > 0 && STRNCMP(theline, *eap->cmdlinep, marker_indent_len) == 0) { - mi = marker_indent_len; + mi = marker_indent_len; } if (STRCMP(marker, theline + mi) == 0) { xfree(theline); break; } if (text_indent_len == -1 && *theline != NUL) { - // set the text indent from the first line. - p = theline; - text_indent_len = 0; - while (ascii_iswhite(*p)) { - p++; - text_indent_len++; - } - text_indent = vim_strnsave(theline, text_indent_len); + // set the text indent from the first line. + p = theline; + text_indent_len = 0; + while (ascii_iswhite(*p)) { + p++; + text_indent_len++; + } + text_indent = vim_strnsave(theline, text_indent_len); } // with "trim": skip the indent matching the first line if (text_indent != NULL) { - for (ti = 0; ti < text_indent_len; ti++) { - if (theline[ti] != text_indent[ti]) { - break; - } + for (ti = 0; ti < text_indent_len; ti++) { + if (theline[ti] != text_indent[ti]) { + break; } + } } tv_list_append_string(l, (char *)(theline + ti), -1); @@ -1379,14 +1363,14 @@ void ex_let(exarg_T *eap) static void ex_let_const(exarg_T *eap, const bool is_const) { - char_u *arg = eap->arg; - char_u *expr = NULL; + char_u *arg = eap->arg; + char_u *expr = NULL; typval_T rettv; int i; int var_count = 0; int semicolon = 0; char_u op[2]; - char_u *argend; + char_u *argend; int first = TRUE; argend = (char_u *)skip_var_list(arg, &var_count, &semicolon); @@ -1444,8 +1428,9 @@ static void ex_let_const(exarg_T *eap, const bool is_const) expr = skipwhite(expr + 1); } - if (eap->skip) + if (eap->skip) { ++emsg_skip; + } i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); if (eap->skip) { if (i != FAIL) { @@ -1460,21 +1445,20 @@ static void ex_let_const(exarg_T *eap, const bool is_const) } } -/* - * Assign the typevalue "tv" to the variable or variables at "arg_start". - * Handles both "var" with any type and "[var, var; var]" with a list type. - * When "op" is not NULL it points to a string with characters that - * must appear after the variable(s). Use "+", "-" or "." for add, subtract - * or concatenate. - * Returns OK or FAIL; - */ -static int ex_let_vars(char_u *arg_start, - typval_T *tv, - int copy, // copy values from "tv", don't move - int semicolon, // from skip_var_list() - int var_count, // from skip_var_list() - int is_const, // lock variables for :const - char_u *op) +/// Assign the typevalue "tv" to the variable or variables at "arg_start". +/// Handles both "var" with any type and "[var, var; var]" with a list type. +/// When "op" is not NULL it points to a string with characters that +/// must appear after the variable(s). Use "+", "-" or "." for add, subtract +/// or concatenate. +/// +/// @param copy copy values from "tv", don't move +/// @param semicolon from skip_var_list() +/// @param var_count from skip_var_list() +/// @param is_const lock variables for :const +/// +/// @return OK or FAIL; +static int ex_let_vars(char_u *arg_start, typval_T *tv, int copy, int semicolon, int var_count, + int is_const, char_u *op) { char_u *arg = arg_start; typval_T ltv; @@ -1559,8 +1543,7 @@ static int ex_let_vars(char_u *arg_start, * for "[var, var; var]" set "semicolon". * Return NULL for an error. */ -static const char_u *skip_var_list(const char_u *arg, int *var_count, - int *semicolon) +static const char_u *skip_var_list(const char_u *arg, int *var_count, int *semicolon) { const char_u *p; const char_u *s; @@ -1578,9 +1561,9 @@ static const char_u *skip_var_list(const char_u *arg, int *var_count, ++*var_count; p = skipwhite(s); - if (*p == ']') + if (*p == ']') { break; - else if (*p == ';') { + } else if (*p == ';') { if (*semicolon == 1) { EMSG(_("E452: Double ; in list of variables")); return NULL; @@ -1592,8 +1575,9 @@ static const char_u *skip_var_list(const char_u *arg, int *var_count, } } return p + 1; - } else + } else { return skip_var_one(arg); + } } /* @@ -1602,21 +1586,21 @@ static const char_u *skip_var_list(const char_u *arg, int *var_count, */ static const char_u *skip_var_one(const char_u *arg) { - if (*arg == '@' && arg[1] != NUL) + if (*arg == '@' && arg[1] != NUL) { return arg + 2; + } return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, - NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); + NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); } /* * List variables for hashtab "ht" with prefix "prefix". * If "empty" is TRUE also list NULL strings as empty strings. */ -void list_hashtable_vars(hashtab_T *ht, const char *prefix, int empty, - int *first) +void list_hashtable_vars(hashtab_T *ht, const char *prefix, int empty, int *first) { - hashitem_T *hi; - dictitem_T *di; + hashitem_T *hi; + dictitem_T *di; int todo; todo = (int)ht->ht_used; @@ -1727,7 +1711,7 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first) if (tofree != NULL) { name = tofree; } - if (get_var_tv((const char *)name, len, &tv, NULL, true, false) + if (get_var_tv(name, len, &tv, NULL, true, false) == FAIL) { error = true; } else { @@ -1740,13 +1724,20 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first) } else { if (arg == arg_subsc && len == 2 && name[1] == ':') { switch (*name) { - case 'g': list_glob_vars(first); break; - case 'b': list_buf_vars(first); break; - case 'w': list_win_vars(first); break; - case 't': list_tab_vars(first); break; - case 'v': list_vim_vars(first); break; - case 's': list_script_vars(first); break; - case 'l': list_func_vars(first); break; + case 'g': + list_glob_vars(first); break; + case 'b': + list_buf_vars(first); break; + case 'w': + list_win_vars(first); break; + case 't': + list_tab_vars(first); break; + case 'v': + list_vim_vars(first); break; + case 's': + list_script_vars(first); break; + case 'l': + list_func_vars(first); break; default: EMSG2(_("E738: Can't list variables for %s"), name); } @@ -1789,8 +1780,7 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first) /// /// @return a pointer to the char just after the var name or NULL in case of /// error. -static char_u *ex_let_one(char_u *arg, typval_T *const tv, - const bool copy, const bool is_const, +static char_u *ex_let_one(char_u *arg, typval_T *const tv, const bool copy, const bool is_const, const char_u *const endchars, const char_u *const op) FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_WARN_UNUSED_RESULT { @@ -1848,9 +1838,9 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, xfree(tofree); } } - // ":let &option = expr": Set option value. - // ":let &l:option = expr": Set local option value. - // ":let &g:option = expr": Set global option value. + // ":let &option = expr": Set option value. + // ":let &l:option = expr": Set local option value. + // ":let &g:option = expr": Set global option value. } else if (*arg == '&') { if (is_const) { EMSG(_("E996: Cannot lock an option")); @@ -1885,11 +1875,16 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, } else { if (opt_type == 1) { // number switch (*op) { - case '+': n = numval + n; break; - case '-': n = numval - n; break; - case '*': n = numval * n; break; - case '/': n = num_divide(numval, n); break; - case '%': n = num_modulus(numval, n); break; + case '+': + n = numval + n; break; + case '-': + n = numval - n; break; + case '*': + n = numval * n; break; + case '/': + n = num_divide(numval, n); break; + case '%': + n = num_modulus(numval, n); break; } } else if (opt_type == 0 && stringval != NULL) { // string char *const oldstringval = stringval; @@ -1908,7 +1903,7 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, *p = c1; xfree(stringval); } - // ":let @r = expr": Set register contents. + // ":let @r = expr": Set register contents. } else if (*arg == '@') { if (is_const) { EMSG(_("E996: Cannot lock a register")); @@ -1921,7 +1916,7 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) { EMSG(_(e_letunexp)); } else { - char_u *s; + char_u *s; char_u *ptofree = NULL; const char *p = tv_get_string_chk(tv); @@ -1958,8 +1953,9 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, } } clear_lval(&lv); - } else + } else { EMSG2(_(e_invarg2), arg); + } return arg_end; } @@ -1989,16 +1985,15 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, /// /// @return A pointer to just after the name, including indexes. Returns NULL /// for a parsing error, but it is still needed to free items in lp. -char_u *get_lval(char_u *const name, typval_T *const rettv, - lval_T *const lp, const bool unlet, const bool skip, - const int flags, const int fne_flags) +char_u *get_lval(char_u *const name, typval_T *const rettv, lval_T *const lp, const bool unlet, + const bool skip, const int flags, const int fne_flags) FUNC_ATTR_NONNULL_ARG(1, 3) { - dictitem_T *v; + dictitem_T *v; typval_T var1; typval_T var2; int empty1 = FALSE; - listitem_T *ni; + listitem_T *ni; hashtab_T *ht = NULL; int quiet = flags & GLV_QUIET; @@ -2028,7 +2023,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, } lp->ll_exp_name = (char *)make_expanded_name(name, expr_start, expr_end, - (char_u *)p); + p); lp->ll_name = lp->ll_exp_name; if (lp->ll_exp_name == NULL) { /* Report an invalid expression in braces, unless the @@ -2080,8 +2075,9 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, return NULL; } if (lp->ll_range) { - if (!quiet) + if (!quiet) { EMSG(_("E708: [:] must come last")); + } return NULL; } @@ -2233,7 +2229,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, } tv_clear(&var1); break; - // existing variable, need to check if it can be changed + // existing variable, need to check if it can be changed } else if (!(flags & GLV_READ_ONLY) && var_check_ro(lp->ll_di->di_flags, (const char *)name, (size_t)(p - name))) { @@ -2312,8 +2308,9 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, if (lp->ll_n2 < 0) { ni = tv_list_find(lp->ll_list, lp->ll_n2); if (ni == NULL) { - if (!quiet) + if (!quiet) { EMSGN(_(e_listidx), lp->ll_n2); + } return NULL; } lp->ll_n2 = tv_list_idx_of_item(lp->ll_list, ni); @@ -2358,12 +2355,12 @@ void clear_lval(lval_T *lp) * "op" is NULL, "+" for "+=", "-" for "-=", "*" for "*=", "/" for "/=", * "%" for "%=", "." for ".=" or "=" for "=". */ -static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, - int copy, const bool is_const, const char *op) +static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, const bool is_const, + const char *op) { int cc; - listitem_T *ri; - dictitem_T *di; + listitem_T *ri; + dictitem_T *di; if (lp->ll_tv == NULL) { cc = *endp; @@ -2422,7 +2419,7 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, // handle +=, -=, *=, /=, %= and .= di = NULL; - if (get_var_tv((const char *)lp->ll_name, (int)STRLEN(lp->ll_name), + if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), &tv, &di, true, false) == OK) { if ((di == NULL || (!var_check_ro(di->di_flags, lp->ll_name, TV_CSTRING) @@ -2568,16 +2565,17 @@ notify: */ void *eval_for_line(const char_u *arg, bool *errp, char_u **nextcmdp, int skip) { - forinfo_T *fi = xcalloc(1, sizeof(forinfo_T)); + forinfo_T *fi = xcalloc(1, sizeof(forinfo_T)); const char_u *expr; typval_T tv; - list_T *l; + list_T *l; *errp = true; // Default: there is an error. expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); - if (expr == NULL) + if (expr == NULL) { return fi; + } expr = skipwhite(expr); if (expr[0] != 'i' || expr[1] != 'n' || !ascii_iswhite(expr[2])) { @@ -2585,8 +2583,9 @@ void *eval_for_line(const char_u *arg, bool *errp, char_u **nextcmdp, int skip) return fi; } - if (skip) + if (skip) { ++emsg_skip; + } if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) { *errp = false; if (!skip) { @@ -2619,8 +2618,9 @@ void *eval_for_line(const char_u *arg, bool *errp, char_u **nextcmdp, int skip) } } } - if (skip) + if (skip) { --emsg_skip; + } return fi; } @@ -2667,7 +2667,7 @@ bool next_for_item(void *fi_void, char_u *arg) */ void free_for_info(void *fi_void) { - forinfo_T *fi = (forinfo_T *)fi_void; + forinfo_T *fi = (forinfo_T *)fi_void; if (fi != NULL && fi->fi_list != NULL) { tv_list_watch_remove(fi->fi_list, &fi->fi_lw); @@ -2685,7 +2685,7 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx) { int got_eq = FALSE; int c; - char_u *p; + char_u *p; if (cmdidx == CMD_let || cmdidx == CMD_const) { xp->xp_context = EXPAND_USER_VARS; @@ -2700,11 +2700,12 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx) } return; } - } else + } else { xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS - : EXPAND_EXPRESSION; + : EXPAND_EXPRESSION; + } while ((xp->xp_pattern = vim_strpbrk(arg, - (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) { + (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) { c = *xp->xp_pattern; if (c == '&') { c = xp->xp_pattern[1]; @@ -2714,9 +2715,9 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx) ? EXPAND_EXPRESSION : EXPAND_NOTHING; } else if (c != ' ') { xp->xp_context = EXPAND_SETTINGS; - if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') + if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') { xp->xp_pattern += 2; - + } } } else if (c == '$') { // environment variable @@ -2750,14 +2751,17 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx) if (xp->xp_pattern[1] == '|') { ++xp->xp_pattern; xp->xp_context = EXPAND_EXPRESSION; - } else + } else { xp->xp_context = EXPAND_COMMANDS; - } else + } + } else { xp->xp_context = EXPAND_EXPRESSION; - } else + } + } else { /* Doesn't look like something valid, expand as an expression * anyway. */ xp->xp_context = EXPAND_EXPRESSION; + } arg = xp->xp_pattern; if (*arg != NUL) { while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) { @@ -2819,8 +2823,7 @@ void ex_lockvar(exarg_T *eap) /// @param[in] deep Levels to (un)lock for :(un)lockvar, -1 to (un)lock /// everything. /// @param[in] callback Appropriate handler for the command. -static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep, - ex_unletlock_callback callback) +static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep, ex_unletlock_callback callback) FUNC_ATTR_NONNULL_ALL { char_u *arg = argstart; @@ -2884,8 +2887,7 @@ static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep, /// @param[in] deep Unused. /// /// @return OK on success, or FAIL on failure. -static int do_unlet_var(lval_T *lp, char_u *name_end, exarg_T *eap, - int deep FUNC_ATTR_UNUSED) +static int do_unlet_var(lval_T *lp, char_u *name_end, exarg_T *eap, int deep FUNC_ATTR_UNUSED) FUNC_ATTR_NONNULL_ALL { int forceit = eap->forceit; @@ -2989,7 +2991,7 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit) if (ht == &globvarht) { d = &globvardict; } else if (ht == &compat_hashtab) { - d = &vimvardict; + d = &vimvardict; } else { dictitem_T *const di = find_var_in_ht(ht, *name, "", 0, false); d = di->di_tv.vval.v_dict; @@ -3002,12 +3004,12 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit) hashitem_T *hi = hash_find(ht, (const char_u *)varname); if (HASHITEM_EMPTY(hi)) { - hi = find_hi_in_scoped_ht((const char *)name, &ht); + hi = find_hi_in_scoped_ht(name, &ht); } if (hi != NULL && !HASHITEM_EMPTY(hi)) { dictitem_T *const di = TV_DICT_HI2DI(hi); - if (var_check_fixed(di->di_flags, (const char *)name, TV_CSTRING) - || var_check_ro(di->di_flags, (const char *)name, TV_CSTRING) + if (var_check_fixed(di->di_flags, name, TV_CSTRING) + || var_check_ro(di->di_flags, name, TV_CSTRING) || var_check_lock(d->dv_lock, name, TV_CSTRING)) { return FAIL; } @@ -3032,8 +3034,9 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit) return OK; } } - if (forceit) + if (forceit) { return OK; + } EMSG2(_("E108: No such variable: \"%s\""), name); return FAIL; } @@ -3050,8 +3053,7 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit) /// @param[in] deep Levels to (un)lock, -1 to (un)lock everything. /// /// @return OK on success, or FAIL on failure. -static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED, - exarg_T *eap, int deep) +static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED, exarg_T *eap, int deep) FUNC_ATTR_NONNULL_ARG(1, 3) { bool lock = eap->cmdidx == CMD_lockvar; @@ -3067,9 +3069,8 @@ static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED, ret = FAIL; } else { // Normal name or expanded name. - dictitem_T *const di = find_var( - (const char *)lp->ll_name, lp->ll_name_len, NULL, - true); + dictitem_T *const di = find_var(lp->ll_name, lp->ll_name_len, NULL, + true); if (di == NULL) { ret = FAIL; } else if ((di->di_flags & DI_FLAGS_FIX) @@ -3089,7 +3090,7 @@ static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED, } } } else if (lp->ll_range) { - listitem_T *li = lp->ll_li; + listitem_T *li = lp->ll_li; // (un)lock a range of List items. while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) { @@ -3129,7 +3130,7 @@ void del_menutrans_vars(void) */ -static char_u *varnamebuf = NULL; +static char_u *varnamebuf = NULL; static size_t varnamebuflen = 0; /* @@ -3163,7 +3164,7 @@ char_u *get_user_var_name(expand_T *xp, int idx) static size_t wdone; static size_t tdone; static size_t vidx; - static hashitem_T *hi; + static hashitem_T *hi; if (idx == 0) { gdone = bdone = wdone = vidx = 0; @@ -3172,14 +3173,17 @@ char_u *get_user_var_name(expand_T *xp, int idx) // Global variables if (gdone < globvarht.ht_used) { - if (gdone++ == 0) + if (gdone++ == 0) { hi = globvarht.ht_array; - else + } else { ++hi; - while (HASHITEM_EMPTY(hi)) + } + while (HASHITEM_EMPTY(hi)) { ++hi; - if (STRNCMP("g:", xp->xp_pattern, 2) == 0) + } + if (STRNCMP("g:", xp->xp_pattern, 2) == 0) { return cat_prefix_varname('g', hi->hi_key); + } return hi->hi_key; } @@ -3189,12 +3193,14 @@ char_u *get_user_var_name(expand_T *xp, int idx) ? &prevwin->w_buffer->b_vars->dv_hashtab : &curbuf->b_vars->dv_hashtab; if (bdone < ht->ht_used) { - if (bdone++ == 0) + if (bdone++ == 0) { hi = ht->ht_array; - else + } else { ++hi; - while (HASHITEM_EMPTY(hi)) + } + while (HASHITEM_EMPTY(hi)) { ++hi; + } return cat_prefix_varname('b', hi->hi_key); } @@ -3204,24 +3210,28 @@ char_u *get_user_var_name(expand_T *xp, int idx) ? &prevwin->w_vars->dv_hashtab : &curwin->w_vars->dv_hashtab; if (wdone < ht->ht_used) { - if (wdone++ == 0) + if (wdone++ == 0) { hi = ht->ht_array; - else + } else { ++hi; - while (HASHITEM_EMPTY(hi)) + } + while (HASHITEM_EMPTY(hi)) { ++hi; + } return cat_prefix_varname('w', hi->hi_key); } // t: variables ht = &curtab->tp_vars->dv_hashtab; if (tdone < ht->ht_used) { - if (tdone++ == 0) + if (tdone++ == 0) { hi = ht->ht_array; - else + } else { ++hi; - while (HASHITEM_EMPTY(hi)) + } + while (HASHITEM_EMPTY(hi)) { ++hi; + } return cat_prefix_varname('t', hi->hi_key); } @@ -3265,8 +3275,7 @@ static int pattern_match(char_u *pat, char_u *text, bool ic) // /// @return OK or FAIL. static int eval_func(char_u **const arg, char_u *const name, const int name_len, - typval_T *const rettv, const bool evaluate, - typval_T *const basetv) + typval_T *const rettv, const bool evaluate, typval_T *const basetv) FUNC_ATTR_NONNULL_ARG(1, 2, 4) { char_u *s = name; @@ -3334,7 +3343,7 @@ static int eval_func(char_u **const arg, char_u *const name, const int name_len, int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate) { int ret; - char_u *p; + char_u *p; const int did_emsg_before = did_emsg; const int called_emsg_before = called_emsg; @@ -3354,8 +3363,9 @@ int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate) } ret = FAIL; } - if (nextcmd != NULL) + if (nextcmd != NULL) { *nextcmd = check_nextcmd(p); + } return ret; } @@ -3364,7 +3374,7 @@ int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate) /* * Handle top level expression: - * expr2 ? expr1 : expr1 + * expr2 ? expr1 : expr1 * * "arg" must point to the first non-white of the expression. * "arg" is advanced to the next non-white after the recognized expression. @@ -3381,8 +3391,9 @@ int eval1(char_u **arg, typval_T *rettv, int evaluate) /* * Get the first variable. */ - if (eval2(arg, rettv, evaluate) == FAIL) + if (eval2(arg, rettv, evaluate) == FAIL) { return FAIL; + } if ((*arg)[0] == '?') { result = FALSE; @@ -3427,8 +3438,9 @@ int eval1(char_u **arg, typval_T *rettv, int evaluate) } return FAIL; } - if (evaluate && !result) + if (evaluate && !result) { *rettv = var2; + } } return OK; @@ -3438,7 +3450,7 @@ int eval1(char_u **arg, typval_T *rettv, int evaluate) /* * Handle first level expression: - * expr2 || expr2 || expr2 logical OR + * expr2 || expr2 || expr2 logical OR * * "arg" must point to the first non-white of the expression. * "arg" is advanced to the next non-white after the recognized expression. @@ -3455,8 +3467,9 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate) /* * Get the first variable. */ - if (eval3(arg, rettv, evaluate) == FAIL) + if (eval3(arg, rettv, evaluate) == FAIL) { return FAIL; + } /* * Repeat until there is no following "||". @@ -3479,8 +3492,9 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate) * Get the second variable. */ *arg = skipwhite(*arg + 2); - if (eval3(arg, &var2, evaluate && !result) == FAIL) + if (eval3(arg, &var2, evaluate && !result) == FAIL) { return FAIL; + } /* * Compute the result. @@ -3507,7 +3521,7 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate) /* * Handle second level expression: - * expr3 && expr3 && expr3 logical AND + * expr3 && expr3 && expr3 logical AND * * "arg" must point to the first non-white of the expression. * "arg" is advanced to the next non-white after the recognized expression. @@ -3524,8 +3538,9 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate) /* * Get the first variable. */ - if (eval4(arg, rettv, evaluate) == FAIL) + if (eval4(arg, rettv, evaluate) == FAIL) { return FAIL; + } /* * Repeat until there is no following "&&". @@ -3548,8 +3563,9 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate) * Get the second variable. */ *arg = skipwhite(*arg + 2); - if (eval4(arg, &var2, evaluate && result) == FAIL) + if (eval4(arg, &var2, evaluate && result) == FAIL) { return FAIL; + } /* * Compute the result. @@ -3576,16 +3592,16 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate) /* * Handle third level expression: - * var1 == var2 - * var1 =~ var2 - * var1 != var2 - * var1 !~ var2 - * var1 > var2 - * var1 >= var2 - * var1 < var2 - * var1 <= var2 - * var1 is var2 - * var1 isnot var2 + * var1 == var2 + * var1 =~ var2 + * var1 != var2 + * var1 !~ var2 + * var1 > var2 + * var1 >= var2 + * var1 < var2 + * var1 <= var2 + * var1 is var2 + * var1 isnot var2 * * "arg" must point to the first non-white of the expression. * "arg" is advanced to the next non-white after the recognized expression. @@ -3595,7 +3611,7 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate) static int eval4(char_u **arg, typval_T *rettv, int evaluate) { typval_T var2; - char_u *p; + char_u *p; exprtype_T type = EXPR_UNKNOWN; int len = 2; bool ic; @@ -3603,8 +3619,9 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) /* * Get the first variable. */ - if (eval5(arg, rettv, evaluate) == FAIL) + if (eval5(arg, rettv, evaluate) == FAIL) { return FAIL; + } p = *arg; switch (p[0]) { @@ -3638,14 +3655,15 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) type = EXPR_SEQUAL; } break; - case 'i': if (p[1] == 's') { + case 'i': + if (p[1] == 's') { if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') { len = 5; } if (!isalnum(p[len]) && p[len] != '_') { type = len == 2 ? EXPR_IS : EXPR_ISNOT; } - } + } break; } @@ -3685,10 +3703,10 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) /* * Handle fourth level expression: - * + number addition - * - number subtraction - * . string concatenation - * .. string concatenation + * + number addition + * - number subtraction + * . string concatenation + * .. string concatenation * * "arg" must point to the first non-white of the expression. * "arg" is advanced to the next non-white after the recognized expression. @@ -3702,21 +3720,23 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) int op; varnumber_T n1, n2; float_T f1 = 0, f2 = 0; - char_u *p; + char_u *p; /* * Get the first variable. */ - if (eval6(arg, rettv, evaluate, FALSE) == FAIL) + if (eval6(arg, rettv, evaluate, FALSE) == FAIL) { return FAIL; + } /* * Repeat computing, until no '+', '-' or '.' is following. */ for (;; ) { op = **arg; - if (op != '+' && op != '-' && op != '.') + if (op != '+' && op != '-' && op != '.') { break; + } if ((op != '+' || (rettv->v_type != VAR_LIST && rettv->v_type != VAR_BLOB)) && (op == '.' || rettv->v_type != VAR_FLOAT)) { @@ -3807,8 +3827,9 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) tv_clear(&var2); return FAIL; } - if (var2.v_type == VAR_FLOAT) + if (var2.v_type == VAR_FLOAT) { f1 = n1; + } } if (var2.v_type == VAR_FLOAT) { f2 = var2.vval.v_float; @@ -3820,24 +3841,27 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) tv_clear(&var2); return FAIL; } - if (rettv->v_type == VAR_FLOAT) + if (rettv->v_type == VAR_FLOAT) { f2 = n2; + } } tv_clear(rettv); // If there is a float on either side the result is a float. if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) { - if (op == '+') + if (op == '+') { f1 = f1 + f2; - else + } else { f1 = f1 - f2; + } rettv->v_type = VAR_FLOAT; rettv->vval.v_float = f1; } else { - if (op == '+') + if (op == '+') { n1 = n1 + n2; - else + } else { n1 = n1 - n2; + } rettv->v_type = VAR_NUMBER; rettv->vval.v_number = n1; } @@ -3876,8 +3900,9 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string) /* * Get the first variable. */ - if (eval7(arg, rettv, evaluate, want_string) == FAIL) + if (eval7(arg, rettv, evaluate, want_string) == FAIL) { return FAIL; + } /* * Repeat computing, until no '*', '/' or '%' is following. @@ -3908,8 +3933,9 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string) * Get the second variable. */ *arg = skipwhite(*arg + 1); - if (eval7(arg, &var2, evaluate, FALSE) == FAIL) + if (eval7(arg, &var2, evaluate, FALSE) == FAIL) { return FAIL; + } if (evaluate) { if (var2.v_type == VAR_FLOAT) { @@ -3942,15 +3968,15 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string) f1 = (f2 == 0 ? ( #ifdef NAN - f1 == 0 + f1 == 0 ? NAN : #endif - (f1 > 0 + (f1 > 0 ? INFINITY : -INFINITY) - ) - : f1 / f2); + ) + : f1 / f2); } else { EMSG(_("E804: Cannot use '%' with Float")); return FAIL; @@ -3976,39 +4002,36 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string) // TODO(ZyX-I): move to eval/expressions -// Handle sixth level expression: -// number number constant -// 0zFFFFFFFF Blob 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 -// #{key: val, key: val} Dictionary with literal keys -// -// 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 -// trailing ->name() method call -// -// "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 -) +/// Handle sixth level expression: +/// number number constant +/// 0zFFFFFFFF Blob 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 +/// #{key: val, key: val} Dictionary with literal keys +/// +/// 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 +/// trailing ->name() method call +/// +/// "arg" must point to the first non-white of the expression. +/// "arg" is advanced to the next non-white after the recognized expression. +/// +/// @param want_string after "." operator +/// +/// @return OK or FAIL. +static int eval7(char_u **arg, typval_T *rettv, int evaluate, int want_string) { varnumber_T n; int len; @@ -4039,8 +4062,7 @@ static int eval7( case '6': case '7': case '8': - case '9': - { + case '9': { char_u *p = skipdigits(*arg + 1); int get_float = false; @@ -4070,7 +4092,7 @@ static int eval7( if (get_float) { float_T f; - *arg += string2float((char *) *arg, &f); + *arg += string2float((char *)*arg, &f); if (evaluate) { rettv->v_type = VAR_FLOAT; rettv->vval.v_float = f; @@ -4122,15 +4144,18 @@ static int eval7( } // String constant: "string". - case '"': ret = get_string_tv(arg, rettv, evaluate); + case '"': + ret = get_string_tv(arg, rettv, evaluate); break; // Literal string constant: 'str''ing'. - case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); + case '\'': + ret = get_lit_string_tv(arg, rettv, evaluate); break; // List: [expr, expr] - case '[': ret = get_list_tv(arg, rettv, evaluate); + case '[': + ret = get_list_tv(arg, rettv, evaluate); break; // Dictionary: #{key: val, key: val} @@ -4145,23 +4170,25 @@ static int eval7( // Lambda: {arg, arg -> expr} // Dictionary: {'key': val, 'key': val} - case '{': ret = get_lambda_tv(arg, rettv, evaluate); - if (ret == NOTDONE) { - ret = dict_get_tv(arg, rettv, evaluate, false); - } + case '{': + ret = get_lambda_tv(arg, rettv, evaluate); + if (ret == NOTDONE) { + ret = dict_get_tv(arg, rettv, evaluate, false); + } break; // Option value: &name - case '&': { + case '&': ret = get_option_tv((const char **)arg, rettv, evaluate); break; - } // Environment variable: $VAR. - case '$': ret = get_env_tv(arg, rettv, evaluate); + case '$': + ret = get_env_tv(arg, rettv, evaluate); break; // Register contents: @r. - case '@': ++*arg; + case '@': + ++*arg; if (evaluate) { rettv->v_type = VAR_STRING; rettv->vval.v_string = get_reg_contents(**arg, kGRegExprSrc); @@ -4172,7 +4199,8 @@ static int eval7( break; // nested expression: (expression). - case '(': *arg = skipwhite(*arg + 1); + case '(': + *arg = skipwhite(*arg + 1); ret = eval1(arg, rettv, evaluate); // recursive! if (**arg == ')') { ++*arg; @@ -4183,7 +4211,8 @@ static int eval7( } break; - default: ret = NOTDONE; + default: + ret = NOTDONE; break; } @@ -4284,11 +4313,8 @@ static int eval7_leader(typval_T *const rettv, const char_u *const start_leader, /// to the name of the Lua function to call (after the /// "v:lua." prefix). /// @return OK on success, FAIL on failure. -static int call_func_rettv(char_u **const arg, - typval_T *const rettv, - const bool evaluate, - dict_T *const selfdict, - typval_T *const basetv, +static int call_func_rettv(char_u **const arg, typval_T *const rettv, const bool evaluate, + dict_T *const selfdict, typval_T *const basetv, const char_u *const lua_funcname) FUNC_ATTR_NONNULL_ARG(1, 2) { @@ -4322,7 +4348,7 @@ static int call_func_rettv(char_u **const arg, funcexe.selfdict = selfdict; funcexe.basetv = basetv; const int ret = get_func_tv(funcname, is_lua ? *arg - funcname : -1, rettv, - (char_u **)arg, &funcexe); + arg, &funcexe); // Clear the funcref afterwards, so that deleting it while // evaluating the arguments is possible (see test55). @@ -4337,8 +4363,8 @@ static int call_func_rettv(char_u **const arg, /// @param verbose if true, give error messages. /// @note "*arg" points to the '-'. /// @return FAIL or OK. @note "*arg" is advanced to after the ')'. -static int eval_lambda(char_u **const arg, typval_T *const rettv, - const bool evaluate, const bool verbose) +static int eval_lambda(char_u **const arg, typval_T *const rettv, const bool evaluate, + const bool verbose) FUNC_ATTR_NONNULL_ALL { // Skip over the ->. @@ -4375,8 +4401,8 @@ static int eval_lambda(char_u **const arg, typval_T *const rettv, /// Evaluate "->method()" or "->v:lua.method()". /// @note "*arg" points to the '-'. /// @return FAIL or OK. "*arg" is advanced to after the ')'. -static int eval_method(char_u **const arg, typval_T *const rettv, - const bool evaluate, const bool verbose) +static int eval_method(char_u **const arg, typval_T *const rettv, const bool evaluate, + const bool verbose) FUNC_ATTR_NONNULL_ALL { // Skip over the ->. @@ -4445,60 +4471,49 @@ static int eval_method(char_u **const arg, typval_T *const rettv, // TODO(ZyX-I): move to eval/expressions -/* - * Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key". - * "*arg" points to the '[' or '.'. - * Returns FAIL or OK. "*arg" is advanced to after the ']'. - */ -static int -eval_index( - char_u **arg, - typval_T *rettv, - int evaluate, - int verbose // give error messages -) +/// Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key". +/// "*arg" points to the '[' or '.'. +/// Returns FAIL or OK. "*arg" is advanced to after the ']'. +/// +/// @param verbose give error messages +static int eval_index(char_u **arg, typval_T *rettv, int evaluate, int verbose) { bool empty1 = false; bool empty2 = false; long n1, n2 = 0; ptrdiff_t len = -1; int range = false; - char_u *key = NULL; + char_u *key = NULL; switch (rettv->v_type) { - case VAR_FUNC: - case VAR_PARTIAL: { - if (verbose) { - EMSG(_("E695: Cannot index a Funcref")); - } - return FAIL; - } - case VAR_FLOAT: { - if (verbose) { - EMSG(_(e_float_as_string)); - } - return FAIL; + case VAR_FUNC: + case VAR_PARTIAL: + if (verbose) { + EMSG(_("E695: Cannot index a Funcref")); } - case VAR_BOOL: - case VAR_SPECIAL: { - if (verbose) { - EMSG(_("E909: Cannot index a special variable")); - } - return FAIL; + return FAIL; + case VAR_FLOAT: + if (verbose) { + EMSG(_(e_float_as_string)); } - case VAR_UNKNOWN: { - if (evaluate) { - return FAIL; - } - FALLTHROUGH; + return FAIL; + case VAR_BOOL: + case VAR_SPECIAL: + if (verbose) { + EMSG(_("E909: Cannot index a special variable")); } - case VAR_STRING: - case VAR_NUMBER: - case VAR_LIST: - case VAR_DICT: - case VAR_BLOB: { - break; + return FAIL; + case VAR_UNKNOWN: + if (evaluate) { + return FAIL; } + FALLTHROUGH; + case VAR_STRING: + case VAR_NUMBER: + case VAR_LIST: + case VAR_DICT: + case VAR_BLOB: + break; } typval_T var1 = TV_INITIAL_VALUE; @@ -4508,10 +4523,12 @@ eval_index( * dict.name */ key = *arg + 1; - for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) + for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) { ; - if (len == 0) + } + if (len == 0) { return FAIL; + } *arg = skipwhite(key + len); } else { /* @@ -4583,180 +4600,177 @@ eval_index( } switch (rettv->v_type) { - case VAR_NUMBER: - case VAR_STRING: { - const char *const s = tv_get_string(rettv); - char *v; - len = (ptrdiff_t)strlen(s); - if (range) { - // The resulting variable is a substring. If the indexes - // are out of range the result is empty. + case VAR_NUMBER: + case VAR_STRING: { + const char *const s = tv_get_string(rettv); + char *v; + len = (ptrdiff_t)strlen(s); + if (range) { + // The resulting variable is a substring. If the indexes + // are out of range the result is empty. + if (n1 < 0) { + n1 = len + n1; if (n1 < 0) { - n1 = len + n1; - if (n1 < 0) { - n1 = 0; - } - } - if (n2 < 0) { - n2 = len + n2; - } else if (n2 >= len) { - n2 = len; - } - if (n1 >= len || n2 < 0 || n1 > n2) { - v = NULL; - } else { - v = xmemdupz(s + n1, (size_t)(n2 - n1 + 1)); + n1 = 0; } + } + if (n2 < 0) { + n2 = len + n2; + } else if (n2 >= len) { + n2 = len; + } + if (n1 >= len || n2 < 0 || n1 > n2) { + v = NULL; } else { - // The resulting variable is a string of a single - // character. If the index is too big or negative the - // result is empty. - if (n1 >= len || n1 < 0) { - v = NULL; - } else { - v = xmemdupz(s + n1, 1); - } + v = xmemdupz(s + n1, (size_t)(n2 - n1 + 1)); + } + } else { + // The resulting variable is a string of a single + // character. If the index is too big or negative the + // result is empty. + if (n1 >= len || n1 < 0) { + v = NULL; + } else { + v = xmemdupz(s + n1, 1); } - tv_clear(rettv); - rettv->v_type = VAR_STRING; - rettv->vval.v_string = (char_u *)v; - break; } - case VAR_BLOB: { - len = tv_blob_len(rettv->vval.v_blob); - if (range) { - // The resulting variable is a sub-blob. If the indexes - // are out of range the result is empty. + tv_clear(rettv); + rettv->v_type = VAR_STRING; + rettv->vval.v_string = (char_u *)v; + break; + } + case VAR_BLOB: + len = tv_blob_len(rettv->vval.v_blob); + if (range) { + // The resulting variable is a sub-blob. If the indexes + // are out of range the result is empty. + if (n1 < 0) { + n1 = len + n1; if (n1 < 0) { - n1 = len + n1; - if (n1 < 0) { - n1 = 0; - } - } - if (n2 < 0) { - n2 = len + n2; - } else if (n2 >= len) { - n2 = len - 1; - } - if (n1 >= len || n2 < 0 || n1 > n2) { - tv_clear(rettv); - rettv->v_type = VAR_BLOB; - rettv->vval.v_blob = NULL; - } else { - blob_T *const blob = tv_blob_alloc(); - ga_grow(&blob->bv_ga, n2 - n1 + 1); - blob->bv_ga.ga_len = n2 - n1 + 1; - for (long i = n1; i <= n2; i++) { - tv_blob_set(blob, i - n1, tv_blob_get(rettv->vval.v_blob, i)); - } - tv_clear(rettv); - tv_blob_set_ret(rettv, blob); + n1 = 0; } + } + if (n2 < 0) { + n2 = len + n2; + } else if (n2 >= len) { + n2 = len - 1; + } + if (n1 >= len || n2 < 0 || n1 > n2) { + tv_clear(rettv); + rettv->v_type = VAR_BLOB; + rettv->vval.v_blob = NULL; } else { - // The resulting variable is a byte value. - // If the index is too big or negative that is an error. - if (n1 < 0) { - n1 = len + n1; - } - if (n1 < len && n1 >= 0) { - const int v = (int)tv_blob_get(rettv->vval.v_blob, n1); - tv_clear(rettv); - rettv->v_type = VAR_NUMBER; - rettv->vval.v_number = v; - } else { - EMSGN(_(e_blobidx), n1); + blob_T *const blob = tv_blob_alloc(); + ga_grow(&blob->bv_ga, n2 - n1 + 1); + blob->bv_ga.ga_len = n2 - n1 + 1; + for (long i = n1; i <= n2; i++) { + tv_blob_set(blob, i - n1, tv_blob_get(rettv->vval.v_blob, i)); } + tv_clear(rettv); + tv_blob_set_ret(rettv, blob); } - break; - } - case VAR_LIST: { - len = tv_list_len(rettv->vval.v_list); + } else { + // The resulting variable is a byte value. + // If the index is too big or negative that is an error. if (n1 < 0) { n1 = len + n1; } - if (!empty1 && (n1 < 0 || n1 >= len)) { - // For a range we allow invalid values and return an empty - // list. A list index out of range is an error. - if (!range) { - if (verbose) { - EMSGN(_(e_listidx), n1); - } - return FAIL; - } - n1 = len; - } - if (range) { - list_T *l; - listitem_T *item; - - if (n2 < 0) { - n2 = len + n2; - } else if (n2 >= len) { - n2 = len - 1; - } - if (!empty2 && (n2 < 0 || n2 + 1 < n1)) { - n2 = -1; - } - l = tv_list_alloc(n2 - n1 + 1); - item = tv_list_find(rettv->vval.v_list, n1); - while (n1++ <= n2) { - tv_list_append_tv(l, TV_LIST_ITEM_TV(item)); - item = TV_LIST_ITEM_NEXT(rettv->vval.v_list, item); - } + if (n1 < len && n1 >= 0) { + const int v = (int)tv_blob_get(rettv->vval.v_blob, n1); tv_clear(rettv); - tv_list_set_ret(rettv, l); + rettv->v_type = VAR_NUMBER; + rettv->vval.v_number = v; } else { - tv_copy(TV_LIST_ITEM_TV(tv_list_find(rettv->vval.v_list, n1)), &var1); - tv_clear(rettv); - *rettv = var1; + EMSGN(_(e_blobidx), n1); } - break; } - case VAR_DICT: { - if (range) { + break; + case VAR_LIST: + len = tv_list_len(rettv->vval.v_list); + if (n1 < 0) { + n1 = len + n1; + } + if (!empty1 && (n1 < 0 || n1 >= len)) { + // For a range we allow invalid values and return an empty + // list. A list index out of range is an error. + if (!range) { if (verbose) { - EMSG(_(e_dictrange)); - } - if (len == -1) { - tv_clear(&var1); + EMSGN(_(e_listidx), n1); } return FAIL; } + n1 = len; + } + if (range) { + list_T *l; + listitem_T *item; - if (len == -1) { - key = (char_u *)tv_get_string_chk(&var1); - if (key == NULL) { - tv_clear(&var1); - return FAIL; - } + if (n2 < 0) { + n2 = len + n2; + } else if (n2 >= len) { + n2 = len - 1; } - - dictitem_T *const item = tv_dict_find(rettv->vval.v_dict, - (const char *)key, len); - - if (item == NULL && verbose) { - emsgf(_(e_dictkey), key); + if (!empty2 && (n2 < 0 || n2 + 1 < n1)) { + n2 = -1; + } + l = tv_list_alloc(n2 - n1 + 1); + item = tv_list_find(rettv->vval.v_list, n1); + while (n1++ <= n2) { + tv_list_append_tv(l, TV_LIST_ITEM_TV(item)); + item = TV_LIST_ITEM_NEXT(rettv->vval.v_list, item); + } + tv_clear(rettv); + tv_list_set_ret(rettv, l); + } else { + tv_copy(TV_LIST_ITEM_TV(tv_list_find(rettv->vval.v_list, n1)), &var1); + tv_clear(rettv); + *rettv = var1; + } + break; + case VAR_DICT: { + if (range) { + if (verbose) { + EMSG(_(e_dictrange)); } if (len == -1) { tv_clear(&var1); } - if (item == NULL || tv_is_luafunc(&item->di_tv)) { + return FAIL; + } + + if (len == -1) { + key = (char_u *)tv_get_string_chk(&var1); + if (key == NULL) { + tv_clear(&var1); return FAIL; } + } - tv_copy(&item->di_tv, &var1); - tv_clear(rettv); - *rettv = var1; - break; + dictitem_T *const item = tv_dict_find(rettv->vval.v_dict, + (const char *)key, len); + + if (item == NULL && verbose) { + emsgf(_(e_dictkey), key); } - case VAR_BOOL: - case VAR_SPECIAL: - case VAR_FUNC: - case VAR_FLOAT: - case VAR_PARTIAL: - case VAR_UNKNOWN: { - break; // Not evaluating, skipping over subscript + if (len == -1) { + tv_clear(&var1); + } + if (item == NULL || tv_is_luafunc(&item->di_tv)) { + return FAIL; } + + tv_copy(&item->di_tv, &var1); + tv_clear(rettv); + *rettv = var1; + break; + } + case VAR_BOOL: + case VAR_SPECIAL: + case VAR_FUNC: + case VAR_FLOAT: + case VAR_PARTIAL: + case VAR_UNKNOWN: + break; // Not evaluating, skipping over subscript } } @@ -4773,12 +4787,11 @@ eval_index( /// @param[in] evaluate If not true, rettv is not populated. /// /// @return OK or FAIL. -int get_option_tv(const char **const arg, typval_T *const rettv, - const bool evaluate) +int get_option_tv(const char **const arg, typval_T *const rettv, const bool evaluate) FUNC_ATTR_NONNULL_ARG(1) { long numval; - char_u *stringval; + char_u *stringval; int opt_type; int c; bool working = (**arg == '+'); // has("+option") @@ -4809,7 +4822,7 @@ int get_option_tv(const char **const arg, typval_T *const rettv, EMSG2(_("E113: Unknown option: %s"), *arg); } ret = FAIL; - } else if (rettv != NULL) { + } else if (rettv != NULL) { if (opt_type == -2) { // hidden string option rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; @@ -4823,8 +4836,9 @@ int get_option_tv(const char **const arg, typval_T *const rettv, rettv->v_type = VAR_STRING; rettv->vval.v_string = stringval; } - } else if (working && (opt_type == -2 || opt_type == -1)) + } else if (working && (opt_type == -2 || opt_type == -1)) { ret = FAIL; + } *option_end = c; // put back for error messages *arg = option_end; @@ -4838,7 +4852,7 @@ int get_option_tv(const char **const arg, typval_T *const rettv, */ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate) { - char_u *p; + char_u *p; unsigned int extra = 0; /* @@ -4880,12 +4894,18 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate) for (p = *arg + 1; *p != NUL && *p != '"'; ) { if (*p == '\\') { switch (*++p) { - case 'b': *name++ = BS; ++p; break; - case 'e': *name++ = ESC; ++p; break; - case 'f': *name++ = FF; ++p; break; - case 'n': *name++ = NL; ++p; break; - case 'r': *name++ = CAR; ++p; break; - case 't': *name++ = TAB; ++p; break; + case 'b': + *name++ = BS; ++p; break; + case 'e': + *name++ = ESC; ++p; break; + case 'f': + *name++ = FF; ++p; break; + case 'n': + *name++ = NL; ++p; break; + case 'r': + *name++ = CAR; ++p; break; + case 't': + *name++ = TAB; ++p; break; case 'X': // hex: "\x1", "\x12" case 'x': @@ -4926,11 +4946,13 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate) case '4': case '5': case '6': - case '7': *name = *p++ - '0'; + case '7': + *name = *p++ - '0'; if (*p >= '0' && *p <= '7') { *name = (*name << 3) + *p++ - '0'; - if (*p >= '0' && *p <= '7') + if (*p >= '0' && *p <= '7') { *name = (*name << 3) + *p++ - '0'; + } } ++name; break; @@ -4947,12 +4969,13 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate) } FALLTHROUGH; - default: MB_COPY_CHAR(p, name); + default: + MB_COPY_CHAR(p, name); break; } - } else + } else { MB_COPY_CHAR(p, name); - + } } *name = NUL; if (*p != NUL) { // just in case @@ -4969,8 +4992,8 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate) */ static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate) { - char_u *p; - char_u *str; + char_u *p; + char_u *str; int reduce = 0; /* @@ -4978,8 +5001,9 @@ static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate) */ for (p = *arg + 1; *p != NUL; MB_PTR_ADV(p)) { if (*p == '\'') { - if (p[1] != '\'') + if (p[1] != '\'') { break; + } ++reduce; ++p; } @@ -5005,8 +5029,9 @@ static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate) for (p = *arg + 1; *p != NUL; ) { if (*p == '\'') { - if (p[1] != '\'') + if (p[1] != '\'') { break; + } ++p; } MB_COPY_CHAR(p, str); @@ -5059,7 +5084,7 @@ void partial_unref(partial_T *pt) /// Return OK or FAIL. static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate) { - list_T *l = NULL; + list_T *l = NULL; if (evaluate) { l = tv_list_alloc(kListLenShouldKnow); @@ -5103,23 +5128,20 @@ failret: return OK; } -bool func_equal( - typval_T *tv1, - typval_T *tv2, - bool ic // ignore case -) { +/// @param ic ignore case +bool func_equal(typval_T *tv1, typval_T *tv2, bool ic) { char_u *s1, *s2; dict_T *d1, *d2; int a1, a2; // empty and NULL function name considered the same s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string - : partial_name(tv1->vval.v_partial); + : partial_name(tv1->vval.v_partial); if (s1 != NULL && *s1 == NUL) { s1 = NULL; } s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string - : partial_name(tv2->vval.v_partial); + : partial_name(tv2->vval.v_partial); if (s2 != NULL && *s2 == NUL) { s2 = NULL; } @@ -5180,9 +5202,9 @@ int get_copyID(void) * are no longer used. But for composite items it's possible that it becomes * unused while the reference count is > 0: When there is a recursive * reference. Example: - * :let l = [1, 2, 3] - * :let d = {9: l} - * :let l[1] = d + * :let l = [1, 2, 3] + * :let d = {9: l} + * :let l[1] = d * * Since this is quite unusual we handle this with garbage collection: every * once in a while find out which lists and dicts are not referenced from any @@ -5190,7 +5212,7 @@ int get_copyID(void) * * Here is a good reference text about garbage collection (refers to Python * but it applies to all reference-counting mechanisms): - * http://python.ca/nas/python/gc/ + * http://python.ca/nas/python/gc/ */ /// Do garbage collection for lists and dicts. @@ -5366,8 +5388,7 @@ bool garbage_collect(bool testing) // This may call us back recursively. did_free = free_unref_funccal(copyID, testing) || did_free; } else if (p_verbose > 0) { - verb_msg(_( - "Not enough memory to set references, garbage collection aborted!")); + verb_msg(_("Not enough memory to set references, garbage collection aborted!")); } #undef ABORTING return did_free; @@ -5461,8 +5482,7 @@ bool set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack) // it is added to ht_stack, if it contains a list it is added to // list_stack. HASHTAB_ITER(cur_ht, hi, { - abort = abort || set_ref_in_item( - &TV_DICT_HI2DI(hi)->di_tv, copyID, &ht_stack, list_stack); + abort = abort || set_ref_in_item(&TV_DICT_HI2DI(hi)->di_tv, copyID, &ht_stack, list_stack); }); } @@ -5528,87 +5548,85 @@ bool set_ref_in_list(list_T *l, int copyID, ht_stack_T **ht_stack) /// @param list_stack Used to add lists to be marked. Can be NULL. /// /// @returns true if setting references failed somehow. -bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, - list_stack_T **list_stack) +bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, list_stack_T **list_stack) FUNC_ATTR_WARN_UNUSED_RESULT { bool abort = false; switch (tv->v_type) { - case VAR_DICT: { - dict_T *dd = tv->vval.v_dict; - if (dd != NULL && dd->dv_copyID != copyID) { - // Didn't see this dict yet. - dd->dv_copyID = copyID; - if (ht_stack == NULL) { - abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack); - } else { - ht_stack_T *const newitem = xmalloc(sizeof(ht_stack_T)); - newitem->ht = &dd->dv_hashtab; - newitem->prev = *ht_stack; - *ht_stack = newitem; - } + case VAR_DICT: { + dict_T *dd = tv->vval.v_dict; + if (dd != NULL && dd->dv_copyID != copyID) { + // Didn't see this dict yet. + dd->dv_copyID = copyID; + if (ht_stack == NULL) { + abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack); + } else { + ht_stack_T *const newitem = xmalloc(sizeof(ht_stack_T)); + newitem->ht = &dd->dv_hashtab; + newitem->prev = *ht_stack; + *ht_stack = newitem; + } - QUEUE *w = NULL; - DictWatcher *watcher = NULL; - QUEUE_FOREACH(w, &dd->watchers, { + QUEUE *w = NULL; + DictWatcher *watcher = NULL; + QUEUE_FOREACH(w, &dd->watchers, { watcher = tv_dict_watcher_node_data(w); set_ref_in_callback(&watcher->callback, copyID, ht_stack, list_stack); }) - } - break; } + break; + } - case VAR_LIST: { - list_T *ll = tv->vval.v_list; - if (ll != NULL && ll->lv_copyID != copyID) { - // Didn't see this list yet. - ll->lv_copyID = copyID; - if (list_stack == NULL) { - abort = set_ref_in_list(ll, copyID, ht_stack); - } else { - list_stack_T *const newitem = xmalloc(sizeof(list_stack_T)); - newitem->list = ll; - newitem->prev = *list_stack; - *list_stack = newitem; - } + case VAR_LIST: { + list_T *ll = tv->vval.v_list; + if (ll != NULL && ll->lv_copyID != copyID) { + // Didn't see this list yet. + ll->lv_copyID = copyID; + if (list_stack == NULL) { + abort = set_ref_in_list(ll, copyID, ht_stack); + } else { + list_stack_T *const newitem = xmalloc(sizeof(list_stack_T)); + newitem->list = ll; + newitem->prev = *list_stack; + *list_stack = newitem; } - break; } + break; + } - case VAR_PARTIAL: { - partial_T *pt = tv->vval.v_partial; + case VAR_PARTIAL: { + partial_T *pt = tv->vval.v_partial; - // A partial does not have a copyID, because it cannot contain itself. - if (pt != NULL) { - abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID); - if (pt->pt_dict != NULL) { - typval_T dtv; + // A partial does not have a copyID, because it cannot contain itself. + if (pt != NULL) { + abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID); + if (pt->pt_dict != NULL) { + typval_T dtv; - dtv.v_type = VAR_DICT; - dtv.vval.v_dict = pt->pt_dict; - abort = abort || set_ref_in_item(&dtv, copyID, ht_stack, list_stack); - } + dtv.v_type = VAR_DICT; + dtv.vval.v_dict = pt->pt_dict; + abort = abort || set_ref_in_item(&dtv, copyID, ht_stack, list_stack); + } - for (int i = 0; i < pt->pt_argc; i++) { - abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID, - ht_stack, list_stack); - } + for (int i = 0; i < pt->pt_argc; i++) { + abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID, + ht_stack, list_stack); } - break; - } - case VAR_FUNC: - abort = set_ref_in_func(tv->vval.v_string, NULL, copyID); - break; - case VAR_UNKNOWN: - case VAR_BOOL: - case VAR_SPECIAL: - case VAR_FLOAT: - case VAR_NUMBER: - case VAR_STRING: - case VAR_BLOB: { - break; } + break; + } + case VAR_FUNC: + abort = set_ref_in_func(tv->vval.v_string, NULL, copyID); + break; + case VAR_UNKNOWN: + case VAR_BOOL: + case VAR_SPECIAL: + case VAR_FLOAT: + case VAR_NUMBER: + case VAR_STRING: + case VAR_BLOB: + break; } return abort; } @@ -5684,15 +5702,14 @@ static int get_literal_key(char_u **arg, typval_T *tv) // Allocate a variable for a Dictionary and fill it from "*arg". // "literal" is true for *{key: val} // Return OK or FAIL. Returns NOTDONE for {expr}. -static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate, - bool literal) +static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate, bool literal) { - dict_T *d = NULL; + dict_T *d = NULL; typval_T tvkey; typval_T tv; - char_u *key = NULL; - dictitem_T *item; - char_u *start = skipwhite(*arg + 1); + char_u *key = NULL; + dictitem_T *item; + char_u *start = skipwhite(*arg + 1); char buf[NUMBUFLEN]; /* @@ -5762,8 +5779,9 @@ static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate, } tv_clear(&tvkey); - if (**arg == '}') + if (**arg == '}') { break; + } if (**arg != ',') { EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); goto failret; @@ -5816,7 +5834,7 @@ size_t string2float(const char *const text, float_T *const ret_value) return 3; } *ret_value = strtod(text, &s); - return (size_t) (s - text); + return (size_t)(s - text); } /// Get the value of an environment variable. @@ -5830,8 +5848,8 @@ static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate) { char_u *name; char_u *string = NULL; - int len; - int cc; + int len; + int cc; ++*arg; name = *arg; @@ -5863,8 +5881,7 @@ static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate) } /// Get the argument list for a given window -void get_arglist_as_rettv(aentry_T *arglist, int argcount, - typval_T *rettv) +void get_arglist_as_rettv(aentry_T *arglist, int argcount, typval_T *rettv) { tv_list_alloc_ret(rettv, argcount); if (arglist != NULL) { @@ -5882,17 +5899,17 @@ void prepare_assert_error(garray_T *gap) ga_init(gap, 1, 100); if (sourcing_name != NULL) { - ga_concat(gap, sourcing_name); + ga_concat(gap, (char *)sourcing_name); if (sourcing_lnum > 0) { - ga_concat(gap, (char_u *)" "); + ga_concat(gap, " "); } } if (sourcing_lnum > 0) { vim_snprintf(buf, ARRAY_SIZE(buf), "line %" PRId64, (int64_t)sourcing_lnum); - ga_concat(gap, (char_u *)buf); + ga_concat(gap, buf); } if (sourcing_name != NULL || sourcing_lnum > 0) { - ga_concat(gap, (char_u *)": "); + ga_concat(gap, ": "); } } @@ -5906,24 +5923,31 @@ static void ga_concat_esc(garray_T *gap, const char_u *p, int clen) if (clen > 1) { memmove(buf, p, clen); buf[clen] = NUL; - ga_concat(gap, buf); + ga_concat(gap, (char *)buf); } else { switch (*p) { - case BS: ga_concat(gap, (char_u *)"\\b"); break; - case ESC: ga_concat(gap, (char_u *)"\\e"); break; - case FF: ga_concat(gap, (char_u *)"\\f"); break; - case NL: ga_concat(gap, (char_u *)"\\n"); break; - case TAB: ga_concat(gap, (char_u *)"\\t"); break; - case CAR: ga_concat(gap, (char_u *)"\\r"); break; - case '\\': ga_concat(gap, (char_u *)"\\\\"); break; - default: - if (*p < ' ') { - vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p); - ga_concat(gap, buf); - } else { - ga_append(gap, *p); - } - break; + case BS: + ga_concat(gap, "\\b"); break; + case ESC: + ga_concat(gap, "\\e"); break; + case FF: + ga_concat(gap, "\\f"); break; + case NL: + ga_concat(gap, "\\n"); break; + case TAB: + ga_concat(gap, "\\t"); break; + case CAR: + ga_concat(gap, "\\r"); break; + case '\\': + ga_concat(gap, "\\\\"); break; + default: + if (*p < ' ') { + vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p); + ga_concat(gap, (char *)buf); + } else { + ga_append(gap, *p); + } + break; } } } @@ -5936,7 +5960,7 @@ static void ga_concat_shorten_esc(garray_T *gap, const char_u *str) char_u buf[NUMBUFLEN]; if (str == NULL) { - ga_concat(gap, (char_u *)"NULL"); + ga_concat(gap, "NULL"); return; } @@ -5950,12 +5974,12 @@ static void ga_concat_shorten_esc(garray_T *gap, const char_u *str) s += clen; } if (same_len > 20) { - ga_concat(gap, (char_u *)"\\["); + ga_concat(gap, "\\["); ga_concat_esc(gap, p, clen); - ga_concat(gap, (char_u *)" occurs "); + ga_concat(gap, " occurs "); vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len); - ga_concat(gap, buf); - ga_concat(gap, (char_u *)" times]"); + ga_concat(gap, (char *)buf); + ga_concat(gap, " times]"); p = s - 1; } else { ga_concat_esc(gap, p, clen); @@ -5964,25 +5988,24 @@ static void ga_concat_shorten_esc(garray_T *gap, const char_u *str) } // Fill "gap" with information about an assert error. -void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, - char_u *exp_str, typval_T *exp_tv, +void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str, typval_T *exp_tv, typval_T *got_tv, assert_type_T atype) { char_u *tofree; if (opt_msg_tv->v_type != VAR_UNKNOWN) { tofree = (char_u *)encode_tv2echo(opt_msg_tv, NULL); - ga_concat(gap, tofree); + ga_concat(gap, (char *)tofree); xfree(tofree); - ga_concat(gap, (char_u *)": "); + ga_concat(gap, ": "); } if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH) { - ga_concat(gap, (char_u *)"Pattern "); + ga_concat(gap, "Pattern "); } else if (atype == ASSERT_NOTEQUAL) { - ga_concat(gap, (char_u *)"Expected not equal to "); + ga_concat(gap, "Expected not equal to "); } else { - ga_concat(gap, (char_u *)"Expected "); + ga_concat(gap, "Expected "); } if (exp_str == NULL) { @@ -5995,11 +6018,11 @@ void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, if (atype != ASSERT_NOTEQUAL) { if (atype == ASSERT_MATCH) { - ga_concat(gap, (char_u *)" does not match "); + ga_concat(gap, " does not match "); } else if (atype == ASSERT_NOTMATCH) { - ga_concat(gap, (char_u *)" does match "); + ga_concat(gap, " does match "); } else { - ga_concat(gap, (char_u *)" but got "); + ga_concat(gap, " but got "); } tofree = (char_u *)encode_tv2string(got_tv, NULL); ga_concat_shorten_esc(gap, tofree); @@ -6103,21 +6126,21 @@ int assert_equalfile(typval_T *argvars) prepare_assert_error(&ga); if (argvars[2].v_type != VAR_UNKNOWN) { char *const tofree = encode_tv2echo(&argvars[2], NULL); - ga_concat(&ga, (char_u *)tofree); + ga_concat(&ga, tofree); xfree(tofree); - ga_concat(&ga, (char_u *)": "); + ga_concat(&ga, ": "); } - ga_concat(&ga, IObuff); + ga_concat(&ga, (char *)IObuff); if (lineidx > 0) { line1[lineidx] = NUL; line2[lineidx] = NUL; - ga_concat(&ga, (char_u *)" after \""); - ga_concat(&ga, (char_u *)line1); + ga_concat(&ga, " after \""); + ga_concat(&ga, line1); if (STRCMP(line1, line2) != 0) { - ga_concat(&ga, (char_u *)"\" vs \""); - ga_concat(&ga, (char_u *)line2); + ga_concat(&ga, "\" vs \""); + ga_concat(&ga, line2); } - ga_concat(&ga, (char_u *)"\""); + ga_concat(&ga, "\""); } assert_error(&ga); ga_clear(&ga); @@ -6143,13 +6166,13 @@ int assert_inrange(typval_T *argvars) prepare_assert_error(&ga); if (argvars[3].v_type != VAR_UNKNOWN) { char_u *const tofree = (char_u *)encode_tv2string(&argvars[3], NULL); - ga_concat(&ga, tofree); + ga_concat(&ga, (char *)tofree); xfree(tofree); } else { char msg[80]; vim_snprintf(msg, sizeof(msg), "Expected range %g - %g, but got %g", flower, fupper, factual); - ga_concat(&ga, (char_u *)msg); + ga_concat(&ga, msg); } assert_error(&ga); ga_clear(&ga); @@ -6170,7 +6193,7 @@ int assert_inrange(typval_T *argvars) char msg[55]; vim_snprintf(msg, sizeof(msg), "range %" PRIdVARNUMBER " - %" PRIdVARNUMBER ",", - lower, upper); + lower, upper); // -V576 fill_assert_error(&ga, &argvars[3], (char_u *)msg, NULL, &argvars[2], ASSERT_INRANGE); assert_error(&ga); @@ -6215,7 +6238,7 @@ int assert_exception(typval_T *argvars) const char *const error = tv_get_string_chk(&argvars[0]); if (vimvars[VV_EXCEPTION].vv_str == NULL) { prepare_assert_error(&ga); - ga_concat(&ga, (char_u *)"v:exception is not set"); + ga_concat(&ga, "v:exception is not set"); assert_error(&ga); ga_clear(&ga); return 1; @@ -6231,16 +6254,15 @@ int assert_exception(typval_T *argvars) return 0; } -static void assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, - const char *cmd) +static void assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, const char *cmd) FUNC_ATTR_NONNULL_ALL { if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) { char *const tofree = encode_tv2echo(&argvars[2], NULL); - ga_concat(gap, (char_u *)tofree); + ga_concat(gap, tofree); xfree(tofree); } else { - ga_concat(gap, (char_u *)cmd); + ga_concat(gap, cmd); } } @@ -6258,11 +6280,11 @@ int assert_beeps(typval_T *argvars, bool no_beep) garray_T ga; prepare_assert_error(&ga); if (no_beep) { - ga_concat(&ga, (const char_u *)"command did beep: "); + ga_concat(&ga, "command did beep: "); } else { - ga_concat(&ga, (const char_u *)"command did not beep: "); + ga_concat(&ga, "command did not beep: "); } - ga_concat(&ga, (const char_u *)cmd); + ga_concat(&ga, cmd); assert_error(&ga); ga_clear(&ga); ret = 1; @@ -6277,9 +6299,9 @@ int assert_fails(typval_T *argvars) FUNC_ATTR_NONNULL_ALL { const char *const cmd = tv_get_string_chk(&argvars[0]); - garray_T ga; + garray_T ga; int ret = 0; - int save_trylevel = trylevel; + int save_trylevel = trylevel; // trylevel must be zero for a ":throw" command to be considered failed trylevel = 0; @@ -6290,7 +6312,7 @@ int assert_fails(typval_T *argvars) do_cmdline_cmd(cmd); if (!called_emsg) { prepare_assert_error(&ga); - ga_concat(&ga, (const char_u *)"command did not fail: "); + ga_concat(&ga, "command did not fail: "); assert_append_cmd_or_arg(&ga, argvars, cmd); assert_error(&ga); ga_clear(&ga); @@ -6304,7 +6326,7 @@ int assert_fails(typval_T *argvars) prepare_assert_error(&ga); fill_assert_error(&ga, &argvars[2], NULL, &argvars[1], &vimvars[VV_ERRMSG].vv_tv, ASSERT_OTHER); - ga_concat(&ga, (char_u *)": "); + ga_concat(&ga, ": "); assert_append_cmd_or_arg(&ga, argvars, cmd); assert_error(&ga); ga_clear(&ga); @@ -6345,7 +6367,7 @@ int assert_match_common(typval_T *argvars, assert_type_T atype) /// Find a window: When using a Window ID in any tab page, when using a number /// in the current tab page. -win_T * find_win_by_nr_or_id(typval_T *vp) +win_T *find_win_by_nr_or_id(typval_T *vp) { int nr = (int)tv_get_number_chk(vp, NULL); @@ -6361,12 +6383,12 @@ win_T * find_win_by_nr_or_id(typval_T *vp) */ void filter_map(typval_T *argvars, typval_T *rettv, int map) { - typval_T *expr; - list_T *l = NULL; - dictitem_T *di; - hashtab_T *ht; - hashitem_T *hi; - dict_T *d = NULL; + typval_T *expr; + list_T *l = NULL; + dictitem_T *di; + hashtab_T *ht; + hashitem_T *hi; + dict_T *d = NULL; typval_T save_val; typval_T save_key; blob_T *b = NULL; @@ -6543,11 +6565,10 @@ theend: return retval; } -void common_function(typval_T *argvars, typval_T *rettv, - bool is_funcref, FunPtr fptr) +void common_function(typval_T *argvars, typval_T *rettv, bool is_funcref, FunPtr fptr) { - char_u *s; - char_u *name; + char_u *s; + char_u *name; bool use_string = false; partial_T *arg_pt = NULL; char_u *trans_name = NULL; @@ -6584,7 +6605,7 @@ void common_function(typval_T *argvars, typval_T *rettv, // Don't check an autoload name for existence here. } else if (trans_name != NULL && (is_funcref ? find_func(trans_name) == NULL - : !translated_function_exists((const char *)trans_name))) { + : !translated_function_exists((const char *)trans_name))) { emsgf(_("E700: Unknown function: %s"), s); } else { int dict_idx = 0; @@ -6760,8 +6781,7 @@ dict_T *get_buffer_info(buf_T *buf) /// be NULL, in this case "$" results in zero return. /// /// @return Line number or 0 in case of error. -linenr_T tv_get_lnum_buf(const typval_T *const tv, - const buf_T *const buf) +linenr_T tv_get_lnum_buf(const typval_T *const tv, const buf_T *const buf) FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT { if (tv->v_type == VAR_STRING @@ -6773,8 +6793,7 @@ linenr_T tv_get_lnum_buf(const typval_T *const tv, return tv_get_number_chk(tv, NULL); } -void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, - typval_T *rettv) +void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, typval_T *rettv) { if (what_arg->v_type == VAR_UNKNOWN) { tv_list_alloc_ret(rettv, kListLenMayKnow); @@ -6845,12 +6864,10 @@ dict_T *get_win_info(win_T *wp, int16_t tpnr, int16_t winnr) return dict; } -// Find window specified by "vp" in tabpage "tp". -win_T * -find_win_by_nr( - typval_T *vp, - tabpage_T *tp // NULL for current tab page -) +/// Find window specified by "vp" in tabpage "tp". +/// +/// @param tp NULL for current tab page +win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp) { int nr = (int)tv_get_number_chk(vp, NULL); @@ -6864,7 +6881,7 @@ find_win_by_nr( // This method accepts NULL as an alias for curtab. if (tp == NULL) { - tp = curtab; + tp = curtab; } FOR_ALL_WINDOWS_IN_TAB(wp, tp) { @@ -6905,15 +6922,10 @@ win_T *find_tabwin(typval_T *wvp, typval_T *tvp) return wp; } -/* - * getwinvar() and gettabwinvar() - */ -void -getwinvar( - typval_T *argvars, - typval_T *rettv, - int off // 1 for gettabwinvar() -) +/// getwinvar() and gettabwinvar() +/// +/// @param off 1 for gettabwinvar() +void getwinvar(typval_T *argvars, typval_T *rettv, int off) { win_T *win, *oldcurwin; dictitem_T *v; @@ -6984,9 +6996,7 @@ getwinvar( * prompt. The third argument to f_inputdialog() specifies the value to return * when the user cancels the prompt. */ -void get_user_input(const typval_T *const argvars, - typval_T *const rettv, - const bool inputdialog, +void get_user_input(const typval_T *const argvars, typval_T *const rettv, const bool inputdialog, const bool secret) FUNC_ATTR_NONNULL_ALL { @@ -7121,8 +7131,7 @@ void get_user_input(const typval_T *const argvars, /// a dictionary, will give an error if not. /// @param[out] rettv Location where result will be saved. /// @param[in] what What to save in rettv. -void dict_list(typval_T *const tv, typval_T *const rettv, - const DictListType what) +void dict_list(typval_T *const tv, typval_T *const rettv, const DictListType what) { if (tv->v_type != VAR_DICT) { EMSG(_(e_dictreq)); @@ -7138,32 +7147,30 @@ void dict_list(typval_T *const tv, typval_T *const rettv, typval_T tv_item = { .v_lock = VAR_UNLOCKED }; switch (what) { - case kDictListKeys: { - tv_item.v_type = VAR_STRING; - tv_item.vval.v_string = vim_strsave(di->di_key); - break; - } - case kDictListValues: { - tv_copy(&di->di_tv, &tv_item); - break; - } - case kDictListItems: { - // items() - list_T *const sub_l = tv_list_alloc(2); - tv_item.v_type = VAR_LIST; - tv_item.vval.v_list = sub_l; - tv_list_ref(sub_l); - - tv_list_append_owned_tv(sub_l, (typval_T) { + case kDictListKeys: + tv_item.v_type = VAR_STRING; + tv_item.vval.v_string = vim_strsave(di->di_key); + break; + case kDictListValues: + tv_copy(&di->di_tv, &tv_item); + break; + case kDictListItems: { + // items() + list_T *const sub_l = tv_list_alloc(2); + tv_item.v_type = VAR_LIST; + tv_item.vval.v_list = sub_l; + tv_list_ref(sub_l); + + tv_list_append_owned_tv(sub_l, (typval_T) { .v_type = VAR_STRING, .v_lock = VAR_UNLOCKED, .vval.v_string = (char_u *)xstrdup((const char *)di->di_key), }); - tv_list_append_tv(sub_l, &di->di_tv); + tv_list_append_tv(sub_l, &di->di_tv); - break; - } + break; + } } tv_list_append_owned_tv(rettv->vval.v_list, tv_item); @@ -7244,9 +7251,7 @@ char **tv_to_argv(typval_T *cmd_tv, const char **cmd, bool *executable) /// @param mp The maphash that contains the mapping information /// @param buffer_value The "buffer" value /// @param compatible True for compatible with old maparg() dict -void mapblock_fill_dict(dict_T *const dict, - const mapblock_T *const mp, - long buffer_value, +void mapblock_fill_dict(dict_T *const dict, const mapblock_T *const mp, long buffer_value, bool compatible) FUNC_ATTR_NONNULL_ALL { @@ -7284,8 +7289,7 @@ void mapblock_fill_dict(dict_T *const dict, tv_dict_add_allocated_str(dict, S_LEN("mode"), mapmode); } -int matchadd_dict_arg(typval_T *tv, const char **conceal_char, - win_T **win) +int matchadd_dict_arg(typval_T *tv, const char **conceal_char, win_T **win) { dictitem_T *di; @@ -7333,18 +7337,18 @@ void screenchar_adjust_grid(ScreenGrid **grid, int *row, int *col) } /// Set line or list of lines in buffer "buf". -void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, - const typval_T *lines, typval_T *rettv) +void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T *lines, + typval_T *rettv) FUNC_ATTR_NONNULL_ARG(4, 5) { linenr_T lnum = lnum_arg + (append ? 1 : 0); const char *line = NULL; - list_T *l = NULL; - listitem_T *li = NULL; - long added = 0; + list_T *l = NULL; + listitem_T *li = NULL; + long added = 0; linenr_T append_lnum; - buf_T *curbuf_save = NULL; - win_T *curwin_save = NULL; + buf_T *curbuf_save = NULL; + win_T *curwin_save = NULL; const bool is_curbuf = buf == curbuf; // When using the current buffer ml_mfp will be set if needed. Useful when @@ -7444,8 +7448,8 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, } if (!is_curbuf) { - curbuf = curbuf_save; - curwin = curwin_save; + curbuf = curbuf_save; + curwin = curwin_save; } } @@ -7470,8 +7474,8 @@ void setwinvar(typval_T *argvars, typval_T *rettv, int off) typval_T *varp = &argvars[off + 2]; if (win != NULL && varname != NULL && varp != NULL) { - win_T *save_curwin; - tabpage_T *save_curtab; + win_T *save_curwin; + tabpage_T *save_curtab; bool need_switch_win = tp != curtab || win != curwin; if (!need_switch_win || switch_win(&save_curwin, &save_curtab, win, tp, true) == OK) { @@ -7539,8 +7543,7 @@ static list_T *string_to_list(const char *str, size_t len, const bool keepempty) } // os_system wrapper. Handles 'verbose', :profile, and v:shell_error. -void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv, - bool retlist) +void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv, bool retlist) { proftime_T wait_time; bool profiling = do_profiling == PROF_YES; @@ -7595,14 +7598,14 @@ void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv, xfree(input); - set_vim_var_nr(VV_SHELL_ERROR, (long) status); + set_vim_var_nr(VV_SHELL_ERROR, (long)status); if (res == NULL) { if (retlist) { // return an empty list when there's no output tv_list_alloc_ret(rettv, 0); } else { - rettv->vval.v_string = (char_u *) xstrdup(""); + rettv->vval.v_string = (char_u *)xstrdup(""); } return; } @@ -7634,7 +7637,7 @@ void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv, *d = NUL; #endif - rettv->vval.v_string = (char_u *) res; + rettv->vval.v_string = (char_u *)res; } } @@ -7687,29 +7690,29 @@ bool callback_from_typval(Callback *const callback, typval_T *const arg) return true; } -bool callback_call(Callback *const callback, const int argcount_in, - typval_T *const argvars_in, typval_T *const rettv) +bool callback_call(Callback *const callback, const int argcount_in, typval_T *const argvars_in, + typval_T *const rettv) FUNC_ATTR_NONNULL_ALL { partial_T *partial; char_u *name; switch (callback->type) { - case kCallbackFuncref: - name = callback->data.funcref; - partial = NULL; - break; + case kCallbackFuncref: + name = callback->data.funcref; + partial = NULL; + break; - case kCallbackPartial: - partial = callback->data.partial; - name = partial_name(partial); - break; + case kCallbackPartial: + partial = callback->data.partial; + name = partial_name(partial); + break; - case kCallbackNone: - return false; - break; + case kCallbackNone: + return false; + break; - default: - abort(); + default: + abort(); } funcexe_T funcexe = FUNCEXE_INIT; @@ -7720,31 +7723,29 @@ bool callback_call(Callback *const callback, const int argcount_in, return call_func(name, -1, rettv, argcount_in, argvars_in, &funcexe); } -static bool set_ref_in_callback(Callback *callback, int copyID, - ht_stack_T **ht_stack, +static bool set_ref_in_callback(Callback *callback, int copyID, ht_stack_T **ht_stack, list_stack_T **list_stack) { typval_T tv; switch (callback->type) { - case kCallbackFuncref: - case kCallbackNone: - break; + case kCallbackFuncref: + case kCallbackNone: + break; - case kCallbackPartial: - tv.v_type = VAR_PARTIAL; - tv.vval.v_partial = callback->data.partial; - return set_ref_in_item(&tv, copyID, ht_stack, list_stack); - break; + case kCallbackPartial: + tv.v_type = VAR_PARTIAL; + tv.vval.v_partial = callback->data.partial; + return set_ref_in_item(&tv, copyID, ht_stack, list_stack); + break; - default: - abort(); + default: + abort(); } return false; } -static bool set_ref_in_callback_reader(CallbackReader *reader, int copyID, - ht_stack_T **ht_stack, +static bool set_ref_in_callback_reader(CallbackReader *reader, int copyID, ht_stack_T **ht_stack, list_stack_T **list_stack) { if (set_ref_in_callback(&reader->cb, copyID, ht_stack, list_stack)) { @@ -7762,7 +7763,7 @@ static bool set_ref_in_callback_reader(CallbackReader *reader, int copyID, timer_T *find_timer_by_nr(varnumber_T xx) { - return pmap_get(uint64_t)(&timers, xx); + return pmap_get(uint64_t)(&timers, xx); } void add_timer_info(typval_T *rettv, timer_T *timer) @@ -7851,9 +7852,7 @@ void timer_due_cb(TimeWatcher *tw, void *data) timer_decref(timer); } -uint64_t timer_start(const long timeout, - const int repeat_count, - const Callback *const callback) +uint64_t timer_start(const long timeout, const int repeat_count, const Callback *const callback) { timer_T *timer = xmalloc(sizeof *timer); timer->refcount = 1; @@ -7924,8 +7923,7 @@ void timer_teardown(void) /// @param[in] binary Whether to write in binary mode. /// /// @return true in case of success, false otherwise. -bool write_list(FileDescriptor *const fp, const list_T *const list, - const bool binary) +bool write_list(FileDescriptor *const fp, const list_T *const list, const bool binary) FUNC_ATTR_NONNULL_ARG(1) { int error = 0; @@ -8123,16 +8121,15 @@ char *save_tv_as_string(typval_T *tv, ptrdiff_t *const len, bool endnl) /// @param[out] ret_fnum Set to fnum for marks. /// /// @return Pointer to position or NULL in case of error (e.g. invalid type). -pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum, - int *const ret_fnum) +pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum, int *const ret_fnum) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { static pos_T pos; - pos_T *pp; + pos_T *pp; // Argument can be [lnum, col, coladd]. if (tv->v_type == VAR_LIST) { - list_T *l; + list_T *l; int len; bool error = false; listitem_T *li; @@ -8350,10 +8347,7 @@ int get_id_len(const char **const arg) * If the name contains 'magic' {}'s, expand them and return the * expanded name in an allocated string via 'alias' - caller must free. */ -int get_name_len(const char **const arg, - char **alias, - bool evaluate, - bool verbose) +int get_name_len(const char **const arg, char **alias, bool evaluate, bool verbose) { int len; @@ -8372,8 +8366,8 @@ int get_name_len(const char **const arg, } // Find the end of the name; check for {} construction. - char_u *expr_start; - char_u *expr_end; + char_u *expr_start; + char_u *expr_end; const char *p = (const char *)find_name_end((char_u *)(*arg), (const char_u **)&expr_start, (const char_u **)&expr_end, @@ -8415,8 +8409,8 @@ int get_name_len(const char **const arg, // "flags" can have FNE_INCL_BR and FNE_CHECK_START. // Return a pointer to just after the name. Equal to "arg" if there is no // valid name. -const char_u *find_name_end(const char_u *arg, const char_u **expr_start, - const char_u **expr_end, int flags) +const char_u *find_name_end(const char_u *arg, const char_u **expr_start, const char_u **expr_end, + int flags) { int mb_nest = 0; int br_nest = 0; @@ -8497,24 +8491,25 @@ const char_u *find_name_end(const char_u *arg, const char_u **expr_start, * Note that this can call itself recursively, to deal with * constructs like foo{bar}{baz}{bam} * The four pointer arguments point to "foo{expre}ss{ion}bar" - * "in_start" ^ - * "expr_start" ^ - * "expr_end" ^ - * "in_end" ^ + * "in_start" ^ + * "expr_start" ^ + * "expr_end" ^ + * "in_end" ^ * * Returns a new allocated string, which the caller must free. * Returns NULL for failure. */ -static char_u *make_expanded_name(const char_u *in_start, char_u *expr_start, - char_u *expr_end, char_u *in_end) +static char_u *make_expanded_name(const char_u *in_start, char_u *expr_start, char_u *expr_end, + char_u *in_end) { char_u c1; - char_u *retval = NULL; - char_u *temp_result; - char_u *nextcmd = NULL; + char_u *retval = NULL; + char_u *temp_result; + char_u *nextcmd = NULL; - if (expr_end == NULL || in_end == NULL) + if (expr_end == NULL || in_end == NULL) { return NULL; + } *expr_start = NUL; *expr_end = NUL; c1 = *in_end; @@ -8541,7 +8536,7 @@ static char_u *make_expanded_name(const char_u *in_start, char_u *expr_start, if (expr_start != NULL) { // Further expansion! temp_result = make_expanded_name(retval, expr_start, - expr_end, temp_result); + expr_end, temp_result); xfree(retval); retval = temp_result; } @@ -8617,8 +8612,9 @@ void set_vim_var_char(int c) */ void set_vcount(long count, long count1, int set_prevcount) { - if (set_prevcount) + if (set_prevcount) { vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; + } vimvars[VV_COUNT].vv_nr = count; vimvars[VV_COUNT1].vv_nr = count1; } @@ -8662,17 +8658,16 @@ void set_vim_var_special(const VimVarIndex idx, const SpecialVarValue val) /// @param[in] val Value to set to. Will be copied. /// @param[in] len Length of that value or -1 in which case strlen() will be /// used. -void set_vim_var_string(const VimVarIndex idx, const char *const val, - const ptrdiff_t len) +void set_vim_var_string(const VimVarIndex idx, const char *const val, const ptrdiff_t len) { tv_clear(&vimvars[idx].vv_di.di_tv); vimvars[idx].vv_type = VAR_STRING; if (val == NULL) { vimvars[idx].vv_str = NULL; } else if (len == -1) { - vimvars[idx].vv_str = (char_u *) xstrdup(val); + vimvars[idx].vv_str = (char_u *)xstrdup(val); } else { - vimvars[idx].vv_str = (char_u *) xstrndup(val, (size_t) len); + vimvars[idx].vv_str = (char_u *)xstrndup(val, (size_t)len); } } @@ -8748,8 +8743,9 @@ void set_reg_var(int c) */ char_u *v_exception(char_u *oldval) { - if (oldval == NULL) + if (oldval == NULL) { return vimvars[VV_EXCEPTION].vv_str; + } vimvars[VV_EXCEPTION].vv_str = oldval; return NULL; @@ -8763,8 +8759,9 @@ char_u *v_exception(char_u *oldval) */ char_u *v_throwpoint(char_u *oldval) { - if (oldval == NULL) + if (oldval == NULL) { return vimvars[VV_THROWPOINT].vv_str; + } vimvars[VV_THROWPOINT].vv_str = oldval; return NULL; @@ -8786,13 +8783,15 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg) } size_t len = 0; - if (eap->force_bin == FORCE_BIN) + if (eap->force_bin == FORCE_BIN) { len = 6; - else if (eap->force_bin == FORCE_NOBIN) + } else if (eap->force_bin == FORCE_NOBIN) { len = 8; + } - if (eap->read_edit) + if (eap->read_edit) { len += 7; + } if (eap->force_ff != 0) { len += 10; // " ++ff=unix" @@ -8807,15 +8806,17 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg) const size_t newval_len = len + 1; char_u *newval = xmalloc(newval_len); - if (eap->force_bin == FORCE_BIN) - sprintf((char *)newval, " ++bin"); - else if (eap->force_bin == FORCE_NOBIN) - sprintf((char *)newval, " ++nobin"); - else + if (eap->force_bin == FORCE_BIN) { + snprintf((char *)newval, newval_len, " ++bin"); + } else if (eap->force_bin == FORCE_NOBIN) { + snprintf((char *)newval, newval_len, " ++nobin"); + } else { *newval = NUL; + } - if (eap->read_edit) + if (eap->read_edit) { STRCAT(newval, " ++edit"); + } if (eap->force_ff != 0) { snprintf((char *)newval + STRLEN(newval), newval_len, " ++ff=%s", @@ -8838,20 +8839,20 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg) return oldval; } -// Get the value of internal variable "name". -// Return OK or FAIL. If OK is returned "rettv" must be cleared. -int get_var_tv( - const char *name, - int len, // length of "name" - typval_T *rettv, // NULL when only checking existence - dictitem_T **dip, // non-NULL when typval's dict item is needed - int verbose, // may give error message - int no_autoload // do not use script autoloading -) +/// Get the value of internal variable "name". +/// Return OK or FAIL. If OK is returned "rettv" must be cleared. +/// +/// @param len length of "name" +/// @param rettv NULL when only checking existence +/// @param dip non-NULL when typval's dict item is needed +/// @param verbose may give error message +/// @param no_autoload do not use script autoloading +int get_var_tv(const char *name, int len, typval_T *rettv, dictitem_T **dip, int verbose, + int no_autoload) { int ret = OK; - typval_T *tv = NULL; - dictitem_T *v; + typval_T *tv = NULL; + dictitem_T *v; v = find_var(name, (size_t)len, NULL, no_autoload); if (v != NULL) { @@ -8934,15 +8935,13 @@ int check_luafunc_name(const char *const str, const bool paren) /// - method call: var->method() /// /// Can all be combined in any order: dict.func(expr)[idx]['func'](expr)->len() -int -handle_subscript( - const char **const arg, - typval_T *rettv, - int evaluate, // do more than finding the end - int verbose, // give error messages - const char_u *const start_leader, // start of '!' and '-' prefixes - const char_u **const end_leaderp // end of '!' and '-' prefixes -) +/// +/// @param evaluate do more than finding the end +/// @param verbose give error messages +/// @param start_leader start of '!' and '-' prefixes +/// @param end_leaderp end of '!' and '-' prefixes +int handle_subscript(const char **const arg, typval_T *rettv, int evaluate, int verbose, + const char_u *const start_leader, const char_u **const end_leaderp) { int ret = OK; dict_T *selfdict = NULL; @@ -9005,10 +9004,12 @@ handle_subscript( tv_dict_unref(selfdict); if (rettv->v_type == VAR_DICT) { selfdict = rettv->vval.v_dict; - if (selfdict != NULL) + if (selfdict != NULL) { ++selfdict->dv_refcount; - } else + } + } else { selfdict = NULL; + } if (eval_index((char_u **)arg, rettv, evaluate, verbose) == FAIL) { tv_clear(rettv); ret = FAIL; @@ -9041,8 +9042,8 @@ void set_selfdict(typval_T *const rettv, dict_T *const selfdict) // Careful: "a:0" variables don't have a name. // When "htp" is not NULL we are writing to the variable, set "htp" to the // hashtab_T used. -dictitem_T *find_var(const char *const name, const size_t name_len, - hashtab_T **htp, int no_autoload) +dictitem_T *find_var(const char *const name, const size_t name_len, hashtab_T **htp, + int no_autoload) { const char *varname; hashtab_T *const ht = find_var_ht(name, name_len, &varname); @@ -9076,26 +9077,31 @@ dictitem_T *find_var(const char *const name, const size_t name_len, /// /// @return pointer to the dictionary item with the found variable or NULL if it /// was not found. -dictitem_T *find_var_in_ht(hashtab_T *const ht, - int htname, - const char *const varname, - const size_t varname_len, - int no_autoload) +dictitem_T *find_var_in_ht(hashtab_T *const ht, int htname, const char *const varname, + const size_t varname_len, int no_autoload) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - hashitem_T *hi; + hashitem_T *hi; if (varname_len == 0) { // Must be something like "s:", otherwise "ht" would be NULL. switch (htname) { - case 's': return (dictitem_T *)&SCRIPT_SV(current_sctx.sc_sid)->sv_var; - case 'g': return (dictitem_T *)&globvars_var; - case 'v': return (dictitem_T *)&vimvars_var; - case 'b': return (dictitem_T *)&curbuf->b_bufvar; - case 'w': return (dictitem_T *)&curwin->w_winvar; - case 't': return (dictitem_T *)&curtab->tp_winvar; - case 'l': return get_funccal_local_var(); - case 'a': return get_funccal_args_var(); + case 's': + return (dictitem_T *)&SCRIPT_SV(current_sctx.sc_sid)->sv_var; + case 'g': + return (dictitem_T *)&globvars_var; + case 'v': + return (dictitem_T *)&vimvars_var; + case 'b': + return (dictitem_T *)&curbuf->b_bufvar; + case 'w': + return (dictitem_T *)&curwin->w_winvar; + case 't': + return (dictitem_T *)&curtab->tp_winvar; + case 'l': + return get_funccal_local_var(); + case 'a': + return get_funccal_args_var(); } return NULL; } @@ -9130,8 +9136,8 @@ dictitem_T *find_var_in_ht(hashtab_T *const ht, /// @param[out] d Scope dictionary. /// /// @return Scope hashtab, NULL if name is not valid. -static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len, - const char **varname, dict_T **d) +static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len, const char **varname, + dict_T **d) { hashitem_T *hi; funccall_T *funccal = get_funccal(); @@ -9185,8 +9191,12 @@ static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len, } else if (*name == 'l' && funccal != NULL) { // local variable *d = &funccal->l_vars; } else if (*name == 's' // script variable - && current_sctx.sc_sid > 0 + && (current_sctx.sc_sid > 0 || current_sctx.sc_sid == SID_STR) && current_sctx.sc_sid <= ga_scripts.ga_len) { + // For anonymous scripts without a script item, create one now so script vars can be used + if (current_sctx.sc_sid == SID_STR) { + new_script_item(NULL, ¤t_sctx.sc_sid); + } *d = &SCRIPT_SV(current_sctx.sc_sid)->sv_dict; } @@ -9202,8 +9212,7 @@ end: /// prefix. /// /// @return Scope hashtab, NULL if name is not valid. -hashtab_T *find_var_ht(const char *name, const size_t name_len, - const char **varname) +hashtab_T *find_var_ht(const char *name, const size_t name_len, const char **varname) { dict_T *d; return find_var_ht_dict(name, name_len, varname, &d); @@ -9216,7 +9225,7 @@ hashtab_T *find_var_ht(const char *name, const size_t name_len, */ char_u *get_var_value(const char *const name) { - dictitem_T *v; + dictitem_T *v; v = find_var(name, strlen(name), NULL, false); if (v == NULL) { @@ -9231,7 +9240,7 @@ char_u *get_var_value(const char *const name) */ void new_script_vars(scid_T id) { - hashtab_T *ht; + hashtab_T *ht; scriptvar_T *sv; ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)); @@ -9241,8 +9250,9 @@ void new_script_vars(scid_T id) * at its init value. Also reset "v_dict", it's always the same. */ for (int i = 1; i <= ga_scripts.ga_len; ++i) { ht = &SCRIPT_VARS(i); - if (ht->ht_mask == HT_INIT_SIZE - 1) + if (ht->ht_mask == HT_INIT_SIZE - 1) { ht->ht_array = ht->ht_smallarray; + } sv = SCRIPT_SV(i); sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; } @@ -9301,8 +9311,8 @@ void vars_clear(hashtab_T *ht) void vars_clear_ext(hashtab_T *ht, int free_val) { int todo; - hashitem_T *hi; - dictitem_T *v; + hashitem_T *hi; + dictitem_T *v; hash_lock(ht); todo = (int)ht->ht_used; @@ -9332,7 +9342,7 @@ void vars_clear_ext(hashtab_T *ht, int free_val) */ static void delete_var(hashtab_T *ht, hashitem_T *hi) { - dictitem_T *di = TV_DICT_HI2DI(hi); + dictitem_T *di = TV_DICT_HI2DI(hi); hash_remove(ht, hi); tv_clear(&di->di_tv); @@ -9353,9 +9363,8 @@ static void list_one_var(dictitem_T *v, const char *prefix, int *first) /// @param[in] name_len Length of the name. May be -1, in this case strlen() /// will be used. /// @param[in,out] first When true clear rest of screen and set to false. -static void list_one_var_a(const char *prefix, const char *name, - const ptrdiff_t name_len, const int type, - const char *string, int *first) +static void list_one_var_a(const char *prefix, const char *name, const ptrdiff_t name_len, + const int type, const char *string, int *first) { // don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" msg_start(); @@ -9371,14 +9380,17 @@ static void list_one_var_a(const char *prefix, const char *name, msg_putchar('*'); } else if (type == VAR_LIST) { msg_putchar('['); - if (*string == '[') + if (*string == '[') { ++string; + } } else if (type == VAR_DICT) { msg_putchar('{'); - if (*string == '{') + if (*string == '{') { ++string; - } else + } + } else { msg_putchar(' '); + } msg_outtrans((char_u *)string); @@ -9400,8 +9412,7 @@ static void list_one_var_a(const char *prefix, const char *name, /// @param[in] name_len Length of the variable name. /// @param tv Variable value. /// @param[in] copy True if value in tv is to be copied. -void set_var(const char *name, const size_t name_len, typval_T *const tv, - const bool copy) +void set_var(const char *name, const size_t name_len, typval_T *const tv, const bool copy) FUNC_ATTR_NONNULL_ALL { set_var_const(name, name_len, tv, copy, false); @@ -9417,13 +9428,12 @@ void set_var(const char *name, const size_t name_len, typval_T *const tv, /// @param tv Variable value. /// @param[in] copy True if value in tv is to be copied. /// @param[in] is_const True if value in tv is to be locked. -static void set_var_const(const char *name, const size_t name_len, - typval_T *const tv, const bool copy, - const bool is_const) +static void set_var_const(const char *name, const size_t name_len, typval_T *const tv, + const bool copy, const bool is_const) FUNC_ATTR_NONNULL_ALL { - dictitem_T *v; - hashtab_T *ht; + dictitem_T *v; + hashtab_T *ht; dict_T *dict; const char *varname; @@ -9438,7 +9448,7 @@ static void set_var_const(const char *name, const size_t name_len, // Search in parent scope which is possible to reference from lambda if (v == NULL) { - v = find_var_in_scoped_ht((const char *)name, name_len, true); + v = find_var_in_scoped_ht(name, name_len, true); } if (tv_is_func(*tv) && !var_check_func_name(name, v == NULL)) { @@ -9567,8 +9577,7 @@ static void set_var_const(const char *name, const size_t name_len, /// /// @return True if variable is read-only: either always or in sandbox when /// sandbox is enabled, false otherwise. -bool var_check_ro(const int flags, const char *name, - size_t name_len) +bool var_check_ro(const int flags, const char *name, size_t name_len) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { const char *error_message = NULL; @@ -9611,8 +9620,7 @@ bool var_check_ro(const int flags, const char *name, /// gettext. /// /// @return True if variable is fixed, false otherwise. -bool var_check_fixed(const int flags, const char *name, - size_t name_len) +bool var_check_fixed(const int flags, const char *name, size_t name_len) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { if (flags & DI_FLAGS_FIX) { @@ -9650,7 +9658,7 @@ bool var_check_func_name(const char *const name, const bool new_var) // Don't allow hiding a function. When "v" is not NULL we might be // assigning another function to the same var, the type is checked // below. - if (new_var && function_exists((const char *)name, false)) { + if (new_var && function_exists(name, false)) { EMSG2(_("E705: Variable name conflicts with existing function: %s"), name); return false; @@ -9696,11 +9704,8 @@ bool valid_varname(const char *varname) /// a copy with (`copy[0] isnot copy[1]`), with non-zero it /// will emit a copy with (`copy[0] is copy[1]`) like in the /// original list. Not used when deep is false. -int var_item_copy(const vimconv_T *const conv, - typval_T *const from, - typval_T *const to, - const bool deep, - const int copyID) +int var_item_copy(const vimconv_T *const conv, typval_T *const from, typval_T *const to, + const bool deep, const int copyID) FUNC_ATTR_NONNULL_ARG(2, 3) { static int recurse = 0; @@ -9732,7 +9737,7 @@ int var_item_copy(const vimconv_T *const conv, from->vval.v_string, NULL)) == NULL) { - to->vval.v_string = (char_u *) xstrdup((char *) from->vval.v_string); + to->vval.v_string = (char_u *)xstrdup((char *)from->vval.v_string); } } break; @@ -9780,21 +9785,22 @@ int var_item_copy(const vimconv_T *const conv, } /* - * ":echo expr1 ..." print each argument separated with a space, add a - * newline at the end. - * ":echon expr1 ..." print each argument plain. + * ":echo expr1 ..." print each argument separated with a space, add a + * newline at the end. + * ":echon expr1 ..." print each argument plain. */ void ex_echo(exarg_T *eap) { - char_u *arg = eap->arg; + char_u *arg = eap->arg; typval_T rettv; bool atstart = true; bool need_clear = true; const int did_emsg_before = did_emsg; const int called_emsg_before = called_emsg; - if (eap->skip) + if (eap->skip) { ++emsg_skip; + } while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) { // If eval1() causes an error message the text from the command may // still need to be cleared. E.g., "echo 22,44". @@ -9865,9 +9871,9 @@ void ex_echohl(exarg_T *eap) } /* - * ":execute expr1 ..." execute the result of an expression. - * ":echomsg expr1 ..." Print a message - * ":echoerr expr1 ..." Print an error + * ":execute expr1 ..." execute the result of an expression. + * ":echomsg expr1 ..." Print a message + * ":echoerr expr1 ..." Print an error * Each gets spaces around each argument and a newline at the end for * echo commands */ @@ -9881,8 +9887,9 @@ void ex_execute(exarg_T *eap) ga_init(&ga, 1, 80); - if (eap->skip) + if (eap->skip) { ++emsg_skip; + } while (*arg != NUL && *arg != '|' && *arg != '\n') { ret = eval1_emsg(&arg, &rettv, !eap->skip); if (ret == FAIL) { @@ -9928,17 +9935,20 @@ void ex_execute(exarg_T *eap) save_did_emsg = did_emsg; msg_ext_set_kind("echoerr"); EMSG((char_u *)ga.ga_data); - if (!force_abort) + if (!force_abort) { did_emsg = save_did_emsg; - } else if (eap->cmdidx == CMD_execute) + } + } else if (eap->cmdidx == CMD_execute) { do_cmdline((char_u *)ga.ga_data, - eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); + eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); + } } ga_clear(&ga); - if (eap->skip) + if (eap->skip) { --emsg_skip; + } eap->nextcmd = check_nextcmd(arg); } @@ -10016,10 +10026,10 @@ void func_do_profile(ufunc_T *fp) */ void func_dump_profile(FILE *fd) { - hashitem_T *hi; + hashitem_T *hi; int todo; - ufunc_T *fp; - ufunc_T **sorttab; + ufunc_T *fp; + ufunc_T **sorttab; int st_len = 0; todo = (int)func_hashtab.ht_used; @@ -10045,7 +10055,7 @@ void func_dump_profile(FILE *fd) bool should_free; const LastSet last_set = (LastSet){ .script_ctx = fp->uf_script_ctx, - .channel_id = 0, + .channel_id = 0, }; char_u *p = get_scriptname(last_set, &should_free); fprintf(fd, " Defined: %s:%" PRIdLINENR "\n", @@ -10065,10 +10075,11 @@ void func_dump_profile(FILE *fd) fprintf(fd, "count total (s) self (s)\n"); for (int i = 0; i < fp->uf_lines.ga_len; ++i) { - if (FUNCLINE(fp, i) == NULL) + if (FUNCLINE(fp, i) == NULL) { continue; + } prof_func_line(fd, fp->uf_tml_count[i], - &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); + &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); fprintf(fd, "%s\n", FUNCLINE(fp, i)); } fprintf(fd, "\n"); @@ -10078,65 +10089,58 @@ void func_dump_profile(FILE *fd) if (st_len > 0) { qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), - prof_total_cmp); + prof_total_cmp); prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), - prof_self_cmp); + prof_self_cmp); prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); } xfree(sorttab); } -static void -prof_sort_list( - FILE *fd, - ufunc_T **sorttab, - int st_len, - char *title, - int prefer_self // when equal print only self time -) +/// @param prefer_self when equal print only self time +static void prof_sort_list(FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self) { int i; - ufunc_T *fp; + ufunc_T *fp; fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); fprintf(fd, "count total (s) self (s) function\n"); for (i = 0; i < 20 && i < st_len; ++i) { fp = sorttab[i]; prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, - prefer_self); - if (fp->uf_name[0] == K_SPECIAL) + prefer_self); + if (fp->uf_name[0] == K_SPECIAL) { fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); - else + } else { fprintf(fd, " %s()\n", fp->uf_name); + } } fprintf(fd, "\n"); } -/* - * Print the count and times for one function or function line. - */ -static void prof_func_line( - FILE *fd, - int count, - proftime_T *total, - proftime_T *self, - int prefer_self // when equal print only self time -) +/// Print the count and times for one function or function line. +/// +/// @param prefer_self when equal print only self time +static void prof_func_line(FILE *fd, int count, proftime_T *total, proftime_T *self, + int prefer_self) { if (count > 0) { fprintf(fd, "%5d ", count); - if (prefer_self && profile_equal(*total, *self)) + if (prefer_self && profile_equal(*total, *self)) { fprintf(fd, " "); - else + } else { fprintf(fd, "%s ", profile_msg(*total)); - if (!prefer_self && profile_equal(*total, *self)) + } + if (!prefer_self && profile_equal(*total, *self)) { fprintf(fd, " "); - else + } else { fprintf(fd, "%s ", profile_msg(*self)); - } else + } + } else { fprintf(fd, " "); + } } /* @@ -10194,8 +10198,7 @@ char *autoload_name(const char *const name, const size_t name_len) /// @param[in] reload If true, load script again when already loaded. /// /// @return true if a package was loaded. -bool script_autoload(const char *const name, const size_t name_len, - const bool reload) +bool script_autoload(const char *const name, const size_t name_len, const bool reload) { // If there is no '#' after name[0] there is no package name. const char *p = memchr(name, AUTOLOAD_CHAR, name_len); @@ -10225,7 +10228,7 @@ bool script_autoload(const char *const name, const size_t name_len, } // Try loading the package from $VIMRUNTIME/autoload/<name>.vim - if (source_runtime((char_u *)scriptname, 0) == OK) { + if (source_runtime(scriptname, 0) == OK) { ret = true; } } @@ -10242,8 +10245,8 @@ bool script_autoload(const char *const name, const size_t name_len, */ void func_line_start(void *cookie) { - funccall_T *fcp = (funccall_T *)cookie; - ufunc_T *fp = fcp->func; + funccall_T *fcp = (funccall_T *)cookie; + ufunc_T *fp = fcp->func; if (fp->uf_profiling && sourcing_lnum >= 1 && sourcing_lnum <= fp->uf_lines.ga_len) { @@ -10264,11 +10267,12 @@ void func_line_start(void *cookie) */ void func_line_exec(void *cookie) { - funccall_T *fcp = (funccall_T *)cookie; - ufunc_T *fp = fcp->func; + funccall_T *fcp = (funccall_T *)cookie; + ufunc_T *fp = fcp->func; - if (fp->uf_profiling && fp->uf_tml_idx >= 0) + if (fp->uf_profiling && fp->uf_tml_idx >= 0) { fp->uf_tml_execed = TRUE; + } } /* @@ -10276,8 +10280,8 @@ void func_line_exec(void *cookie) */ void func_line_end(void *cookie) { - funccall_T *fcp = (funccall_T *)cookie; - ufunc_T *fp = fcp->func; + funccall_T *fcp = (funccall_T *)cookie; + ufunc_T *fp = fcp->func; if (fp->uf_profiling && fp->uf_tml_idx >= 0) { if (fp->uf_tml_execed) { @@ -10288,7 +10292,7 @@ void func_line_end(void *cookie) profile_add(fp->uf_tml_total[fp->uf_tml_idx], fp->uf_tml_start); fp->uf_tml_self[fp->uf_tml_idx] = profile_self(fp->uf_tml_self[fp->uf_tml_idx], fp->uf_tml_start, - fp->uf_tml_children); + fp->uf_tml_children); } fp->uf_tml_idx = -1; } @@ -10299,10 +10303,11 @@ static var_flavour_T var_flavour(char_u *varname) char_u *p = varname; if (ASCII_ISUPPER(*p)) { - while (*(++p)) + while (*(++p)) { if (ASCII_ISLOWER(*p)) { return VAR_FLAVOUR_SESSION; } + } return VAR_FLAVOUR_SHADA; } else { return VAR_FLAVOUR_DEFAULT; @@ -10320,26 +10325,26 @@ static var_flavour_T var_flavour(char_u *varname) /// /// @return Pointer that needs to be passed to next `var_shada_iter` invocation /// or NULL to indicate that iteration is over. -const void *var_shada_iter(const void *const iter, const char **const name, - typval_T *rettv, var_flavour_T flavour) +const void *var_shada_iter(const void *const iter, const char **const name, typval_T *rettv, + var_flavour_T flavour) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(2, 3) { const hashitem_T *hi; const hashitem_T *hifirst = globvarht.ht_array; - const size_t hinum = (size_t) globvarht.ht_mask + 1; + const size_t hinum = (size_t)globvarht.ht_mask + 1; *name = NULL; if (iter == NULL) { hi = globvarht.ht_array; - while ((size_t) (hi - hifirst) < hinum + while ((size_t)(hi - hifirst) < hinum && (HASHITEM_EMPTY(hi) || !(var_flavour(hi->hi_key) & flavour))) { hi++; } - if ((size_t) (hi - hifirst) == hinum) { + if ((size_t)(hi - hifirst) == hinum) { return NULL; } } else { - hi = (const hashitem_T *) iter; + hi = (const hashitem_T *)iter; } *name = (char *)TV_DICT_HI2DI(hi)->di_key; tv_copy(&TV_DICT_HI2DI(hi)->di_tv, rettv); @@ -10368,9 +10373,8 @@ int store_session_globals(FILE *fd) && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) { // Escape special characters with a backslash. Turn a LF and // CR into \n and \r. - char_u *const p = vim_strsave_escaped( - (const char_u *)tv_get_string(&this_var->di_tv), - (const char_u *)"\\\"\n\r"); + char_u *const p = vim_strsave_escaped((const char_u *)tv_get_string(&this_var->di_tv), + (const char_u *)"\\\"\n\r"); for (char_u *t = p; *t != NUL; t++) { if (*t == '\n') { *t = 'n'; @@ -10381,10 +10385,10 @@ int store_session_globals(FILE *fd) if ((fprintf(fd, "let %s = %c%s%c", this_var->di_key, ((this_var->di_tv.v_type == VAR_STRING) ? '"' - : ' '), + : ' '), p, ((this_var->di_tv.v_type == VAR_STRING) ? '"' - : ' ')) < 0) + : ' ')) < 0) || put_eol(fd) == FAIL) { xfree(p); return FAIL; @@ -10451,26 +10455,24 @@ void reset_v_option_vars(void) set_vim_var_string(VV_OPTION_TYPE, NULL, -1); } -/* - * Adjust a filename, according to a string of modifiers. - * *fnamep must be NUL terminated when called. When returning, the length is - * determined by *fnamelen. - * Returns VALID_ flags or -1 for failure. - * When there is an error, *fnamep is set to NULL. - */ -int -modify_fname( - char_u *src, // string with modifiers - bool tilde_file, // "~" is a file name, not $HOME - size_t *usedlen, // characters after src that are used - char_u **fnamep, // file name so far - char_u **bufp, // buffer for allocated file name or NULL - size_t *fnamelen // length of fnamep -) +/// Adjust a filename, according to a string of modifiers. +/// *fnamep must be NUL terminated when called. When returning, the length is +/// determined by *fnamelen. +/// Returns VALID_ flags or -1 for failure. +/// When there is an error, *fnamep is set to NULL. +/// +/// @param src string with modifiers +/// @param tilde_file "~" is a file name, not $HOME +/// @param usedlen characters after src that are used +/// @param fnamep file name so far +/// @param bufp buffer for allocated file name or NULL +/// @param fnamelen length of fnamep +int modify_fname(char_u *src, bool tilde_file, size_t *usedlen, char_u **fnamep, char_u **bufp, + size_t *fnamelen) { int valid = 0; - char_u *tail; - char_u *s, *p, *pbuf; + char_u *tail; + char_u *s, *p, *pbuf; char_u dirname[MAXPATHL]; int c; int has_fullname = 0; @@ -10492,13 +10494,13 @@ repeat: # endif || (*fnamep)[1] == NUL) #endif - && !(tilde_file && (*fnamep)[1] == NUL) - ) { + && !(tilde_file && (*fnamep)[1] == NUL)) { *fnamep = expand_env_save(*fnamep); xfree(*bufp); // free any allocated file name *bufp = *fnamep; - if (*fnamep == NULL) + if (*fnamep == NULL) { return -1; + } } // When "/." or "/.." is used: force expansion to get rid of it. @@ -10518,8 +10520,9 @@ repeat: *fnamep = (char_u *)FullName_save((char *)(*fnamep), *p != NUL); xfree(*bufp); // free any allocated file name *bufp = *fnamep; - if (*fnamep == NULL) + if (*fnamep == NULL) { return -1; + } } // Append a path separator to a directory. @@ -10528,8 +10531,9 @@ repeat: *fnamep = vim_strnsave(*fnamep, STRLEN(*fnamep) + 2); xfree(*bufp); // free any allocated file name *bufp = *fnamep; - if (*fnamep == NULL) + if (*fnamep == NULL) { return -1; + } add_pathsep((char *)*fnamep); } } @@ -10546,12 +10550,14 @@ repeat: pbuf = NULL; // Need full path first (use expand_env() to remove a "~/") if (!has_fullname) { - if (c == '.' && **fnamep == '~') + if (c == '.' && **fnamep == '~') { p = pbuf = expand_env_save(*fnamep); - else + } else { p = pbuf = (char_u *)FullName_save((char *)*fnamep, FALSE); - } else + } + } else { p = *fnamep; + } has_fullname = 0; @@ -10678,7 +10684,7 @@ repeat: && (src[*usedlen + 1] == 's' || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) { int sep; - char_u *flags; + char_u *flags; int didit = FALSE; flags = (char_u *)""; @@ -10742,17 +10748,16 @@ repeat: /// When "sub" is NULL "expr" is used, must be a VAR_FUNC or VAR_PARTIAL. /// "flags" can be "g" to do a global substitute. /// Returns an allocated string, NULL for error. -char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, - typval_T *expr, char_u *flags) +char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, typval_T *expr, char_u *flags) { int sublen; regmatch_T regmatch; int do_all; - char_u *tail; - char_u *end; + char_u *tail; + char_u *end; garray_T ga; - char_u *save_cpo; - char_u *zero_width = NULL; + char_u *save_cpo; + char_u *zero_width = NULL; // Make 'cpoptions' empty, so that the 'l' flag doesn't work here save_cpo = p_cpo; @@ -10788,7 +10793,7 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, // - The text after the match. sublen = vim_regsub(®match, sub, expr, tail, false, true, false); ga_grow(&ga, (int)((end - tail) + sublen - - (regmatch.endp[0] - regmatch.startp[0]))); + (regmatch.endp[0] - regmatch.startp[0]))); // copy the text up to where the match is int i = (int)(regmatch.startp[0] - tail); @@ -10798,14 +10803,17 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, + ga.ga_len + i, true, true, false); ga.ga_len += i + sublen - 1; tail = regmatch.endp[0]; - if (*tail == NUL) + if (*tail == NUL) { break; - if (!do_all) + } + if (!do_all) { break; + } } - if (ga.ga_data != NULL) + if (ga.ga_data != NULL) { STRCPY((char *)ga.ga_data + ga.ga_len, tail); + } vim_regfree(regmatch.regprog); } @@ -10825,9 +10833,7 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, /// common code for getting job callbacks for jobstart, termopen and rpcstart /// /// @return true/false on success/failure. -bool common_job_callbacks(dict_T *vopts, - CallbackReader *on_stdout, - CallbackReader *on_stderr, +bool common_job_callbacks(dict_T *vopts, CallbackReader *on_stdout, CallbackReader *on_stderr, Callback *on_exit) { if (tv_dict_get_callback(vopts, S_LEN("on_stdout"), &on_stdout->cb) @@ -10888,8 +10894,7 @@ void script_host_eval(char *name, typval_T *argvars, typval_T *rettv) /// @param discard Clears the value returned by the provider and returns /// an empty typval_T. -typval_T eval_call_provider(char *provider, char *method, list_T *arguments, - bool discard) +typval_T eval_call_provider(char *provider, char *method, list_T *arguments, bool discard) { if (!eval_has_provider(provider)) { emsgf("E319: No \"%s\" provider found. Run \":checkhealth provider\"", @@ -11052,59 +11057,59 @@ void ex_checkhealth(exarg_T *eap) void invoke_prompt_callback(void) { - typval_T rettv; - typval_T argv[2]; - char_u *text; - char_u *prompt; - linenr_T lnum = curbuf->b_ml.ml_line_count; - - // Add a new line for the prompt before invoking the callback, so that - // text can always be inserted above the last line. - ml_append(lnum, (char_u *)"", 0, false); - curwin->w_cursor.lnum = lnum + 1; - curwin->w_cursor.col = 0; - - if (curbuf->b_prompt_callback.type == kCallbackNone) { - return; - } - text = ml_get(lnum); - prompt = prompt_text(); - if (STRLEN(text) >= STRLEN(prompt)) { - text += STRLEN(prompt); - } - argv[0].v_type = VAR_STRING; - argv[0].vval.v_string = vim_strsave(text); - argv[1].v_type = VAR_UNKNOWN; + typval_T rettv; + typval_T argv[2]; + char_u *text; + char_u *prompt; + linenr_T lnum = curbuf->b_ml.ml_line_count; + + // Add a new line for the prompt before invoking the callback, so that + // text can always be inserted above the last line. + ml_append(lnum, (char_u *)"", 0, false); + curwin->w_cursor.lnum = lnum + 1; + curwin->w_cursor.col = 0; + + if (curbuf->b_prompt_callback.type == kCallbackNone) { + return; + } + text = ml_get(lnum); + prompt = prompt_text(); + if (STRLEN(text) >= STRLEN(prompt)) { + text += STRLEN(prompt); + } + argv[0].v_type = VAR_STRING; + argv[0].vval.v_string = vim_strsave(text); + argv[1].v_type = VAR_UNKNOWN; - callback_call(&curbuf->b_prompt_callback, 1, argv, &rettv); - tv_clear(&argv[0]); - tv_clear(&rettv); + callback_call(&curbuf->b_prompt_callback, 1, argv, &rettv); + tv_clear(&argv[0]); + tv_clear(&rettv); } // Return true When the interrupt callback was invoked. bool invoke_prompt_interrupt(void) { - typval_T rettv; - typval_T argv[1]; + typval_T rettv; + typval_T argv[1]; - if (curbuf->b_prompt_interrupt.type == kCallbackNone) { - return false; - } - argv[0].v_type = VAR_UNKNOWN; + if (curbuf->b_prompt_interrupt.type == kCallbackNone) { + return false; + } + argv[0].v_type = VAR_UNKNOWN; - got_int = false; // don't skip executing commands - callback_call(&curbuf->b_prompt_interrupt, 0, argv, &rettv); - tv_clear(&rettv); - return true; + got_int = false; // don't skip executing commands + callback_call(&curbuf->b_prompt_interrupt, 0, argv, &rettv); + tv_clear(&rettv); + return true; } -// Compare "typ1" and "typ2". Put the result in "typ1". -int typval_compare( - typval_T *typ1, // first operand - typval_T *typ2, // second operand - exprtype_T type, // operator - bool ic // ignore case -) +/// Compare "typ1" and "typ2". Put the result in "typ1". +/// +/// @param typ1 first operand +/// @param typ2 second operand +/// @param type operator +/// @param ic ignore case +int typval_compare(typval_T *typ1, typval_T *typ2, exprtype_T type, bool ic) FUNC_ATTR_NONNULL_ALL { varnumber_T n1, n2; @@ -11140,7 +11145,7 @@ int typval_compare( } else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST) { if (type_is) { n1 = typ1->v_type == typ2->v_type - && typ1->vval.v_list == typ2->vval.v_list; + && typ1->vval.v_list == typ2->vval.v_list; if (type == EXPR_ISNOT) { n1 = !n1; } @@ -11163,7 +11168,7 @@ int typval_compare( } else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT) { if (type_is) { n1 = typ1->v_type == typ2->v_type - && typ1->vval.v_dict == typ2->vval.v_dict; + && typ1->vval.v_dict == typ2->vval.v_dict; if (type == EXPR_ISNOT) { n1 = !n1; } @@ -11218,17 +11223,24 @@ int typval_compare( const float_T f2 = tv_get_float(typ2); n1 = false; switch (type) { - case EXPR_IS: - case EXPR_EQUAL: n1 = f1 == f2; break; - case EXPR_ISNOT: - case EXPR_NEQUAL: n1 = f1 != f2; break; - case EXPR_GREATER: n1 = f1 > f2; break; - case EXPR_GEQUAL: n1 = f1 >= f2; break; - case EXPR_SMALLER: n1 = f1 < f2; break; - case EXPR_SEQUAL: n1 = f1 <= f2; break; - case EXPR_UNKNOWN: - case EXPR_MATCH: - case EXPR_NOMATCH: break; // avoid gcc warning + case EXPR_IS: + case EXPR_EQUAL: + n1 = f1 == f2; break; + case EXPR_ISNOT: + case EXPR_NEQUAL: + n1 = f1 != f2; break; + case EXPR_GREATER: + n1 = f1 > f2; break; + case EXPR_GEQUAL: + n1 = f1 >= f2; break; + case EXPR_SMALLER: + n1 = f1 < f2; break; + case EXPR_SEQUAL: + n1 = f1 <= f2; break; + case EXPR_UNKNOWN: + case EXPR_MATCH: + case EXPR_NOMATCH: + break; // avoid gcc warning } } else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER) && type != EXPR_MATCH && type != EXPR_NOMATCH) { @@ -11237,17 +11249,24 @@ int typval_compare( n1 = tv_get_number(typ1); n2 = tv_get_number(typ2); switch (type) { - case EXPR_IS: - case EXPR_EQUAL: n1 = n1 == n2; break; - case EXPR_ISNOT: - case EXPR_NEQUAL: n1 = n1 != n2; break; - case EXPR_GREATER: n1 = n1 > n2; break; - case EXPR_GEQUAL: n1 = n1 >= n2; break; - case EXPR_SMALLER: n1 = n1 < n2; break; - case EXPR_SEQUAL: n1 = n1 <= n2; break; - case EXPR_UNKNOWN: - case EXPR_MATCH: - case EXPR_NOMATCH: break; // avoid gcc warning + case EXPR_IS: + case EXPR_EQUAL: + n1 = n1 == n2; break; + case EXPR_ISNOT: + case EXPR_NEQUAL: + n1 = n1 != n2; break; + case EXPR_GREATER: + n1 = n1 > n2; break; + case EXPR_GEQUAL: + n1 = n1 >= n2; break; + case EXPR_SMALLER: + n1 = n1 < n2; break; + case EXPR_SEQUAL: + n1 = n1 <= n2; break; + case EXPR_UNKNOWN: + case EXPR_MATCH: + case EXPR_NOMATCH: + break; // avoid gcc warning } } else { char buf1[NUMBUFLEN]; @@ -11262,23 +11281,30 @@ int typval_compare( } n1 = false; switch (type) { - case EXPR_IS: - case EXPR_EQUAL: n1 = i == 0; break; - case EXPR_ISNOT: - case EXPR_NEQUAL: n1 = i != 0; break; - case EXPR_GREATER: n1 = i > 0; break; - case EXPR_GEQUAL: n1 = i >= 0; break; - case EXPR_SMALLER: n1 = i < 0; break; - case EXPR_SEQUAL: n1 = i <= 0; break; - - case EXPR_MATCH: - case EXPR_NOMATCH: - n1 = pattern_match((char_u *)s2, (char_u *)s1, ic); - if (type == EXPR_NOMATCH) { - n1 = !n1; - } - break; - case EXPR_UNKNOWN: break; // avoid gcc warning + case EXPR_IS: + case EXPR_EQUAL: + n1 = i == 0; break; + case EXPR_ISNOT: + case EXPR_NEQUAL: + n1 = i != 0; break; + case EXPR_GREATER: + n1 = i > 0; break; + case EXPR_GEQUAL: + n1 = i >= 0; break; + case EXPR_SMALLER: + n1 = i < 0; break; + case EXPR_SEQUAL: + n1 = i <= 0; break; + + case EXPR_MATCH: + case EXPR_NOMATCH: + n1 = pattern_match((char_u *)s2, (char_u *)s1, ic); + if (type == EXPR_NOMATCH) { + n1 = !n1; + } + break; + case EXPR_UNKNOWN: + break; // avoid gcc warning } } tv_clear(typ1); @@ -11303,7 +11329,7 @@ bool var_exists(const char *var) // get_name_len() takes care of expanding curly braces const char *name = var; - const int len = get_name_len((const char **)&var, &tofree, true, false); + const int len = get_name_len(&var, &tofree, true, false); if (len > 0) { typval_T tv; diff --git a/src/nvim/eval.h b/src/nvim/eval.h index 2452a0a8c8..3d656656de 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -3,7 +3,7 @@ #include "nvim/buffer_defs.h" #include "nvim/channel.h" -#include "nvim/eval/funcs.h" // For FunPtr +#include "nvim/eval/funcs.h" // For FunPtr #include "nvim/event/time.h" // For TimeWatcher #include "nvim/ex_cmds_defs.h" // For exarg_T #include "nvim/os/fileio.h" // For FileDescriptor @@ -24,46 +24,46 @@ EXTERN ufunc_T dumuf; /* * Structure returned by get_lval() and used by set_var_lval(). * For a plain name: - * "name" points to the variable name. - * "exp_name" is NULL. - * "tv" is NULL + * "name" points to the variable name. + * "exp_name" is NULL. + * "tv" is NULL * For a magic braces name: - * "name" points to the expanded variable name. - * "exp_name" is non-NULL, to be freed later. - * "tv" is NULL + * "name" points to the expanded variable name. + * "exp_name" is non-NULL, to be freed later. + * "tv" is NULL * For an index in a list: - * "name" points to the (expanded) variable name. - * "exp_name" NULL or non-NULL, to be freed later. - * "tv" points to the (first) list item value - * "li" points to the (first) list item - * "range", "n1", "n2" and "empty2" indicate what items are used. + * "name" points to the (expanded) variable name. + * "exp_name" NULL or non-NULL, to be freed later. + * "tv" points to the (first) list item value + * "li" points to the (first) list item + * "range", "n1", "n2" and "empty2" indicate what items are used. * For an existing Dict item: - * "name" points to the (expanded) variable name. - * "exp_name" NULL or non-NULL, to be freed later. - * "tv" points to the dict item value - * "newkey" is NULL + * "name" points to the (expanded) variable name. + * "exp_name" NULL or non-NULL, to be freed later. + * "tv" points to the dict item value + * "newkey" is NULL * For a non-existing Dict item: - * "name" points to the (expanded) variable name. - * "exp_name" NULL or non-NULL, to be freed later. - * "tv" points to the Dictionary typval_T - * "newkey" is the key for the new item. + * "name" points to the (expanded) variable name. + * "exp_name" NULL or non-NULL, to be freed later. + * "tv" points to the Dictionary typval_T + * "newkey" is the key for the new item. */ typedef struct lval_S { - const char *ll_name; ///< Start of variable name (can be NULL). - size_t ll_name_len; ///< Length of the .ll_name. - char *ll_exp_name; ///< NULL or expanded name in allocated memory. - typval_T *ll_tv; ///< Typeval of item being used. If "newkey" - ///< isn't NULL it's the Dict to which to add the item. - listitem_T *ll_li; ///< The list item or NULL. - list_T *ll_list; ///< The list or NULL. - bool ll_range; ///< true when a [i:j] range was used. - bool ll_empty2; ///< Second index is empty: [i:]. - long ll_n1; ///< First index for list. - long ll_n2; ///< Second index for list range. - dict_T *ll_dict; ///< The Dictionary or NULL. - dictitem_T *ll_di; ///< The dictitem or NULL. - char_u *ll_newkey; ///< New key for Dict in allocated memory or NULL. - blob_T *ll_blob; ///< The Blob or NULL. + const char *ll_name; ///< Start of variable name (can be NULL). + size_t ll_name_len; ///< Length of the .ll_name. + char *ll_exp_name; ///< NULL or expanded name in allocated memory. + typval_T *ll_tv; ///< Typeval of item being used. If "newkey" + ///< isn't NULL it's the Dict to which to add the item. + listitem_T *ll_li; ///< The list item or NULL. + list_T *ll_list; ///< The list or NULL. + bool ll_range; ///< true when a [i:j] range was used. + bool ll_empty2; ///< Second index is empty: [i:]. + long ll_n1; ///< First index for list. + long ll_n2; ///< Second index for list range. + dict_T *ll_dict; ///< The Dictionary or NULL. + dictitem_T *ll_di; ///< The dictitem or NULL. + char_u *ll_newkey; ///< New key for Dict in allocated memory or NULL. + blob_T *ll_blob; ///< The Blob or NULL. } lval_T; /// enum used by var_flavour() @@ -75,100 +75,100 @@ typedef enum { /// Defines for Vim variables typedef enum { - VV_COUNT, - VV_COUNT1, - VV_PREVCOUNT, - VV_ERRMSG, - VV_WARNINGMSG, - VV_STATUSMSG, - VV_SHELL_ERROR, - VV_THIS_SESSION, - VV_VERSION, - VV_LNUM, - VV_TERMRESPONSE, - VV_FNAME, - VV_LANG, - VV_LC_TIME, - VV_CTYPE, - VV_CC_FROM, - VV_CC_TO, - VV_FNAME_IN, - VV_FNAME_OUT, - VV_FNAME_NEW, - VV_FNAME_DIFF, - VV_CMDARG, - VV_FOLDSTART, - VV_FOLDEND, - VV_FOLDDASHES, - VV_FOLDLEVEL, - VV_PROGNAME, - VV_SEND_SERVER, - VV_DYING, - VV_EXCEPTION, - VV_THROWPOINT, - VV_REG, - VV_CMDBANG, - VV_INSERTMODE, - VV_VAL, - VV_KEY, - VV_PROFILING, - VV_FCS_REASON, - VV_FCS_CHOICE, - VV_BEVAL_BUFNR, - VV_BEVAL_WINNR, - VV_BEVAL_WINID, - VV_BEVAL_LNUM, - VV_BEVAL_COL, - VV_BEVAL_TEXT, - VV_SCROLLSTART, - VV_SWAPNAME, - VV_SWAPCHOICE, - VV_SWAPCOMMAND, - VV_CHAR, - VV_MOUSE_WIN, - VV_MOUSE_WINID, - VV_MOUSE_LNUM, - VV_MOUSE_COL, - VV_OP, - VV_SEARCHFORWARD, - VV_HLSEARCH, - VV_OLDFILES, - VV_WINDOWID, - VV_PROGPATH, - VV_COMPLETED_ITEM, - VV_OPTION_NEW, - VV_OPTION_OLD, - VV_OPTION_TYPE, - VV_ERRORS, - VV_FALSE, - VV_TRUE, - VV_NULL, - VV_NUMBERMAX, - VV_NUMBERMIN, - VV_NUMBERSIZE, - VV_VIM_DID_ENTER, - VV_TESTING, - VV_TYPE_NUMBER, - VV_TYPE_STRING, - VV_TYPE_FUNC, - VV_TYPE_LIST, - VV_TYPE_DICT, - VV_TYPE_FLOAT, - VV_TYPE_BOOL, - VV_TYPE_BLOB, - VV_EVENT, - VV_ECHOSPACE, - VV_ARGV, - VV_COLLATE, - VV_EXITING, - // Neovim - VV_STDERR, - VV_MSGPACK_TYPES, - VV__NULL_STRING, // String with NULL value. For test purposes only. - VV__NULL_LIST, // List with NULL value. For test purposes only. - VV__NULL_DICT, // Dictionary with NULL value. For test purposes only. - VV__NULL_BLOB, // Blob with NULL value. For test purposes only. - VV_LUA, + VV_COUNT, + VV_COUNT1, + VV_PREVCOUNT, + VV_ERRMSG, + VV_WARNINGMSG, + VV_STATUSMSG, + VV_SHELL_ERROR, + VV_THIS_SESSION, + VV_VERSION, + VV_LNUM, + VV_TERMRESPONSE, + VV_FNAME, + VV_LANG, + VV_LC_TIME, + VV_CTYPE, + VV_CC_FROM, + VV_CC_TO, + VV_FNAME_IN, + VV_FNAME_OUT, + VV_FNAME_NEW, + VV_FNAME_DIFF, + VV_CMDARG, + VV_FOLDSTART, + VV_FOLDEND, + VV_FOLDDASHES, + VV_FOLDLEVEL, + VV_PROGNAME, + VV_SEND_SERVER, + VV_DYING, + VV_EXCEPTION, + VV_THROWPOINT, + VV_REG, + VV_CMDBANG, + VV_INSERTMODE, + VV_VAL, + VV_KEY, + VV_PROFILING, + VV_FCS_REASON, + VV_FCS_CHOICE, + VV_BEVAL_BUFNR, + VV_BEVAL_WINNR, + VV_BEVAL_WINID, + VV_BEVAL_LNUM, + VV_BEVAL_COL, + VV_BEVAL_TEXT, + VV_SCROLLSTART, + VV_SWAPNAME, + VV_SWAPCHOICE, + VV_SWAPCOMMAND, + VV_CHAR, + VV_MOUSE_WIN, + VV_MOUSE_WINID, + VV_MOUSE_LNUM, + VV_MOUSE_COL, + VV_OP, + VV_SEARCHFORWARD, + VV_HLSEARCH, + VV_OLDFILES, + VV_WINDOWID, + VV_PROGPATH, + VV_COMPLETED_ITEM, + VV_OPTION_NEW, + VV_OPTION_OLD, + VV_OPTION_TYPE, + VV_ERRORS, + VV_FALSE, + VV_TRUE, + VV_NULL, + VV_NUMBERMAX, + VV_NUMBERMIN, + VV_NUMBERSIZE, + VV_VIM_DID_ENTER, + VV_TESTING, + VV_TYPE_NUMBER, + VV_TYPE_STRING, + VV_TYPE_FUNC, + VV_TYPE_LIST, + VV_TYPE_DICT, + VV_TYPE_FLOAT, + VV_TYPE_BOOL, + VV_TYPE_BLOB, + VV_EVENT, + VV_ECHOSPACE, + VV_ARGV, + VV_COLLATE, + VV_EXITING, + // Neovim + VV_STDERR, + VV_MSGPACK_TYPES, + VV__NULL_STRING, // String with NULL value. For test purposes only. + VV__NULL_LIST, // List with NULL value. For test purposes only. + VV__NULL_DICT, // Dictionary with NULL value. For test purposes only. + VV__NULL_BLOB, // Blob with NULL value. For test purposes only. + VV_LUA, } VimVarIndex; /// All recognized msgpack types @@ -208,7 +208,7 @@ typedef enum { } GetLvalFlags; /// flags for find_name_end() -#define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ +#define FNE_INCL_BR 1 // find_name_end(): include [] in name #define FNE_CHECK_START 2 /* find_name_end(): check name starts with valid character */ diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index c0a18b3236..dfc51d80af 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -72,6 +72,7 @@ return { chansend={args=2}, char2nr={args={1, 2}, base=1}, charidx={args={2, 3}}, + chdir={args=1, base=1}, cindent={args=1, base=1}, clearmatches={args={0, 1}, base=1}, col={args=1, base=1}, @@ -102,44 +103,44 @@ return { diff_hlID={args=2, base=1}, empty={args=1, base=1}, environ={}, - escape={args=2}, + escape={args=2, base=1}, eval={args=1, base=1}, eventhandler={}, - executable={args=1}, - execute={args={1, 2}}, - exepath={args=1}, - exists={args=1}, + executable={args=1, base=1}, + execute={args={1, 2}, base=1}, + exepath={args=1, base=1}, + exists={args=1, base=1}, exp={args=1, base=1, func="float_op_wrapper", data="&exp"}, - expand={args={1, 3}}, - expandcmd={args=1}, + expand={args={1, 3}, base=1}, + expandcmd={args=1, base=1}, extend={args={2, 3}, base=1}, - feedkeys={args={1, 2}}, - file_readable={args=1, func='f_filereadable'}, -- obsolete - filereadable={args=1}, - filewritable={args=1}, + feedkeys={args={1, 2}, base=1}, + file_readable={args=1, base=1, func='f_filereadable'}, -- obsolete + filereadable={args=1, base=1}, + filewritable={args=1, base=1}, filter={args=2, base=1}, - finddir={args={1, 3}}, - findfile={args={1, 3}}, + finddir={args={1, 3}, base=1}, + findfile={args={1, 3}, base=1}, flatten={args={1, 2}}, float2nr={args=1, base=1}, floor={args=1, base=1, func="float_op_wrapper", data="&floor"}, fmod={args=2, base=1}, - fnameescape={args=1}, - fnamemodify={args=2}, - foldclosed={args=1}, - foldclosedend={args=1}, - foldlevel={args=1}, + fnameescape={args=1, base=1}, + fnamemodify={args=2, base=1}, + foldclosed={args=1, base=1}, + foldclosedend={args=1, base=1}, + foldlevel={args=1, base=1}, foldtext={}, - foldtextresult={args=1}, + foldtextresult={args=1, base=1}, foreground={}, - funcref={args={1, 3}}, - ['function']={args={1, 3}}, + funcref={args={1, 3}, base=1}, + ['function']={args={1, 3}, base=1}, garbagecollect={args={0, 1}}, get={args={2, 3}, base=1}, getbufinfo={args={0, 1}}, - getbufline={args={2, 3}}, - getbufvar={args={2, 3}}, - getchangelist={args={1, 1}}, + getbufline={args={2, 3}, base=1}, + getbufvar={args={2, 3}, base=1}, + getchangelist={args={0, 1}, base=1}, getchar={args={0, 1}}, getcharmod={}, getcharsearch={}, @@ -148,65 +149,67 @@ return { getcmdpos={}, getcmdtype={}, getcmdwintype={}, - getcompletion={args={2, 3}}, + getcompletion={args={2, 3}, base=1}, getcurpos={}, - getcwd={args={0,2}}, - getenv={args={1}}, + getcwd={args={0, 2}, base=1}, + getenv={args={1}, base=1}, getfontname={args={0, 1}}, - getfperm={args=1}, - getfsize={args=1}, - getftime={args=1}, - getftype={args=1}, - getjumplist={args={0, 2}}, - getline={args={1, 2}}, + getfperm={args=1, base=1}, + getfsize={args=1, base=1}, + getftime={args=1, base=1}, + getftype={args=1, base=1}, + getjumplist={args={0, 2}, base=1}, + getline={args={1, 2}, base=1}, getloclist={args={1, 2}}, getmarklist={args={0, 1}}, getmatches={args={0, 1}}, + getmousepos={}, getpid={}, - getpos={args=1}, + getpos={args=1, base=1}, getqflist={args={0, 1}}, - getreg={args={0, 3}}, - getregtype={args={0, 1}}, - gettabinfo={args={0, 1}}, - gettabvar={args={2, 3}}, - gettabwinvar={args={3, 4}}, - gettagstack={args={0, 1}}, - getwininfo={args={0, 1}}, - getwinpos={args={0, 1}}, + getreg={args={0, 3}, base=1}, + getreginfo={args={0, 1}, base=1}, + getregtype={args={0, 1}, base=1}, + gettabinfo={args={0, 1}, base=1}, + gettabvar={args={2, 3}, base=1}, + gettabwinvar={args={3, 4}, base=1}, + gettagstack={args={0, 1}, base=1}, + getwininfo={args={0, 1}, base=1}, + getwinpos={args={0, 1}, base=1}, getwinposx={}, getwinposy={}, - getwinvar={args={2, 3}}, - glob={args={1, 4}}, - glob2regpat={args=1}, - globpath={args={2, 5}}, + getwinvar={args={2, 3}, base=1}, + glob={args={1, 4}, base=1}, + glob2regpat={args=1, base=1}, + globpath={args={2, 5}, base=2}, has={args=1}, has_key={args=2, base=1}, - haslocaldir={args={0,2}}, - hasmapto={args={1, 3}}, - highlightID={args=1, func='f_hlID'}, -- obsolete - highlight_exists={args=1, func='f_hlexists'}, -- obsolete - histadd={args=2}, - histdel={args={1, 2}}, - histget={args={1, 2}}, - histnr={args=1}, - hlID={args=1}, - hlexists={args=1}, + haslocaldir={args={0, 2}, base=1}, + hasmapto={args={1, 3}, base=1}, + highlightID={args=1, base=1, func='f_hlID'}, -- obsolete + highlight_exists={args=1, base=1, func='f_hlexists'}, -- obsolete + histadd={args=2, base=2}, + histdel={args={1, 2}, base=1}, + histget={args={1, 2}, base=1}, + histnr={args=1, base=1}, + hlID={args=1, base=1}, + hlexists={args=1, base=1}, hostname={}, - iconv={args=3}, - indent={args=1}, + iconv={args=3, base=1}, + indent={args=1, base=1}, index={args={2, 4}, base=1}, - input={args={1, 3}}, - inputdialog={args={1, 3}}, - inputlist={args=1}, + input={args={1, 3}, base=1}, + inputdialog={args={1, 3}, base=1}, + inputlist={args=1, base=1}, inputrestore={}, inputsave={}, - inputsecret={args={1, 2}}, + inputsecret={args={1, 2}, base=1}, insert={args={2, 3}, base=1}, interrupt={args=0}, invert={args=1, base=1}, - isdirectory={args=1}, + isdirectory={args=1, base=1}, isinf={args=1, base=1}, - islocked={args=1}, + islocked={args=1, base=1}, isnan={args=1, base=1}, id={args=1}, items={args=1, base=1}, @@ -218,76 +221,76 @@ return { jobstop={args=1}, jobwait={args={1, 2}}, join={args={1, 2}, base=1}, - json_decode={args=1}, - json_encode={args=1}, + json_decode={args=1, base=1}, + json_encode={args=1, base=1}, keys={args=1, base=1}, last_buffer_nr={}, -- obsolete len={args=1, base=1}, - libcall={args=3}, - libcallnr={args=3}, - line={args={1, 2}}, - line2byte={args=1}, - lispindent={args=1}, - list2str={args={1, 2}}, + libcall={args=3, base=3}, + libcallnr={args=3, base=3}, + line={args={1, 2}, base=1}, + line2byte={args=1, base=1}, + lispindent={args=1, base=1}, + list2str={args={1, 2}, base=1}, localtime={}, log={args=1, base=1, func="float_op_wrapper", data="&log"}, log10={args=1, base=1, func="float_op_wrapper", data="&log10"}, - luaeval={args={1, 2}}, + luaeval={args={1, 2}, base=1}, map={args=2, base=1}, - maparg={args={1, 4}}, - mapcheck={args={1, 3}}, - match={args={2, 4}}, - matchadd={args={2, 5}}, - matchaddpos={args={2, 5}}, - matcharg={args=1}, - matchdelete={args={1, 2}}, - matchend={args={2, 4}}, - matchlist={args={2, 4}}, - matchstr={args={2, 4}}, - matchstrpos={args={2,4}}, + maparg={args={1, 4}, base=1}, + mapcheck={args={1, 3}, base=1}, + match={args={2, 4}, base=1}, + matchadd={args={2, 5}, base=1}, + matchaddpos={args={2, 5}, base=1}, + matcharg={args=1, base=1}, + matchdelete={args={1, 2}, base=1}, + matchend={args={2, 4}, base=1}, + matchlist={args={2, 4}, base=1}, + matchstr={args={2, 4}, base=1}, + matchstrpos={args={2,4}, base=1}, max={args=1, base=1}, menu_get={args={1, 2}}, min={args=1, base=1}, - mkdir={args={1, 3}}, - mode={args={0, 1}}, + mkdir={args={1, 3}, base=1}, + mode={args={0, 1}, base=1}, msgpackdump={args={1, 2}}, msgpackparse={args=1}, - nextnonblank={args=1}, - nr2char={args={1, 2}}, + nextnonblank={args=1, base=1}, + nr2char={args={1, 2}, base=1}, ['or']={args=2, base=1}, - pathshorten={args=1}, + pathshorten={args=1, base=1}, pow={args=2, base=1}, - prevnonblank={args=1}, + prevnonblank={args=1, base=1}, printf={args=varargs(1), base=2}, prompt_getprompt={args=1}, - prompt_setcallback={args={2, 2}}, - prompt_setinterrupt={args={2, 2}}, - prompt_setprompt={args={2, 2}}, + prompt_setcallback={args={2, 2}, base=1}, + prompt_setinterrupt={args={2, 2}, base=1}, + prompt_setprompt={args={2, 2}, base=1}, pum_getpos={}, pumvisible={}, - py3eval={args=1}, - pyeval={args=1}, - pyxeval={args=1}, - perleval={args=1}, - range={args={1, 3}}, - readdir={args={1, 2}}, - readfile={args={1, 3}}, + py3eval={args=1, base=1}, + pyeval={args=1, base=1}, + pyxeval={args=1, base=1}, + perleval={args=1, base=1}, + range={args={1, 3}, base=1}, + readdir={args={1, 2}, base=1}, + readfile={args={1, 3}, base=1}, reg_executing={}, reg_recording={}, - reltime={args={0, 2}}, - reltimefloat={args=1}, - reltimestr={args=1}, + reltime={args={0, 2}, base=1}, + reltimefloat={args=1, base=1}, + reltimestr={args=1, base=1}, remove={args={2, 3}, base=1}, - rename={args=2}, + rename={args=2, base=1}, ['repeat']={args=2, base=1}, - resolve={args=1}, + resolve={args=1, base=1}, reverse={args=1, base=1}, round={args=1, base=1, func="float_op_wrapper", data="&round"}, rpcnotify={args=varargs(2)}, rpcrequest={args=varargs(2)}, rpcstart={args={1, 2}}, rpcstop={args=1}, - rubyeval={args=1}, + rubyeval={args=1, base=1}, screenattr={args=2}, screenchar={args=2}, screenchars={args=2}, @@ -309,7 +312,7 @@ return { setcharsearch={args=1}, setcmdpos={args=1}, setenv={args=2}, - setfperm={args=2}, + setfperm={args=2, base=1}, setline={args=2}, setloclist={args={2, 4}}, setmatches={args={1, 2}}, diff --git a/src/nvim/eval/decode.h b/src/nvim/eval/decode.h index 77fc4c78c2..f1be5a1f69 100644 --- a/src/nvim/eval/decode.h +++ b/src/nvim/eval/decode.h @@ -1,9 +1,8 @@ #ifndef NVIM_EVAL_DECODE_H #define NVIM_EVAL_DECODE_H -#include <stddef.h> - #include <msgpack.h> +#include <stddef.h> #include "nvim/eval/typval.h" #include "nvim/globals.h" diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index 1c0afc89f5..2d4d9fdea9 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -29,7 +29,6 @@ #include "nvim/message.h" #include "nvim/vim.h" // For _() -#define ga_concat(a, b) ga_concat(a, (char_u *)b) #define utf_ptr2char(b) utf_ptr2char((char_u *)b) #define utf_ptr2len(b) ((size_t)utf_ptr2len((char_u *)b)) #define utf_char2len(b) ((size_t)utf_char2len(b)) @@ -142,7 +141,7 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack, char *const key = encode_tv2string(&key_tv, NULL); vim_snprintf((char *)IObuff, IOSIZE, key_msg, key); xfree(key); - ga_concat(&msg_ga, IObuff); + ga_concat(&msg_ga, (char *)IObuff); break; } case kMPConvPairs: @@ -163,7 +162,7 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack, || (TV_LIST_ITEM_TV(li)->v_type != VAR_LIST && tv_list_len(TV_LIST_ITEM_TV(li)->vval.v_list) <= 0)) { vim_snprintf((char *)IObuff, IOSIZE, idx_msg, idx); - ga_concat(&msg_ga, IObuff); + ga_concat(&msg_ga, (char *)IObuff); } else { assert(li != NULL); listitem_T *const first_item = @@ -173,7 +172,7 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack, char *const key = encode_tv2echo(&key_tv, NULL); vim_snprintf((char *)IObuff, IOSIZE, key_pair_msg, key, idx); xfree(key); - ga_concat(&msg_ga, IObuff); + ga_concat(&msg_ga, (char *)IObuff); } break; } @@ -193,7 +192,7 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack, case kMPConvPartialList: { const int idx = (int)(v.data.a.arg - v.data.a.argv) - 1; vim_snprintf((char *)IObuff, IOSIZE, partial_arg_i_msg, idx); - ga_concat(&msg_ga, IObuff); + ga_concat(&msg_ga, (char *)IObuff); break; } } @@ -268,9 +267,8 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s || TV_LIST_ITEM_TV(state->li)->vval.v_string != NULL); for (size_t i = state->offset; i < state->li_length && p < buf_end; i++) { assert(TV_LIST_ITEM_TV(state->li)->vval.v_string != NULL); - const char ch = (char)( - TV_LIST_ITEM_TV(state->li)->vval.v_string[state->offset++]); - *p++ = (char)((char)ch == (char)NL ? (char)NUL : (char)ch); + const char ch = (char)(TV_LIST_ITEM_TV(state->li)->vval.v_string[state->offset++]); + *p++ = (char)(ch == (char)NL ? (char)NUL : ch); } if (p < buf_end) { state->li = TV_LIST_ITEM_NEXT(state->list, state->li); @@ -356,20 +354,20 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s const float_T flt_ = (flt); \ switch (xfpclassify(flt_)) { \ case FP_NAN: { \ - ga_concat(gap, (char_u *)"str2float('nan')"); \ + ga_concat(gap, "str2float('nan')"); \ break; \ } \ case FP_INFINITE: { \ if (flt_ < 0) { \ ga_append(gap, '-'); \ } \ - ga_concat(gap, (char_u *)"str2float('inf')"); \ + ga_concat(gap, "str2float('inf')"); \ break; \ } \ default: { \ char numbuf[NUMBUFLEN]; \ vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \ - ga_concat(gap, (char_u *)numbuf); \ + ga_concat(gap, numbuf); \ } \ } \ } while (0) @@ -570,7 +568,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s default: { \ char numbuf[NUMBUFLEN]; \ vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \ - ga_concat(gap, (char_u *)numbuf); \ + ga_concat(gap, numbuf); \ break; \ } \ } \ @@ -875,7 +873,7 @@ char *encode_tv2echo(typval_T *tv, size_t *len) ga_init(&ga, (int)sizeof(char), 80); if (tv->v_type == VAR_STRING || tv->v_type == VAR_FUNC) { if (tv->vval.v_string != NULL) { - ga_concat(&ga, tv->vval.v_string); + ga_concat(&ga, (char *)tv->vval.v_string); } } else { const int eve_ret = encode_vim_to_echo(&ga, tv, N_(":echo argument")); diff --git a/src/nvim/eval/encode.h b/src/nvim/eval/encode.h index 596bb49ae0..8755ff48ac 100644 --- a/src/nvim/eval/encode.h +++ b/src/nvim/eval/encode.h @@ -1,9 +1,8 @@ #ifndef NVIM_EVAL_ENCODE_H #define NVIM_EVAL_ENCODE_H -#include <stddef.h> - #include <msgpack.h> +#include <stddef.h> #include "nvim/eval.h" #include "nvim/garray.h" @@ -49,8 +48,7 @@ static inline ListReaderState encode_init_lrstate(const list_T *const list) .offset = 0, .li_length = (TV_LIST_ITEM_TV(tv_list_first(list))->vval.v_string == NULL ? 0 - : STRLEN(TV_LIST_ITEM_TV( - tv_list_first(list))->vval.v_string)), + : STRLEN(TV_LIST_ITEM_TV(tv_list_first(list))->vval.v_string)), }; } diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index b17b462ed0..946bde060d 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -28,6 +28,7 @@ #include "nvim/file_search.h" #include "nvim/fileio.h" #include "nvim/fold.h" +#include "nvim/globals.h" #include "nvim/if_cscope.h" #include "nvim/indent.h" #include "nvim/indent_c.h" @@ -80,16 +81,16 @@ KHASH_MAP_INIT_STR(functions, VimLFuncDef) #ifdef INCLUDE_GENERATED_DECLARATIONS # include "eval/funcs.c.generated.h" -#ifdef _MSC_VER +# ifdef _MSC_VER // This prevents MSVC from replacing the functions with intrinsics, // and causing errors when trying to get their addresses in funcs.generated.h -#pragma function(ceil) -#pragma function(floor) -#endif +# pragma function(ceil) +# pragma function(floor) +# endif PRAGMA_DIAG_PUSH_IGNORE_MISSING_PROTOTYPES PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH -#include "funcs.generated.h" +# include "funcs.generated.h" PRAGMA_DIAG_POP PRAGMA_DIAG_POP #endif @@ -248,7 +249,7 @@ static int non_zero_arg(typval_T *argvars) static void float_op_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr) { float_T f; - float_T (*function)(float_T) = (float_T (*)(float_T))fptr; + float_T (*function)(float_T) = (float_T (*)(float_T)) fptr; rettv->v_type = VAR_FLOAT; if (tv_get_float_chk(argvars, &f)) { @@ -491,7 +492,7 @@ static void f_assert_report(typval_T *argvars, typval_T *rettv, FunPtr fptr) garray_T ga; prepare_assert_error(&ga); - ga_concat(&ga, (const char_u *)tv_get_string(&argvars[0])); + ga_concat(&ga, tv_get_string(&argvars[0])); assert_error(&ga); ga_clear(&ga); rettv->vval.v_number = 1; @@ -803,7 +804,7 @@ buf_T *tv_get_buf_from_arg(typval_T *const tv) FUNC_ATTR_NONNULL_ALL /// Get the buffer from "arg" and give an error and return NULL if it is not /// valid. -buf_T * get_buf_arg(typval_T *arg) +buf_T *get_buf_arg(typval_T *arg) { buf_T *buf; @@ -1062,6 +1063,45 @@ static void f_charidx(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_number = len > 0 ? len - 1 : 0; } +// "chdir(dir)" function +static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + char_u *cwd; + CdScope scope = kCdScopeGlobal; + + rettv->v_type = VAR_STRING; + rettv->vval.v_string = NULL; + + if (argvars[0].v_type != VAR_STRING) { + // Returning an empty string means it failed. + // No error message, for historic reasons. + return; + } + + // Return the current directory + cwd = xmalloc(MAXPATHL); + if (cwd != NULL) { + if (os_dirname(cwd, MAXPATHL) != FAIL) { +#ifdef BACKSLASH_IN_FILENAME + slash_adjust(cwd); +#endif + rettv->vval.v_string = vim_strsave(cwd); + } + xfree(cwd); + } + + if (curwin->w_localdir != NULL) { + scope = kCdScopeWindow; + } else if (curtab->tp_localdir != NULL) { + scope = kCdScopeTabpage; + } + + if (!changedir_func(argvars[0].vval.v_string, scope)) { + // Directory change failed + XFREE_CLEAR(rettv->vval.v_string); + } +} + /* * "cindent(lnum)" function */ @@ -1081,7 +1121,7 @@ static void f_cindent(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } -static win_T * get_optional_window(typval_T *argvars, int idx) +static win_T *get_optional_window(typval_T *argvars, int idx) { win_T *win = curwin; @@ -1802,7 +1842,7 @@ static void f_did_filetype(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_diff_filler(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - rettv->vval.v_number = diff_check_fill(curwin, tv_get_lnum(argvars)); + rettv->vval.v_number = MAX(0, diff_check(curwin, tv_get_lnum(argvars))); } /* @@ -1923,13 +1963,13 @@ static void f_environ(typval_T *argvars, typval_T *rettv, FunPtr fptr) os_copy_fullenv(env, env_size); for (ssize_t i = env_size - 1; i >= 0; i--) { - const char * str = env[i]; + const char *str = env[i]; const char * const end = strchr(str + (str[0] == '=' ? 1 : 0), '='); assert(end != NULL); ptrdiff_t len = end - str; assert(len > 0); - const char * value = str + len + 1; + const char *value = str + len + 1; char c = env[i][len]; env[i][len] = NUL; @@ -2695,13 +2735,13 @@ static void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - linenr_T foldstart; - linenr_T foldend; + linenr_T foldstart; + linenr_T foldend; char_u *dashes; - linenr_T lnum; + linenr_T lnum; char_u *s; char_u *r; - int len; + int len; char *txt; rettv->v_type = VAR_STRING; @@ -3088,10 +3128,16 @@ f_getbufvar_end: static void f_getchangelist(typval_T *argvars, typval_T *rettv, FunPtr fptr) { tv_list_alloc_ret(rettv, 2); - vim_ignored = tv_get_number(&argvars[0]); // issue errmsg if type error - emsg_off++; - const buf_T *const buf = tv_get_buf(&argvars[0], false); - emsg_off--; + + const buf_T *buf; + if (argvars[0].v_type == VAR_UNKNOWN) { + buf = curbuf; + } else { + vim_ignored = tv_get_number(&argvars[0]); // issue errmsg if type error + emsg_off++; + buf = tv_get_buf(&argvars[0], false); + emsg_off--; + } if (buf == NULL) { return; } @@ -3310,10 +3356,10 @@ static void f_getcmdwintype(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr) { char_u *pat; - expand_T xpc; - bool filtered = false; - int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH - | WILD_NO_BEEP; + expand_T xpc; + bool filtered = false; + int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH + | WILD_NO_BEEP; if (argvars[1].v_type != VAR_STRING) { EMSG2(_(e_invarg2), "type must be a string"); @@ -3399,8 +3445,8 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr) // Numbers of the scope objects (window, tab) we want the working directory // of. A `-1` means to skip this scope, a `0` means the current object. int scope_number[] = { - [kCdScopeWindow] = 0, // Number of window to look at. - [kCdScopeTab ] = 0, // Number of tab to look at. + [kCdScopeWindow ] = 0, // Number of window to look at. + [kCdScopeTabpage] = 0, // Number of tab to look at. }; char_u *cwd = NULL; // Current working directory to print @@ -3443,8 +3489,8 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr) } // Find the tabpage by number - if (scope_number[kCdScopeTab] > 0) { - tp = find_tabpage(scope_number[kCdScopeTab]); + if (scope_number[kCdScopeTabpage] > 0) { + tp = find_tabpage(scope_number[kCdScopeTabpage]); if (!tp) { EMSG(_("E5000: Cannot find tab number.")); return; @@ -3453,7 +3499,7 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr) // Find the window in `tp` by number, `NULL` if none. if (scope_number[kCdScopeWindow] >= 0) { - if (scope_number[kCdScopeTab] < 0) { + if (scope_number[kCdScopeTabpage] < 0) { EMSG(_("E5001: Higher scope cannot be -1 if lower scope is >= 0.")); return; } @@ -3477,7 +3523,7 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr) break; } FALLTHROUGH; - case kCdScopeTab: + case kCdScopeTabpage: assert(tp); from = tp->tp_localdir; if (from) { @@ -3741,7 +3787,7 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (cur->conceal_char) { char buf[MB_MAXBYTES + 1]; - buf[utf_char2bytes((int)cur->conceal_char, (char_u *)buf)] = NUL; + buf[utf_char2bytes(cur->conceal_char, (char_u *)buf)] = NUL; tv_dict_add_str(dict, S_LEN("conceal"), buf); } @@ -3750,6 +3796,59 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } +// "getmousepos()" function +void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + dict_T *d; + win_T *wp; + int row = mouse_row; + int col = mouse_col; + int grid = mouse_grid; + varnumber_T winid = 0; + varnumber_T winrow = 0; + varnumber_T wincol = 0; + linenr_T line = 0; + varnumber_T column = 0; + + tv_dict_alloc_ret(rettv); + d = rettv->vval.v_dict; + + tv_dict_add_nr(d, S_LEN("screenrow"), (varnumber_T)mouse_row + 1); + tv_dict_add_nr(d, S_LEN("screencol"), (varnumber_T)mouse_col + 1); + + wp = mouse_find_win(&grid, &row, &col); + if (wp != NULL) { + int height = wp->w_height + wp->w_status_height; + // The height is adjusted by 1 when there is a bottom border. This is not + // necessary for a top border since `row` starts at -1 in that case. + if (row < height + wp->w_border_adj[2]) { + winid = wp->handle; + winrow = row + 1 + wp->w_border_adj[0]; // Adjust by 1 for top border + wincol = col + 1 + wp->w_border_adj[3]; // Adjust by 1 for left border + if (row >= 0 && row < wp->w_height && col >= 0 && col < wp->w_width) { + char_u *p; + int count; + + mouse_comp_pos(wp, &row, &col, &line); + + // limit to text length plus one + p = ml_get_buf(wp->w_buffer, line, false); + count = (int)STRLEN(p); + if (col > count) { + col = count; + } + + column = col + 1; + } + } + } + tv_dict_add_nr(d, S_LEN("winid"), winid); + tv_dict_add_nr(d, S_LEN("winrow"), winrow); + tv_dict_add_nr(d, S_LEN("wincol"), wincol); + tv_dict_add_nr(d, S_LEN("line"), (varnumber_T)line); + tv_dict_add_nr(d, S_LEN("column"), column); +} + /* * "getpid()" function */ @@ -4113,8 +4212,8 @@ static void f_win_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) // static void win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags) { - int dir; - int height = wp->w_height; + int dir; + int height = wp->w_height; win_T *oldwin = curwin; if (wp == targetwin) { @@ -4153,7 +4252,7 @@ static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr) { win_T *wp; win_T *targetwin; - int flags = 0, size = 0; + int flags = 0, size = 0; wp = find_win_by_nr_or_id(&argvars[0]); targetwin = find_win_by_nr_or_id(&argvars[1]); @@ -4303,7 +4402,7 @@ static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr) globpath((char_u *)tv_get_string(&argvars[0]), (char_u *)file, &ga, flags); if (rettv->v_type == VAR_STRING) { - rettv->vval.v_string = ga_concat_strings_sep(&ga, "\n"); + rettv->vval.v_string = (char_u *)ga_concat_strings_sep(&ga, "\n"); } else { tv_list_alloc_ret(rettv, ga.ga_len); for (int i = 0; i < ga.ga_len; i++) { @@ -4553,8 +4652,8 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr) // Numbers of the scope objects (window, tab) we want the working directory // of. A `-1` means to skip this scope, a `0` means the current object. int scope_number[] = { - [kCdScopeWindow] = 0, // Number of window to look at. - [kCdScopeTab ] = 0, // Number of tab to look at. + [kCdScopeWindow ] = 0, // Number of window to look at. + [kCdScopeTabpage] = 0, // Number of tab to look at. }; tabpage_T *tp = curtab; // The tabpage to look at. @@ -4592,8 +4691,8 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr) } // Find the tabpage by number - if (scope_number[kCdScopeTab] > 0) { - tp = find_tabpage(scope_number[kCdScopeTab]); + if (scope_number[kCdScopeTabpage] > 0) { + tp = find_tabpage(scope_number[kCdScopeTabpage]); if (!tp) { EMSG(_("E5000: Cannot find tab number.")); return; @@ -4602,7 +4701,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr) // Find the window in `tp` by number, `NULL` if none. if (scope_number[kCdScopeWindow] >= 0) { - if (scope_number[kCdScopeTab] < 0) { + if (scope_number[kCdScopeTabpage] < 0) { EMSG(_("E5001: Higher scope cannot be -1 if lower scope is >= 0.")); return; } @@ -4621,7 +4720,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr) assert(win); rettv->vval.v_number = win->w_localdir ? 1 : 0; break; - case kCdScopeTab: + case kCdScopeTabpage: assert(tp); rettv->vval.v_number = tp->tp_localdir ? 1 : 0; break; @@ -5096,7 +5195,7 @@ static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr) EMSG(_(e_trailing)); } else { if (lv.ll_tv == NULL) { - di = find_var((const char *)lv.ll_name, lv.ll_name_len, NULL, true); + di = find_var(lv.ll_name, lv.ll_name_len, NULL, true); if (di != NULL) { // Consider a variable locked when: // 1. the variable itself is locked @@ -5177,7 +5276,7 @@ static void f_jobpid(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - Process *proc = (Process *)&data->stream.proc; + Process *proc = &data->stream.proc; rettv->vval.v_number = proc->pid; } @@ -5246,7 +5345,7 @@ static const char *required_env_vars[] = { static dict_T *create_environment(const dictitem_T *job_env, const bool clear_env, const bool pty, const char * const pty_term_name) { - dict_T * env = tv_dict_alloc(); + dict_T *env = tv_dict_alloc(); if (!clear_env) { typval_T temp_env = TV_INITIAL_VALUE; @@ -5475,7 +5574,7 @@ static void f_jobstop(typval_T *argvars, typval_T *rettv, FunPtr fptr) // Ignore return code, but show error later. (void)channel_close(data->id, kChannelPartRpc, &error); } - process_stop((Process *)&data->stream.proc); + process_stop(&data->stream.proc); rettv->vval.v_number = 1; if (error) { EMSG(error); @@ -5850,7 +5949,7 @@ static void f_list2str(typval_T *argvars, typval_T *rettv, FunPtr fptr) TV_LIST_ITER_CONST(l, li, { buf[utf_char2bytes(tv_get_number(TV_LIST_ITEM_TV(li)), buf)] = NUL; - ga_concat(&ga, buf); + ga_concat(&ga, (char *)buf); }); ga_append(&ga, NUL); @@ -5931,7 +6030,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr) FUNC_ATTR_NONNULL_ALL { - const char *const str = (const char *)tv_get_string_chk(&argvars[0]); + const char *const str = tv_get_string_chk(&argvars[0]); if (str == NULL) { return; } @@ -5968,7 +6067,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, const SomeMatchType type) { char_u *str = NULL; - long len = 0; + long len = 0; char_u *expr = NULL; regmatch_T regmatch; char_u *save_cpo; @@ -6082,7 +6181,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, } } - match = vim_regexec_nl(®match, str, (colnr_T)startcol); + match = vim_regexec_nl(®match, str, startcol); if (match && --nth <= 0) { break; @@ -6293,7 +6392,7 @@ static void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr) : 0)); if (id >= 1 && id <= 3) { - matchitem_T *const m = (matchitem_T *)get_match(curwin, id); + matchitem_T *const m = get_match(curwin, id); if (m != NULL) { tv_list_append_string(rettv->vval.v_list, @@ -6940,7 +7039,7 @@ static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr) } else { tv_list_alloc_ret(rettv, (end - start) / stride); for (i = start; stride > 0 ? i <= end : i >= end; i += stride) { - tv_list_append_number(rettv->vval.v_list, (varnumber_T)i); + tv_list_append_number(rettv->vval.v_list, i); } } } @@ -7218,6 +7317,62 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) fclose(fd); } +/// "getreginfo()" function +static void f_getreginfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + const char *strregname; + if (argvars[0].v_type != VAR_UNKNOWN) { + strregname = tv_get_string_chk(&argvars[0]); + if (strregname == NULL) { + return; + } + } else { + strregname = (const char *)get_vim_var_str(VV_REG); + } + + int regname = (strregname == NULL ? '"' : *strregname); + if (regname == 0 || regname == '@') { + regname = '"'; + } + + tv_dict_alloc_ret(rettv); + dict_T *const dict = rettv->vval.v_dict; + + list_T *const list = get_reg_contents(regname, kGRegExprSrc | kGRegList); + if (list == NULL) { + return; + } + (void)tv_dict_add_list(dict, S_LEN("regcontents"), list); + + char buf[NUMBUFLEN + 2]; + buf[0] = NUL; + buf[1] = NUL; + colnr_T reglen = 0; + switch (get_reg_type(regname, ®len)) { + case kMTLineWise: + buf[0] = 'V'; + break; + case kMTCharWise: + buf[0] = 'v'; + break; + case kMTBlockWise: + vim_snprintf(buf, sizeof(buf), "%c%d", Ctrl_V, reglen + 1); + break; + case kMTUnknown: + abort(); + } + (void)tv_dict_add_str(dict, S_LEN("regtype"), buf); + + buf[0] = get_register_name(get_unname_register()); + buf[1] = NUL; + if (regname == '"') { + (void)tv_dict_add_str(dict, S_LEN("points_to"), buf); + } else { + (void)tv_dict_add_bool(dict, S_LEN("isunnamed"), + regname == buf[0] ? kBoolVarTrue : kBoolVarFalse); + } +} + // "reg_executing()" function static void f_reg_executing(typval_T *argvars, typval_T *rettv, FunPtr fptr) { @@ -8365,20 +8520,22 @@ static void f_searchpairpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) tv_list_append_number(rettv->vval.v_list, (varnumber_T)col); } -/* - * Search for a start/middle/end thing. - * Used by searchpair(), see its documentation for the details. - * Returns 0 or -1 for no match, - */ -long do_searchpair(const char *spat, // start pattern - const char *mpat, // middle pattern - const char *epat, // end pattern - int dir, // BACKWARD or FORWARD - const typval_T *skip, // skip expression - int flags, // SP_SETPCMARK and other SP_ values - pos_T *match_pos, linenr_T lnum_stop, // stop at this line if not zero - long time_limit // stop after this many msec - ) +/// Search for a start/middle/end thing. +/// Used by searchpair(), see its documentation for the details. +/// +/// @param spat start pattern +/// @param mpat middle pattern +/// @param epat end pattern +/// @param dir BACKWARD or FORWARD +/// @param skip skip expression +/// @param flags SP_SETPCMARK and other SP_ values +/// @param lnum_stop stop at this line if not zero +/// @param time_limit stop after this many msec +/// +/// @returns 0 or -1 for no match, +long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir, + const typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, + long time_limit) FUNC_ATTR_NONNULL_ARG(1, 2, 3) { char_u *save_cpo; @@ -9001,7 +9158,7 @@ static void f_setpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) { pos_T pos; int fnum; - colnr_T curswant = -1; + colnr_T curswant = -1; rettv->vval.v_number = -1; const char *const name = tv_get_string_chk(argvars); @@ -9039,6 +9196,36 @@ static void f_setqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr) set_qf_ll_list(NULL, argvars, rettv); } +/// Translate a register type string to the yank type and block length +static int get_yank_type(char_u **const pp, MotionType *const yank_type, long *const block_len) + FUNC_ATTR_NONNULL_ALL +{ + char_u *stropt = *pp; + switch (*stropt) { + case 'v': + case 'c': // character-wise selection + *yank_type = kMTCharWise; + break; + case 'V': + case 'l': // line-wise selection + *yank_type = kMTLineWise; + break; + case 'b': + case Ctrl_V: // block-wise selection + *yank_type = kMTBlockWise; + if (ascii_isdigit(stropt[1])) { + stropt++; + *block_len = getdigits_long(&stropt, false, 0) - 1; + stropt--; + } + break; + default: + return FAIL; + } + *pp = stropt; + return OK; +} + /* * "setreg()" function */ @@ -9063,8 +9250,53 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr) regname = '"'; } + const typval_T *regcontents = NULL; + int pointreg = 0; + if (argvars[1].v_type == VAR_DICT) { + dict_T *const d = argvars[1].vval.v_dict; + + if (tv_dict_len(d) == 0) { + // Empty dict, clear the register (like setreg(0, [])) + char_u *lstval[2] = { NULL, NULL }; + write_reg_contents_lst(regname, lstval, false, kMTUnknown, -1); + return; + } + + dictitem_T *const di = tv_dict_find(d, "regcontents", -1); + if (di != NULL) { + regcontents = &di->di_tv; + } + + const char *stropt = tv_dict_get_string(d, "regtype", false); + if (stropt != NULL) { + const int ret = get_yank_type((char_u **)&stropt, &yank_type, &block_len); + + if (ret == FAIL || *(++stropt) != NUL) { + EMSG2(_(e_invargval), "value"); + return; + } + } + + if (regname == '"') { + stropt = tv_dict_get_string(d, "points_to", false); + if (stropt != NULL) { + pointreg = *stropt; + regname = pointreg; + } + } else if (tv_dict_get_number(d, "isunnamed")) { + pointreg = regname; + } + } else { + regcontents = &argvars[1]; + } + bool set_unnamed = false; if (argvars[2].v_type != VAR_UNKNOWN) { + if (yank_type != kMTUnknown) { + EMSG2(_(e_toomanyarg), "setreg"); + return; + } + const char *stropt = tv_get_string_chk(&argvars[2]); if (stropt == NULL) { return; // Type error. @@ -9075,33 +9307,18 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr) case 'A': // append append = true; break; - case 'v': - case 'c': // character-wise selection - yank_type = kMTCharWise; - break; - case 'V': - case 'l': // line-wise selection - yank_type = kMTLineWise; - break; - case 'b': - case Ctrl_V: // block-wise selection - yank_type = kMTBlockWise; - if (ascii_isdigit(stropt[1])) { - stropt++; - block_len = getdigits_long((char_u **)&stropt, true, 0) - 1; - stropt--; - } - break; case 'u': case '"': // unnamed register set_unnamed = true; break; + default: + get_yank_type((char_u **)&stropt, &yank_type, &block_len); } } } - if (argvars[1].v_type == VAR_LIST) { - list_T *ll = argvars[1].vval.v_list; + if (regcontents != NULL && regcontents->v_type == VAR_LIST) { + list_T *const ll = regcontents->vval.v_list; // If the list is NULL handle like an empty list. const int len = tv_list_len(ll); @@ -9137,14 +9354,17 @@ free_lstval: xfree(*--curallocval); } xfree(lstval); - } else { - const char *strval = tv_get_string_chk(&argvars[1]); + } else if (regcontents != NULL) { + const char *const strval = tv_get_string_chk(regcontents); if (strval == NULL) { return; } write_reg_contents_ex(regname, (const char_u *)strval, STRLEN(strval), append, yank_type, block_len); } + if (pointreg != 0) { + get_yank_register(pointreg, YREG_YANK); + } rettv->vval.v_number = 0; if (set_unnamed) { @@ -9201,7 +9421,7 @@ static void f_settagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr) static char *e_invact2 = N_("E962: Invalid action: '%s'"); win_T *wp; dict_T *d; - int action = 'r'; + int action = 'r'; rettv->vval.v_number = -1; @@ -9424,7 +9644,7 @@ static void f_sign_jump(typval_T *argvars, typval_T *rettv, FunPtr fptr) } // Sign group - const char * sign_group_chk = tv_get_string_chk(&argvars[1]); + const char *sign_group_chk = tv_get_string_chk(&argvars[1]); if (sign_group_chk == NULL) { return; } @@ -10683,7 +10903,7 @@ static void f_strridx(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_strtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr) { rettv->v_type = VAR_STRING; - rettv->vval.v_string = (char_u *)transstr(tv_get_string(&argvars[0])); + rettv->vval.v_string = (char_u *)transstr(tv_get_string(&argvars[0]), true); } /* @@ -11187,7 +11407,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (new_cwd && *new_cwd != NUL) { cwd = new_cwd; // The new cwd must be a directory. - if (!os_isdir_executable((const char *)cwd)) { + if (!os_isdir_executable(cwd)) { EMSG2(_(e_invarg2), "expected valid directory"); shell_free_argv(argv); return; @@ -11834,10 +12054,10 @@ static void f_winrestcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr) FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { snprintf((char *)buf, sizeof(buf), "%dresize %d|", winnr, wp->w_height); - ga_concat(&ga, buf); + ga_concat(&ga, (char *)buf); snprintf((char *)buf, sizeof(buf), "vert %dresize %d|", winnr, wp->w_width); - ga_concat(&ga, buf); + ga_concat(&ga, (char *)buf); winnr++; } } diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 3bc4ec9381..6300ce6150 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -100,7 +100,7 @@ void list_write_log(const char *const fname) } } -#ifdef EXITFREE +# ifdef EXITFREE /// Free list log void list_free_log(void) { @@ -110,7 +110,7 @@ void list_free_log(void) chunk = list_log_first; } } -#endif +# endif #endif //{{{2 List item @@ -789,12 +789,12 @@ static int list_join_inner(garray_T *const gap, list_T *const l, const char *con if (first) { first = false; } else { - ga_concat(gap, (const char_u *)sep); + ga_concat(gap, sep); } const Join *const p = ((const Join *)join_gap->ga_data) + i; if (p->s != NULL) { - ga_concat(gap, p->s); + ga_concat(gap, (char *)p->s); } line_breakcheck(); } @@ -2861,7 +2861,7 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic, const boo char buf2[NUMBUFLEN]; const char *s1 = tv_get_string_buf(tv1, buf1); const char *s2 = tv_get_string_buf(tv2, buf2); - return mb_strcmp_ic((bool)ic, s1, s2) == 0; + return mb_strcmp_ic(ic, s1, s2) == 0; } case VAR_BOOL: return tv1->vval.v_bool == tv2->vval.v_bool; @@ -3260,7 +3260,7 @@ const char *tv_get_string(const typval_T *const tv) const char *tv_get_string_buf(const typval_T *const tv, char *const buf) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT { - const char *const res = (const char *)tv_get_string_buf_chk(tv, buf); + const char *const res = tv_get_string_buf_chk(tv, buf); return res != NULL ? res : ""; } diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 5aecaccee9..a28feffd0b 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -1,23 +1,23 @@ #ifndef NVIM_EVAL_TYPVAL_H #define NVIM_EVAL_TYPVAL_H +#include <assert.h> #include <inttypes.h> +#include <stdbool.h> #include <stddef.h> #include <string.h> -#include <stdbool.h> -#include <assert.h> -#include "nvim/types.h" -#include "nvim/hashtab.h" -#include "nvim/garray.h" -#include "nvim/mbyte.h" #include "nvim/func_attr.h" -#include "nvim/lib/queue.h" -#include "nvim/profile.h" // for proftime_T -#include "nvim/pos.h" // for linenr_T +#include "nvim/garray.h" #include "nvim/gettext.h" -#include "nvim/message.h" +#include "nvim/hashtab.h" +#include "nvim/lib/queue.h" #include "nvim/macros.h" +#include "nvim/mbyte.h" +#include "nvim/message.h" +#include "nvim/pos.h" // for linenr_T +#include "nvim/profile.h" // for proftime_T +#include "nvim/types.h" #ifdef LOG_LIST_ACTIONS # include "nvim/memory.h" #endif @@ -156,8 +156,8 @@ typedef enum { typedef struct listitem_S listitem_T; struct listitem_S { - listitem_T *li_next; ///< Next item in list. - listitem_T *li_prev; ///< Previous item in list. + listitem_T *li_next; ///< Next item in list. + listitem_T *li_prev; ///< Previous item in list. typval_T li_tv; ///< Item value. }; @@ -195,25 +195,25 @@ typedef struct { } staticList10_T; #define TV_LIST_STATIC10_INIT { \ - .sl_list = { \ - .lv_first = NULL, \ - .lv_last = NULL, \ - .lv_refcount = 0, \ - .lv_len = 0, \ - .lv_watch = NULL, \ - .lv_idx_item = NULL, \ - .lv_lock = VAR_FIXED, \ - .lv_used_next = NULL, \ - .lv_used_prev = NULL, \ - }, \ - } + .sl_list = { \ + .lv_first = NULL, \ + .lv_last = NULL, \ + .lv_refcount = 0, \ + .lv_len = 0, \ + .lv_watch = NULL, \ + .lv_idx_item = NULL, \ + .lv_lock = VAR_FIXED, \ + .lv_used_next = NULL, \ + .lv_used_prev = NULL, \ + }, \ +} #define TV_DICTITEM_STRUCT(...) \ - struct { \ - typval_T di_tv; /* Structure that holds scope dictionary itself. */ \ - uint8_t di_flags; /* Flags. */ \ - char_u di_key[__VA_ARGS__]; /* Key value. */ \ - } + struct { \ + typval_T di_tv; /* Structure that holds scope dictionary itself. */ \ + uint8_t di_flags; /* Flags. */ \ + char_u di_key[__VA_ARGS__]; /* Key value. */ \ + } /// Structure to hold a scope dictionary /// @@ -321,40 +321,40 @@ struct funccall_S { /// Structure to hold info for a user function. struct ufunc { - int uf_varargs; ///< variable nr of arguments - int uf_flags; - int uf_calls; ///< nr of active calls - bool uf_cleared; ///< func_clear() was already called - garray_T uf_args; ///< arguments - garray_T uf_def_args; ///< default argument expressions - garray_T uf_lines; ///< function lines - int uf_profiling; ///< true when func is being profiled - int uf_prof_initialized; + int uf_varargs; ///< variable nr of arguments + int uf_flags; + int uf_calls; ///< nr of active calls + bool uf_cleared; ///< func_clear() was already called + garray_T uf_args; ///< arguments + garray_T uf_def_args; ///< default argument expressions + garray_T uf_lines; ///< function lines + int uf_profiling; ///< true when func is being profiled + int uf_prof_initialized; // Managing cfuncs - cfunc_T uf_cb; ///< C function extension callback + cfunc_T uf_cb; ///< C function extension callback cfunc_free_T uf_cb_free; ///< C function extension free callback - void *uf_cb_state; ///< State of C function extension. + void *uf_cb_state; ///< State of C function extension. // Profiling the function as a whole. - int uf_tm_count; ///< nr of calls - proftime_T uf_tm_total; ///< time spent in function + children - proftime_T uf_tm_self; ///< time spent in function itself - proftime_T uf_tm_children; ///< time spent in children this call + int uf_tm_count; ///< nr of calls + proftime_T uf_tm_total; ///< time spent in function + children + proftime_T uf_tm_self; ///< time spent in function itself + proftime_T uf_tm_children; ///< time spent in children this call // Profiling the function per line. - int *uf_tml_count; ///< nr of times line was executed - proftime_T *uf_tml_total; ///< time spent in a line + children - proftime_T *uf_tml_self; ///< time spent in a line itself - proftime_T uf_tml_start; ///< start time for current line - proftime_T uf_tml_children; ///< time spent in children for this line - proftime_T uf_tml_wait; ///< start wait time for current line - int uf_tml_idx; ///< index of line being timed; -1 if none - int uf_tml_execed; ///< line being timed was executed - sctx_T uf_script_ctx; ///< SCTX where function was defined, - ///< used for s: variables - int uf_refcount; ///< reference count, see func_name_refcount() - funccall_T *uf_scoped; ///< l: local variables for closure - char_u uf_name[]; ///< Name of function (actual size equals name); - ///< can start with <SNR>123_ - ///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR) + int *uf_tml_count; ///< nr of times line was executed + proftime_T *uf_tml_total; ///< time spent in a line + children + proftime_T *uf_tml_self; ///< time spent in a line itself + proftime_T uf_tml_start; ///< start time for current line + proftime_T uf_tml_children; ///< time spent in children for this line + proftime_T uf_tml_wait; ///< start wait time for current line + int uf_tml_idx; ///< index of line being timed; -1 if none + int uf_tml_execed; ///< line being timed was executed + sctx_T uf_script_ctx; ///< SCTX where function was defined, + ///< used for s: variables + int uf_refcount; ///< reference count, see func_name_refcount() + funccall_T *uf_scoped; ///< l: local variables for closure + char_u uf_name[]; ///< Name of function (actual size equals name); + ///< can start with <SNR>123_ + ///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR) }; struct partial_S { @@ -452,10 +452,8 @@ static inline void list_log(const list_T *const l, /// @param[in] li1 List item 1. /// @param[in] li2 List item 2, often used for integers and not list items. /// @param[in] action Logged action. -static inline void list_log(const list_T *const l, - const listitem_T *const li1, - const listitem_T *const li2, - const char *const action) +static inline void list_log(const list_T *const l, const listitem_T *const li1, + const listitem_T *const li2, const char *const action) { ListLog *tgt; if (list_log_first == NULL) { @@ -484,7 +482,7 @@ static inline void list_log(const list_T *const l, /// Convert a hashitem pointer to a dictitem pointer #define TV_DICT_HI2DI(hi) \ - ((dictitem_T *)((hi)->hi_key - offsetof(dictitem_T, di_key))) + ((dictitem_T *)((hi)->hi_key - offsetof(dictitem_T, di_key))) static inline void tv_list_ref(list_T *const l) REAL_FATTR_ALWAYS_INLINE; @@ -538,8 +536,7 @@ static inline VarLockStatus tv_list_locked(const list_T *const l) /// /// @param[out] l List to modify. /// @param[in] lock New lock status. -static inline void tv_list_set_lock(list_T *const l, - const VarLockStatus lock) +static inline void tv_list_set_lock(list_T *const l, const VarLockStatus lock) { if (l == NULL) { assert(lock == VAR_FIXED); @@ -554,8 +551,7 @@ static inline void tv_list_set_lock(list_T *const l, /// /// @param[out] l List to modify. /// @param[in] copyid New copyID. -static inline void tv_list_set_copyid(list_T *const l, - const int copyid) +static inline void tv_list_set_copyid(list_T *const l, const int copyid) FUNC_ATTR_NONNULL_ALL { l->lv_copyID = copyid; @@ -793,10 +789,10 @@ static inline void tv_init(typval_T *const tv) } #define TV_INITIAL_VALUE \ - ((typval_T) { \ - .v_type = VAR_UNKNOWN, \ - .v_lock = VAR_UNLOCKED, \ - }) + ((typval_T) { \ + .v_type = VAR_UNKNOWN, \ + .v_lock = VAR_UNLOCKED, \ + }) /// Empty string /// @@ -815,16 +811,16 @@ extern bool tv_in_free_unref_items; /// @param li Name of the variable with current listitem_T entry. /// @param code Cycle body. #define _TV_LIST_ITER_MOD(modifier, l, li, code) \ - do { \ - modifier list_T *const l_ = (l); \ - list_log(l_, NULL, NULL, "iter" #modifier); \ - if (l_ != NULL) { \ - for (modifier listitem_T *li = l_->lv_first; \ - li != NULL; li = li->li_next) { \ - code \ - } \ + do { \ + modifier list_T *const l_ = (l); \ + list_log(l_, NULL, NULL, "iter" #modifier); \ + if (l_ != NULL) { \ + for (modifier listitem_T *li = l_->lv_first; \ + li != NULL; li = li->li_next) { \ + code \ } \ - } while (0) + } \ + } while (0) /// Iterate over a list /// @@ -835,7 +831,7 @@ extern bool tv_in_free_unref_items; /// @param li Name of the variable with current listitem_T entry. /// @param code Cycle body. #define TV_LIST_ITER(l, li, code) \ - _TV_LIST_ITER_MOD(, l, li, code) + _TV_LIST_ITER_MOD(, l, li, code) /// Iterate over a list /// @@ -846,7 +842,7 @@ extern bool tv_in_free_unref_items; /// @param li Name of the variable with current listitem_T entry. /// @param code Cycle body. #define TV_LIST_ITER_CONST(l, li, code) \ - _TV_LIST_ITER_MOD(const, l, li, code) + _TV_LIST_ITER_MOD(const, l, li, code) // Below macros are macros to avoid duplicating code for functionally identical // const and non-const function variants. @@ -883,14 +879,14 @@ extern bool tv_in_free_unref_items; /// @param di Name of the variable with current dictitem_T entry. /// @param code Cycle body. #define TV_DICT_ITER(d, di, code) \ - HASHTAB_ITER(&(d)->dv_hashtab, di##hi_, { \ + HASHTAB_ITER(&(d)->dv_hashtab, di##hi_, { \ + { \ + dictitem_T *const di = TV_DICT_HI2DI(di##hi_); \ { \ - dictitem_T *const di = TV_DICT_HI2DI(di##hi_); \ - { \ - code \ - } \ + code \ } \ - }) + } \ + }) static inline bool tv_get_float_chk(const typval_T *const tv, float_T *const ret_f) @@ -907,8 +903,7 @@ bool emsgf(const char *const fmt, ...); /// @param[out] ret_f Location where resulting float is stored. /// /// @return true in case of success, false if tv is not a number or float. -static inline bool tv_get_float_chk(const typval_T *const tv, - float_T *const ret_f) +static inline bool tv_get_float_chk(const typval_T *const tv, float_T *const ret_f) { if (tv->v_type == VAR_FLOAT) { *ret_f = tv->vval.v_float; diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h index cd1be1eecc..ece51cb046 100644 --- a/src/nvim/eval/typval_encode.c.h +++ b/src/nvim/eval/typval_encode.c.h @@ -240,15 +240,15 @@ /// /// This name will only be used by one of the above macros which are defined by /// the caller. Functions defined here do not use first argument directly. -#include <stddef.h> -#include <inttypes.h> #include <assert.h> +#include <inttypes.h> +#include <stddef.h> -#include "nvim/lib/kvec.h" -#include "nvim/eval/typval.h" #include "nvim/eval/encode.h" -#include "nvim/func_attr.h" +#include "nvim/eval/typval.h" #include "nvim/eval/typval_encode.h" +#include "nvim/func_attr.h" +#include "nvim/lib/kvec.h" /// Dummy variable used because some macros need lvalue /// @@ -257,12 +257,12 @@ const dict_T *const TYPVAL_ENCODE_NODICT_VAR = NULL; static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - void *const val, int *const val_copyID, - const MPConvStack *const mpstack, const int copyID, - const MPConvStackValType conv_type, - const char *const objname) - REAL_FATTR_NONNULL_ARG(2, 3, 4, 7) REAL_FATTR_WARN_UNUSED_RESULT + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, + void *const val, int *const val_copyID, + const MPConvStack *const mpstack, const int copyID, + const MPConvStackValType conv_type, + const char *const objname) +REAL_FATTR_NONNULL_ARG(2, 3, 4, 7) REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_ALWAYS_INLINE; /// Function for checking whether container references itself @@ -280,11 +280,9 @@ static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( /// /// @return NOTDONE in case of success, what to return in case of failure. static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - void *const val, int *const val_copyID, - const MPConvStack *const mpstack, const int copyID, - const MPConvStackValType conv_type, - const char *const objname) + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, void *const val, int *const val_copyID, + const MPConvStack *const mpstack, const int copyID, const MPConvStackValType conv_type, + const char *const objname) { if (*val_copyID == copyID) { TYPVAL_ENCODE_CONV_RECURSE(val, conv_type); @@ -295,11 +293,11 @@ static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( } static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - MPConvStack *const mpstack, MPConvStackVal *const cur_mpsv, - typval_T *const tv, const int copyID, - const char *const objname) - REAL_FATTR_NONNULL_ARG(2, 4, 6) REAL_FATTR_WARN_UNUSED_RESULT; + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, + MPConvStack *const mpstack, MPConvStackVal *const cur_mpsv, + typval_T *const tv, const int copyID, + const char *const objname) +REAL_FATTR_NONNULL_ARG(2, 4, 6) REAL_FATTR_WARN_UNUSED_RESULT; /// Convert single value /// @@ -319,42 +317,35 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( /// /// @return OK in case of success, FAIL in case of failure. static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - MPConvStack *const mpstack, MPConvStackVal *const cur_mpsv, - typval_T *const tv, const int copyID, - const char *const objname) + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, MPConvStack *const mpstack, + MPConvStackVal *const cur_mpsv, typval_T *const tv, const int copyID, const char *const objname) { switch (tv->v_type) { - case VAR_STRING: { - TYPVAL_ENCODE_CONV_STRING(tv, tv->vval.v_string, tv_strlen(tv)); - break; - } - case VAR_NUMBER: { - TYPVAL_ENCODE_CONV_NUMBER(tv, tv->vval.v_number); - break; - } - case VAR_FLOAT: { - TYPVAL_ENCODE_CONV_FLOAT(tv, tv->vval.v_float); - break; - } - case VAR_BLOB: { - TYPVAL_ENCODE_CONV_BLOB(tv, tv->vval.v_blob, - tv_blob_len(tv->vval.v_blob)); - break; - } - case VAR_FUNC: { - TYPVAL_ENCODE_CONV_FUNC_START(tv, tv->vval.v_string); - TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, 0); - TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1); - TYPVAL_ENCODE_CONV_FUNC_END(tv); - break; - } - case VAR_PARTIAL: { - partial_T *const pt = tv->vval.v_partial; - (void)pt; - TYPVAL_ENCODE_CONV_FUNC_START( // -V547 - tv, (pt == NULL ? NULL : partial_name(pt))); - _mp_push(*mpstack, ((MPConvStackVal) { // -V779 + case VAR_STRING: + TYPVAL_ENCODE_CONV_STRING(tv, tv->vval.v_string, tv_strlen(tv)); + break; + case VAR_NUMBER: + TYPVAL_ENCODE_CONV_NUMBER(tv, tv->vval.v_number); + break; + case VAR_FLOAT: + TYPVAL_ENCODE_CONV_FLOAT(tv, tv->vval.v_float); + break; + case VAR_BLOB: + TYPVAL_ENCODE_CONV_BLOB(tv, tv->vval.v_blob, + tv_blob_len(tv->vval.v_blob)); + break; + case VAR_FUNC: + TYPVAL_ENCODE_CONV_FUNC_START(tv, tv->vval.v_string); + TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, 0); + TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1); + TYPVAL_ENCODE_CONV_FUNC_END(tv); + break; + case VAR_PARTIAL: { + partial_T *const pt = tv->vval.v_partial; + (void)pt; + TYPVAL_ENCODE_CONV_FUNC_START( // -V547 + tv, (pt == NULL ? NULL : partial_name(pt))); + _mp_push(*mpstack, ((MPConvStackVal) { // -V779 .type = kMPConvPartial, .tv = tv, .saved_copyID = copyID - 1, @@ -365,19 +356,19 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( }, }, })); + break; + } + case VAR_LIST: { + if (tv->vval.v_list == NULL || tv_list_len(tv->vval.v_list) == 0) { + TYPVAL_ENCODE_CONV_EMPTY_LIST(tv); break; } - case VAR_LIST: { - if (tv->vval.v_list == NULL || tv_list_len(tv->vval.v_list) == 0) { - TYPVAL_ENCODE_CONV_EMPTY_LIST(tv); - break; - } - const int saved_copyID = tv_list_copyid(tv->vval.v_list); - _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_list, lv_copyID, copyID, - kMPConvList); - TYPVAL_ENCODE_CONV_LIST_START(tv, tv_list_len(tv->vval.v_list)); - assert(saved_copyID != copyID); - _mp_push(*mpstack, ((MPConvStackVal) { + const int saved_copyID = tv_list_copyid(tv->vval.v_list); + _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_list, lv_copyID, copyID, + kMPConvList); + TYPVAL_ENCODE_CONV_LIST_START(tv, tv_list_len(tv->vval.v_list)); + assert(saved_copyID != copyID); + _mp_push(*mpstack, ((MPConvStackVal) { .type = kMPConvList, .tv = tv, .saved_copyID = saved_copyID, @@ -388,159 +379,151 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( }, }, })); - TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, _mp_last(*mpstack)); + TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, _mp_last(*mpstack)); + break; + } + case VAR_BOOL: + switch (tv->vval.v_bool) { + case kBoolVarTrue: + case kBoolVarFalse: + TYPVAL_ENCODE_CONV_BOOL(tv, tv->vval.v_bool == kBoolVarTrue); break; } - case VAR_BOOL: { - switch (tv->vval.v_bool) { - case kBoolVarTrue: - case kBoolVarFalse: { - TYPVAL_ENCODE_CONV_BOOL(tv, tv->vval.v_bool == kBoolVarTrue); - break; - } - } + break; + case VAR_SPECIAL: + switch (tv->vval.v_special) { + case kSpecialVarNull: + TYPVAL_ENCODE_CONV_NIL(tv); // -V1037 break; } - case VAR_SPECIAL: { - switch (tv->vval.v_special) { - case kSpecialVarNull: { - TYPVAL_ENCODE_CONV_NIL(tv); // -V1037 + break; + case VAR_DICT: { + if (tv->vval.v_dict == NULL + || tv->vval.v_dict->dv_hashtab.ht_used == 0) { + TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, tv->vval.v_dict); + break; + } + const dictitem_T *type_di; + const dictitem_T *val_di; + if (TYPVAL_ENCODE_ALLOW_SPECIALS + && tv->vval.v_dict->dv_hashtab.ht_used == 2 + && (type_di = tv_dict_find((dict_T *)tv->vval.v_dict, + S_LEN("_TYPE"))) != NULL + && type_di->di_tv.v_type == VAR_LIST + && (val_di = tv_dict_find((dict_T *)tv->vval.v_dict, + S_LEN("_VAL"))) != NULL) { + size_t i; + for (i = 0; i < ARRAY_SIZE(eval_msgpack_type_lists); i++) { + if (type_di->di_tv.vval.v_list == eval_msgpack_type_lists[i]) { break; } } - break; - } - case VAR_DICT: { - if (tv->vval.v_dict == NULL - || tv->vval.v_dict->dv_hashtab.ht_used == 0) { - TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, tv->vval.v_dict); - break; + if (i == ARRAY_SIZE(eval_msgpack_type_lists)) { + goto _convert_one_value_regular_dict; } - const dictitem_T *type_di; - const dictitem_T *val_di; - if (TYPVAL_ENCODE_ALLOW_SPECIALS - && tv->vval.v_dict->dv_hashtab.ht_used == 2 - && (type_di = tv_dict_find((dict_T *)tv->vval.v_dict, - S_LEN("_TYPE"))) != NULL - && type_di->di_tv.v_type == VAR_LIST - && (val_di = tv_dict_find((dict_T *)tv->vval.v_dict, - S_LEN("_VAL"))) != NULL) { - size_t i; - for (i = 0; i < ARRAY_SIZE(eval_msgpack_type_lists); i++) { - if (type_di->di_tv.vval.v_list == eval_msgpack_type_lists[i]) { - break; - } + switch ((MessagePackType)i) { + case kMPNil: + TYPVAL_ENCODE_CONV_NIL(tv); + break; + case kMPBoolean: + if (val_di->di_tv.v_type != VAR_NUMBER) { + goto _convert_one_value_regular_dict; } - if (i == ARRAY_SIZE(eval_msgpack_type_lists)) { + TYPVAL_ENCODE_CONV_BOOL(tv, val_di->di_tv.vval.v_number); + break; + case kMPInteger: { + const list_T *val_list; + varnumber_T sign; + varnumber_T highest_bits; + varnumber_T high_bits; + varnumber_T low_bits; + // List of 4 integers; first is signed (should be 1 or -1, but + // this is not checked), second is unsigned and have at most + // one (sign is -1) or two (sign is 1) non-zero bits (number of + // bits is not checked), other unsigned and have at most 31 + // non-zero bits (number of bits is not checked). + if (val_di->di_tv.v_type != VAR_LIST + || tv_list_len(val_list = val_di->di_tv.vval.v_list) != 4) { goto _convert_one_value_regular_dict; } - switch ((MessagePackType)i) { - case kMPNil: { - TYPVAL_ENCODE_CONV_NIL(tv); - break; - } - case kMPBoolean: { - if (val_di->di_tv.v_type != VAR_NUMBER) { - goto _convert_one_value_regular_dict; - } - TYPVAL_ENCODE_CONV_BOOL(tv, val_di->di_tv.vval.v_number); - break; - } - case kMPInteger: { - const list_T *val_list; - varnumber_T sign; - varnumber_T highest_bits; - varnumber_T high_bits; - varnumber_T low_bits; - // List of 4 integers; first is signed (should be 1 or -1, but - // this is not checked), second is unsigned and have at most - // one (sign is -1) or two (sign is 1) non-zero bits (number of - // bits is not checked), other unsigned and have at most 31 - // non-zero bits (number of bits is not checked). - if (val_di->di_tv.v_type != VAR_LIST - || tv_list_len(val_list = val_di->di_tv.vval.v_list) != 4) { - goto _convert_one_value_regular_dict; - } - const listitem_T *const sign_li = tv_list_first(val_list); - if (TV_LIST_ITEM_TV(sign_li)->v_type != VAR_NUMBER - || (sign = TV_LIST_ITEM_TV(sign_li)->vval.v_number) == 0) { - goto _convert_one_value_regular_dict; - } + const listitem_T *const sign_li = tv_list_first(val_list); + if (TV_LIST_ITEM_TV(sign_li)->v_type != VAR_NUMBER + || (sign = TV_LIST_ITEM_TV(sign_li)->vval.v_number) == 0) { + goto _convert_one_value_regular_dict; + } - const listitem_T *const highest_bits_li = ( - TV_LIST_ITEM_NEXT(val_list, sign_li)); - if (TV_LIST_ITEM_TV(highest_bits_li)->v_type != VAR_NUMBER - || ((highest_bits - = TV_LIST_ITEM_TV(highest_bits_li)->vval.v_number) - < 0)) { - goto _convert_one_value_regular_dict; - } + const listitem_T *const highest_bits_li = ( + TV_LIST_ITEM_NEXT(val_list, sign_li)); + if (TV_LIST_ITEM_TV(highest_bits_li)->v_type != VAR_NUMBER + || ((highest_bits + = TV_LIST_ITEM_TV(highest_bits_li)->vval.v_number) + < 0)) { + goto _convert_one_value_regular_dict; + } - const listitem_T *const high_bits_li = ( - TV_LIST_ITEM_NEXT(val_list, highest_bits_li)); - if (TV_LIST_ITEM_TV(high_bits_li)->v_type != VAR_NUMBER - || ((high_bits = TV_LIST_ITEM_TV(high_bits_li)->vval.v_number) - < 0)) { - goto _convert_one_value_regular_dict; - } + const listitem_T *const high_bits_li = ( + TV_LIST_ITEM_NEXT(val_list, highest_bits_li)); + if (TV_LIST_ITEM_TV(high_bits_li)->v_type != VAR_NUMBER + || ((high_bits = TV_LIST_ITEM_TV(high_bits_li)->vval.v_number) + < 0)) { + goto _convert_one_value_regular_dict; + } - const listitem_T *const low_bits_li = tv_list_last(val_list); - if (TV_LIST_ITEM_TV(low_bits_li)->v_type != VAR_NUMBER - || ((low_bits = TV_LIST_ITEM_TV(low_bits_li)->vval.v_number) - < 0)) { - goto _convert_one_value_regular_dict; - } + const listitem_T *const low_bits_li = tv_list_last(val_list); + if (TV_LIST_ITEM_TV(low_bits_li)->v_type != VAR_NUMBER + || ((low_bits = TV_LIST_ITEM_TV(low_bits_li)->vval.v_number) + < 0)) { + goto _convert_one_value_regular_dict; + } - const uint64_t number = ((uint64_t)(((uint64_t)highest_bits) << 62) - | (uint64_t)(((uint64_t)high_bits) << 31) - | (uint64_t)low_bits); - if (sign > 0) { - TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, number); - } else { - TYPVAL_ENCODE_CONV_NUMBER(tv, -number); - } - break; - } - case kMPFloat: { - if (val_di->di_tv.v_type != VAR_FLOAT) { - goto _convert_one_value_regular_dict; - } - TYPVAL_ENCODE_CONV_FLOAT(tv, val_di->di_tv.vval.v_float); - break; - } - case kMPString: - case kMPBinary: { - const bool is_string = ((MessagePackType)i == kMPString); - if (val_di->di_tv.v_type != VAR_LIST) { - goto _convert_one_value_regular_dict; - } - size_t len; - char *buf; - if (!encode_vim_list_to_buf(val_di->di_tv.vval.v_list, &len, - &buf)) { - goto _convert_one_value_regular_dict; - } - if (is_string) { - TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len); - } else { // -V523 - TYPVAL_ENCODE_CONV_STRING(tv, buf, len); - } - xfree(buf); - break; - } - case kMPArray: { - if (val_di->di_tv.v_type != VAR_LIST) { - goto _convert_one_value_regular_dict; - } - const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list); - _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_di->di_tv.vval.v_list, - lv_copyID, copyID, - kMPConvList); - TYPVAL_ENCODE_CONV_LIST_START( - tv, tv_list_len(val_di->di_tv.vval.v_list)); - assert(saved_copyID != copyID && saved_copyID != copyID - 1); - _mp_push(*mpstack, ((MPConvStackVal) { + const uint64_t number = ((uint64_t)(((uint64_t)highest_bits) << 62) + | (uint64_t)(((uint64_t)high_bits) << 31) + | (uint64_t)low_bits); + if (sign > 0) { + TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, number); + } else { + TYPVAL_ENCODE_CONV_NUMBER(tv, -number); + } + break; + } + case kMPFloat: + if (val_di->di_tv.v_type != VAR_FLOAT) { + goto _convert_one_value_regular_dict; + } + TYPVAL_ENCODE_CONV_FLOAT(tv, val_di->di_tv.vval.v_float); + break; + case kMPString: + case kMPBinary: { + const bool is_string = ((MessagePackType)i == kMPString); + if (val_di->di_tv.v_type != VAR_LIST) { + goto _convert_one_value_regular_dict; + } + size_t len; + char *buf; + if (!encode_vim_list_to_buf(val_di->di_tv.vval.v_list, &len, + &buf)) { + goto _convert_one_value_regular_dict; + } + if (is_string) { + TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len); + } else { // -V523 + TYPVAL_ENCODE_CONV_STRING(tv, buf, len); + } + xfree(buf); + break; + } + case kMPArray: { + if (val_di->di_tv.v_type != VAR_LIST) { + goto _convert_one_value_regular_dict; + } + const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list); + _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_di->di_tv.vval.v_list, + lv_copyID, copyID, + kMPConvList); + TYPVAL_ENCODE_CONV_LIST_START(tv, tv_list_len(val_di->di_tv.vval.v_list)); + assert(saved_copyID != copyID && saved_copyID != copyID - 1); + _mp_push(*mpstack, ((MPConvStackVal) { .tv = tv, .type = kMPConvList, .saved_copyID = saved_copyID, @@ -551,31 +534,31 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( }, }, })); - break; - } - case kMPMap: { - if (val_di->di_tv.v_type != VAR_LIST) { - goto _convert_one_value_regular_dict; - } - list_T *const val_list = val_di->di_tv.vval.v_list; - if (val_list == NULL || tv_list_len(val_list) == 0) { - TYPVAL_ENCODE_CONV_EMPTY_DICT( // -V501 - tv, TYPVAL_ENCODE_NODICT_VAR); - break; - } - TV_LIST_ITER_CONST(val_list, li, { + break; + } + case kMPMap: { + if (val_di->di_tv.v_type != VAR_LIST) { + goto _convert_one_value_regular_dict; + } + list_T *const val_list = val_di->di_tv.vval.v_list; + if (val_list == NULL || tv_list_len(val_list) == 0) { + TYPVAL_ENCODE_CONV_EMPTY_DICT( // -V501 + tv, TYPVAL_ENCODE_NODICT_VAR); + break; + } + TV_LIST_ITER_CONST(val_list, li, { if (TV_LIST_ITEM_TV(li)->v_type != VAR_LIST || tv_list_len(TV_LIST_ITEM_TV(li)->vval.v_list) != 2) { goto _convert_one_value_regular_dict; } }); - const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list); - _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_list, lv_copyID, copyID, - kMPConvPairs); - TYPVAL_ENCODE_CONV_DICT_START(tv, TYPVAL_ENCODE_NODICT_VAR, - tv_list_len(val_list)); - assert(saved_copyID != copyID && saved_copyID != copyID - 1); - _mp_push(*mpstack, ((MPConvStackVal) { + const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list); + _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_list, lv_copyID, copyID, + kMPConvPairs); + TYPVAL_ENCODE_CONV_DICT_START(tv, TYPVAL_ENCODE_NODICT_VAR, + tv_list_len(val_list)); + assert(saved_copyID != copyID && saved_copyID != copyID - 1); + _mp_push(*mpstack, ((MPConvStackVal) { .tv = tv, .type = kMPConvPairs, .saved_copyID = saved_copyID, @@ -586,46 +569,45 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( }, }, })); - break; - } - case kMPExt: { - const list_T *val_list; - varnumber_T type; - if (val_di->di_tv.v_type != VAR_LIST - || tv_list_len((val_list = val_di->di_tv.vval.v_list)) != 2 - || (TV_LIST_ITEM_TV(tv_list_first(val_list))->v_type - != VAR_NUMBER) - || ((type - = TV_LIST_ITEM_TV(tv_list_first(val_list))->vval.v_number) - > INT8_MAX) - || type < INT8_MIN - || (TV_LIST_ITEM_TV(tv_list_last(val_list))->v_type - != VAR_LIST)) { - goto _convert_one_value_regular_dict; - } - size_t len; - char *buf; - if (!( - encode_vim_list_to_buf( - TV_LIST_ITEM_TV(tv_list_last(val_list))->vval.v_list, &len, - &buf))) { - goto _convert_one_value_regular_dict; - } - TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type); - xfree(buf); - break; - } + break; + } + case kMPExt: { + const list_T *val_list; + varnumber_T type; + if (val_di->di_tv.v_type != VAR_LIST + || tv_list_len((val_list = val_di->di_tv.vval.v_list)) != 2 + || (TV_LIST_ITEM_TV(tv_list_first(val_list))->v_type + != VAR_NUMBER) + || ((type + = TV_LIST_ITEM_TV(tv_list_first(val_list))->vval.v_number) + > INT8_MAX) + || type < INT8_MIN + || (TV_LIST_ITEM_TV(tv_list_last(val_list))->v_type + != VAR_LIST)) { + goto _convert_one_value_regular_dict; + } + size_t len; + char *buf; + if (!( + encode_vim_list_to_buf(TV_LIST_ITEM_TV(tv_list_last(val_list))->vval.v_list, &len, + &buf))) { + goto _convert_one_value_regular_dict; } + TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type); + xfree(buf); break; } + } + break; + } _convert_one_value_regular_dict: {} - const int saved_copyID = tv->vval.v_dict->dv_copyID; - _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_dict, dv_copyID, copyID, - kMPConvDict); - TYPVAL_ENCODE_CONV_DICT_START(tv, tv->vval.v_dict, - tv->vval.v_dict->dv_hashtab.ht_used); - assert(saved_copyID != copyID); - _mp_push(*mpstack, ((MPConvStackVal) { + const int saved_copyID = tv->vval.v_dict->dv_copyID; + _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_dict, dv_copyID, copyID, + kMPConvDict); + TYPVAL_ENCODE_CONV_DICT_START(tv, tv->vval.v_dict, + tv->vval.v_dict->dv_hashtab.ht_used); + assert(saved_copyID != copyID); + _mp_push(*mpstack, ((MPConvStackVal) { .tv = tv, .type = kMPConvDict, .saved_copyID = saved_copyID, @@ -638,14 +620,13 @@ _convert_one_value_regular_dict: {} }, }, })); - TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, tv->vval.v_dict, - _mp_last(*mpstack)); - break; - } - case VAR_UNKNOWN: { - internal_error(STR(_TYPVAL_ENCODE_CONVERT_ONE_VALUE) "()"); - return FAIL; - } + TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, tv->vval.v_dict, + _mp_last(*mpstack)); + break; + } + case VAR_UNKNOWN: + internal_error(STR(_TYPVAL_ENCODE_CONVERT_ONE_VALUE) "()"); + return FAIL; } typval_encode_stop_converting_one_item: return OK; @@ -654,9 +635,9 @@ typval_encode_stop_converting_one_item: } TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - typval_T *const tv, const char *const objname) - REAL_FATTR_NONNULL_ARG(2, 3) REAL_FATTR_WARN_UNUSED_RESULT; + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, + typval_T *const tv, const char *const objname) +REAL_FATTR_NONNULL_ARG(2, 3) REAL_FATTR_WARN_UNUSED_RESULT; /// Convert the whole typval /// @@ -668,8 +649,8 @@ TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE( /// /// @return OK in case of success, FAIL in case of failure. TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - typval_T *const top_tv, const char *const objname) + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, typval_T *const top_tv, + const char *const objname) { const int copyID = get_copyID(); MPConvStack mpstack; @@ -687,125 +668,121 @@ typval_encode_stop_converting_one_item: MPConvStackVal *cur_mpsv = &_mp_last(mpstack); typval_T *tv = NULL; switch (cur_mpsv->type) { - case kMPConvDict: { - if (!cur_mpsv->data.d.todo) { - (void)_mp_pop(mpstack); - cur_mpsv->data.d.dict->dv_copyID = cur_mpsv->saved_copyID; - TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, *cur_mpsv->data.d.dictp); - continue; - } else if (cur_mpsv->data.d.todo - != cur_mpsv->data.d.dict->dv_hashtab.ht_used) { - TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(cur_mpsv->tv, - *cur_mpsv->data.d.dictp); - } - while (HASHITEM_EMPTY(cur_mpsv->data.d.hi)) { - cur_mpsv->data.d.hi++; - } - dictitem_T *const di = TV_DICT_HI2DI(cur_mpsv->data.d.hi); - cur_mpsv->data.d.todo--; + case kMPConvDict: { + if (!cur_mpsv->data.d.todo) { + (void)_mp_pop(mpstack); + cur_mpsv->data.d.dict->dv_copyID = cur_mpsv->saved_copyID; + TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, *cur_mpsv->data.d.dictp); + continue; + } else if (cur_mpsv->data.d.todo + != cur_mpsv->data.d.dict->dv_hashtab.ht_used) { + TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(cur_mpsv->tv, + *cur_mpsv->data.d.dictp); + } + while (HASHITEM_EMPTY(cur_mpsv->data.d.hi)) { cur_mpsv->data.d.hi++; - TYPVAL_ENCODE_CONV_STR_STRING(NULL, &di->di_key[0], - strlen((char *)&di->di_key[0])); - TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv, - *cur_mpsv->data.d.dictp); - tv = &di->di_tv; - break; } - case kMPConvList: { - if (cur_mpsv->data.l.li == NULL) { - (void)_mp_pop(mpstack); - tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID); - TYPVAL_ENCODE_CONV_LIST_END(cur_mpsv->tv); - continue; - } else if (cur_mpsv->data.l.li - != tv_list_first(cur_mpsv->data.l.list)) { - TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(cur_mpsv->tv); - } - tv = TV_LIST_ITEM_TV(cur_mpsv->data.l.li); - cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list, - cur_mpsv->data.l.li); - break; + dictitem_T *const di = TV_DICT_HI2DI(cur_mpsv->data.d.hi); + cur_mpsv->data.d.todo--; + cur_mpsv->data.d.hi++; + TYPVAL_ENCODE_CONV_STR_STRING(NULL, &di->di_key[0], + strlen((char *)&di->di_key[0])); + TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv, + *cur_mpsv->data.d.dictp); + tv = &di->di_tv; + break; + } + case kMPConvList: + if (cur_mpsv->data.l.li == NULL) { + (void)_mp_pop(mpstack); + tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID); + TYPVAL_ENCODE_CONV_LIST_END(cur_mpsv->tv); + continue; + } else if (cur_mpsv->data.l.li + != tv_list_first(cur_mpsv->data.l.list)) { + TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(cur_mpsv->tv); } - case kMPConvPairs: { - if (cur_mpsv->data.l.li == NULL) { - (void)_mp_pop(mpstack); - tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID); - TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR); - continue; - } else if (cur_mpsv->data.l.li - != tv_list_first(cur_mpsv->data.l.list)) { - TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS( - cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR); - } - const list_T *const kv_pair = ( - TV_LIST_ITEM_TV(cur_mpsv->data.l.li)->vval.v_list); - TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK( - encode_vim_to__error_ret, *TV_LIST_ITEM_TV(tv_list_first(kv_pair))); - if ( - _TYPVAL_ENCODE_CONVERT_ONE_VALUE( - TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack, cur_mpsv, - TV_LIST_ITEM_TV(tv_list_first(kv_pair)), copyID, objname) - == FAIL) { - goto encode_vim_to__error_ret; - } - TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv, - TYPVAL_ENCODE_NODICT_VAR); - tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair)); - cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list, - cur_mpsv->data.l.li); - break; + tv = TV_LIST_ITEM_TV(cur_mpsv->data.l.li); + cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list, + cur_mpsv->data.l.li); + break; + case kMPConvPairs: { + if (cur_mpsv->data.l.li == NULL) { + (void)_mp_pop(mpstack); + tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID); + TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR); + continue; + } else if (cur_mpsv->data.l.li + != tv_list_first(cur_mpsv->data.l.list)) { + TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR); } - case kMPConvPartial: { - partial_T *const pt = cur_mpsv->data.p.pt; - tv = cur_mpsv->tv; - (void)tv; - switch (cur_mpsv->data.p.stage) { - case kMPConvPartialArgs: { - TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, - pt == NULL ? 0 : pt->pt_argc); - cur_mpsv->data.p.stage = kMPConvPartialSelf; - if (pt != NULL && pt->pt_argc > 0) { - TYPVAL_ENCODE_CONV_LIST_START(NULL, pt->pt_argc); - _mp_push(mpstack, ((MPConvStackVal) { - .type = kMPConvPartialList, - .tv = NULL, - .saved_copyID = copyID - 1, - .data = { - .a = { - .arg = pt->pt_argv, - .argv = pt->pt_argv, - .todo = (size_t)pt->pt_argc, - }, + const list_T *const kv_pair = ( + TV_LIST_ITEM_TV(cur_mpsv->data.l.li)->vval.v_list); + TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(encode_vim_to__error_ret, + *TV_LIST_ITEM_TV(tv_list_first(kv_pair))); + if ( + _TYPVAL_ENCODE_CONVERT_ONE_VALUE(TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack, cur_mpsv, + TV_LIST_ITEM_TV(tv_list_first(kv_pair)), copyID, objname) + == FAIL) { + goto encode_vim_to__error_ret; + } + TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv, + TYPVAL_ENCODE_NODICT_VAR); + tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair)); + cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list, + cur_mpsv->data.l.li); + break; + } + case kMPConvPartial: { + partial_T *const pt = cur_mpsv->data.p.pt; + tv = cur_mpsv->tv; + (void)tv; + switch (cur_mpsv->data.p.stage) { + case kMPConvPartialArgs: + TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, + pt == NULL ? 0 : pt->pt_argc); + cur_mpsv->data.p.stage = kMPConvPartialSelf; + if (pt != NULL && pt->pt_argc > 0) { + TYPVAL_ENCODE_CONV_LIST_START(NULL, pt->pt_argc); + _mp_push(mpstack, ((MPConvStackVal) { + .type = kMPConvPartialList, + .tv = NULL, + .saved_copyID = copyID - 1, + .data = { + .a = { + .arg = pt->pt_argv, + .argv = pt->pt_argv, + .todo = (size_t)pt->pt_argc, }, - })); + }, + })); + } + break; + case kMPConvPartialSelf: { + cur_mpsv->data.p.stage = kMPConvPartialEnd; + dict_T *const dict = pt == NULL ? NULL : pt->pt_dict; + if (dict != NULL) { + TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, dict->dv_hashtab.ht_used); + if (dict->dv_hashtab.ht_used == 0) { + TYPVAL_ENCODE_CONV_EMPTY_DICT(NULL, pt->pt_dict); + continue; + } + const int saved_copyID = dict->dv_copyID; + const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(TYPVAL_ENCODE_FIRST_ARG_NAME, + dict, &dict->dv_copyID, + &mpstack, copyID, kMPConvDict, + objname); + if (te_csr_ret != NOTDONE) { + if (te_csr_ret == FAIL) { + goto encode_vim_to__error_ret; + } else { + continue; } - break; } - case kMPConvPartialSelf: { - cur_mpsv->data.p.stage = kMPConvPartialEnd; - dict_T *const dict = pt == NULL ? NULL : pt->pt_dict; - if (dict != NULL) { - TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, dict->dv_hashtab.ht_used); - if (dict->dv_hashtab.ht_used == 0) { - TYPVAL_ENCODE_CONV_EMPTY_DICT(NULL, pt->pt_dict); - continue; - } - const int saved_copyID = dict->dv_copyID; - const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( - TYPVAL_ENCODE_FIRST_ARG_NAME, - dict, &dict->dv_copyID, &mpstack, copyID, kMPConvDict, - objname); - if (te_csr_ret != NOTDONE) { - if (te_csr_ret == FAIL) { - goto encode_vim_to__error_ret; - } else { - continue; - } - } - TYPVAL_ENCODE_CONV_DICT_START(NULL, pt->pt_dict, - dict->dv_hashtab.ht_used); - assert(saved_copyID != copyID && saved_copyID != copyID - 1); - _mp_push(mpstack, ((MPConvStackVal) { + TYPVAL_ENCODE_CONV_DICT_START(NULL, pt->pt_dict, + dict->dv_hashtab.ht_used); + assert(saved_copyID != copyID && saved_copyID != copyID - 1); + _mp_push(mpstack, ((MPConvStackVal) { .type = kMPConvDict, .tv = NULL, .saved_copyID = saved_copyID, @@ -818,33 +795,31 @@ typval_encode_stop_converting_one_item: }, }, })); - TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(NULL, pt->pt_dict, - _mp_last(mpstack)); - } else { - TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1); - } - break; - } - case kMPConvPartialEnd: { - TYPVAL_ENCODE_CONV_FUNC_END(tv); - (void)_mp_pop(mpstack); - break; - } + TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(NULL, pt->pt_dict, + _mp_last(mpstack)); + } else { + TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1); } - continue; + break; } - case kMPConvPartialList: { - if (!cur_mpsv->data.a.todo) { - (void)_mp_pop(mpstack); - TYPVAL_ENCODE_CONV_LIST_END(NULL); - continue; - } else if (cur_mpsv->data.a.argv != cur_mpsv->data.a.arg) { - TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(NULL); - } - tv = cur_mpsv->data.a.arg++; - cur_mpsv->data.a.todo--; + case kMPConvPartialEnd: + TYPVAL_ENCODE_CONV_FUNC_END(tv); + (void)_mp_pop(mpstack); break; } + continue; + } + case kMPConvPartialList: + if (!cur_mpsv->data.a.todo) { + (void)_mp_pop(mpstack); + TYPVAL_ENCODE_CONV_LIST_END(NULL); + continue; + } else if (cur_mpsv->data.a.argv != cur_mpsv->data.a.arg) { + TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(NULL); + } + tv = cur_mpsv->data.a.arg++; + cur_mpsv->data.a.todo--; + break; } assert(tv != NULL); if (_TYPVAL_ENCODE_CONVERT_ONE_VALUE(TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack, diff --git a/src/nvim/eval/typval_encode.h b/src/nvim/eval/typval_encode.h index 3475f6d8b3..d5cf431870 100644 --- a/src/nvim/eval/typval_encode.h +++ b/src/nvim/eval/typval_encode.h @@ -5,14 +5,14 @@ #ifndef NVIM_EVAL_TYPVAL_ENCODE_H #define NVIM_EVAL_TYPVAL_ENCODE_H -#include <stddef.h> +#include <assert.h> #include <inttypes.h> +#include <stddef.h> #include <string.h> -#include <assert.h> -#include "nvim/lib/kvec.h" #include "nvim/eval/typval.h" #include "nvim/func_attr.h" +#include "nvim/lib/kvec.h" /// Type of the stack entry typedef enum { @@ -87,7 +87,7 @@ static inline size_t tv_strlen(const typval_T *const tv) assert(tv->v_type == VAR_STRING); return (tv->vval.v_string == NULL ? 0 - : strlen((char *) tv->vval.v_string)); + : strlen((char *)tv->vval.v_string)); } /// Code for checking whether container references itself @@ -100,19 +100,19 @@ static inline size_t tv_strlen(const typval_T *const tv) /// @param conv_type Type of the conversion, @see MPConvStackValType. #define _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val, copyID_attr, copyID, \ conv_type) \ - do { \ - const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( \ - TYPVAL_ENCODE_FIRST_ARG_NAME, \ - (val), &(val)->copyID_attr, mpstack, copyID, conv_type, objname); \ - if (te_csr_ret != NOTDONE) { \ - return te_csr_ret; \ - } \ - } while (0) + do { \ + const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(TYPVAL_ENCODE_FIRST_ARG_NAME, \ + (val), &(val)->copyID_attr, mpstack, \ + copyID, conv_type, objname); \ + if (te_csr_ret != NOTDONE) { \ + return te_csr_ret; \ + } \ + } while (0) #define _TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf) \ - pref##name##suf + pref##name##suf #define _TYPVAL_ENCODE_FUNC_NAME_INNER(pref, name, suf) \ - _TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf) + _TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf) /// Construct function name, possibly using macros /// @@ -125,22 +125,22 @@ static inline size_t tv_strlen(const typval_T *const tv) /// /// @return Concat: pref + #TYPVAL_ENCODE_NAME + suf. #define _TYPVAL_ENCODE_FUNC_NAME(pref, suf) \ - _TYPVAL_ENCODE_FUNC_NAME_INNER(pref, TYPVAL_ENCODE_NAME, suf) + _TYPVAL_ENCODE_FUNC_NAME_INNER(pref, TYPVAL_ENCODE_NAME, suf) /// Self reference checker function name #define _TYPVAL_ENCODE_CHECK_SELF_REFERENCE \ - _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _check_self_reference) + _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _check_self_reference) /// Entry point function name #define _TYPVAL_ENCODE_ENCODE \ - _TYPVAL_ENCODE_FUNC_NAME(encode_vim_to_, ) + _TYPVAL_ENCODE_FUNC_NAME(encode_vim_to_, ) /// Name of the …convert_one_value function #define _TYPVAL_ENCODE_CONVERT_ONE_VALUE \ - _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _convert_one_value) + _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _convert_one_value) /// Name of the dummy const dict_T *const variable #define TYPVAL_ENCODE_NODICT_VAR \ - _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _nodict_var) + _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _nodict_var) #endif // NVIM_EVAL_TYPVAL_ENCODE_H diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 2137804fdd..f4393a79dc 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -39,7 +39,7 @@ #define FC_CFUNC 0x800 // C function extension #ifdef INCLUDE_GENERATED_DECLARATIONS -#include "eval/userfunc.c.generated.h" +# include "eval/userfunc.c.generated.h" #endif hashtab_T func_hashtab; @@ -68,11 +68,11 @@ void func_init(void) static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, int *varargs, garray_T *default_args, bool skip) { - bool mustend = false; + bool mustend = false; char_u *arg = *argp; char_u *p = arg; - int c; - int i; + int c; + int i; if (newargs != NULL) { ga_init(newargs, (int)sizeof(char_u *), 3); @@ -203,10 +203,10 @@ static void register_closure(ufunc_T *fp) /// Get a name for a lambda. Returned in static memory. -char_u * get_lambda_name(void) +char_u *get_lambda_name(void) { - static char_u name[30]; - static int lambda_no = 0; + static char_u name[30]; + static int lambda_no = 0; snprintf((char *)name, sizeof(name), "<lambda>%d", ++lambda_no); return name; @@ -217,16 +217,16 @@ char_u * get_lambda_name(void) /// @return OK or FAIL. Returns NOTDONE for dict or {expr}. int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate) { - garray_T newargs = GA_EMPTY_INIT_VALUE; + garray_T newargs = GA_EMPTY_INIT_VALUE; garray_T *pnewargs; ufunc_T *fp = NULL; partial_T *pt = NULL; - int varargs; - int ret; + int varargs; + int ret; char_u *start = skipwhite(*arg + 1); char_u *s, *e; bool *old_eval_lavars = eval_lavars_used; - bool eval_lavars = false; + bool eval_lavars = false; // First, check if this is a lambda expression. "->" must exists. ret = get_function_args(&start, '-', NULL, NULL, NULL, true); @@ -402,15 +402,15 @@ void emsg_funcname(char *ermsg, const char_u *name) } } -/* - * Allocate a variable for the result of a function. - * Return OK or FAIL. - */ -int get_func_tv(const char_u *name, // name of the function - int len, // length of "name" or -1 to use strlen() - typval_T *rettv, char_u **arg, // argument, pointing to the '(' - funcexe_T *funcexe // various values - ) +/// Allocate a variable for the result of a function. +/// +/// @param name name of the function +/// @param len length of "name" or -1 to use strlen() +/// @param arg argument, pointing to the '(' +/// @param funcexe various values +/// +/// @return OK or FAIL. +int get_func_tv(const char_u *name, int len, typval_T *rettv, char_u **arg, funcexe_T *funcexe) { char_u *argp; int ret = OK; @@ -1436,17 +1436,18 @@ static void argv_add_base(typval_T *const basetv, typval_T **const argvars, int /// Call a function with its resolved parameters /// +/// @param funcname name of the function +/// @param len length of "name" or -1 to use strlen() +/// @param rettv [out] value goes here +/// @param argcount_in number of "argvars" +/// @param argvars_in vars for arguments, must have "argcount" PLUS ONE elements! +/// @param funcexe more arguments +/// /// @return FAIL if function cannot be called, else OK (even if an error /// occurred while executing the function! Set `msg_list` to capture /// the error, see do_cmdline()). -int call_func(const char_u *funcname, // name of the function - int len, // length of "name" or -1 to use strlen() - typval_T *rettv, // [out] value goes here - int argcount_in, // number of "argvars" - typval_T *argvars_in, // vars for arguments, must have "argcount" - // PLUS ONE elements! - funcexe_T *funcexe // more arguments - ) +int call_func(const char_u *funcname, int len, typval_T *rettv, int argcount_in, + typval_T *argvars_in, funcexe_T *funcexe) FUNC_ATTR_NONNULL_ARG(1, 3, 5, 6) { int ret = FAIL; @@ -1690,11 +1691,12 @@ static void list_func_head(ufunc_T *fp, int indent, bool force) /// TFN_NO_DEREF: do not dereference a Funcref /// Advances "pp" to just after the function name (if no error). /// +/// @param skip only find the end, don't evaluate +/// @param fdp return: info about dictionary used +/// @param partial return: partial of a FuncRef +/// /// @return the function name in allocated memory, or NULL for failure. -char_u *trans_function_name(char_u **pp, bool skip, // only find the end, don't evaluate - int flags, funcdict_T *fdp, // return: info about dictionary used - partial_T **partial // return: partial of a FuncRef - ) +char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp, partial_T **partial) FUNC_ATTR_NONNULL_ARG(1) { char_u *name = NULL; @@ -1709,8 +1711,8 @@ char_u *trans_function_name(char_u **pp, bool skip, // only } start = *pp; - /* Check for hard coded <SNR>: already translated function ID (from a user - * command). */ + // Check for hard coded <SNR>: already translated function ID (from a user + // command). if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA && (*pp)[2] == (int)KE_SNR) { *pp += 3; @@ -2032,8 +2034,8 @@ void ex_function(exarg_T *eap) } } - /* An error in a function call during evaluation of an expression in magic - * braces should not cause the function not to be defined. */ + // An error in a function call during evaluation of an expression in magic + // braces should not cause the function not to be defined. saved_did_emsg = did_emsg; did_emsg = FALSE; @@ -2105,8 +2107,8 @@ void ex_function(exarg_T *eap) ga_init(&newlines, (int)sizeof(char_u *), 3); if (!eap->skip) { - /* Check the name of the function. Unless it's a dictionary function - * (that we are overwriting). */ + // Check the name of the function. Unless it's a dictionary function + // (that we are overwriting). if (name != NULL) { arg = name; } else { @@ -2164,8 +2166,8 @@ void ex_function(exarg_T *eap) } } - /* When there is a line break use what follows for the function body. - * Makes 'exe "func Test()\n...\nendfunc"' work. */ + // When there is a line break use what follows for the function body. + // Makes 'exe "func Test()\n...\nendfunc"' work. if (*p == '\n') { line_arg = p + 1; } else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) { @@ -2176,9 +2178,9 @@ void ex_function(exarg_T *eap) * Read the body of the function, until ":endfunction" is found. */ if (KeyTyped) { - /* Check if the function already exists, don't let the user type the - * whole function before telling him it doesn't work! For a script we - * need to skip the body to be able to find what follows. */ + // Check if the function already exists, don't let the user type the + // whole function before telling him it doesn't work! For a script we + // need to skip the body to be able to find what follows. if (!eap->skip && !eap->forceit) { if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) { EMSG(_(e_funcdict)); @@ -2305,8 +2307,8 @@ void ex_function(exarg_T *eap) break; } - /* Increase indent inside "if", "while", "for" and "try", decrease - * at "end". */ + // Increase indent inside "if", "while", "for" and "try", decrease + // at "end". if (indent > 2 && STRNCMP(p, "end", 3) == 0) { indent -= 2; } else if (STRNCMP(p, "if", 2) == 0 @@ -2421,8 +2423,8 @@ void ex_function(exarg_T *eap) } } - /* Don't define the function when skipping commands or when an error was - * detected. */ + // Don't define the function when skipping commands or when an error was + // detected. if (eap->skip || did_emsg) { goto erret; } @@ -2640,8 +2642,8 @@ bool function_exists(const char *const name, bool no_deref) NULL); nm = skipwhite(nm); - /* Only accept "funcname", "funcname ", "funcname (..." and - * "funcname(...", not "funcname!...". */ + // Only accept "funcname", "funcname ", "funcname (..." and + // "funcname(...", not "funcname!...". if (p != NULL && (*nm == NUL || *nm == '(')) { n = translated_function_exists(p); } @@ -2903,9 +2905,9 @@ void ex_return(exarg_T *eap) } } - /* When skipping or the return gets pending, advance to the next command - * in this line (!returning). Otherwise, ignore the rest of the line. - * Following lines will be ignored by get_func_line(). */ + // When skipping or the return gets pending, advance to the next command + // in this line (!returning). Otherwise, ignore the rest of the line. + // Following lines will be ignored by get_func_line(). if (returning) { eap->nextcmd = NULL; } else if (eap->nextcmd == NULL) { // no argument @@ -3098,9 +3100,9 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv) } if (reanimate) { - /* The pending return value could be overwritten by a ":return" - * without argument in a finally clause; reset the default - * return value. */ + // The pending return value could be overwritten by a ":return" + // without argument in a finally clause; reset the default + // return value. current_funccal->rettv->v_type = VAR_NUMBER; current_funccal->rettv->vval.v_number = 0; } @@ -3109,9 +3111,9 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv) } else { current_funccal->returned = TRUE; - /* If the return is carried out now, store the return value. For - * a return immediately after reanimation, the value is already - * there. */ + // If the return is carried out now, store the return value. For + // a return immediately after reanimation, the value is already + // there. if (!reanimate && rettv != NULL) { tv_clear(current_funccal->rettv); *current_funccal->rettv = *(typval_T *)rettv; diff --git a/src/nvim/eval/userfunc.h b/src/nvim/eval/userfunc.h index 3f111343d2..ed86aaad4a 100644 --- a/src/nvim/eval/userfunc.h +++ b/src/nvim/eval/userfunc.h @@ -8,7 +8,7 @@ typedef struct { dict_T *fd_dict; ///< Dictionary used. char_u *fd_newkey; ///< New key in "dict" in allocated memory. - dictitem_T *fd_di; ///< Dictionary item used. + dictitem_T *fd_di; ///< Dictionary item used. } funcdict_T; typedef struct funccal_entry funccal_entry_T; diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h index fdd4f17d5c..cf079681d0 100644 --- a/src/nvim/event/defs.h +++ b/src/nvim/event/defs.h @@ -11,7 +11,7 @@ typedef struct message { argv_callback handler; void *argv[EVENT_HANDLER_MAX_ARGC]; } Event; -typedef void(*event_scheduler)(Event event, void *data); +typedef void (*event_scheduler)(Event event, void *data); #define VA_EVENT_INIT(event, h, a) \ do { \ diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h index f5dd23ac8b..acd1d1a334 100644 --- a/src/nvim/event/loop.h +++ b/src/nvim/event/loop.h @@ -2,14 +2,13 @@ #define NVIM_EVENT_LOOP_H #include <stdint.h> - #include <uv.h> +#include "nvim/event/multiqueue.h" #include "nvim/lib/klist.h" #include "nvim/os/time.h" -#include "nvim/event/multiqueue.h" -typedef void * WatcherPtr; +typedef void *WatcherPtr; #define _noop(x) KLIST_INIT(WatcherPtr, WatcherPtr, _noop) @@ -65,7 +64,7 @@ typedef struct loop { break; \ } else if (remaining > 0) { \ uint64_t now = os_hrtime(); \ - remaining -= (int) ((now - before) / 1000000); \ + remaining -= (int)((now - before) / 1000000); \ before = now; \ if (remaining <= 0) { \ break; \ diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h index 20c02e4900..2b22cd95dc 100644 --- a/src/nvim/event/process.h +++ b/src/nvim/event/process.h @@ -1,10 +1,10 @@ #ifndef NVIM_EVENT_PROCESS_H #define NVIM_EVENT_PROCESS_H +#include "nvim/eval/typval.h" #include "nvim/event/loop.h" #include "nvim/event/rstream.h" #include "nvim/event/wstream.h" -#include "nvim/eval/typval.h" typedef enum { kProcessTypeUv, diff --git a/src/nvim/event/rstream.h b/src/nvim/event/rstream.h index f30ad79ee5..77418c59a2 100644 --- a/src/nvim/event/rstream.h +++ b/src/nvim/event/rstream.h @@ -3,7 +3,6 @@ #include <stdbool.h> #include <stddef.h> - #include <uv.h> #include "nvim/event/loop.h" diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index 8569b92d56..b34fd73d52 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.c @@ -20,7 +20,7 @@ // For compatibility with libuv < 1.19.0 (tested on 1.18.0) #if UV_VERSION_MINOR < 19 -#define uv_stream_get_write_queue_size(stream) stream->write_queue_size +# define uv_stream_get_write_queue_size(stream) stream->write_queue_size #endif /// Sets the stream associated with `fd` to "blocking" mode. diff --git a/src/nvim/event/stream.h b/src/nvim/event/stream.h index a5c33a66a2..02e816b4be 100644 --- a/src/nvim/event/stream.h +++ b/src/nvim/event/stream.h @@ -3,7 +3,6 @@ #include <stdbool.h> #include <stddef.h> - #include <uv.h> #include "nvim/event/loop.h" @@ -18,7 +17,7 @@ typedef struct stream Stream; /// @param data User-defined data /// @param eof If the stream reached EOF. typedef void (*stream_read_cb)(Stream *stream, RBuffer *buf, size_t count, - void *data, bool eof); + void *data, bool eof); /// Type of function called when the Stream has information about a write /// request. diff --git a/src/nvim/event/wstream.h b/src/nvim/event/wstream.h index 9008de0d97..d599d29913 100644 --- a/src/nvim/event/wstream.h +++ b/src/nvim/event/wstream.h @@ -1,9 +1,8 @@ #ifndef NVIM_EVENT_WSTREAM_H #define NVIM_EVENT_WSTREAM_H -#include <stdint.h> #include <stdbool.h> - +#include <stdint.h> #include <uv.h> #include "nvim/event/loop.h" diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index f8186c000e..4a23f284cc 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -361,8 +361,8 @@ static int linelen(int *has_tab) return len; } -/* Buffer for two lines used during sorting. They are allocated to - * contain the longest line being sorted. */ +// Buffer for two lines used during sorting. They are allocated to +// contain the longest line being sorted. static char_u *sortbuf1; static char_u *sortbuf2; @@ -404,9 +404,9 @@ static int sort_compare(const void *s1, const void *s2) sorti_T l2 = *(sorti_T *)s2; int result = 0; - /* If the user interrupts, there's no way to stop qsort() immediately, but - * if we return 0 every time, qsort will assume it's done sorting and - * exit. */ + // If the user interrupts, there's no way to stop qsort() immediately, but + // if we return 0 every time, qsort will assume it's done sorting and + // exit. if (sort_abort) { return 0; } @@ -702,11 +702,11 @@ void ex_sort(exarg_T *eap) mark_adjust(eap->line2, MAXLNUM, -deleted, 0L, kExtmarkNOOP); } - extmark_splice(curbuf, eap->line1-1, 0, - count, 0, old_count, - lnum - eap->line2, 0, new_count, kExtmarkUndo); - if (change_occurred || deleted != 0) { + extmark_splice(curbuf, eap->line1-1, 0, + count, 0, old_count, + lnum - eap->line2, 0, new_count, kExtmarkUndo); + changed_lines(eap->line1, 0, eap->line2 + 1, -deleted, true); } @@ -1439,11 +1439,11 @@ static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char_u *cmd, if (linecount > p_report) { if (do_in) { - vim_snprintf((char *)msg_buf, sizeof(msg_buf), + vim_snprintf(msg_buf, sizeof(msg_buf), _("%" PRId64 " lines filtered"), (int64_t)linecount); - if (msg(msg_buf) && !msg_scroll) { + if (msg((char_u *)msg_buf) && !msg_scroll) { // save message to display it after redraw - set_keep_msg(msg_buf, 0); + set_keep_msg((char_u *)msg_buf, 0); } } else { msgmore((long)linecount); @@ -1733,8 +1733,8 @@ int rename_buffer(char_u *new_fname) */ void ex_file(exarg_T *eap) { - /* ":0file" removes the file name. Check for illegal uses ":3file", - * "0file name", etc. */ + // ":0file" removes the file name. Check for illegal uses ":3file", + // "0file name", etc. if (eap->addr_count > 0 && (*eap->arg != NUL || eap->line2 > 0 @@ -1800,7 +1800,7 @@ int do_write(exarg_T *eap) int retval = FAIL; char_u *free_fname = NULL; buf_T *alt_buf = NULL; - int name_was_missing; + int name_was_missing; if (not_writing()) { // check 'write' option return FAIL; @@ -1888,11 +1888,11 @@ int do_write(exarg_T *eap) retval = FAIL; goto theend; } - /* Exchange the file names for the current and the alternate - * buffer. This makes it look like we are now editing the buffer - * under the new name. Must be done before buf_write(), because - * if there is no file name and 'cpo' contains 'F', it will set - * the file name. */ + // Exchange the file names for the current and the alternate + // buffer. This makes it look like we are now editing the buffer + // under the new name. Must be done before buf_write(), because + // if there is no file name and 'cpo' contains 'F', it will set + // the file name. fname = alt_buf->b_fname; alt_buf->b_fname = curbuf->b_fname; curbuf->b_fname = fname; @@ -1923,8 +1923,8 @@ int do_write(exarg_T *eap) do_modelines(0); } - /* Autocommands may have changed buffer names, esp. when - * 'autochdir' is set. */ + // Autocommands may have changed buffer names, esp. when + // 'autochdir' is set. fname = curbuf->b_sfname; } @@ -2003,11 +2003,11 @@ int check_overwrite(exarg_T *eap, buf_T *buf, char_u *fname, char_u *ffname, int char_u *p; char_u *swapname; - /* We only try the first entry in 'directory', without checking if - * it's writable. If the "." directory is not writable the write - * will probably fail anyway. - * Use 'shortname' of the current buffer, since there is no buffer - * for the written file. */ + // We only try the first entry in 'directory', without checking if + // it's writable. If the "." directory is not writable the write + // will probably fail anyway. + // Use 'shortname' of the current buffer, since there is no buffer + // for the written file. if (*p_dir == NUL) { dir = xmalloc(5); STRCPY(dir, "."); @@ -2294,8 +2294,8 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new char_u *new_name = NULL; bool did_set_swapcommand = false; buf_T *buf; - bufref_T bufref; - bufref_T old_curbuf; + bufref_T bufref; + bufref_T old_curbuf; char_u *free_fname = NULL; int retval = FAIL; long n; @@ -2466,8 +2466,8 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new } } - /* May jump to last used line number for a loaded buffer or when asked - * for explicitly */ + // May jump to last used line number for a loaded buffer or when asked + // for explicitly if ((oldbuf && newlnum == ECMD_LASTL) || newlnum == ECMD_LAST) { pos = buflist_findfpos(buf); newlnum = pos->lnum; @@ -2577,10 +2577,10 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new } } - /* May get the window options from the last time this buffer - * was in this window (or another window). If not used - * before, reset the local window options to the global - * values. Also restores old folding stuff. */ + // May get the window options from the last time this buffer + // was in this window (or another window). If not used + // before, reset the local window options to the global + // values. Also restores old folding stuff. get_winopts(curbuf); did_get_winopts = true; } @@ -2621,10 +2621,10 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new goto theend; } - /* Since we are starting to edit a file, consider the filetype to be - * unset. Helps for when an autocommand changes files and expects syntax - * highlighting to work in the other file. */ - did_filetype = FALSE; + // Since we are starting to edit a file, consider the filetype to be + // unset. Helps for when an autocommand changes files and expects syntax + // highlighting to work in the other file. + did_filetype = false; /* * other_file oldbuf @@ -2828,8 +2828,8 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new && !auto_buf) { int msg_scroll_save = msg_scroll; - /* Obey the 'O' flag in 'cpoptions': overwrite any previous file - * message. */ + // Obey the 'O' flag in 'cpoptions': overwrite any previous file + // message. if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0) { msg_scroll = FALSE; } @@ -2953,8 +2953,8 @@ void ex_append(exarg_T *eap) } } if (eap->getline == NULL) { - /* No getline() function, use the lines that follow. This ends - * when there is no more. */ + // No getline() function, use the lines that follow. This ends + // when there is no more. if (eap->nextcmd == NULL || *eap->nextcmd == NUL) { break; } @@ -3078,7 +3078,7 @@ void ex_change(exarg_T *eap) void ex_z(exarg_T *eap) { char_u *x; - int64_t bigness; + int64_t bigness; char_u *kind; int minus = 0; linenr_T start, end, curs, i; @@ -3750,8 +3750,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle sub_firstline = vim_strsave(ml_get(sub_firstlnum)); } - /* Save the line number of the last change for the final - * cursor position (just like Vi). */ + // Save the line number of the last change for the final + // cursor position (just like Vi). curwin->w_cursor.lnum = lnum; do_again = FALSE; @@ -3778,8 +3778,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle goto skip; } - /* Normally we continue searching for a match just after the - * previous match. */ + // Normally we continue searching for a match just after the + // previous match. matchcol = regmatch.endpos[0].col; prev_matchcol = matchcol; @@ -3818,8 +3818,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle do_check_cursorbind(); } - /* When 'cpoptions' contains "u" don't sync undo when - * asking for confirmation. */ + // When 'cpoptions' contains "u" don't sync undo when + // asking for confirmation. if (vim_strchr(p_cpo, CPO_UNDO) != NULL) { ++no_u_sync; } @@ -3970,11 +3970,11 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle } if (typed == 'n') { - /* For a multi-line match, put matchcol at the NUL at - * the end of the line and set nmatch to one, so that - * we continue looking for a match on the next line. - * Avoids that ":%s/\nB\@=//gc" and ":%s/\n/,\r/gc" - * get stuck when pressing 'n'. */ + // For a multi-line match, put matchcol at the NUL at + // the end of the line and set nmatch to one, so that + // we continue looking for a match on the next line. + // Avoids that ":%s/\nB\@=//gc" and ":%s/\n/,\r/gc" + // get stuck when pressing 'n'. if (nmatch > 1) { matchcol = (colnr_T)STRLEN(sub_firstline); skip_match = true; @@ -3986,8 +3986,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle } } - /* Move the cursor to the start of the match, so that we can - * use "\=col("."). */ + // Move the cursor to the start of the match, so that we can + // use "\=col("."). curwin->w_cursor.col = regmatch.startpos[0].col; // When the match included the "$" of the last line it may @@ -4178,11 +4178,11 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle // strings, e.g. :s/$/pat/g or :s/[a-z]* /(&)/g. // But ":s/\n/#/" is OK. skip: - /* We already know that we did the last subst when we are at - * the end of the line, except that a pattern like - * "bar\|\nfoo" may match at the NUL. "lnum" can be below - * "line2" when there is a \zs in the pattern after a line - * break. */ + // We already know that we did the last subst when we are at + // the end of the line, except that a pattern like + // "bar\|\nfoo" may match at the NUL. "lnum" can be below + // "line2" when there is a \zs in the pattern after a line + // break. lastone = (skip_match || got_int || got_quit @@ -4249,8 +4249,8 @@ skip: nmatch_tl = 0; } - /* When asking, undo is saved each time, must also set - * changed flag each time. */ + // When asking, undo is saved each time, must also set + // changed flag each time. if (subflags.do_ask) { changed_bytes(lnum, 0); } else { @@ -4278,9 +4278,9 @@ skip: * 5. break if there isn't another match in this line */ if (nmatch <= 0) { - /* If the match found didn't start where we were - * searching, do the next search in the line where we - * found the match. */ + // If the match found didn't start where we were + // searching, do the next search in the line where we + // found the match. if (nmatch == -1) { lnum -= regmatch.startpos[0].lnum; } @@ -4329,9 +4329,9 @@ skip: curbuf->deleted_bytes2 = 0; if (first_line != 0) { - /* Need to subtract the number of added lines from "last_line" to get - * the line number before the change (same as adding the number of - * deleted lines). */ + // Need to subtract the number of added lines from "last_line" to get + // the line number before the change (same as adding the number of + // deleted lines). i = curbuf->b_ml.ml_line_count - old_line_count; changed_lines(first_line, 0, last_line - i, i, false); @@ -4409,7 +4409,7 @@ skip: pre_src_id = (int)nvim_create_namespace((String)STRING_INIT); } if (pre_hl_id == 0) { - pre_hl_id = syn_check_group((char_u *)S_LEN("Substitute")); + pre_hl_id = syn_check_group(S_LEN("Substitute")); } curbuf->b_changed = save_b_changed; // preserve 'modified' during preview preview_buf = show_sub(eap, old_cursor, &preview_lines, @@ -4451,24 +4451,24 @@ bool do_sub_msg(bool count_only) *msg_buf = NUL; } if (sub_nsubs == 1) { - vim_snprintf_add((char *)msg_buf, sizeof(msg_buf), + vim_snprintf_add(msg_buf, sizeof(msg_buf), "%s", count_only ? _("1 match") : _("1 substitution")); } else { - vim_snprintf_add((char *)msg_buf, sizeof(msg_buf), + vim_snprintf_add(msg_buf, sizeof(msg_buf), count_only ? _("%" PRId64 " matches") : _("%" PRId64 " substitutions"), (int64_t)sub_nsubs); } if (sub_nlines == 1) { - vim_snprintf_add((char *)msg_buf, sizeof(msg_buf), + vim_snprintf_add(msg_buf, sizeof(msg_buf), "%s", _(" on 1 line")); } else { - vim_snprintf_add((char *)msg_buf, sizeof(msg_buf), + vim_snprintf_add(msg_buf, sizeof(msg_buf), _(" on %" PRId64 " lines"), (int64_t)sub_nlines); } - if (msg(msg_buf)) { + if (msg((char_u *)msg_buf)) { // save message to display it after redraw - set_keep_msg(msg_buf, 0); + set_keep_msg((char_u *)msg_buf, 0); } return true; } @@ -4842,9 +4842,9 @@ void ex_help(exarg_T *eap) } fclose(helpfd); - /* Split off help window; put it at far top if no position - * specified, the current window is vertically split and - * narrow. */ + // Split off help window; put it at far top if no position + // specified, the current window is vertically split and + // narrow. n = WSP_HELP; if (cmdmod.split == 0 && curwin->w_width != Columns && curwin->w_width < 80) { @@ -4884,9 +4884,9 @@ void ex_help(exarg_T *eap) do_tag(tag, DT_HELP, 1, FALSE, TRUE); - /* Delete the empty buffer if we're not using it. Careful: autocommands - * may have jumped to another window, check that the buffer is not in a - * window. */ + // Delete the empty buffer if we're not using it. Careful: autocommands + // may have jumped to another window, check that the buffer is not in a + // window. if (empty_fnum != 0 && curbuf->b_fnum != empty_fnum) { buf = buflist_findnr(empty_fnum); if (buf != NULL && buf->b_nwindows == 0) { @@ -5057,11 +5057,11 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches, bool } if (i < 0) { // no match in table - /* Replace "\S" with "/\\S", etc. Otherwise every tag is matched. - * Also replace "\%^" and "\%(", they match every tag too. - * Also "\zs", "\z1", etc. - * Also "\@<", "\@=", "\@<=", etc. - * And also "\_$" and "\_^". */ + // Replace "\S" with "/\\S", etc. Otherwise every tag is matched. + // Also replace "\%^" and "\%(", they match every tag too. + // Also "\zs", "\z1", etc. + // Also "\@<", "\@=", "\@<=", etc. + // And also "\_$" and "\_^". if (arg[0] == '\\' && ((arg[1] != NUL && arg[2] == NUL) || (vim_strchr((char_u *)"%_z@", arg[1]) != NULL @@ -5158,8 +5158,8 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches, bool *d++ = '\\'; } - /* "CTRL-\_" -> "CTRL-\\_" to avoid the special meaning of "\_" in - * "CTRL-\_CTRL-N" */ + // "CTRL-\_" -> "CTRL-\\_" to avoid the special meaning of "\_" in + // "CTRL-\_CTRL-N" if (STRNICMP(s, "CTRL-\\_", 7) == 0) { STRCPY(d, "CTRL-\\\\"); d += 7; @@ -5213,9 +5213,9 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches, bool } if (find_tags(IObuff, num_matches, matches, flags, MAXCOL, NULL) == OK && *num_matches > 0) { - /* Sort the matches found on the heuristic number that is after the - * tag name. */ - qsort((void *)*matches, (size_t)*num_matches, + // Sort the matches found on the heuristic number that is after the + // tag name. + qsort((void *)(*matches), (size_t)(*num_matches), sizeof(char_u *), help_compare); // Delete more than TAG_MANY to reduce the size of the listing. while (*num_matches > TAG_MANY) { @@ -5549,8 +5549,9 @@ static void helptags_one(char_u *dir, const char_u *ext, const char_u *tagfname, if (add_help_tags || path_full_compare((char_u *)"$VIMRUNTIME/doc", dir, false, true) == kEqualFiles) { - s = xmalloc(18 + STRLEN(tagfname)); - sprintf((char *)s, "help-tags\t%s\t1\n", tagfname); + size_t s_len = 18 + STRLEN(tagfname); + s = xmalloc(s_len); + snprintf((char *)s, s_len, "help-tags\t%s\t1\n", tagfname); GA_APPEND(char_u *, &ga, s); } @@ -5611,10 +5612,11 @@ static void helptags_one(char_u *dir, const char_u *ext, const char_u *tagfname, && (vim_strchr((char_u *)" \t\n\r", s[1]) != NULL || s[1] == '\0')) { *p2 = '\0'; - ++p1; - s = xmalloc((p2 - p1) + STRLEN(fname) + 2); + p1++; + size_t s_len= (p2 - p1) + STRLEN(fname) + 2; + s = xmalloc(s_len); GA_APPEND(char_u *, &ga, s); - sprintf((char *)s, "%s\t%s", p1, fname); + snprintf((char *)s, s_len, "%s\t%s", p1, fname); // find next '*' p2 = vim_strchr(p2 + 1, '*'); @@ -5798,8 +5800,7 @@ void ex_helptags(exarg_T *eap) } if (STRCMP(eap->arg, "ALL") == 0) { - do_in_path(p_rtp, (char_u *)"doc", DIP_ALL + DIP_DIR, - helptags_cb, &add_help_tags); + do_in_path(p_rtp, "doc", DIP_ALL + DIP_DIR, helptags_cb, &add_help_tags); } else { ExpandInit(&xpc); xpc.xp_context = EXPAND_DIRECTORIES; diff --git a/src/nvim/ex_cmds.h b/src/nvim/ex_cmds.h index 1b54b3a898..c34ffa1d3b 100644 --- a/src/nvim/ex_cmds.h +++ b/src/nvim/ex_cmds.h @@ -3,11 +3,11 @@ #include <stdbool.h> -#include "nvim/os/time.h" -#include "nvim/pos.h" -#include "nvim/eval/typval.h" #include "nvim/buffer_defs.h" +#include "nvim/eval/typval.h" #include "nvim/ex_cmds_defs.h" +#include "nvim/os/time.h" +#include "nvim/pos.h" // flags for do_ecmd() #define ECMD_HIDE 0x01 // don't free the current buffer @@ -18,10 +18,10 @@ #define ECMD_ADDBUF 0x10 // don't edit, just add to buffer list #define ECMD_ALTBUF 0x20 // like ECMD_ADDBUF and set the alternate file -/* for lnum argument in do_ecmd() */ -#define ECMD_LASTL (linenr_T)0 /* use last position in loaded file */ -#define ECMD_LAST (linenr_T)-1 /* use last position in all files */ -#define ECMD_ONE (linenr_T)1 /* use first line */ +// for lnum argument in do_ecmd() +#define ECMD_LASTL (linenr_T)0 // use last position in loaded file +#define ECMD_LAST (linenr_T)-1 // use last position in all files +#define ECMD_ONE (linenr_T)1 // use first line /// Previous :substitute replacement string definition typedef struct { diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 575c5c9cbd..5d40d7a16a 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -6,79 +6,53 @@ /// Some more functions for command line commands #include <assert.h> +#include <fcntl.h> #include <inttypes.h> #include <stdbool.h> #include <string.h> -#include <fcntl.h> -#include "nvim/vim.h" #include "nvim/ascii.h" +#include "nvim/vim.h" #ifdef HAVE_LOCALE_H # include <locale.h> #endif -#include "nvim/ex_cmds2.h" +#include "nvim/api/private/defs.h" +#include "nvim/api/private/helpers.h" #include "nvim/buffer.h" #include "nvim/change.h" #include "nvim/charset.h" #include "nvim/debugger.h" #include "nvim/eval/userfunc.h" #include "nvim/ex_cmds.h" +#include "nvim/ex_cmds2.h" #include "nvim/ex_eval.h" #include "nvim/ex_getln.h" #include "nvim/fileio.h" +#include "nvim/garray.h" +#include "nvim/lua/executor.h" #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" +#include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/garray.h" -#include "nvim/memory.h" #include "nvim/move.h" #include "nvim/normal.h" #include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/os/fs_defs.h" +#include "nvim/os/shell.h" #include "nvim/os_unix.h" #include "nvim/path.h" +#include "nvim/profile.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" #include "nvim/strings.h" #include "nvim/undo.h" #include "nvim/version.h" #include "nvim/window.h" -#include "nvim/profile.h" -#include "nvim/os/shell.h" -#include "nvim/os/fs_defs.h" -#include "nvim/api/private/helpers.h" -#include "nvim/api/private/defs.h" -#include "nvim/lua/executor.h" - /// Growarray to store info about already sourced scripts. -/// Also store the dev/ino, so that we don't have to stat() each -/// script when going through the list. -typedef struct scriptitem_S { - char_u *sn_name; - bool file_id_valid; - FileID file_id; - bool sn_prof_on; ///< true when script is/was profiled - bool sn_pr_force; ///< forceit: profile functions in this script - proftime_T sn_pr_child; ///< time set when going into first child - int sn_pr_nest; ///< nesting for sn_pr_child - // profiling the script as a whole - int sn_pr_count; ///< nr of times sourced - proftime_T sn_pr_total; ///< time spent in script + children - proftime_T sn_pr_self; ///< time spent in script itself - proftime_T sn_pr_start; ///< time at script start - proftime_T sn_pr_children; ///< time in children after script start - // profiling the script per line - garray_T sn_prl_ga; ///< things stored for every line - proftime_T sn_prl_start; ///< start time for current line - proftime_T sn_prl_children; ///< time spent in children for this line - proftime_T sn_prl_wait; ///< wait start time for current line - linenr_T sn_prl_idx; ///< index of line being timed; -1 if none - int sn_prl_execed; ///< line being timed was executed -} scriptitem_T; - static garray_T script_items = { 0, 0, sizeof(scriptitem_T), 4, NULL }; #define SCRIPT_ITEM(id) (((scriptitem_T *)script_items.ga_data)[(id) - 1]) @@ -109,20 +83,20 @@ struct source_cookie { vimconv_T conv; ///< type of conversion }; -# define PRL_ITEM(si, idx) (((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)]) +#define PRL_ITEM(si, idx) (((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)]) #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ex_cmds2.c.generated.h" #endif -static char_u *profile_fname = NULL; +static char_u *profile_fname = NULL; /// ":profile cmd args" void ex_profile(exarg_T *eap) { static proftime_T pause_time; - char_u *e; + char_u *e; int len; e = skiptowhite(eap->arg); @@ -277,7 +251,7 @@ void set_context_in_profile_cmd(expand_T *xp, const char *arg) /// Dump the profiling info. void profile_dump(void) { - FILE *fd; + FILE *fd; if (profile_fname != NULL) { fd = os_fopen((char *)profile_fname, "w"); @@ -317,7 +291,7 @@ static void profile_reset(void) } // Reset functions. - size_t n = func_hashtab.ht_used; + size_t n = func_hashtab.ht_used; hashitem_T *hi = func_hashtab.ht_array; for (; n > (size_t)0; hi++) { @@ -362,11 +336,11 @@ static void profile_init(scriptitem_T *si) } /// Save time when starting to invoke another script or function. -void script_prof_save( - proftime_T *tm // place to store wait time -) +/// +/// @param tm place to store wait time +void script_prof_save(proftime_T *tm) { - scriptitem_T *si; + scriptitem_T *si; if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) { si = &SCRIPT_ITEM(current_sctx.sc_sid); @@ -380,7 +354,7 @@ void script_prof_save( /// Count time spent in children after invoking another script or function. void script_prof_restore(proftime_T *tm) { - scriptitem_T *si; + scriptitem_T *si; if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) { si = &SCRIPT_ITEM(current_sctx.sc_sid); @@ -412,9 +386,9 @@ void prof_inchar_exit(void) /// Dump the profiling results for all scripts in file "fd". static void script_dump_profile(FILE *fd) { - scriptitem_T *si; - FILE *sfd; - sn_prl_T *pp; + scriptitem_T *si; + FILE *sfd; + sn_prl_T *pp; for (int id = 1; id <= script_items.ga_len; id++) { si = &SCRIPT_ITEM(id); @@ -699,7 +673,7 @@ bool check_changed_any(bool hidden, bool unload) int i; int bufnum = 0; size_t bufcount = 0; - int *bufnrs; + int *bufnrs; // Make a list of all buffers, with the most important ones first. FOR_ALL_BUFFERS(buf) { @@ -829,7 +803,7 @@ int check_fname(void) int buf_write_all(buf_T *buf, int forceit) { int retval; - buf_T *old_curbuf = curbuf; + buf_T *old_curbuf = curbuf; retval = (buf_write(buf, buf->b_ffname, buf->b_fname, (linenr_T)1, buf->b_ml.ml_line_count, NULL, @@ -852,7 +826,7 @@ int buf_write_all(buf_T *buf, int forceit) /// Return a pointer to the start of the next argument. static char_u *do_one_arg(char_u *str) { - char_u *p; + char_u *p; bool inbacktick; inbacktick = false; @@ -936,8 +910,8 @@ static int do_arglist(char_u *str, int what, int after, bool will_edit) { garray_T new_ga; int exp_count; - char_u **exp_files; - char_u *p; + char_u **exp_files; + char_u *p; int match; int arg_escaped = true; @@ -1037,9 +1011,8 @@ static bool editing_arg_idx(win_T *win) || (win->w_buffer->b_fnum != WARGLIST(win)[win->w_arg_idx].ae_fnum && (win->w_buffer->b_ffname == NULL - || !(path_full_compare( - alist_name(&WARGLIST(win)[win->w_arg_idx]), - win->w_buffer->b_ffname, true, true) & kEqualFiles)))); + || !(path_full_compare(alist_name(&WARGLIST(win)[win->w_arg_idx]), + win->w_buffer->b_ffname, true, true) & kEqualFiles)))); } /// Check if window "win" is editing the w_arg_idx file in its argument list. @@ -1102,7 +1075,7 @@ void ex_args(exarg_T *eap) xfree(items); } } else if (eap->cmdidx == CMD_arglocal) { - garray_T *gap = &curwin->w_alist->al_ga; + garray_T *gap = &curwin->w_alist->al_ga; // ":argslocal": make a local copy of the global argument list. ga_grow(gap, GARGCOUNT); @@ -1158,7 +1131,7 @@ void ex_argument(exarg_T *eap) void do_argfile(exarg_T *eap, int argn) { int other; - char_u *p; + char_u *p; int old_arg_idx = curwin->w_arg_idx; if (argn < 0 || argn >= ARGCOUNT) { @@ -1310,9 +1283,9 @@ void ex_argdelete(exarg_T *eap) curwin->w_arg_idx = (int)eap->line1; } if (ARGCOUNT == 0) { - curwin->w_arg_idx = 0; + curwin->w_arg_idx = 0; } else if (curwin->w_arg_idx >= ARGCOUNT) { - curwin->w_arg_idx = ARGCOUNT - 1; + curwin->w_arg_idx = ARGCOUNT - 1; } } } else { @@ -1325,11 +1298,11 @@ void ex_argdelete(exarg_T *eap) void ex_listdo(exarg_T *eap) { int i; - win_T *wp; - tabpage_T *tp; + win_T *wp; + tabpage_T *tp; int next_fnum = 0; - char_u *save_ei = NULL; - char_u *p_shm_save; + char_u *save_ei = NULL; + char_u *p_shm_save; if (eap->cmdidx != CMD_windo && eap->cmdidx != CMD_tabdo) { // Don't do syntax HL autocommands. Skipping the syntax file is a @@ -1610,9 +1583,9 @@ char_u *get_arglist_name(expand_T *xp FUNC_ATTR_UNUSED, int idx) /// ":compiler[!] {name}" void ex_compiler(exarg_T *eap) { - char_u *buf; - char_u *old_cur_comp = NULL; - char_u *p; + char_u *buf; + char_u *old_cur_comp = NULL; + char_u *p; if (*eap->arg == NUL) { // List all compiler scripts. @@ -1641,10 +1614,10 @@ void ex_compiler(exarg_T *eap) do_unlet(S_LEN("b:current_compiler"), true); snprintf((char *)buf, bufsize, "compiler/%s.vim", eap->arg); - if (source_runtime(buf, DIP_ALL) == FAIL) { + if (source_runtime((char *)buf, DIP_ALL) == FAIL) { // Try lua compiler snprintf((char *)buf, bufsize, "compiler/%s.lua", eap->arg); - if (source_runtime(buf, DIP_ALL) == FAIL) { + if (source_runtime((char *)buf, DIP_ALL) == FAIL) { EMSG2(_("E666: compiler not supported: %s"), eap->arg); } } @@ -1703,9 +1676,9 @@ void init_pyxversion(void) // otherwise return 0. static int requires_py_version(char_u *filename) { - FILE *file; - int requires_py_version = 0; - int i, lines; + FILE *file; + int requires_py_version = 0; + int i, lines; lines = (int)p_mls; if (lines < 0) { @@ -1824,7 +1797,7 @@ static void cmd_source(char_u *fname, exarg_T *eap) || eap->cstack->cs_idx >= 0); // ":source" read ex commands - } else if (do_source(fname, false, DOSO_NONE) == FAIL) { + } else if (do_source((char *)fname, false, DOSO_NONE) == FAIL) { EMSG2(_(e_notopen), fname); } } @@ -1940,9 +1913,30 @@ static char_u *get_str_line(int c, void *cookie, int indent, bool do_concat) return ga.ga_data; } -static int source_using_linegetter(void *cookie, - LineGetter fgetline, - const char *traceback_name) +/// Create a new script item and allocate script-local vars. @see new_script_vars +/// +/// @param name File name of the script. NULL for anonymous :source. +/// @param[out] sid_out SID of the new item. +/// @return pointer to the created script item. +scriptitem_T *new_script_item(char_u *const name, scid_T *const sid_out) +{ + static scid_T last_current_SID = 0; + const scid_T sid = ++last_current_SID; + if (sid_out != NULL) { + *sid_out = sid; + } + ga_grow(&script_items, (int)(sid - script_items.ga_len)); + while (script_items.ga_len < sid) { + script_items.ga_len++; + SCRIPT_ITEM(script_items.ga_len).sn_name = NULL; + SCRIPT_ITEM(script_items.ga_len).sn_prof_on = false; + } + SCRIPT_ITEM(sid).sn_name = name; + new_script_vars(sid); // Allocate the local script variables to use for this script. + return &SCRIPT_ITEM(sid); +} + +static int source_using_linegetter(void *cookie, LineGetter fgetline, const char *traceback_name) { char_u *save_sourcing_name = sourcing_name; linenr_T save_sourcing_lnum = sourcing_lnum; @@ -1951,9 +1945,9 @@ static int source_using_linegetter(void *cookie, sourcing_name = (char_u *)traceback_name; } else { snprintf((char *)sourcing_name_buf, sizeof(sourcing_name_buf), - "%s called at %s:%"PRIdLINENR, traceback_name, save_sourcing_name, + "%s called at %s:%" PRIdLINENR, traceback_name, save_sourcing_name, save_sourcing_lnum); - sourcing_name = sourcing_name_buf; + sourcing_name = sourcing_name_buf; // -V507 reassigned below, before return. } sourcing_lnum = 0; @@ -1987,13 +1981,13 @@ static void cmd_source_buffer(const exarg_T *const eap) if (ga.ga_len > 400) { ga_set_growsize(&ga, MAX(ga.ga_len, 8000)); } - ga_concat(&ga, ml_get(curr_lnum)); + ga_concat(&ga, (char *)ml_get(curr_lnum)); ga_append(&ga, NL); } ((char_u *)ga.ga_data)[ga.ga_len - 1] = NUL; const GetStrLineCookie cookie = { - .buf = ga.ga_data, - .offset = 0, + .buf = ga.ga_data, + .offset = 0, }; if (curbuf->b_fname && path_with_extension((const char *)curbuf->b_fname, "lua")) { @@ -2012,8 +2006,8 @@ static void cmd_source_buffer(const exarg_T *const eap) int do_source_str(const char *cmd, const char *traceback_name) { GetStrLineCookie cookie = { - .buf = (char_u *)cmd, - .offset = 0, + .buf = (char_u *)cmd, + .offset = 0, }; return source_using_linegetter((void *)&cookie, get_str_line, traceback_name); } @@ -2030,23 +2024,22 @@ int do_source_str(const char *cmd, const char *traceback_name) /// @param is_vimrc DOSO_ value /// /// @return FAIL if file could not be opened, OK otherwise -int do_source(char_u *fname, int check_other, int is_vimrc) +int do_source(char *fname, int check_other, int is_vimrc) { struct source_cookie cookie; - char_u *save_sourcing_name; + char_u *save_sourcing_name; linenr_T save_sourcing_lnum; - char_u *p; - char_u *fname_exp; - char_u *firstline = NULL; + char_u *p; + char_u *fname_exp; + char_u *firstline = NULL; int retval = FAIL; - static scid_T last_current_SID = 0; static int last_current_SID_seq = 0; int save_debug_break_level = debug_break_level; - scriptitem_T *si = NULL; + scriptitem_T *si = NULL; proftime_T wait_start; bool trigger_source_post = false; - p = expand_env_save(fname); + p = expand_env_save((char_u *)fname); if (p == NULL) { return retval; } @@ -2115,7 +2108,7 @@ int do_source(char_u *fname, int check_other, int is_vimrc) verbose_leave(); } if (is_vimrc == DOSO_VIMRC) { - vimrc_found(fname_exp, (char_u *)"MYVIMRC"); + vimrc_found((char *)fname_exp, "MYVIMRC"); } #ifdef USE_CRNL @@ -2186,15 +2179,7 @@ int do_source(char_u *fname, int check_other, int is_vimrc) } } if (current_sctx.sc_sid == 0) { - current_sctx.sc_sid = ++last_current_SID; - ga_grow(&script_items, (int)(current_sctx.sc_sid - script_items.ga_len)); - while (script_items.ga_len < current_sctx.sc_sid) { - script_items.ga_len++; - SCRIPT_ITEM(script_items.ga_len).sn_name = NULL; - SCRIPT_ITEM(script_items.ga_len).sn_prof_on = false; - } - si = &SCRIPT_ITEM(current_sctx.sc_sid); - si->sn_name = fname_exp; + si = new_script_item(fname_exp, ¤t_sctx.sc_sid); fname_exp = vim_strsave(si->sn_name); // used for autocmd if (file_id_ok) { si->file_id_valid = true; @@ -2202,9 +2187,6 @@ int do_source(char_u *fname, int check_other, int is_vimrc) } else { si->file_id_valid = false; } - - // Allocate the local script variables to use for this script. - new_script_vars(current_sctx.sc_sid); } if (l_do_profiling == PROF_YES) { @@ -2343,7 +2325,7 @@ void ex_scriptnames(exarg_T *eap) } } -# if defined(BACKSLASH_IN_FILENAME) +#if defined(BACKSLASH_IN_FILENAME) /// Fix slashes in the list of script names for 'shellslash'. void scriptnames_slash_adjust(void) { @@ -2354,7 +2336,7 @@ void scriptnames_slash_adjust(void) } } -# endif +#endif /// Get a pointer to a script name. Used for ":verbose set". /// Message appended to "Last set from " @@ -2363,35 +2345,40 @@ char_u *get_scriptname(LastSet last_set, bool *should_free) *should_free = false; switch (last_set.script_ctx.sc_sid) { - case SID_MODELINE: - return (char_u *)_("modeline"); - case SID_CMDARG: - return (char_u *)_("--cmd argument"); - case SID_CARG: - return (char_u *)_("-c argument"); - case SID_ENV: - return (char_u *)_("environment variable"); - case SID_ERROR: - return (char_u *)_("error handler"); - case SID_WINLAYOUT: - return (char_u *)_("changed window size"); - case SID_LUA: - return (char_u *)_("Lua"); - case SID_API_CLIENT: - vim_snprintf((char *)IObuff, IOSIZE, - _("API client (channel id %" PRIu64 ")"), - last_set.channel_id); + case SID_MODELINE: + return (char_u *)_("modeline"); + case SID_CMDARG: + return (char_u *)_("--cmd argument"); + case SID_CARG: + return (char_u *)_("-c argument"); + case SID_ENV: + return (char_u *)_("environment variable"); + case SID_ERROR: + return (char_u *)_("error handler"); + case SID_WINLAYOUT: + return (char_u *)_("changed window size"); + case SID_LUA: + return (char_u *)_("Lua"); + case SID_API_CLIENT: + snprintf((char *)IObuff, IOSIZE, _("API client (channel id %" PRIu64 ")"), last_set.channel_id); + return IObuff; + case SID_STR: + return (char_u *)_("anonymous :source"); + default: { + char_u *const sname = SCRIPT_ITEM(last_set.script_ctx.sc_sid).sn_name; + if (sname == NULL) { + snprintf((char *)IObuff, IOSIZE, _("anonymous :source (script id %d)"), + last_set.script_ctx.sc_sid); return IObuff; - case SID_STR: - return (char_u *)_("anonymous :source"); - default: - *should_free = true; - return home_replace_save(NULL, - SCRIPT_ITEM(last_set.script_ctx.sc_sid).sn_name); + } + + *should_free = true; + return home_replace_save(NULL, sname); + } } } -# if defined(EXITFREE) +#if defined(EXITFREE) void free_scriptnames(void) { profile_reset(); @@ -2399,11 +2386,11 @@ void free_scriptnames(void) # define FREE_SCRIPTNAME(item) xfree((item)->sn_name) GA_DEEP_CLEAR(&script_items, scriptitem_T, FREE_SCRIPTNAME); } -# endif +#endif linenr_T get_sourced_lnum(LineGetter fgetline, void *cookie) { - return fgetline == getsourceline + return fgetline == getsourceline ? ((struct source_cookie *)cookie)->sourcing_lnum : sourcing_lnum; } @@ -2462,7 +2449,7 @@ char_u *getsourceline(int c, void *cookie, int indent, bool do_concat) garray_T ga; ga_init(&ga, (int)sizeof(char_u), 400); - ga_concat(&ga, line); + ga_concat(&ga, (char *)line); while (sp->nextline != NULL && concat_continued_line(&ga, 400, sp->nextline, STRLEN(sp->nextline))) { @@ -2476,7 +2463,7 @@ char_u *getsourceline(int c, void *cookie, int indent, bool do_concat) } if (line != NULL && sp->conv.vc_type != CONV_NONE) { - char_u *s; + char_u *s; // Convert the encoding of the script line. s = string_convert(&sp->conv, line, NULL); @@ -2502,7 +2489,7 @@ static char_u *get_one_sourceline(struct source_cookie *sp) garray_T ga; int len; int c; - char_u *buf; + char_u *buf; #ifdef USE_CRNL int has_cr; // CR-LF found #endif @@ -2605,8 +2592,8 @@ retry: /// until later and we need to store the time now. void script_line_start(void) { - scriptitem_T *si; - sn_prl_T *pp; + scriptitem_T *si; + sn_prl_T *pp; if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) { return; @@ -2637,7 +2624,7 @@ void script_line_start(void) /// Called when actually executing a function line. void script_line_exec(void) { - scriptitem_T *si; + scriptitem_T *si; if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) { return; @@ -2651,8 +2638,8 @@ void script_line_exec(void) /// Called when done with a function line. void script_line_end(void) { - scriptitem_T *si; - sn_prl_T *pp; + scriptitem_T *si; + sn_prl_T *pp; if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) { return; @@ -2677,8 +2664,8 @@ void script_line_end(void) /// Without the multi-byte feature it's simply ignored. void ex_scriptencoding(exarg_T *eap) { - struct source_cookie *sp; - char_u *name; + struct source_cookie *sp; + char_u *name; if (!getline_equal(eap->getline, eap->cookie, getsourceline)) { EMSG(_("E167: :scriptencoding used outside of a sourced file")); @@ -2743,14 +2730,13 @@ void do_finish(exarg_T *eap, int reanimate) bool source_finished(LineGetter fgetline, void *cookie) { return getline_equal(fgetline, cookie, getsourceline) - && ((struct source_cookie *)getline_cookie( - fgetline, cookie))->finished; + && ((struct source_cookie *)getline_cookie(fgetline, cookie))->finished; } /// ":checktime [buffer]" void ex_checktime(exarg_T *eap) { - buf_T *buf; + buf_T *buf; int save_no_check_timestamps = no_check_timestamps; no_check_timestamps = 0; @@ -2790,17 +2776,17 @@ char *get_mess_lang(void) { char *p; -# ifdef HAVE_GET_LOCALE_VAL -# if defined(LC_MESSAGES) +#ifdef HAVE_GET_LOCALE_VAL +# if defined(LC_MESSAGES) p = get_locale_val(LC_MESSAGES); -# else +# else // This is necessary for Win32, where LC_MESSAGES is not defined and $LANG // may be set to the LCID number. LC_COLLATE is the best guess, LC_TIME // and LC_MONETARY may be set differently for a Japanese working in the // US. p = get_locale_val(LC_COLLATE); -# endif -# else +# endif +#else p = os_getenv("LC_ALL"); if (!is_valid_mess_lang(p)) { p = os_getenv("LC_MESSAGES"); @@ -2808,7 +2794,7 @@ char *get_mess_lang(void) p = os_getenv("LANG"); } } -# endif +#endif return is_valid_mess_lang(p) ? p : NULL; } @@ -2817,7 +2803,7 @@ char *get_mess_lang(void) /// Get the language used for messages from the environment. static char_u *get_mess_env(void) { - char_u *p; + char_u *p; p = (char_u *)os_getenv("LC_ALL"); if (p == NULL) { @@ -2846,37 +2832,37 @@ void set_lang_var(void) { const char *loc; -# ifdef HAVE_GET_LOCALE_VAL +#ifdef HAVE_GET_LOCALE_VAL loc = get_locale_val(LC_CTYPE); -# else +#else // setlocale() not supported: use the default value loc = "C"; -# endif +#endif set_vim_var_string(VV_CTYPE, loc, -1); // When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall // back to LC_CTYPE if it's empty. -# ifdef HAVE_WORKING_LIBINTL +#ifdef HAVE_WORKING_LIBINTL loc = (char *)get_mess_env(); -# elif defined(LC_MESSAGES) +#elif defined(LC_MESSAGES) loc = get_locale_val(LC_MESSAGES); -# else +#else // In Windows LC_MESSAGES is not defined fallback to LC_CTYPE loc = get_locale_val(LC_CTYPE); -# endif +#endif set_vim_var_string(VV_LANG, loc, -1); -# ifdef HAVE_GET_LOCALE_VAL +#ifdef HAVE_GET_LOCALE_VAL loc = get_locale_val(LC_TIME); -# endif +#endif set_vim_var_string(VV_LC_TIME, loc, -1); -# ifdef HAVE_GET_LOCALE_VAL +#ifdef HAVE_GET_LOCALE_VAL loc = get_locale_val(LC_COLLATE); -# else +#else // setlocale() not supported: use the default value loc = "C"; -# endif +#endif set_vim_var_string(VV_COLLATE, loc, -1); } @@ -2888,16 +2874,16 @@ void set_lang_var(void) /// void ex_language(exarg_T *eap) { - char *loc; - char_u *p; - char_u *name; + char *loc; + char_u *p; + char_u *name; int what = LC_ALL; - char *whatstr = ""; -#ifdef LC_MESSAGES -# define VIM_LC_MESSAGES LC_MESSAGES -#else -# define VIM_LC_MESSAGES 6789 -#endif + char *whatstr = ""; +# ifdef LC_MESSAGES +# define VIM_LC_MESSAGES LC_MESSAGES +# else +# define VIM_LC_MESSAGES 6789 +# endif name = eap->arg; @@ -2926,43 +2912,43 @@ void ex_language(exarg_T *eap) } if (*name == NUL) { -#ifdef HAVE_WORKING_LIBINTL +# ifdef HAVE_WORKING_LIBINTL if (what == VIM_LC_MESSAGES) { p = get_mess_env(); } else { -#endif - p = (char_u *)setlocale(what, NULL); -#ifdef HAVE_WORKING_LIBINTL - } -#endif +# endif + p = (char_u *)setlocale(what, NULL); +# ifdef HAVE_WORKING_LIBINTL + } +# endif if (p == NULL || *p == NUL) { p = (char_u *)"Unknown"; } smsg(_("Current %slanguage: \"%s\""), whatstr, p); } else { -#ifndef LC_MESSAGES +# ifndef LC_MESSAGES if (what == VIM_LC_MESSAGES) { loc = ""; } else { -#endif - loc = setlocale(what, (char *)name); -#ifdef LC_NUMERIC - // Make sure strtod() uses a decimal point, not a comma. - setlocale(LC_NUMERIC, "C"); -#endif -#ifndef LC_MESSAGES - } -#endif +# endif + loc = setlocale(what, (char *)name); +# ifdef LC_NUMERIC + // Make sure strtod() uses a decimal point, not a comma. + setlocale(LC_NUMERIC, "C"); +# endif +# ifndef LC_MESSAGES + } +# endif if (loc == NULL) { EMSG2(_("E197: Cannot set language to \"%s\""), name); } else { -#ifdef HAVE_NL_MSG_CAT_CNTR +# ifdef HAVE_NL_MSG_CAT_CNTR // Need to do this for GNU gettext, otherwise cached translations // will be used again. extern int _nl_msg_cat_cntr; _nl_msg_cat_cntr++; -#endif +# endif // Reset $LC_ALL, otherwise it would overrule everything. os_setenv("LC_ALL", "", 1); @@ -2991,7 +2977,7 @@ void ex_language(exarg_T *eap) static char_u **locales = NULL; // Array of all available locales -#ifndef WIN32 +# ifndef WIN32 static bool did_init_locales = false; /// Return an array of strings for all available locales + NULL for the @@ -2999,7 +2985,7 @@ static bool did_init_locales = false; static char_u **find_locales(void) { garray_T locales_ga; - char_u *loc; + char_u *loc; char *saveptr = NULL; // Find all available locales by running command "locale -a". If this @@ -3026,20 +3012,20 @@ static char_u **find_locales(void) ((char_u **)locales_ga.ga_data)[locales_ga.ga_len] = NULL; return (char_u **)locales_ga.ga_data; } -#endif +# endif /// Lazy initialization of all available locales. static void init_locales(void) { -#ifndef WIN32 +# ifndef WIN32 if (!did_init_locales) { did_init_locales = true; locales = find_locales(); } -#endif +# endif } -# if defined(EXITFREE) +# if defined(EXITFREE) void free_locales(void) { int i; @@ -3051,7 +3037,7 @@ void free_locales(void) } } -# endif +# endif /// Function given to ExpandGeneric() to obtain the possible arguments of the /// ":language" command. @@ -3137,7 +3123,7 @@ static void script_host_do_range(char *name, exarg_T *eap) /// ":drop" /// Opens the first argument in a window. When there are two or more arguments /// the argument list is redefined. -void ex_drop(exarg_T *eap) +void ex_drop(exarg_T *eap) { bool split = false; buf_T *buf; diff --git a/src/nvim/ex_cmds2.h b/src/nvim/ex_cmds2.h index de4e1429b7..d426ff28f8 100644 --- a/src/nvim/ex_cmds2.h +++ b/src/nvim/ex_cmds2.h @@ -16,6 +16,31 @@ #define CCGD_ALLBUF 8 // may write all buffers #define CCGD_EXCMD 16 // may suggest using ! +/// Also store the dev/ino, so that we don't have to stat() each +/// script when going through the list. +typedef struct scriptitem_S { + char_u *sn_name; + bool file_id_valid; + FileID file_id; + bool sn_prof_on; ///< true when script is/was profiled + bool sn_pr_force; ///< forceit: profile functions in this script + proftime_T sn_pr_child; ///< time set when going into first child + int sn_pr_nest; ///< nesting for sn_pr_child + // profiling the script as a whole + int sn_pr_count; ///< nr of times sourced + proftime_T sn_pr_total; ///< time spent in script + children + proftime_T sn_pr_self; ///< time spent in script itself + proftime_T sn_pr_start; ///< time at script start + proftime_T sn_pr_children; ///< time in children after script start + // profiling the script per line + garray_T sn_prl_ga; ///< things stored for every line + proftime_T sn_prl_start; ///< start time for current line + proftime_T sn_prl_children; ///< time spent in children for this line + proftime_T sn_prl_wait; ///< wait start time for current line + linenr_T sn_prl_idx; ///< index of line being timed; -1 if none + int sn_prl_execed; ///< line being timed was executed +} scriptitem_T; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ex_cmds2.h.generated.h" #endif diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h index d64b14c9c5..171f8ed5cd 100644 --- a/src/nvim/ex_cmds_defs.h +++ b/src/nvim/ex_cmds_defs.h @@ -4,8 +4,8 @@ #include <stdbool.h> #include <stdint.h> -#include "nvim/pos.h" // for linenr_T #include "nvim/normal.h" +#include "nvim/pos.h" // for linenr_T #include "nvim/regexp_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -83,10 +83,10 @@ typedef enum { typedef struct exarg exarg_T; -/* behavior for bad character, "++bad=" argument */ -#define BAD_REPLACE '?' /* replace it with '?' (default) */ -#define BAD_KEEP -1 /* leave it */ -#define BAD_DROP -2 /* erase it */ +// behavior for bad character, "++bad=" argument +#define BAD_REPLACE '?' // replace it with '?' (default) +#define BAD_KEEP -1 // leave it +#define BAD_DROP -2 // erase it typedef void (*ex_func_T)(exarg_T *eap); @@ -130,8 +130,8 @@ typedef struct { eslist_T *cs_emsg_silent_list; // saved values of "emsg_silent" int cs_lflags; // loop flags: CSL_ flags } cstack_T; -# define cs_rettv cs_pend.csp_rv -# define cs_exception cs_pend.csp_ex +#define cs_rettv cs_pend.csp_rv +#define cs_exception cs_pend.csp_ex // Flags for the cs_lflags item in cstack_T. enum { @@ -143,10 +143,10 @@ enum { /// Arguments used for Ex commands. struct exarg { - char_u *arg; ///< argument of the command - char_u *nextcmd; ///< next command (NULL if none) - char_u *cmd; ///< the name of the command (except for :make) - char_u **cmdlinep; ///< pointer to pointer of allocated cmdline + char_u *arg; ///< argument of the command + char_u *nextcmd; ///< next command (NULL if none) + char_u *cmd; ///< the name of the command (except for :make) + char_u **cmdlinep; ///< pointer to pointer of allocated cmdline cmdidx_T cmdidx; ///< the index for the command uint32_t argt; ///< flags for the command int skip; ///< don't execute the command, only parse it @@ -156,7 +156,7 @@ struct exarg { linenr_T line2; ///< the second line number or count cmd_addr_T addr_type; ///< type of the count/range int flags; ///< extra flags after count: EXFLAG_ - char_u *do_ecmd_cmd; ///< +command arg to be used in edited file + char_u *do_ecmd_cmd; ///< +command arg to be used in edited file linenr_T do_ecmd_lnum; ///< the line number in an edited file int append; ///< TRUE with ":w >>file" command int usefilter; ///< TRUE with ":w !command" and ":r!command" @@ -170,7 +170,7 @@ struct exarg { int useridx; ///< user command index char_u *errmsg; ///< returned error message LineGetter getline; ///< Function used to get the next line - void *cookie; ///< argument for getline() + void *cookie; ///< argument for getline() cstack_T *cstack; ///< condition stack for ":if" etc. long verbose_save; ///< saved value of p_verbose int save_msg_silent; ///< saved value of msg_silent diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 34497eb212..4524026e3f 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -99,7 +99,7 @@ static garray_T ucmds = { 0, 0, sizeof(ucmd_T), 4, NULL }; #define USER_CMD_GA(gap, i) (&((ucmd_T *)((gap)->ga_data))[i]) // Whether a command index indicates a user command. -# define IS_USER_CMDIDX(idx) ((int)(idx) < 0) +#define IS_USER_CMDIDX(idx) ((int)(idx) < 0) // Struct for storing a line inside a while/for loop typedef struct { @@ -197,8 +197,8 @@ void do_exmode(void) exmode_active = true; State = NORMAL; - /* When using ":global /pat/ visual" and then "Q" we return to continue - * the :global command. */ + // When using ":global /pat/ visual" and then "Q" we return to continue + // the :global command. if (global_busy) { return; } @@ -231,8 +231,8 @@ void do_exmode(void) EMSG(_(e_emptybuf)); } else { if (ex_pressedreturn) { - /* go up one line, to overwrite the ":<CR>" line, so the - * output doesn't contain empty lines. */ + // go up one line, to overwrite the ":<CR>" line, so the + // output doesn't contain empty lines. msg_row = prev_msg_row; if (prev_msg_row == Rows - 1) { msg_row--; @@ -304,6 +304,7 @@ int do_cmdline_cmd(const char *cmd) /// DOCMD_KEYTYPED - Don't reset KeyTyped. /// DOCMD_EXCRESET - Reset the exception environment (used for debugging). /// DOCMD_KEEPLINE - Store first typed line (for repeating with "."). +/// DOCMD_PREVIEW - During 'inccommand' preview. /// /// @param cookie argument for fgetline() /// @@ -373,8 +374,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags) ++ex_nesting_level; } - /* Get the function or script name and the address where the next breakpoint - * line and the debug tick for a function or script are stored. */ + // Get the function or script name and the address where the next breakpoint + // line and the debug tick for a function or script are stored. if (getline_is_func) { fname = func_name(real_cookie); breakpoint = func_breakpoint(real_cookie); @@ -499,11 +500,11 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags) } if (cstack.cs_looplevel > 0) { - /* Inside a while/for loop we need to store the lines and use them - * again. Pass a different "fgetline" function to do_one_cmd() - * below, so that it stores lines in or reads them from - * "lines_ga". Makes it possible to define a function inside a - * while/for loop. */ + // Inside a while/for loop we need to store the lines and use them + // again. Pass a different "fgetline" function to do_one_cmd() + // below, so that it stores lines in or reads them from + // "lines_ga". Makes it possible to define a function inside a + // while/for loop. cmd_getline = get_loop_line; cmd_cookie = (void *)&cmd_loop_cookie; cmd_loop_cookie.lines_gap = &lines_ga; @@ -606,13 +607,13 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags) recursive--; // Ignore trailing '|'-separated commands in preview-mode ('inccommand'). - if (State & CMDPREVIEW) { + if ((State & CMDPREVIEW) && (flags & DOCMD_PREVIEW)) { next_cmdline = NULL; } if (cmd_cookie == (void *)&cmd_loop_cookie) { - /* Use "current_line" from "cmd_loop_cookie", it may have been - * incremented when defining a function. */ + // Use "current_line" from "cmd_loop_cookie", it may have been + // incremented when defining a function. current_line = cmd_loop_cookie.current_line; } @@ -670,8 +671,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags) cstack.cs_lflags |= CSL_HAD_LOOP; line_breakcheck(); // check if CTRL-C typed - /* Check for the next breakpoint at or after the ":while" - * or ":for". */ + // Check for the next breakpoint at or after the ":while" + // or ":for". if (breakpoint != NULL) { *breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline), fname, @@ -723,8 +724,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags) cstack.cs_flags[cstack.cs_idx] |= CSF_ACTIVE | CSF_FINALLY; } - /* Update global "trylevel" for recursive calls to do_cmdline() from - * within this loop. */ + // Update global "trylevel" for recursive calls to do_cmdline() from + // within this loop. trylevel = initial_trylevel + cstack.cs_trylevel; // If the outermost try conditional (across function calls and sourced @@ -805,9 +806,9 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags) trylevel = initial_trylevel; } - /* If a missing ":endtry", ":endwhile", ":endfor", or ":endif" or a memory - * lack was reported above and the error message is to be converted to an - * exception, do this now after rewinding the cstack. */ + // If a missing ":endtry", ":endwhile", ":endfor", or ":endif" or a memory + // lack was reported above and the error message is to be converted to an + // exception, do this now after rewinding the cstack. do_errthrow(&cstack, getline_equal(fgetline, cookie, get_func_line) ? (char_u *)"endfunction" : (char_u *)NULL); @@ -1013,9 +1014,9 @@ int getline_equal(LineGetter fgetline, void *cookie, LineGetter func) LineGetter gp; struct loop_cookie *cp; - /* When "fgetline" is "get_loop_line()" use the "cookie" to find the - * function that's originally used to obtain the lines. This may be - * nested several levels. */ + // When "fgetline" is "get_loop_line()" use the "cookie" to find the + // function that's originally used to obtain the lines. This may be + // nested several levels. gp = fgetline; cp = (struct loop_cookie *)cookie; while (gp == get_loop_line) { @@ -1029,14 +1030,14 @@ int getline_equal(LineGetter fgetline, void *cookie, LineGetter func) /// getline function. Otherwise return "cookie". /// /// @param cookie argument for fgetline() -void * getline_cookie(LineGetter fgetline, void *cookie) +void *getline_cookie(LineGetter fgetline, void *cookie) { LineGetter gp; struct loop_cookie *cp; - /* When "fgetline" is "get_loop_line()" use the "cookie" to find the - * cookie that's originally used to obtain the lines. This may be nested - * several levels. */ + // When "fgetline" is "get_loop_line()" use the "cookie" to find the + // cookie that's originally used to obtain the lines. This may be nested + // several levels. gp = fgetline; cp = (struct loop_cookie *)cookie; while (gp == get_loop_line) { @@ -1249,8 +1250,8 @@ static char_u *skip_colon_white(const char_u *p, bool skipleadingwhite) /// This function may be called recursively! /// /// @param cookie argument for fgetline() -static char_u * do_one_cmd(char_u **cmdlinep, int flags, cstack_T *cstack, LineGetter fgetline, - void *cookie) +static char_u *do_one_cmd(char_u **cmdlinep, int flags, cstack_T *cstack, LineGetter fgetline, + void *cookie) { char_u *p; linenr_T lnum; @@ -2624,9 +2625,9 @@ static char_u *find_command(exarg_T *eap, int *full) } len = (int)(p - eap->cmd); if (*eap->cmd == 'd' && (p[-1] == 'l' || p[-1] == 'p')) { - /* Check for ":dl", ":dell", etc. to ":deletel": that's - * :delete with the 'l' flag. Same for 'p'. */ - for (i = 0; i < len; ++i) { + // Check for ":dl", ":dell", etc. to ":deletel": that's + // :delete with the 'l' flag. Same for 'p'. + for (i = 0; i < len; i++) { if (eap->cmd[i] != ((char_u *)"delete")[i]) { break; } @@ -2904,7 +2905,7 @@ int cmd_exists(const char *const name) /// probably won't change that much -- webb. /// /// @param buff buffer for command string -const char * set_one_cmd_context(expand_T *xp, const char *buff) +const char *set_one_cmd_context(expand_T *xp, const char *buff) { size_t len = 0; exarg_T ea; @@ -4434,8 +4435,8 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp) continue; } - /* Wildcards won't be expanded below, the replacement is taken - * literally. But do expand "~/file", "~user/file" and "$HOME/file". */ + // Wildcards won't be expanded below, the replacement is taken + // literally. But do expand "~/file", "~user/file" and "$HOME/file". if (vim_strchr(repl, '$') != NULL || vim_strchr(repl, '~') != NULL) { char_u *l = repl; @@ -4462,8 +4463,8 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp) && !(eap->argt & EX_NOSPC)) { char_u *l; #ifdef BACKSLASH_IN_FILENAME - /* Don't escape a backslash here, because rem_backslash() doesn't - * remove it later. */ + // Don't escape a backslash here, because rem_backslash() doesn't + // remove it later. static char_u *nobslash = (char_u *)" \t\"|"; # define ESCAPE_CHARS nobslash #else @@ -5636,7 +5637,7 @@ static void ex_command(exarg_T *eap) uint32_t argt = 0; long def = -1; int flags = 0; - int compl = EXPAND_NOTHING; + int compl = EXPAND_NOTHING; char_u *compl_arg = NULL; cmd_addr_T addr_type_arg = ADDR_NONE; int has_attr = (eap->arg[0] == '-'); @@ -5696,7 +5697,7 @@ void ex_comclear(exarg_T *eap) uc_clear(&curbuf->b_ucmds); } -static void free_ucmd(ucmd_T * cmd) { +static void free_ucmd(ucmd_T *cmd) { xfree(cmd->uc_name); xfree(cmd->uc_rep); xfree(cmd->uc_compl_arg); @@ -6948,7 +6949,7 @@ static void ex_goto(exarg_T *eap) */ void alist_clear(alist_T *al) { -# define FREE_AENTRY_FNAME(arg) xfree(arg->ae_fname) +#define FREE_AENTRY_FNAME(arg) xfree(arg->ae_fname) GA_DEEP_CLEAR(&al->al_ga, aentry_T, FREE_AENTRY_FNAME); } @@ -7204,8 +7205,8 @@ void ex_splitview(exarg_T *eap) } } else if (win_split(eap->addr_count > 0 ? (int)eap->line2 : 0, *eap->cmd == 'v' ? WSP_VERT : 0) != FAIL) { - /* Reset 'scrollbind' when editing another file, but keep it when - * doing ":split" without arguments. */ + // Reset 'scrollbind' when editing another file, but keep it when + // doing ":split" without arguments. if (*eap->arg != NUL ) { RESET_BINDING(curwin); @@ -7401,8 +7402,8 @@ static void ex_find(exarg_T *eap) fname = find_file_in_path(eap->arg, STRLEN(eap->arg), FNAME_MESS, TRUE, curbuf->b_ffname); if (eap->addr_count > 0) { - /* Repeat finding the file "count" times. This matters when it - * appears several times in the path. */ + // Repeat finding the file "count" times. This matters when it + // appears several times in the path. count = eap->line2; while (fname != NULL && --count > 0) { xfree(fname); @@ -7500,16 +7501,16 @@ void do_exedit(exarg_T *eap, win_T *old_curwin) // After a split we can use an existing buffer. + (old_curwin != NULL ? ECMD_OLDBUF : 0) + (eap->cmdidx == CMD_badd ? ECMD_ADDBUF : 0) - + (eap->cmdidx == CMD_balt ? ECMD_ALTBUF : 0) - , old_curwin == NULL ? curwin : NULL) == FAIL) { + + (eap->cmdidx == CMD_balt ? ECMD_ALTBUF : 0), + old_curwin == NULL ? curwin : NULL) == FAIL) { // Editing the file failed. If the window was split, close it. if (old_curwin != NULL) { need_hide = (curbufIsChanged() && curbuf->b_nwindows <= 1); if (!need_hide || buf_hide(curbuf)) { cleanup_T cs; - /* Reset the error/interrupt/exception state here so that - * aborting() returns FALSE when closing a window. */ + // Reset the error/interrupt/exception state here so that + // aborting() returns FALSE when closing a window. enter_cleanup(&cs); win_close(curwin, !need_hide && !buf_hide(curbuf)); @@ -7674,8 +7675,8 @@ static void ex_read(exarg_T *eap) } } else { if (empty && exmode_active) { - /* Delete the empty line that remains. Historically ex does - * this but vi doesn't. */ + // Delete the empty line that remains. Historically ex does + // this but vi doesn't. if (eap->line2 == 0) { lnum = curbuf->b_ml.ml_line_count; } else { @@ -7706,6 +7707,21 @@ void free_cd_dir(void) #endif +// Get the previous directory for the given chdir scope. +static char_u *get_prevdir(CdScope scope) +{ + switch (scope) { + case kCdScopeTabpage: + return curtab->tp_prevdir; + break; + case kCdScopeWindow: + return curwin->w_prevdir; + break; + default: + return prev_dir; + } +} + /// Deal with the side effects of changing the current directory. /// /// @param scope Scope of the function call (global, tab or window). @@ -7715,14 +7731,15 @@ void post_chdir(CdScope scope, bool trigger_dirchanged) XFREE_CLEAR(curwin->w_localdir); // Overwrite the tab-local CWD for :cd, :tcd. - if (scope >= kCdScopeTab) { + if (scope >= kCdScopeTabpage) { XFREE_CLEAR(curtab->tp_localdir); } if (scope < kCdScopeGlobal) { + char_u *pdir = get_prevdir(scope); // If still in global directory, set CWD as the global directory. - if (globaldir == NULL && prev_dir != NULL) { - globaldir = vim_strsave(prev_dir); + if (globaldir == NULL && pdir != NULL) { + globaldir = vim_strsave(pdir); } } @@ -7735,7 +7752,7 @@ void post_chdir(CdScope scope, bool trigger_dirchanged) // We are now in the global directory, no need to remember its name. XFREE_CLEAR(globaldir); break; - case kCdScopeTab: + case kCdScopeTabpage: curtab->tp_localdir = (char_u *)xstrdup(cwd); break; case kCdScopeWindow: @@ -7748,59 +7765,92 @@ void post_chdir(CdScope scope, bool trigger_dirchanged) shorten_fnames(true); if (trigger_dirchanged) { - do_autocmd_dirchanged(cwd, scope, false); + do_autocmd_dirchanged(cwd, scope, kCdCauseManual); } } -/// `:cd`, `:tcd`, `:lcd`, `:chdir`, `:tchdir` and `:lchdir`. -void ex_cd(exarg_T *eap) +/// Change directory function used by :cd/:tcd/:lcd Ex commands and the chdir() function. +/// @param new_dir The directory to change to. +/// @param scope Scope of the function call (global, tab or window). +/// @return true if the directory is successfully changed. +bool changedir_func(char_u *new_dir, CdScope scope) { - char_u *new_dir; char_u *tofree; + char_u *pdir = NULL; + bool retval = false; - new_dir = eap->arg; -#if !defined(UNIX) - // for non-UNIX ":cd" means: print current directory - if (*new_dir == NUL) { - ex_pwd(NULL); - } else -#endif - { - if (allbuf_locked()) { - return; - } + if (new_dir == NULL || allbuf_locked()) { + return false; + } - // ":cd -": Change to previous directory - if (STRCMP(new_dir, "-") == 0) { - if (prev_dir == NULL) { - EMSG(_("E186: No previous directory")); - return; - } - new_dir = prev_dir; + // ":cd -": Change to previous directory + if (STRCMP(new_dir, "-") == 0) { + pdir = get_prevdir(scope); + if (pdir == NULL) { + EMSG(_("E186: No previous directory")); + return false; } + new_dir = pdir; + } - // Save current directory for next ":cd -" - tofree = prev_dir; - if (os_dirname(NameBuff, MAXPATHL) == OK) { - prev_dir = vim_strsave(NameBuff); - } else { - prev_dir = NULL; - } + // Free the previous directory + tofree = get_prevdir(scope); + + if (os_dirname(NameBuff, MAXPATHL) == OK) { + pdir = vim_strsave(NameBuff); + } else { + pdir = NULL; + } + + switch (scope) { + case kCdScopeTabpage: + curtab->tp_prevdir = pdir; + break; + case kCdScopeWindow: + curwin->w_prevdir = pdir; + break; + default: + prev_dir = pdir; + } #if defined(UNIX) - // On Unix ":cd" means: go to home directory. - if (*new_dir == NUL) { - // Use NameBuff for home directory name. - expand_env((char_u *)"$HOME", NameBuff, MAXPATHL); - new_dir = NameBuff; - } + // On Unix ":cd" means: go to home directory. + if (*new_dir == NUL) { + // Use NameBuff for home directory name. + expand_env((char_u *)"$HOME", NameBuff, MAXPATHL); + new_dir = NameBuff; + } #endif - CdScope scope = kCdScopeGlobal; // Depends on command invoked + if (vim_chdir(new_dir) == 0) { + bool dir_differs = pdir == NULL || pathcmp((char *)pdir, (char *)new_dir, -1) != 0; + post_chdir(scope, dir_differs); + retval = true; + } else { + EMSG(_(e_failed)); + } + xfree(tofree); + + return retval; +} + +/// ":cd", ":tcd", ":lcd", ":chdir", "tchdir" and ":lchdir". +void ex_cd(exarg_T *eap) +{ + char_u *new_dir; + new_dir = eap->arg; +#if !defined(UNIX) && !defined(VMS) + // for non-UNIX ":cd" means: print current directory + if (*new_dir == NUL) { + ex_pwd(NULL); + } else +#endif + { + CdScope scope = kCdScopeGlobal; switch (eap->cmdidx) { case CMD_tcd: case CMD_tchdir: - scope = kCdScopeTab; + scope = kCdScopeTabpage; break; case CMD_lcd: case CMD_lchdir: @@ -7809,18 +7859,12 @@ void ex_cd(exarg_T *eap) default: break; } - - if (vim_chdir(new_dir)) { - EMSG(_(e_failed)); - } else { - post_chdir(scope, true); + if (changedir_func(new_dir, scope)) { // Echo the new current directory if the command was typed. if (KeyTyped || p_verbose >= 5) { ex_pwd(eap); } } - - xfree(tofree); } } @@ -7833,7 +7877,17 @@ static void ex_pwd(exarg_T *eap) #ifdef BACKSLASH_IN_FILENAME slash_adjust(NameBuff); #endif - msg(NameBuff); + if (p_verbose > 0) { + char *context = "global"; + if (curwin->w_localdir != NULL) { + context = "window"; + } else if (curtab->tp_localdir != NULL) { + context = "tabpage"; + } + smsg("[%s] %s", context, (char *)NameBuff); + } else { + msg(NameBuff); + } } else { EMSG(_("E187: Unknown")); } @@ -8297,8 +8351,8 @@ static void ex_redir(exarg_T *eap) } } - /* Make sure redirection is not off. Can happen for cmdline completion - * that indirectly invokes a command to catch its output. */ + // Make sure redirection is not off. Can happen for cmdline completion + // that indirectly invokes a command to catch its output. if (redir_fd != NULL || redir_reg || redir_vname) { redir_off = false; @@ -9432,14 +9486,14 @@ static void ex_filetype(exarg_T *eap) } if (STRCMP(arg, "on") == 0 || STRCMP(arg, "detect") == 0) { if (*arg == 'o' || !filetype_detect) { - source_runtime((char_u *)FILETYPE_FILE, DIP_ALL); + source_runtime(FILETYPE_FILE, DIP_ALL); filetype_detect = kTrue; if (plugin) { - source_runtime((char_u *)FTPLUGIN_FILE, DIP_ALL); + source_runtime(FTPLUGIN_FILE, DIP_ALL); filetype_plugin = kTrue; } if (indent) { - source_runtime((char_u *)INDENT_FILE, DIP_ALL); + source_runtime(INDENT_FILE, DIP_ALL); filetype_indent = kTrue; } } @@ -9450,15 +9504,15 @@ static void ex_filetype(exarg_T *eap) } else if (STRCMP(arg, "off") == 0) { if (plugin || indent) { if (plugin) { - source_runtime((char_u *)FTPLUGOF_FILE, DIP_ALL); + source_runtime(FTPLUGOF_FILE, DIP_ALL); filetype_plugin = kFalse; } if (indent) { - source_runtime((char_u *)INDOFF_FILE, DIP_ALL); + source_runtime(INDOFF_FILE, DIP_ALL); filetype_indent = kFalse; } } else { - source_runtime((char_u *)FTOFF_FILE, DIP_ALL); + source_runtime(FTOFF_FILE, DIP_ALL); filetype_detect = kFalse; } } else { @@ -9470,15 +9524,15 @@ static void ex_filetype(exarg_T *eap) void filetype_maybe_enable(void) { if (filetype_detect == kNone) { - source_runtime((char_u *)FILETYPE_FILE, true); + source_runtime(FILETYPE_FILE, true); filetype_detect = kTrue; } if (filetype_plugin == kNone) { - source_runtime((char_u *)FTPLUGIN_FILE, true); + source_runtime(FTPLUGIN_FILE, true); filetype_plugin = kTrue; } if (filetype_indent == kNone) { - source_runtime((char_u *)INDENT_FILE, true); + source_runtime(INDENT_FILE, true); filetype_indent = kTrue; } } diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h index 292e01dd6b..7ec4fad277 100644 --- a/src/nvim/ex_docmd.h +++ b/src/nvim/ex_docmd.h @@ -11,8 +11,9 @@ #define DOCMD_KEYTYPED 0x08 // don't reset KeyTyped #define DOCMD_EXCRESET 0x10 // reset exception environment (for debugging #define DOCMD_KEEPLINE 0x20 // keep typed line for repeating with "." +#define DOCMD_PREVIEW 0x40 // during 'inccommand' preview -/* defines for eval_vars() */ +// defines for eval_vars() #define VALID_PATH 1 #define VALID_HEAD 2 diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index 54776c35e7..09a1350f17 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -7,23 +7,23 @@ /// /// Functions for Ex command line for the +eval feature. #include <assert.h> -#include <stdbool.h> #include <inttypes.h> #include <limits.h> +#include <stdbool.h> -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/debugger.h" -#include "nvim/ex_eval.h" #include "nvim/charset.h" +#include "nvim/debugger.h" #include "nvim/eval.h" #include "nvim/eval/userfunc.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_docmd.h" -#include "nvim/message.h" +#include "nvim/ex_eval.h" #include "nvim/memory.h" +#include "nvim/message.h" #include "nvim/regexp.h" #include "nvim/strings.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ex_eval.c.generated.h" @@ -111,8 +111,9 @@ int aborting(void) */ void update_force_abort(void) { - if (cause_abort) + if (cause_abort) { force_abort = TRUE; + } } /* @@ -134,8 +135,8 @@ int should_abort(int retcode) */ int aborted_in_try(void) { - /* This function is only called after an error. In this case, "force_abort" - * determines whether searching for finally clauses is necessary. */ + // This function is only called after an error. In this case, "force_abort" + // determines whether searching for finally clauses is necessary. return force_abort; } @@ -248,8 +249,9 @@ bool cause_errthrow(const char_u *mesg, bool severe, bool *ignore) */ if (msg_list != NULL) { plist = msg_list; - while (*plist != NULL) + while (*plist != NULL) { plist = &(*plist)->next; + } elem = xmalloc(sizeof(struct msglist)); elem->msg = vim_strsave(mesg); @@ -257,19 +259,20 @@ bool cause_errthrow(const char_u *mesg, bool severe, bool *ignore) elem->throw_msg = NULL; *plist = elem; if (plist == msg_list || severe) { - char_u *tmsg; + char_u *tmsg; - /* Skip the extra "Vim " prefix for message "E458". */ + // Skip the extra "Vim " prefix for message "E458". tmsg = elem->msg; if (STRNCMP(tmsg, "Vim E", 5) == 0 && ascii_isdigit(tmsg[5]) && ascii_isdigit(tmsg[6]) && ascii_isdigit(tmsg[7]) && tmsg[8] == ':' - && tmsg[9] == ' ') + && tmsg[9] == ' ') { (*msg_list)->throw_msg = &tmsg[4]; - else + } else { (*msg_list)->throw_msg = tmsg; + } } } return true; @@ -281,7 +284,7 @@ bool cause_errthrow(const char_u *mesg, bool severe, bool *ignore) */ static void free_msglist(struct msglist *l) { - struct msglist *messages, *next; + struct msglist *messages, *next; messages = l; while (messages != NULL) { @@ -318,18 +321,20 @@ void do_errthrow(cstack_T *cstack, char_u *cmdname) force_abort = TRUE; } - /* If no exception is to be thrown or the conversion should be done after - * returning to a previous invocation of do_one_cmd(), do nothing. */ - if (msg_list == NULL || *msg_list == NULL) + // If no exception is to be thrown or the conversion should be done after + // returning to a previous invocation of do_one_cmd(), do nothing. + if (msg_list == NULL || *msg_list == NULL) { return; + } - if (throw_exception(*msg_list, ET_ERROR, cmdname) == FAIL) + if (throw_exception(*msg_list, ET_ERROR, cmdname) == FAIL) { free_msglist(*msg_list); - else { - if (cstack != NULL) + } else { + if (cstack != NULL) { do_throw(cstack); - else + } else { need_rethrow = TRUE; + } } *msg_list = NULL; } @@ -357,36 +362,35 @@ int do_intthrow(cstack_T *cstack) } } else { #endif - // Throw an interrupt exception, so that everything will be aborted - // (except for executing finally clauses), until the interrupt exception - // is caught; if still uncaught at the top level, the script processing - // will be terminated then. - If an interrupt exception is already - // being thrown, do nothing. - - if (current_exception) { - if (current_exception->type == ET_INTERRUPT) { - return false; - } + // Throw an interrupt exception, so that everything will be aborted + // (except for executing finally clauses), until the interrupt exception + // is caught; if still uncaught at the top level, the script processing + // will be terminated then. - If an interrupt exception is already + // being thrown, do nothing. - // An interrupt exception replaces any user or error exception. - discard_current_exception(); - } - if (throw_exception("Vim:Interrupt", ET_INTERRUPT, NULL) != FAIL) { - do_throw(cstack); + if (current_exception) { + if (current_exception->type == ET_INTERRUPT) { + return false; } -#ifdef THROW_TEST + + // An interrupt exception replaces any user or error exception. + discard_current_exception(); + } + if (throw_exception("Vim:Interrupt", ET_INTERRUPT, NULL) != FAIL) { + do_throw(cstack); } +#ifdef THROW_TEST +} #endif return true; } // Get an exception message that is to be stored in current_exception->value. -char_u *get_exception_string(void *value, except_type_T type, char_u *cmdname, - int *should_free) +char_u *get_exception_string(void *value, except_type_T type, char_u *cmdname, int *should_free) { - char_u *ret, *mesg; - char_u *p, *val; + char_u *ret, *mesg; + char_u *p, *val; if (type == ET_ERROR) { *should_free = true; @@ -434,7 +438,7 @@ char_u *get_exception_string(void *value, except_type_T type, char_u *cmdname, } } else { *should_free = FALSE; - ret = (char_u *) value; + ret = (char_u *)value; } return ret; @@ -447,7 +451,7 @@ char_u *get_exception_string(void *value, except_type_T type, char_u *cmdname, // error exception. static int throw_exception(void *value, except_type_T type, char_u *cmdname) { - except_T *excp; + except_T *excp; int should_free; /* @@ -466,14 +470,16 @@ static int throw_exception(void *value, except_type_T type, char_u *cmdname) excp = xmalloc(sizeof(except_T)); - if (type == ET_ERROR) - /* Store the original message and prefix the exception value with - * "Vim:" or, if a command name is given, "Vim(cmdname):". */ + if (type == ET_ERROR) { + // Store the original message and prefix the exception value with + // "Vim:" or, if a command name is given, "Vim(cmdname):". excp->messages = (struct msglist *)value; + } excp->value = get_exception_string(value, type, cmdname, &should_free); - if (excp->value == NULL && should_free) + if (excp->value == NULL && should_free) { goto nomem; + } excp->type = type; excp->throw_name = vim_strsave(sourcing_name == NULL @@ -483,24 +489,27 @@ static int throw_exception(void *value, except_type_T type, char_u *cmdname) if (p_verbose >= 13 || debug_break_level > 0) { int save_msg_silent = msg_silent; - if (debug_break_level > 0) - msg_silent = FALSE; /* display messages */ - else + if (debug_break_level > 0) { + msg_silent = FALSE; // display messages + } else { verbose_enter(); + } ++no_wait_return; - if (debug_break_level > 0 || *p_vfile == NUL) - msg_scroll = TRUE; /* always scroll up, don't overwrite */ - + if (debug_break_level > 0 || *p_vfile == NUL) { + msg_scroll = TRUE; // always scroll up, don't overwrite + } smsg(_("Exception thrown: %s"), excp->value); msg_puts("\n"); // don't overwrite this either - if (debug_break_level > 0 || *p_vfile == NUL) + if (debug_break_level > 0 || *p_vfile == NUL) { cmdline_row = msg_row; + } --no_wait_return; - if (debug_break_level > 0) + if (debug_break_level > 0) { msg_silent = save_msg_silent; - else + } else { verbose_leave(); + } } current_exception = excp; @@ -521,7 +530,7 @@ fail: */ static void discard_exception(except_T *excp, bool was_finished) { - char_u *saved_IObuff; + char_u *saved_IObuff; if (current_exception == excp) { current_exception = NULL; @@ -535,13 +544,15 @@ static void discard_exception(except_T *excp, bool was_finished) int save_msg_silent = msg_silent; saved_IObuff = vim_strsave(IObuff); - if (debug_break_level > 0) - msg_silent = FALSE; /* display messages */ - else + if (debug_break_level > 0) { + msg_silent = FALSE; // display messages + } else { verbose_enter(); + } ++no_wait_return; - if (debug_break_level > 0 || *p_vfile == NUL) - msg_scroll = TRUE; /* always scroll up, don't overwrite */ + if (debug_break_level > 0 || *p_vfile == NUL) { + msg_scroll = TRUE; // always scroll up, don't overwrite + } smsg(was_finished ? _("Exception finished: %s") : _("Exception discarded: %s"), excp->value); @@ -558,10 +569,12 @@ static void discard_exception(except_T *excp, bool was_finished) xstrlcpy((char *)IObuff, (const char *)saved_IObuff, IOSIZE); xfree(saved_IObuff); } - if (excp->type != ET_INTERRUPT) + if (excp->type != ET_INTERRUPT) { xfree(excp->value); - if (excp->type == ET_ERROR) + } + if (excp->type == ET_ERROR) { free_msglist(excp->messages); + } xfree(excp->throw_name); xfree(excp); } @@ -586,7 +599,7 @@ static void catch_exception(except_T *excp) { excp->caught = caught_stack; caught_stack = excp; - set_vim_var_string(VV_EXCEPTION, (char *) excp->value, -1); + set_vim_var_string(VV_EXCEPTION, (char *)excp->value, -1); if (*excp->throw_name != NUL) { if (excp->throw_lnum != 0) { vim_snprintf((char *)IObuff, IOSIZE, _("%s, line %" PRId64), @@ -594,7 +607,7 @@ static void catch_exception(except_T *excp) } else { vim_snprintf((char *)IObuff, IOSIZE, "%s", excp->throw_name); } - set_vim_var_string(VV_THROWPOINT, (char *) IObuff, -1); + set_vim_var_string(VV_THROWPOINT, (char *)IObuff, -1); } else { // throw_name not set on an exception from a command that was typed. set_vim_var_string(VV_THROWPOINT, NULL, -1); @@ -603,24 +616,27 @@ static void catch_exception(except_T *excp) if (p_verbose >= 13 || debug_break_level > 0) { int save_msg_silent = msg_silent; - if (debug_break_level > 0) - msg_silent = FALSE; /* display messages */ - else + if (debug_break_level > 0) { + msg_silent = FALSE; // display messages + } else { verbose_enter(); + } ++no_wait_return; - if (debug_break_level > 0 || *p_vfile == NUL) - msg_scroll = TRUE; /* always scroll up, don't overwrite */ - + if (debug_break_level > 0 || *p_vfile == NUL) { + msg_scroll = TRUE; // always scroll up, don't overwrite + } smsg(_("Exception caught: %s"), excp->value); msg_puts("\n"); // don't overwrite this either - if (debug_break_level > 0 || *p_vfile == NUL) + if (debug_break_level > 0 || *p_vfile == NUL) { cmdline_row = msg_row; + } --no_wait_return; - if (debug_break_level > 0) + if (debug_break_level > 0) { msg_silent = save_msg_silent; - else + } else { verbose_leave(); + } } } @@ -634,7 +650,7 @@ static void finish_exception(except_T *excp) } caught_stack = caught_stack->caught; if (caught_stack != NULL) { - set_vim_var_string(VV_EXCEPTION, (char *) caught_stack->value, -1); + set_vim_var_string(VV_EXCEPTION, (char *)caught_stack->value, -1); if (*caught_stack->throw_name != NUL) { if (caught_stack->throw_lnum != 0) { vim_snprintf((char *)IObuff, IOSIZE, @@ -644,7 +660,7 @@ static void finish_exception(except_T *excp) vim_snprintf((char *)IObuff, IOSIZE, "%s", caught_stack->throw_name); } - set_vim_var_string(VV_THROWPOINT, (char *) IObuff, -1); + set_vim_var_string(VV_THROWPOINT, (char *)IObuff, -1); } else { // throw_name not set on an exception from a command that was // typed. @@ -688,7 +704,7 @@ static void report_pending(int action, int pending, void *value) case RP_RESUME: mesg = _("%s resumed"); break; - /* case RP_DISCARD: */ + // case RP_DISCARD: default: mesg = _("%s discarded"); break; @@ -708,7 +724,7 @@ static void report_pending(int action, int pending, void *value) s = ":finish"; break; case CSTP_RETURN: - /* ":return" command producing value, allocated */ + // ":return" command producing value, allocated s = (char *)get_return_cmd(value); break; @@ -718,30 +734,34 @@ static void report_pending(int action, int pending, void *value) mesg, _("Exception")); mesg = (char *)concat_str(IObuff, (char_u *)": %s"); s = (char *)((except_T *)value)->value; - } else if ((pending & CSTP_ERROR) && (pending & CSTP_INTERRUPT)) + } else if ((pending & CSTP_ERROR) && (pending & CSTP_INTERRUPT)) { s = _("Error and interrupt"); - else if (pending & CSTP_ERROR) + } else if (pending & CSTP_ERROR) { s = _("Error"); - else /* if (pending & CSTP_INTERRUPT) */ + } else { // if (pending & CSTP_INTERRUPT) s = _("Interrupt"); + } } save_msg_silent = msg_silent; - if (debug_break_level > 0) - msg_silent = FALSE; /* display messages */ + if (debug_break_level > 0) { + msg_silent = FALSE; // display messages + } ++no_wait_return; - msg_scroll = TRUE; /* always scroll up, don't overwrite */ + msg_scroll = TRUE; // always scroll up, don't overwrite smsg(mesg, s); msg_puts("\n"); // don't overwrite this either cmdline_row = msg_row; --no_wait_return; - if (debug_break_level > 0) + if (debug_break_level > 0) { msg_silent = save_msg_silent; + } - if (pending == CSTP_RETURN) + if (pending == CSTP_RETURN) { xfree(s); - else if (pending & CSTP_THROW) + } else if (pending & CSTP_THROW) { xfree(mesg); + } } /* @@ -751,11 +771,13 @@ static void report_pending(int action, int pending, void *value) void report_make_pending(int pending, void *value) { if (p_verbose >= 14 || debug_break_level > 0) { - if (debug_break_level <= 0) + if (debug_break_level <= 0) { verbose_enter(); + } report_pending(RP_MAKE, pending, value); - if (debug_break_level <= 0) + if (debug_break_level <= 0) { verbose_leave(); + } } } @@ -766,11 +788,13 @@ void report_make_pending(int pending, void *value) void report_resume_pending(int pending, void *value) { if (p_verbose >= 14 || debug_break_level > 0) { - if (debug_break_level <= 0) + if (debug_break_level <= 0) { verbose_enter(); + } report_pending(RP_RESUME, pending, value); - if (debug_break_level <= 0) + if (debug_break_level <= 0) { verbose_leave(); + } } } @@ -781,11 +805,13 @@ void report_resume_pending(int pending, void *value) void report_discard_pending(int pending, void *value) { if (p_verbose >= 14 || debug_break_level > 0) { - if (debug_break_level <= 0) + if (debug_break_level <= 0) { verbose_enter(); + } report_pending(RP_DISCARD, pending, value); - if (debug_break_level <= 0) + if (debug_break_level <= 0) { verbose_leave(); + } } } @@ -808,9 +834,9 @@ void ex_if(exarg_T *eap) int result; cstack_T *const cstack = eap->cstack; - if (cstack->cs_idx == CSTACK_LEN - 1) + if (cstack->cs_idx == CSTACK_LEN - 1) { eap->errmsg = (char_u *)N_("E579: :if nesting too deep"); - else { + } else { ++cstack->cs_idx; cstack->cs_flags[cstack->cs_idx] = 0; @@ -820,11 +846,13 @@ void ex_if(exarg_T *eap) result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip); if (!skip && !error) { - if (result) + if (result) { cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE | CSF_TRUE; - } else - /* set TRUE, so this conditional will never get active */ + } + } else { + // set TRUE, so this conditional will never get active cstack->cs_flags[cstack->cs_idx] = CSF_TRUE; + } } } @@ -884,13 +912,15 @@ void ex_else(exarg_T *eap) skip = TRUE; } - /* if skipping or the ":if" was TRUE, reset ACTIVE, otherwise set it */ + // if skipping or the ":if" was TRUE, reset ACTIVE, otherwise set it if (skip || cstack->cs_flags[cstack->cs_idx] & CSF_TRUE) { - if (eap->errmsg == NULL) + if (eap->errmsg == NULL) { cstack->cs_flags[cstack->cs_idx] = CSF_TRUE; - skip = TRUE; /* don't evaluate an ":elseif" */ - } else + } + skip = TRUE; // don't evaluate an ":elseif" + } else { cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE; + } /* * When debugging or a breakpoint was encountered, display the debug prompt @@ -910,22 +940,25 @@ void ex_else(exarg_T *eap) if (eap->cmdidx == CMD_elseif) { bool error; result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip); - /* When throwing error exceptions, we want to throw always the first - * of several errors in a row. This is what actually happens when - * a conditional error was detected above and there is another failure - * when parsing the expression. Since the skip flag is set in this - * case, the parsing error will be ignored by emsg(). */ + // When throwing error exceptions, we want to throw always the first + // of several errors in a row. This is what actually happens when + // a conditional error was detected above and there is another failure + // when parsing the expression. Since the skip flag is set in this + // case, the parsing error will be ignored by emsg(). if (!skip && !error) { - if (result) + if (result) { cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE | CSF_TRUE; - else + } else { cstack->cs_flags[cstack->cs_idx] = 0; - } else if (eap->errmsg == NULL) - /* set TRUE, so this conditional will never get active */ + } + } else if (eap->errmsg == NULL) { + // set TRUE, so this conditional will never get active cstack->cs_flags[cstack->cs_idx] = CSF_TRUE; - } else + } + } else { cstack->cs_flags[cstack->cs_idx] |= CSF_ELSE; + } } /* @@ -938,9 +971,9 @@ void ex_while(exarg_T *eap) int result; cstack_T *const cstack = eap->cstack; - if (cstack->cs_idx == CSTACK_LEN - 1) + if (cstack->cs_idx == CSTACK_LEN - 1) { eap->errmsg = (char_u *)N_("E585: :while/:for nesting too deep"); - else { + } else { /* * The loop flag is set when we have jumped back from the matching * ":endwhile" or ":endfor". When not set, need to initialise this @@ -967,21 +1000,22 @@ void ex_while(exarg_T *eap) * ":for var in list-expr" */ if ((cstack->cs_lflags & CSL_HAD_LOOP) != 0) { - /* Jumping here from a ":continue" or ":endfor": use the - * previously evaluated list. */ + // Jumping here from a ":continue" or ":endfor": use the + // previously evaluated list. fi = cstack->cs_forinfo[cstack->cs_idx]; error = FALSE; } else { - /* Evaluate the argument and get the info in a structure. */ + // Evaluate the argument and get the info in a structure. fi = eval_for_line(eap->arg, &error, &eap->nextcmd, skip); cstack->cs_forinfo[cstack->cs_idx] = fi; } - /* use the element at the start of the list and advance */ - if (!error && fi != NULL && !skip) + // use the element at the start of the list and advance + if (!error && fi != NULL && !skip) { result = next_for_item(fi, eap->arg); - else + } else { result = FALSE; + } if (!result) { free_for_info(fi); @@ -999,12 +1033,13 @@ void ex_while(exarg_T *eap) cstack->cs_lflags ^= CSL_HAD_LOOP; } else { cstack->cs_lflags &= ~CSL_HAD_LOOP; - /* If the ":while" evaluates to FALSE or ":for" is past the end of - * the list, show the debug prompt at the ":endwhile"/":endfor" as - * if there was a ":break" in a ":while"/":for" evaluating to - * TRUE. */ - if (!skip && !error) + // If the ":while" evaluates to FALSE or ":for" is past the end of + // the list, show the debug prompt at the ":endwhile"/":endfor" as + // if there was a ":break" in a ":while"/":for" evaluating to + // TRUE. + if (!skip && !error) { cstack->cs_flags[cstack->cs_idx] |= CSF_TRUE; + } } } } @@ -1017,9 +1052,9 @@ void ex_continue(exarg_T *eap) int idx; cstack_T *const cstack = eap->cstack; - if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) + if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) { eap->errmsg = (char_u *)N_("E586: :continue without :while or :for"); - else { + } else { /* Try to find the matching ":while". This might stop at a try * conditional not in its finally clause (which is then to be executed * next). Therefore, deactivate all conditionals except the ":while" @@ -1033,7 +1068,7 @@ void ex_continue(exarg_T *eap) * Set CSL_HAD_CONT, so do_cmdline() will jump back to the * matching ":while". */ - cstack->cs_lflags |= CSL_HAD_CONT; /* let do_cmdline() handle it */ + cstack->cs_lflags |= CSL_HAD_CONT; // let do_cmdline() handle it } else { /* If a try conditional not in its finally clause is reached first, * make the ":continue" pending for execution at the ":endtry". */ @@ -1073,7 +1108,7 @@ void ex_endwhile(exarg_T *eap) { cstack_T *const cstack = eap->cstack; int idx; - char_u *err; + char_u *err; int csf; int fl; @@ -1085,36 +1120,39 @@ void ex_endwhile(exarg_T *eap) csf = CSF_FOR; } - if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) + if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) { eap->errmsg = err; - else { + } else { fl = cstack->cs_flags[cstack->cs_idx]; if (!(fl & csf)) { - /* If we are in a ":while" or ":for" but used the wrong endloop - * command, do not rewind to the next enclosing ":for"/":while". */ - if (fl & CSF_WHILE) + // If we are in a ":while" or ":for" but used the wrong endloop + // command, do not rewind to the next enclosing ":for"/":while". + if (fl & CSF_WHILE) { eap->errmsg = (char_u *)_("E732: Using :endfor with :while"); - else if (fl & CSF_FOR) + } else if (fl & CSF_FOR) { eap->errmsg = (char_u *)_("E733: Using :endwhile with :for"); + } } if (!(fl & (CSF_WHILE | CSF_FOR))) { - if (!(fl & CSF_TRY)) + if (!(fl & CSF_TRY)) { eap->errmsg = e_endif; - else if (fl & CSF_FINALLY) + } else if (fl & CSF_FINALLY) { eap->errmsg = e_endtry; - /* Try to find the matching ":while" and report what's missing. */ + } + // Try to find the matching ":while" and report what's missing. for (idx = cstack->cs_idx; idx > 0; --idx) { fl = cstack->cs_flags[idx]; if ((fl & CSF_TRY) && !(fl & CSF_FINALLY)) { - /* Give up at a try conditional not in its finally clause. - * Ignore the ":endwhile"/":endfor". */ + // Give up at a try conditional not in its finally clause. + // Ignore the ":endwhile"/":endfor". eap->errmsg = err; return; } - if (fl & csf) + if (fl & csf) { break; + } } - /* Cleanup and rewind all contained (and unclosed) conditionals. */ + // Cleanup and rewind all contained (and unclosed) conditionals. (void)cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE); rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel); } @@ -1130,8 +1168,9 @@ void ex_endwhile(exarg_T *eap) */ else if (cstack->cs_flags[cstack->cs_idx] & CSF_TRUE && !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE) - && dbg_check_skipped(eap)) + && dbg_check_skipped(eap)) { (void)do_intthrow(cstack); + } /* * Set loop flag, so do_cmdline() will jump back to the matching @@ -1216,13 +1255,14 @@ void do_throw(cstack_T *cstack) * the matching catch clause or the finally clause. */ if (!(cstack->cs_flags[idx] & CSF_CAUGHT)) { - if (cstack->cs_flags[idx] & CSF_ACTIVE) + if (cstack->cs_flags[idx] & CSF_ACTIVE) { cstack->cs_flags[idx] |= CSF_THROWN; - else - /* THROWN may have already been set for a catchable exception - * that has been discarded. Ensure it is reset for the new - * exception. */ + } else { + // THROWN may have already been set for a catchable exception + // that has been discarded. Ensure it is reset for the new + // exception. cstack->cs_flags[idx] &= ~CSF_THROWN; + } } cstack->cs_flags[idx] &= ~CSF_ACTIVE; cstack->cs_exception[idx] = current_exception; @@ -1237,9 +1277,9 @@ void ex_try(exarg_T *eap) int skip; cstack_T *const cstack = eap->cstack; - if (cstack->cs_idx == CSTACK_LEN - 1) + if (cstack->cs_idx == CSTACK_LEN - 1) { eap->errmsg = (char_u *)N_("E601: :try nesting too deep"); - else { + } else { ++cstack->cs_idx; ++cstack->cs_trylevel; cstack->cs_flags[cstack->cs_idx] = CSF_TRY; @@ -1248,9 +1288,9 @@ void ex_try(exarg_T *eap) skip = CHECK_SKIP; if (!skip) { - /* Set ACTIVE and TRUE. TRUE means that the corresponding ":catch" - * commands should check for a match if an exception is thrown and - * that the finally clause needs to be executed. */ + // Set ACTIVE and TRUE. TRUE means that the corresponding ":catch" + // commands should check for a match if an exception is thrown and + // that the finally clause needs to be executed. cstack->cs_flags[cstack->cs_idx] |= CSF_ACTIVE | CSF_TRUE; /* @@ -1278,7 +1318,6 @@ void ex_try(exarg_T *eap) emsg_silent = 0; } } - } } @@ -1291,38 +1330,41 @@ void ex_catch(exarg_T *eap) int give_up = FALSE; int skip = FALSE; int caught = FALSE; - char_u *end; + char_u *end; char_u save_char = 0; - char_u *save_cpo; + char_u *save_cpo; regmatch_T regmatch; int prev_got_int; cstack_T *const cstack = eap->cstack; - char_u *pat; + char_u *pat; if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0) { eap->errmsg = (char_u *)N_("E603: :catch without :try"); give_up = TRUE; } else { if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) { - /* Report what's missing if the matching ":try" is not in its - * finally clause. */ + // Report what's missing if the matching ":try" is not in its + // finally clause. eap->errmsg = get_end_emsg(cstack); skip = TRUE; } - for (idx = cstack->cs_idx; idx > 0; --idx) - if (cstack->cs_flags[idx] & CSF_TRY) + for (idx = cstack->cs_idx; idx > 0; --idx) { + if (cstack->cs_flags[idx] & CSF_TRY) { break; + } + } if (cstack->cs_flags[idx] & CSF_FINALLY) { /* Give up for a ":catch" after ":finally" and ignore it. * Just parse. */ eap->errmsg = (char_u *)N_("E604: :catch after :finally"); give_up = TRUE; - } else + } else { rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR, - &cstack->cs_looplevel); + &cstack->cs_looplevel); + } } - if (ends_excmd(*eap->arg)) { /* no argument, catch all errors */ + if (ends_excmd(*eap->arg)) { // no argument, catch all errors pat = (char_u *)".*"; end = NULL; eap->nextcmd = find_nextcmd(eap->arg); @@ -1390,7 +1432,7 @@ void ex_catch(exarg_T *eap) prev_got_int = got_int; got_int = FALSE; caught = vim_regexec_nl(®match, current_exception->value, - (colnr_T)0); + (colnr_T)0); got_int |= prev_got_int; vim_regfree(regmatch.regprog); } @@ -1430,8 +1472,9 @@ void ex_catch(exarg_T *eap) } } - if (end != NULL) + if (end != NULL) { eap->nextcmd = find_nextcmd(end); + } } /* @@ -1444,28 +1487,31 @@ void ex_finally(exarg_T *eap) int pending = CSTP_NONE; cstack_T *const cstack = eap->cstack; - if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0) + if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0) { eap->errmsg = (char_u *)N_("E606: :finally without :try"); - else { + } else { if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) { eap->errmsg = get_end_emsg(cstack); - for (idx = cstack->cs_idx - 1; idx > 0; --idx) - if (cstack->cs_flags[idx] & CSF_TRY) + for (idx = cstack->cs_idx - 1; idx > 0; --idx) { + if (cstack->cs_flags[idx] & CSF_TRY) { break; - /* Make this error pending, so that the commands in the following - * finally clause can be executed. This overrules also a pending - * ":continue", ":break", ":return", or ":finish". */ + } + } + // Make this error pending, so that the commands in the following + // finally clause can be executed. This overrules also a pending + // ":continue", ":break", ":return", or ":finish". pending = CSTP_ERROR; - } else + } else { idx = cstack->cs_idx; + } if (cstack->cs_flags[idx] & CSF_FINALLY) { - /* Give up for a multiple ":finally" and ignore it. */ + // Give up for a multiple ":finally" and ignore it. eap->errmsg = (char_u *)N_("E607: multiple :finally"); return; } rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR, - &cstack->cs_looplevel); + &cstack->cs_looplevel); /* * Don't do something when the corresponding try block never got active @@ -1478,14 +1524,14 @@ void ex_finally(exarg_T *eap) skip = !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE); if (!skip) { - /* When debugging or a breakpoint was encountered, display the - * debug prompt (if not already done). The user then knows that the - * finally clause is executed. */ + // When debugging or a breakpoint was encountered, display the + // debug prompt (if not already done). The user then knows that the + // finally clause is executed. if (dbg_check_skipped(eap)) { - /* Handle a ">quit" debug command as if an interrupt had - * occurred before the ":finally". That is, discard the - * original exception and replace it by an interrupt - * exception. */ + // Handle a ">quit" debug command as if an interrupt had + // occurred before the ":finally". That is, discard the + // original exception and replace it by an interrupt + // exception. (void)do_intthrow(cstack); } @@ -1517,7 +1563,7 @@ void ex_finally(exarg_T *eap) if (pending == CSTP_ERROR || did_emsg || got_int || current_exception) { if (cstack->cs_pending[cstack->cs_idx] == CSTP_RETURN) { report_discard_pending(CSTP_RETURN, - cstack->cs_rettv[cstack->cs_idx]); + cstack->cs_rettv[cstack->cs_idx]); discard_pending_return(cstack->cs_rettv[cstack->cs_idx]); } if (pending == CSTP_ERROR && !did_emsg) { @@ -1564,7 +1610,7 @@ void ex_endtry(exarg_T *eap) int skip; int rethrow = FALSE; int pending = CSTP_NONE; - void *rettv = NULL; + void *rettv = NULL; cstack_T *const cstack = eap->cstack; if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0) { @@ -1585,13 +1631,13 @@ void ex_endtry(exarg_T *eap) if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) { eap->errmsg = get_end_emsg(cstack); - /* Find the matching ":try" and report what's missing. */ + // Find the matching ":try" and report what's missing. idx = cstack->cs_idx; do --idx; while (idx > 0 && !(cstack->cs_flags[idx] & CSF_TRY)); rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR, - &cstack->cs_looplevel); + &cstack->cs_looplevel); skip = TRUE; /* @@ -1656,10 +1702,11 @@ void ex_endtry(exarg_T *eap) if (!skip) { pending = cstack->cs_pending[idx]; cstack->cs_pending[idx] = CSTP_NONE; - if (pending == CSTP_RETURN) + if (pending == CSTP_RETURN) { rettv = cstack->cs_rettv[idx]; - else if (pending & CSTP_THROW) + } else if (pending & CSTP_THROW) { current_exception = cstack->cs_exception[idx]; + } } /* @@ -1679,19 +1726,19 @@ void ex_endtry(exarg_T *eap) if (!skip) { report_resume_pending(pending, - (pending == CSTP_RETURN) ? rettv : - (pending & CSTP_THROW) ? (void *)current_exception : NULL); + (pending == CSTP_RETURN) ? rettv : + (pending & CSTP_THROW) ? (void *)current_exception : NULL); switch (pending) { case CSTP_NONE: break; - /* Reactivate a pending ":continue", ":break", ":return", - * ":finish" from the try block or a catch clause of this try - * conditional. This is skipped, if there was an error in an - * (unskipped) conditional command or an interrupt afterwards - * or if the finally clause is present and executed a new error, - * interrupt, throw, ":continue", ":break", ":return", or - * ":finish". */ + // Reactivate a pending ":continue", ":break", ":return", + // ":finish" from the try block or a catch clause of this try + // conditional. This is skipped, if there was an error in an + // (unskipped) conditional command or an interrupt afterwards + // or if the finally clause is present and executed a new error, + // interrupt, throw, ":continue", ":break", ":return", or + // ":finish". case CSTP_CONTINUE: ex_continue(eap); break; @@ -1788,7 +1835,7 @@ void enter_cleanup(cleanup_T *csp) did_emsg = got_int = need_rethrow = false; current_exception = NULL; - /* Report if required by the 'verbose' option or when debugging. */ + // Report if required by the 'verbose' option or when debugging. report_make_pending(pending, csp->exception); } else { csp->pending = CSTP_NONE; @@ -1815,13 +1862,14 @@ void leave_cleanup(cleanup_T *csp) { int pending = csp->pending; - if (pending == CSTP_NONE) /* nothing to do */ + if (pending == CSTP_NONE) { // nothing to do return; + } - /* If there was an aborting error, an interrupt, or an uncaught exception - * after the corresponding call to enter_cleanup(), discard what has been - * made pending by it. Report this to the user if required by the - * 'verbose' option or when debugging. */ + // If there was an aborting error, an interrupt, or an uncaught exception + // after the corresponding call to enter_cleanup(), discard what has been + // made pending by it. Report this to the user if required by the + // 'verbose' option or when debugging. if (aborting() || need_rethrow) { if (pending & CSTP_THROW) { // Cancel the pending exception (includes report). @@ -1830,10 +1878,11 @@ void leave_cleanup(cleanup_T *csp) report_discard_pending(pending, NULL); } - /* If an error was about to be converted to an exception when - * enter_cleanup() was called, free the message list. */ - if (msg_list != NULL) + // If an error was about to be converted to an exception when + // enter_cleanup() was called, free the message list. + if (msg_list != NULL) { free_global_msglist(); + } } /* * If there was no new error, interrupt, or throw between the calls @@ -1846,9 +1895,9 @@ void leave_cleanup(cleanup_T *csp) * called, we need to rethrow it. Make it the exception currently * being thrown. */ - if (pending & CSTP_THROW) + if (pending & CSTP_THROW) { current_exception = csp->exception; - + } /* * If an error was about to be converted to an exception when * enter_cleanup() was called, let "cause_abort" take the part of @@ -1871,8 +1920,7 @@ void leave_cleanup(cleanup_T *csp) } // Report if required by the 'verbose' option or when debugging. - report_resume_pending( - pending, ((pending & CSTP_THROW) ? (void *)current_exception : NULL)); + report_resume_pending(pending, ((pending & CSTP_THROW) ? (void *)current_exception : NULL)); } } @@ -1920,7 +1968,7 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive) case CSTP_RETURN: report_discard_pending(CSTP_RETURN, - cstack->cs_rettv[idx]); + cstack->cs_rettv[idx]); discard_pending_return(cstack->cs_rettv[idx]); cstack->cs_pending[idx] = CSTP_NONE; break; @@ -1948,32 +1996,36 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive) */ if (!(cstack->cs_flags[idx] & CSF_FINALLY)) { if ((cstack->cs_flags[idx] & CSF_ACTIVE) - && (cstack->cs_flags[idx] & CSF_CAUGHT)) + && (cstack->cs_flags[idx] & CSF_CAUGHT)) { finish_exception((except_T *)cstack->cs_exception[idx]); - /* Stop at this try conditional - except the try block never - * got active (because of an inactive surrounding conditional - * or when the ":try" appeared after an error or interrupt or - * throw). */ + } + // Stop at this try conditional - except the try block never + // got active (because of an inactive surrounding conditional + // or when the ":try" appeared after an error or interrupt or + // throw). if (cstack->cs_flags[idx] & CSF_TRUE) { - if (searched_cond == 0 && !inclusive) + if (searched_cond == 0 && !inclusive) { break; + } stop = TRUE; } } } - /* Stop on the searched conditional type (even when the surrounding - * conditional is not active or something has been made pending). - * If "inclusive" is TRUE and "searched_cond" is CSF_TRY|CSF_SILENT, - * check first whether "emsg_silent" needs to be restored. */ + // Stop on the searched conditional type (even when the surrounding + // conditional is not active or something has been made pending). + // If "inclusive" is TRUE and "searched_cond" is CSF_TRY|CSF_SILENT, + // check first whether "emsg_silent" needs to be restored. if (cstack->cs_flags[idx] & searched_cond) { - if (!inclusive) + if (!inclusive) { break; + } stop = TRUE; } cstack->cs_flags[idx] &= ~CSF_ACTIVE; - if (stop && searched_cond != (CSF_TRY | CSF_SILENT)) + if (stop && searched_cond != (CSF_TRY | CSF_SILENT)) { break; + } /* * When leaving a try conditional that reset "emsg_silent" on its @@ -1982,7 +2034,7 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive) */ if ((cstack->cs_flags[idx] & CSF_TRY) && (cstack->cs_flags[idx] & CSF_SILENT)) { - eslist_T *elem; + eslist_T *elem; elem = cstack->cs_emsg_silent_list; cstack->cs_emsg_silent_list = elem->next; @@ -1990,8 +2042,9 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive) xfree(elem); cstack->cs_flags[idx] &= ~CSF_SILENT; } - if (stop) + if (stop) { break; + } } return idx; } @@ -2001,10 +2054,12 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive) */ static char_u *get_end_emsg(cstack_T *cstack) { - if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE) + if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE) { return e_endwhile; - if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR) + } + if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR) { return e_endfor; + } return e_endif; } @@ -2016,14 +2071,15 @@ static char_u *get_end_emsg(cstack_T *cstack) * type. * Also free "for info" structures where needed. */ -void rewind_conditionals(cstack_T *cstack, int idx, int cond_type, - int *cond_level) +void rewind_conditionals(cstack_T *cstack, int idx, int cond_type, int *cond_level) { while (cstack->cs_idx > idx) { - if (cstack->cs_flags[cstack->cs_idx] & cond_type) + if (cstack->cs_flags[cstack->cs_idx] & cond_type) { --*cond_level; - if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR) + } + if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR) { free_for_info(cstack->cs_forinfo[cstack->cs_idx]); + } --cstack->cs_idx; } } @@ -2043,18 +2099,21 @@ int has_loop_cmd(char_u *p) { int len; - /* skip modifiers, white space and ':' */ + // skip modifiers, white space and ':' for (;; ) { - while (*p == ' ' || *p == '\t' || *p == ':') + while (*p == ' ' || *p == '\t' || *p == ':') { ++p; + } len = modifier_len(p); - if (len == 0) + if (len == 0) { break; + } p += len; } if ((p[0] == 'w' && p[1] == 'h') - || (p[0] == 'f' && p[1] == 'o' && p[2] == 'r')) + || (p[0] == 'f' && p[1] == 'o' && p[2] == 'r')) { return TRUE; + } return FALSE; } diff --git a/src/nvim/ex_eval.h b/src/nvim/ex_eval.h index d8388c9156..d3ba43a469 100644 --- a/src/nvim/ex_eval.h +++ b/src/nvim/ex_eval.h @@ -1,22 +1,22 @@ #ifndef NVIM_EX_EVAL_H #define NVIM_EX_EVAL_H -#include "nvim/pos.h" // for linenr_T #include "nvim/ex_cmds_defs.h" // for exarg_T +#include "nvim/pos.h" // for linenr_T /* There is no CSF_IF, the lack of CSF_WHILE, CSF_FOR and CSF_TRY means ":if" * was used. */ -# define CSF_TRUE 0x0001 /* condition was TRUE */ -# define CSF_ACTIVE 0x0002 /* current state is active */ -# define CSF_ELSE 0x0004 /* ":else" has been passed */ -# define CSF_WHILE 0x0008 /* is a ":while" */ -# define CSF_FOR 0x0010 /* is a ":for" */ +#define CSF_TRUE 0x0001 // condition was TRUE +#define CSF_ACTIVE 0x0002 // current state is active +#define CSF_ELSE 0x0004 // ":else" has been passed +#define CSF_WHILE 0x0008 // is a ":while" +#define CSF_FOR 0x0010 // is a ":for" -# define CSF_TRY 0x0100 /* is a ":try" */ -# define CSF_FINALLY 0x0200 /* ":finally" has been passed */ -# define CSF_THROWN 0x0400 /* exception thrown to this try conditional */ -# define CSF_CAUGHT 0x0800 /* exception caught by this try conditional */ -# define CSF_SILENT 0x1000 /* "emsg_silent" reset by ":try" */ +#define CSF_TRY 0x0100 // is a ":try" +#define CSF_FINALLY 0x0200 // ":finally" has been passed +#define CSF_THROWN 0x0400 // exception thrown to this try conditional +#define CSF_CAUGHT 0x0800 // exception caught by this try conditional +#define CSF_SILENT 0x1000 // "emsg_silent" reset by ":try" /* Note that CSF_ELSE is only used when CSF_TRY and CSF_WHILE are unset * (an ":if"), and CSF_SILENT is only used when CSF_TRY is set. */ @@ -24,14 +24,14 @@ * What's pending for being reactivated at the ":endtry" of this try * conditional: */ -# define CSTP_NONE 0 /* nothing pending in ":finally" clause */ -# define CSTP_ERROR 1 /* an error is pending */ -# define CSTP_INTERRUPT 2 /* an interrupt is pending */ -# define CSTP_THROW 4 /* a throw is pending */ -# define CSTP_BREAK 8 /* ":break" is pending */ -# define CSTP_CONTINUE 16 /* ":continue" is pending */ -# define CSTP_RETURN 24 /* ":return" is pending */ -# define CSTP_FINISH 32 /* ":finish" is pending */ +#define CSTP_NONE 0 // nothing pending in ":finally" clause +#define CSTP_ERROR 1 // an error is pending +#define CSTP_INTERRUPT 2 // an interrupt is pending +#define CSTP_THROW 4 // a throw is pending +#define CSTP_BREAK 8 // ":break" is pending +#define CSTP_CONTINUE 16 // ":continue" is pending +#define CSTP_RETURN 24 // ":return" is pending +#define CSTP_FINISH 32 // ":finish" is pending /* * A list of error messages that can be converted to an exception. "throw_msg" @@ -40,9 +40,9 @@ * message in the list. See cause_errthrow() below. */ struct msglist { - char_u *msg; /* original message */ - char_u *throw_msg; /* msg to throw: usually original one */ - struct msglist *next; /* next of several messages in a row */ + char_u *msg; // original message + char_u *throw_msg; // msg to throw: usually original one + struct msglist *next; // next of several messages in a row }; // The exception types. @@ -60,11 +60,11 @@ typedef enum typedef struct vim_exception except_T; struct vim_exception { except_type_T type; // exception type - char_u *value; // exception value - struct msglist *messages; // message(s) causing error exception - char_u *throw_name; // name of the throw point + char_u *value; // exception value + struct msglist *messages; // message(s) causing error exception + char_u *throw_name; // name of the throw point linenr_T throw_lnum; // line number of the throw point - except_T *caught; // next exception on the caught stack + except_T *caught; // next exception on the caught stack }; /* @@ -74,8 +74,8 @@ struct vim_exception { */ typedef struct cleanup_stuff cleanup_T; struct cleanup_stuff { - int pending; /* error/interrupt/exception state */ - except_T *exception; /* exception value */ + int pending; // error/interrupt/exception state + except_T *exception; // exception value }; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index b90773ce83..62a4d48645 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -6,49 +6,56 @@ */ #include <assert.h> +#include <inttypes.h> #include <stdbool.h> -#include <string.h> #include <stdlib.h> -#include <inttypes.h> +#include <string.h> -#include "nvim/assert.h" -#include "nvim/log.h" -#include "nvim/vim.h" -#include "nvim/ascii.h" +#include "nvim/api/private/helpers.h" #include "nvim/arabic.h" -#include "nvim/ex_getln.h" +#include "nvim/ascii.h" +#include "nvim/assert.h" #include "nvim/buffer.h" #include "nvim/charset.h" #include "nvim/cursor.h" +#include "nvim/cursor_shape.h" #include "nvim/digraph.h" #include "nvim/edit.h" #include "nvim/eval.h" #include "nvim/eval/userfunc.h" +#include "nvim/event/loop.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" +#include "nvim/ex_getln.h" #include "nvim/fileio.h" #include "nvim/func_attr.h" +#include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/highlight.h" +#include "nvim/highlight_defs.h" #include "nvim/if_cscope.h" #include "nvim/indent.h" +#include "nvim/keymap.h" +#include "nvim/lib/kvec.h" +#include "nvim/log.h" +#include "nvim/lua/executor.h" #include "nvim/main.h" #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" +#include "nvim/memory.h" #include "nvim/menu.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/memory.h" -#include "nvim/cursor_shape.h" -#include "nvim/keymap.h" -#include "nvim/garray.h" -#include "nvim/move.h" #include "nvim/mouse.h" +#include "nvim/move.h" #include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" +#include "nvim/os/time.h" #include "nvim/os_unix.h" #include "nvim/path.h" #include "nvim/popupmnu.h" @@ -56,22 +63,15 @@ #include "nvim/screen.h" #include "nvim/search.h" #include "nvim/sign.h" -#include "nvim/strings.h" #include "nvim/state.h" +#include "nvim/strings.h" #include "nvim/syntax.h" #include "nvim/tag.h" -#include "nvim/window.h" #include "nvim/ui.h" -#include "nvim/os/input.h" -#include "nvim/os/os.h" -#include "nvim/event/loop.h" -#include "nvim/os/time.h" -#include "nvim/lib/kvec.h" -#include "nvim/api/private/helpers.h" -#include "nvim/highlight_defs.h" -#include "nvim/lua/executor.h" -#include "nvim/viml/parser/parser.h" +#include "nvim/vim.h" #include "nvim/viml/parser/expressions.h" +#include "nvim/viml/parser/parser.h" +#include "nvim/window.h" /// Command-line colors: one chunk /// @@ -110,21 +110,21 @@ typedef enum { * structure. */ struct cmdline_info { - char_u *cmdbuff; // pointer to command line buffer + char_u *cmdbuff; // pointer to command line buffer int cmdbufflen; // length of cmdbuff int cmdlen; // number of chars in command line int cmdpos; // current cursor position int cmdspos; // cursor column on screen int cmdfirstc; // ':', '/', '?', '=', '>' or NUL int cmdindent; // number of spaces before cmdline - char_u *cmdprompt; // message in front of cmdline + char_u *cmdprompt; // message in front of cmdline int cmdattr; // attributes for prompt int overstrike; // Typing mode on the command line. Shared by // getcmdline() and put_on_cmdline(). - expand_T *xpc; // struct being used for expansion, xp_pattern - // may point into cmdbuff + expand_T *xpc; // struct being used for expansion, xp_pattern + // may point into cmdbuff int xp_context; // type of expansion - char_u *xp_arg; // user-defined expansion arg + char_u *xp_arg; // user-defined expansion arg int input_fn; // when TRUE Invoked for input() function unsigned prompt_id; ///< Prompt number, used to disable coloring on errors. Callback highlight_callback; ///< Callback used for coloring user input. @@ -140,25 +140,25 @@ static unsigned last_prompt_id = 0; // Struct to store the viewstate during 'incsearch' highlighting. typedef struct { - colnr_T vs_curswant; - colnr_T vs_leftcol; - linenr_T vs_topline; - int vs_topfill; - linenr_T vs_botline; - int vs_empty_rows; + colnr_T vs_curswant; + colnr_T vs_leftcol; + linenr_T vs_topline; + int vs_topfill; + linenr_T vs_botline; + int vs_empty_rows; } viewstate_T; // Struct to store the state of 'incsearch' highlighting. typedef struct { - pos_T search_start; // where 'incsearch' starts searching - pos_T save_cursor; + pos_T search_start; // where 'incsearch' starts searching + pos_T save_cursor; viewstate_T init_viewstate; viewstate_T old_viewstate; - pos_T match_start; - pos_T match_end; - bool did_incsearch; - bool incsearch_postponed; - int magic_save; + pos_T match_start; + pos_T match_end; + bool did_incsearch; + bool incsearch_postponed; + int magic_save; } incsearch_state_T; typedef struct command_line_state { @@ -178,9 +178,9 @@ typedef struct command_line_state { int did_wild_list; // did wild_list() recently int wim_index; // index in wim_flags[] int res; - int save_msg_scroll; - int save_State; // remember State when called - char_u *save_p_icm; + int save_msg_scroll; + int save_State; // remember State when called + char_u *save_p_icm; int some_key_typed; // one of the keys was typed // mouse drag and release events are ignored, unless they are // preceded with a mouse down event @@ -198,9 +198,9 @@ typedef struct cmdline_info CmdlineInfo; * TODO: make it local to getcmdline() and pass it around. */ static struct cmdline_info ccline; -static int cmd_showtail; /* Only show path tail in lists ? */ +static int cmd_showtail; // Only show path tail in lists ? -static int new_cmdpos; /* position set by set_cmdline_pos() */ +static int new_cmdpos; // position set by set_cmdline_pos() /// currently displayed block of context static Array cmdline_block = ARRAY_DICT_INIT; @@ -210,11 +210,11 @@ static Array cmdline_block = ARRAY_DICT_INIT; */ typedef void *(*user_expand_func_T)(const char_u *, int, typval_T *); -static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL}; -static int hisidx[HIST_COUNT] = {-1, -1, -1, -1, -1}; /* lastused entry */ -static int hisnum[HIST_COUNT] = {0, 0, 0, 0, 0}; -/* identifying (unique) number of newest history entry */ -static int hislen = 0; /* actual length of history tables */ +static histentry_T *(history[HIST_COUNT]) = { NULL, NULL, NULL, NULL, NULL }; +static int hisidx[HIST_COUNT] = { -1, -1, -1, -1, -1 }; // lastused entry +static int hisnum[HIST_COUNT] = { 0, 0, 0, 0, 0 }; +// identifying (unique) number of newest history entry +static int hislen = 0; // actual length of history tables /// Flag for command_line_handle_key to ignore <C-c> /// @@ -230,7 +230,22 @@ static int compl_match_arraysize; static int compl_startcol; static int compl_selected; +/// |:checkhealth| completion items +/// +/// Regenerates on every new command line prompt, to accomodate changes on the +/// runtime files. +typedef struct { + garray_T names; // healthcheck names + unsigned last_gen; // last_prompt_id where names were generated +} CheckhealthComp; + +/// Cookie used when converting filepath to name +struct healthchecks_cookie { + garray_T *names; // global healthchecks + bool is_lua; // true if the current entry is a Lua healthcheck +}; +static CheckhealthComp healthchecks = { GA_INIT(sizeof(char_u *), 10), 0 }; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ex_getln.c.generated.h" @@ -273,11 +288,72 @@ static void init_incsearch_state(incsearch_state_T *s) save_viewstate(&s->old_viewstate); } +/// Completion for |:checkhealth| command. +/// +/// Given to ExpandGeneric() to obtain all available heathcheck names. +/// @param[in] idx Index of the healthcheck item. +/// @param[in] xp Not used. +static char_u *get_healthcheck_names(expand_T *xp, int idx) +{ + // Generate the first time or on new prompt. + if (healthchecks.last_gen == 0 || healthchecks.last_gen != last_prompt_id) { + ga_clear_strings(&healthchecks.names); + char *patterns[3] = { "autoload/health/**.vim", "lua/**/**/health/init.lua", // NOLINT + "lua/**/**/health.lua" }; // NOLINT + for (int i = 0; i < 3; i++) { + struct healthchecks_cookie hcookie = { .names = &healthchecks.names, .is_lua = i != 0 }; + do_in_runtimepath((char_u *)patterns[i], DIP_ALL, get_healthcheck_cb, &hcookie); + + if (healthchecks.names.ga_len > 0) { + ga_remove_duplicate_strings(&healthchecks.names); + } + } + // Tracked to regenerate items on next prompt. + healthchecks.last_gen = last_prompt_id; + } + return idx < + (int)healthchecks.names.ga_len ? ((char_u **)(healthchecks.names.ga_data))[idx] : NULL; +} + +/// Transform healthcheck file path into it's name. +/// +/// Used as a callback for do_in_runtimepath +/// @param[in] path Expanded path to a possible healthcheck. +/// @param[out] cookie Array where names will be inserted. +static void get_healthcheck_cb(char_u *path, void *cookie) +{ + if (path != NULL) { + struct healthchecks_cookie *hcookie = (struct healthchecks_cookie *)cookie; + char *pattern; + char *sub = "\\1"; + char_u *res; + + if (hcookie->is_lua) { + // Lua: transform "../lua/vim/lsp/health.lua" into "vim.lsp" + pattern = ".*lua[\\/]\\(.\\{-}\\)[\\/]health\\([\\/]init\\)\\?\\.lua$"; + } else { + // Vim: transform "../autoload/health/provider.vim" into "provider" + pattern = ".*[\\/]\\([^\\/]*\\)\\.vim$"; + } + + res = do_string_sub(path, (char_u *)pattern, (char_u *)sub, NULL, (char_u *)"g"); + if (hcookie->is_lua && res != NULL) { + // Replace slashes with dots as represented by the healthcheck plugin. + char_u *ares = do_string_sub(res, (char_u *)"[\\/]", (char_u *)".", NULL, (char_u *)"g"); + xfree(res); + res = ares; + } + + if (res != NULL) { + GA_APPEND(char_u *, hcookie->names, res); + } + } +} + // Return true when 'incsearch' highlighting is to be done. // Sets search_first_line and search_last_line to the address range. -static bool do_incsearch_highlighting(int firstc, int *search_delim, - incsearch_state_T *s, int *skiplen, - int *patlen) +static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_state_T *s, + int *skiplen, int *patlen) FUNC_ATTR_NONNULL_ALL { char_u *cmd; @@ -384,7 +460,7 @@ static bool do_incsearch_highlighting(int firstc, int *search_delim, // Don't do 'hlsearch' highlighting if the pattern matches everything. if (!use_last_pat) { char_u c = *end; - int empty; + int empty; *end = NUL; empty = empty_pattern(p); @@ -425,8 +501,7 @@ theend: } // May do 'incsearch' highlighting if desired. -static void may_do_incsearch_highlighting(int firstc, long count, - incsearch_state_T *s) +static void may_do_incsearch_highlighting(int firstc, long count, incsearch_state_T *s) { pos_T end_pos; proftime_T tm; @@ -472,7 +547,7 @@ static void may_do_incsearch_highlighting(int firstc, long count, // Use the previous pattern for ":s//". next_char = ccline.cmdbuff[skiplen + patlen]; use_last_pat = patlen == 0 && skiplen > 0 - && ccline.cmdbuff[skiplen - 1] == next_char; + && ccline.cmdbuff[skiplen - 1] == next_char; // If there is no pattern, don't do anything. if (patlen == 0 && !use_last_pat) { @@ -624,8 +699,7 @@ static int may_add_char_to_search(int firstc, int *c, incsearch_state_T *s) return OK; } -static void finish_incsearch_highlighting(int gotesc, incsearch_state_T *s, - bool call_update_screen) +static void finish_incsearch_highlighting(int gotesc, incsearch_state_T *s, bool call_update_screen) { if (s->did_incsearch) { s->did_incsearch = false; @@ -872,7 +946,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent) && s->firstc != NUL && (s->some_key_typed || s->histype == HIST_SEARCH)) { add_to_history(s->histype, ccline.cmdbuff, true, - s->histype == HIST_SEARCH ? s->firstc : NUL); + s->histype == HIST_SEARCH ? s->firstc : NUL); if (s->firstc == ':') { xfree(new_last_cmdline); new_last_cmdline = vim_strsave(ccline.cmdbuff); @@ -973,12 +1047,18 @@ static int command_line_execute(VimState *state, int key) // typed by the user directly, not when the result of a // mapping. switch (s->c) { - case K_RIGHT: s->c = K_LEFT; break; - case K_S_RIGHT: s->c = K_S_LEFT; break; - case K_C_RIGHT: s->c = K_C_LEFT; break; - case K_LEFT: s->c = K_RIGHT; break; - case K_S_LEFT: s->c = K_S_RIGHT; break; - case K_C_LEFT: s->c = K_C_RIGHT; break; + case K_RIGHT: + s->c = K_LEFT; break; + case K_S_RIGHT: + s->c = K_S_LEFT; break; + case K_C_RIGHT: + s->c = K_C_LEFT; break; + case K_LEFT: + s->c = K_RIGHT; break; + case K_S_LEFT: + s->c = K_S_RIGHT; break; + case K_C_LEFT: + s->c = K_C_RIGHT; break; } } } @@ -1078,7 +1158,7 @@ static int command_line_execute(VimState *state, int key) redrawcmd(); save_p_ls = -1; wild_menu_showing = 0; - // don't redraw statusline if WM_LIST is showing + // don't redraw statusline if WM_LIST is showing } else if (wild_menu_showing != WM_LIST) { win_redraw_last_status(topframe); wild_menu_showing = 0; // must be before redraw_statuslines #8385 @@ -1155,7 +1235,7 @@ static int command_line_execute(VimState *state, int key) s->c = (int)p_wc; KeyTyped = true; // in case the key was mapped } else if (STRNCMP(s->xpc.xp_pattern, upseg + 1, 3) == 0 - && s->c == K_DOWN) { + && s->c == K_DOWN) { // If in a direct ancestor, strip off one ../ to go down int found = false; @@ -1242,7 +1322,7 @@ static int command_line_execute(VimState *state, int key) vungetc(s->c); s->c = Ctrl_BSL; } else if (s->c == 'e') { - char_u *p = NULL; + char_u *p = NULL; int len; // Replace the command line with the result of an expression. @@ -1318,7 +1398,7 @@ static int command_line_execute(VimState *state, int key) || s->c == '\r' || s->c == K_KENTER || (s->c == ESC - && (!KeyTyped || vim_strchr(p_cpo, CPO_ESC) != NULL))) { + && (!KeyTyped || vim_strchr(p_cpo, CPO_ESC) != NULL))) { // In Ex mode a backslash escapes a newline. if (exmode_active && s->c != ESC @@ -1419,7 +1499,7 @@ static int command_line_execute(VimState *state, int key) } (void)showmatches(&s->xpc, p_wmnu - && ((wim_flags[s->wim_index] & WIM_LIST) == 0)); + && ((wim_flags[s->wim_index] & WIM_LIST) == 0)); redrawcmd(); s->did_wild_list = true; @@ -1464,7 +1544,7 @@ static int command_line_execute(VimState *state, int key) } } - if (s->c == NUL || s->c == K_ZERO) { + if (s->c == NUL || s->c == K_ZERO) { // NUL is stored as NL s->c = NL; } @@ -1476,8 +1556,7 @@ static int command_line_execute(VimState *state, int key) // May adjust 'incsearch' highlighting for typing CTRL-G and CTRL-T, go to next // or previous match. // Returns FAIL when calling command_line_not_changed. -static int may_do_command_line_next_incsearch(int firstc, long count, - incsearch_state_T *s, +static int may_do_command_line_next_incsearch(int firstc, long count, incsearch_state_T *s, bool next_match) FUNC_ATTR_NONNULL_ALL { @@ -1500,7 +1579,7 @@ static int may_do_command_line_next_incsearch(int firstc, long count, ui_busy_start(); ui_flush(); - pos_T t; + pos_T t; char_u *pat; int search_flags = SEARCH_NOOF; char_u save; @@ -1656,7 +1735,7 @@ static int command_line_handle_key(CommandLineState *s) if (s->c == K_DEL) { ccline.cmdpos += mb_off_next(ccline.cmdbuff, - ccline.cmdbuff + ccline.cmdpos); + ccline.cmdbuff + ccline.cmdpos); } if (ccline.cmdpos > 0) { @@ -1980,8 +2059,9 @@ static int command_line_handle_key(CommandLineState *s) return command_line_not_changed(s); case Ctrl_A: // all matches - if (nextwild(&s->xpc, WILD_ALL, 0, s->firstc != '@') == FAIL) + if (nextwild(&s->xpc, WILD_ALL, 0, s->firstc != '@') == FAIL) { break; + } return command_line_changed(s); case Ctrl_L: @@ -1999,7 +2079,7 @@ static int command_line_handle_key(CommandLineState *s) case Ctrl_P: // previous match if (s->xpc.xp_numfiles > 0) { if (nextwild(&s->xpc, (s->c == Ctrl_P) ? WILD_PREV : WILD_NEXT, - 0, s->firstc != '@') == FAIL) { + 0, s->firstc != '@') == FAIL) { break; } return command_line_not_changed(s); @@ -2033,7 +2113,7 @@ static int command_line_handle_key(CommandLineState *s) if (s->hiscnt != s->save_hiscnt) { // jumped to other entry - char_u *p; + char_u *p; int len = 0; int old_firstc; @@ -2251,7 +2331,7 @@ static int command_line_changed(CommandLineState *s) State |= CMDPREVIEW; emsg_silent++; // Block error reporting as the command may be incomplete msg_silent++; // Block messages, namely ones that prompt - do_cmdline(ccline.cmdbuff, NULL, NULL, DOCMD_KEEPLINE|DOCMD_NOWAIT); + do_cmdline(ccline.cmdbuff, NULL, NULL, DOCMD_KEEPLINE|DOCMD_NOWAIT|DOCMD_PREVIEW); msg_silent--; // Unblock messages emsg_silent--; // Unblock error reporting @@ -2261,7 +2341,6 @@ static int command_line_changed(CommandLineState *s) update_topline(curwin); redrawcmdline(); - } else if (State & CMDPREVIEW) { State = (State & ~CMDPREVIEW); close_preview_windows(); @@ -2298,32 +2377,27 @@ static void abandon_cmdline(void) redraw_cmdline = true; } -/* - * getcmdline() - accept a command line starting with firstc. - * - * firstc == ':' get ":" command line. - * firstc == '/' or '?' get search pattern - * firstc == '=' get expression - * firstc == '@' get text for input() function - * firstc == '>' get text for debug mode - * firstc == NUL get text for :insert command - * firstc == -1 like NUL, and break on CTRL-C - * - * The line is collected in ccline.cmdbuff, which is reallocated to fit the - * command line. - * - * Careful: getcmdline() can be called recursively! - * - * Return pointer to allocated string if there is a commandline, NULL - * otherwise. - */ -char_u * -getcmdline ( - int firstc, - long count, // only used for incremental search - int indent, // indent for inside conditionals - bool do_concat FUNC_ATTR_UNUSED -) +/// getcmdline() - accept a command line starting with firstc. +/// +/// firstc == ':' get ":" command line. +/// firstc == '/' or '?' get search pattern +/// firstc == '=' get expression +/// firstc == '@' get text for input() function +/// firstc == '>' get text for debug mode +/// firstc == NUL get text for :insert command +/// firstc == -1 like NUL, and break on CTRL-C +/// +/// The line is collected in ccline.cmdbuff, which is reallocated to fit the +/// command line. +/// +/// Careful: getcmdline() can be called recursively! +/// +/// Return pointer to allocated string if there is a commandline, NULL +/// otherwise. +/// +/// @param count only used for incremental search +/// @param indent indent for inside conditionals +char_u *getcmdline(int firstc, long count, int indent, bool do_concat FUNC_ATTR_UNUSED) { // Be prepared for situations where cmdline can be invoked recursively. // That includes cmd mappings, event handlers, as well as update_screen() @@ -2348,9 +2422,8 @@ getcmdline ( /// @param[in] highlight_callback Callback used for highlighting user input. /// /// @return [allocated] Command line or NULL. -char *getcmdline_prompt(const char firstc, const char *const prompt, - const int attr, const int xp_context, - const char *const xp_arg, +char *getcmdline_prompt(const char firstc, const char *const prompt, const int attr, + const int xp_context, const char *const xp_arg, const Callback highlight_callback) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC { @@ -2390,8 +2463,9 @@ char *getcmdline_prompt(const char firstc, const char *const prompt, * another window or buffer. Used when editing the command line etc. */ int text_locked(void) { - if (cmdwin_type != 0) + if (cmdwin_type != 0) { return TRUE; + } return textlock != 0; } @@ -2404,7 +2478,7 @@ void text_locked_msg(void) EMSG(_(get_text_locked_msg())); } -char_u * get_text_locked_msg(void) { +char_u *get_text_locked_msg(void) { if (cmdwin_type != 0) { return e_cmdwin; } else { @@ -2438,8 +2512,9 @@ int allbuf_locked(void) static int cmdline_charsize(int idx) { - if (cmdline_star > 0) /* showing '*', always 1 position */ + if (cmdline_star > 0) { // showing '*', always 1 position return 1; + } return ptr2cells(ccline.cmdbuff + idx); } @@ -2459,8 +2534,9 @@ static int cmd_screencol(int bytepos) int col = cmd_startcol(); if (KeyTyped) { m = Columns * Rows; - if (m < 0) /* overflow, Columns or Rows at weird value */ + if (m < 0) { // overflow, Columns or Rows at weird value m = MAXCOL; + } } else { m = MAXCOL; } @@ -2492,20 +2568,16 @@ static void correct_screencol(int idx, int cells, int *col) } } -/* - * Get an Ex command line for the ":" command. - */ -char_u * -getexline( - int c, // normally ':', NUL for ":append" - void *cookie, - int indent, // indent for inside conditionals - bool do_concat -) +/// Get an Ex command line for the ":" command. +/// +/// @param c normally ':', NUL for ":append" +/// @param indent indent for inside conditionals +char_u *getexline(int c, void *cookie, int indent, bool do_concat) { - /* When executing a register, remove ':' that's in front of each line. */ - if (exec_from_reg && vpeekc() == ':') + // When executing a register, remove ':' that's in front of each line. + if (exec_from_reg && vpeekc() == ':') { (void)vgetc(); + } return getcmdline(c, 1L, indent, do_concat); } @@ -2532,10 +2604,11 @@ static void alloc_cmdbuff(int len) /* * give some extra space to avoid having to allocate all the time */ - if (len < 80) + if (len < 80) { len = 100; - else + } else { len += 20; + } ccline.cmdbuff = xmalloc((size_t)len); ccline.cmdbufflen = len; @@ -2551,7 +2624,7 @@ static void realloc_cmdbuff(int len) } char_u *p = ccline.cmdbuff; - alloc_cmdbuff(len); /* will get some more */ + alloc_cmdbuff(len); // will get some more /* There isn't always a NUL after the command, but it may need to be * there, thus copy up to the NUL and add a NUL. */ memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen); @@ -2564,22 +2637,23 @@ static void realloc_cmdbuff(int len) && ccline.xpc->xp_context != EXPAND_UNSUCCESSFUL) { int i = (int)(ccline.xpc->xp_pattern - p); - /* If xp_pattern points inside the old cmdbuff it needs to be adjusted - * to point into the newly allocated memory. */ - if (i >= 0 && i <= ccline.cmdlen) + // If xp_pattern points inside the old cmdbuff it needs to be adjusted + // to point into the newly allocated memory. + if (i >= 0 && i <= ccline.cmdlen) { ccline.xpc->xp_pattern = ccline.cmdbuff + i; + } } } -static char_u *arshape_buf = NULL; +static char_u *arshape_buf = NULL; -# if defined(EXITFREE) +#if defined(EXITFREE) void free_arshape_buf(void) { xfree(arshape_buf); } -# endif +#endif enum { MAX_CB_ERRORS = 1 }; @@ -2605,8 +2679,7 @@ static void color_expr_cmdline(const CmdlineInfo *const colored_ccline, ParserHighlight colors; kvi_init(colors); ParserState pstate; - viml_parser_init( - &pstate, parser_simple_get_line, &plines_p, &colors); + viml_parser_init(&pstate, parser_simple_get_line, &plines_p, &colors); ExprAST east = viml_pexpr_parse(&pstate, kExprFlagsDisallowEOC); viml_pexpr_free_ast(east); viml_parser_destroy(&pstate); @@ -2626,9 +2699,9 @@ static void color_expr_cmdline(const CmdlineInfo *const colored_ccline, const int id = syn_name2id((const char_u *)chunk.group); const int attr = (id == 0 ? 0 : syn_id2attr(id)); kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) { - .start = (int)chunk.start.col, - .end = (int)chunk.end_col, - .attr = attr, + .start = (int)chunk.start.col, + .end = (int)chunk.end_col, + .attr = attr, })); prev_end = chunk.end_col; } @@ -2716,8 +2789,7 @@ static bool color_cmdline(CmdlineInfo *colored_ccline) color_cb = colored_ccline->highlight_callback; } else if (colored_ccline->cmdfirstc == ':') { try_enter(&tstate); - err_errmsg = N_( - "E5408: Unable to get g:Nvim_color_cmdline callback: %s"); + err_errmsg = N_("E5408: Unable to get g:Nvim_color_cmdline callback: %s"); dgc_ret = tv_dict_get_callback(&globvardict, S_LEN("Nvim_color_cmdline"), &color_cb); tl_ret = try_leave(&tstate, &err); @@ -2785,7 +2857,7 @@ static bool color_cmdline(CmdlineInfo *colored_ccline) } bool error = false; const varnumber_T start = ( - tv_get_number_chk(TV_LIST_ITEM_TV(tv_list_first(l)), &error)); + tv_get_number_chk(TV_LIST_ITEM_TV(tv_list_first(l)), &error)); if (error) { goto color_cmdline_error; } else if (!(prev_end <= start && start < colored_ccline->cmdlen)) { @@ -2805,8 +2877,8 @@ static bool color_cmdline(CmdlineInfo *colored_ccline) .attr = 0, })); } - const varnumber_T end = tv_get_number_chk( - TV_LIST_ITEM_TV(TV_LIST_ITEM_NEXT(l, tv_list_first(l))), &error); + const varnumber_T end = + tv_get_number_chk(TV_LIST_ITEM_TV(TV_LIST_ITEM_NEXT(l, tv_list_first(l))), &error); if (error) { goto color_cmdline_error; } else if (!(start < end && end <= colored_ccline->cmdlen)) { @@ -2822,8 +2894,7 @@ static bool color_cmdline(CmdlineInfo *colored_ccline) goto color_cmdline_error; } prev_end = end; - const char *const group = tv_get_string_chk( - TV_LIST_ITEM_TV(tv_list_last(l))); + const char *const group = tv_get_string_chk(TV_LIST_ITEM_TV(tv_list_last(l))); if (group == NULL) { goto color_cmdline_error; } @@ -3043,7 +3114,7 @@ static void ui_ext_cmdline_show(CmdlineInfo *line) line->cmdindent, line->level); if (line->special_char) { - ui_call_cmdline_special_char(cchar_to_string((char)(line->special_char)), + ui_call_cmdline_special_char(cchar_to_string(line->special_char), line->special_shift, line->level); } @@ -3141,8 +3212,8 @@ void putcmdline(char c, int shift) } msg_no_more = false; } else if (ccline.redraw_state != kCmdRedrawAll) { - ui_call_cmdline_special_char(cchar_to_string((char)(c)), shift, - ccline.level); + ui_call_cmdline_special_char(cchar_to_string(c), shift, + ccline.level); } cursorcmd(); ccline.special_char = c; @@ -3182,15 +3253,16 @@ void put_on_cmdline(char_u *str, int len, int redraw) int m; int c; - if (len < 0) + if (len < 0) { len = (int)STRLEN(str); + } realloc_cmdbuff(ccline.cmdlen + len + 1); if (!ccline.overstrike) { memmove(ccline.cmdbuff + ccline.cmdpos + len, - ccline.cmdbuff + ccline.cmdpos, - (size_t)(ccline.cmdlen - ccline.cmdpos)); + ccline.cmdbuff + ccline.cmdpos, + (size_t)(ccline.cmdlen - ccline.cmdpos)); ccline.cmdlen += len; } else { // Count nr of characters in the new string. @@ -3232,11 +3304,12 @@ void put_on_cmdline(char_u *str, int len, int redraw) if (arabic_combine(utf_ptr2char(ccline.cmdbuff + ccline.cmdpos - i), c)) { ccline.cmdpos -= i; len += i; - } else + } else { i = 0; + } } if (i != 0) { - /* Also backup the cursor position. */ + // Also backup the cursor position. i = ptr2cells(ccline.cmdbuff + ccline.cmdpos); ccline.cmdspos -= i; msg_col -= i; @@ -3252,9 +3325,10 @@ void put_on_cmdline(char_u *str, int len, int redraw) i = cmdline_row; cursorcmd(); draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos); - /* Avoid clearing the rest of the line too often. */ - if (cmdline_row != i || ccline.overstrike) + // Avoid clearing the rest of the line too often. + if (cmdline_row != i || ccline.overstrike) { msg_clr_eos(); + } msg_no_more = FALSE; } if (KeyTyped) { @@ -3348,8 +3422,8 @@ void restore_cmdline_alloc(char_u *p) /// @returns FAIL for failure, OK otherwise static bool cmdline_paste(int regname, bool literally, bool remcr) { - char_u *arg; - char_u *p; + char_u *arg; + char_u *p; bool allocated; struct cmdline_info save_ccline; @@ -3364,8 +3438,9 @@ static bool cmdline_paste(int regname, bool literally, bool remcr) /* A register containing CTRL-R can cause an endless loop. Allow using * CTRL-C to break the loop. */ line_breakcheck(); - if (got_int) + if (got_int) { return FAIL; + } /* Need to save and restore ccline. And set "textlock" to avoid nasty @@ -3377,18 +3452,19 @@ static bool cmdline_paste(int regname, bool literally, bool remcr) restore_cmdline(&save_ccline); if (i) { - /* Got the value of a special register in "arg". */ - if (arg == NULL) + // Got the value of a special register in "arg". + if (arg == NULL) { return FAIL; + } - /* When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate - * part of the word. */ + // When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate + // part of the word. p = arg; if (p_is && regname == Ctrl_W) { - char_u *w; + char_u *w; int len; - /* Locate start of last word in the cmd buffer. */ + // Locate start of last word in the cmd buffer. for (w = ccline.cmdbuff + ccline.cmdpos; w > ccline.cmdbuff; ) { len = utf_head_off(ccline.cmdbuff, w - 1) + 1; if (!vim_iswordc(utf_ptr2char(w - len))) { @@ -3397,13 +3473,15 @@ static bool cmdline_paste(int regname, bool literally, bool remcr) w -= len; } len = (int)((ccline.cmdbuff + ccline.cmdpos) - w); - if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0) + if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0) { p += len; + } } cmdline_paste_str(p, literally); - if (allocated) + if (allocated) { xfree(arg); + } return OK; } @@ -3420,9 +3498,9 @@ void cmdline_paste_str(char_u *s, int literally) { int c, cv; - if (literally) + if (literally) { put_on_cmdline(s, -1, TRUE); - else + } else { while (*s != NUL) { cv = *s; if (cv == Ctrl_V && s[1]) { @@ -3436,6 +3514,7 @@ void cmdline_paste_str(char_u *s, int literally) } stuffcharReadbuff(c); } + } } /// Delete characters on the command line, from "from" to the current position. @@ -3453,8 +3532,9 @@ static void cmdline_del(int from) // overwritten. void redrawcmdline(void) { - if (cmd_silent) + if (cmd_silent) { return; + } need_wait_return = false; compute_cmdrow(); redrawcmd(); @@ -3466,8 +3546,9 @@ static void redrawcmdprompt(void) { int i; - if (cmd_silent) + if (cmd_silent) { return; + } if (ui_has(kUICmdline)) { ccline.redraw_state = kCmdRedrawAll; return; @@ -3494,15 +3575,16 @@ static void redrawcmdprompt(void) */ void redrawcmd(void) { - if (cmd_silent) + if (cmd_silent) { return; + } if (ui_has(kUICmdline)) { draw_cmdline(0, ccline.cmdlen); return; } - /* when 'incsearch' is set there may be no command line while redrawing */ + // when 'incsearch' is set there may be no command line while redrawing if (ccline.cmdbuff == NULL) { cmd_cursor_goto(cmdline_row, 0); msg_clr_eos(); @@ -3514,7 +3596,7 @@ void redrawcmd(void) msg_start(); redrawcmdprompt(); - /* Don't use more prompt, truncate the cmdline if it doesn't fit. */ + // Don't use more prompt, truncate the cmdline if it doesn't fit. msg_no_more = TRUE; draw_cmdline(0, ccline.cmdlen); msg_clr_eos(); @@ -3530,7 +3612,7 @@ void redrawcmd(void) * An emsg() before may have set msg_scroll. This is used in normal mode, * in cmdline mode we can reset them now. */ - msg_scroll = FALSE; /* next message overwrites cmdline */ + msg_scroll = FALSE; // next message overwrites cmdline // Typing ':' at the more prompt may set skip_redraw. We don't want this // in cmdline mode. @@ -3553,8 +3635,9 @@ void compute_cmdrow(void) static void cursorcmd(void) { - if (cmd_silent) + if (cmd_silent) { return; + } if (ui_has(kUICmdline)) { if (ccline.redraw_state < kCmdRedrawPos) { @@ -3642,28 +3725,27 @@ static int sort_func_compare(const void *s1, const void *s2) char_u *p1 = *(char_u **)s1; char_u *p2 = *(char_u **)s2; - if (*p1 != '<' && *p2 == '<') return -1; - if (*p1 == '<' && *p2 != '<') return 1; + if (*p1 != '<' && *p2 == '<') { + return -1; + } + if (*p1 == '<' && *p2 != '<') { + return 1; + } return STRCMP(p1, p2); } -/* - * Return FAIL if this is not an appropriate context in which to do - * completion of anything, return OK if it is (even if there are no matches). - * For the caller, this means that the character is just passed through like a - * normal character (instead of being expanded). This allows :s/^I^D etc. - */ -static int -nextwild ( - expand_T *xp, - int type, - int options, /* extra options for ExpandOne() */ - int escape /* if TRUE, escape the returned matches */ -) +/// Return FAIL if this is not an appropriate context in which to do +/// completion of anything, return OK if it is (even if there are no matches). +/// For the caller, this means that the character is just passed through like a +/// normal character (instead of being expanded). This allows :s/^I^D etc. +/// +/// @param options extra options for ExpandOne() +/// @param escape if TRUE, escape the returned matches +static int nextwild(expand_T *xp, int type, int options, int escape) { int i, j; - char_u *p1; - char_u *p2; + char_u *p1; + char_u *p2; int difflen; if (xp->xp_numfiles == -1) { @@ -3673,10 +3755,10 @@ nextwild ( if (xp->xp_context == EXPAND_UNSUCCESSFUL) { beep_flush(); - return OK; /* Something illegal on command line */ + return OK; // Something illegal on command line } if (xp->xp_context == EXPAND_NOTHING) { - /* Caller can use the character as a normal char instead */ + // Caller can use the character as a normal char instead return FAIL; } @@ -3696,12 +3778,12 @@ nextwild ( // Translate string into pattern and expand it. p1 = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context); const int use_options = ( - options - | WILD_HOME_REPLACE - | WILD_ADD_SLASH - | WILD_SILENT - | (escape ? WILD_ESCAPE : 0) - | (p_wic ? WILD_ICASE : 0)); + options + | WILD_HOME_REPLACE + | WILD_ADD_SLASH + | WILD_SILENT + | (escape ? WILD_ESCAPE : 0) + | (p_wic ? WILD_ICASE : 0)); p2 = ExpandOne(xp, p1, vim_strnsave(&ccline.cmdbuff[i], xp->xp_pattern_len), use_options, type); xfree(p1); @@ -3746,67 +3828,62 @@ nextwild ( /* When expanding a ":map" command and no matches are found, assume that * the key is supposed to be inserted literally */ - if (xp->xp_context == EXPAND_MAPPINGS && p2 == NULL) + if (xp->xp_context == EXPAND_MAPPINGS && p2 == NULL) { return FAIL; + } - if (xp->xp_numfiles <= 0 && p2 == NULL) + if (xp->xp_numfiles <= 0 && p2 == NULL) { beep_flush(); - else if (xp->xp_numfiles == 1) - /* free expanded pattern */ + } else if (xp->xp_numfiles == 1) { + // free expanded pattern (void)ExpandOne(xp, NULL, NULL, 0, WILD_FREE); + } return OK; } -/* - * Do wildcard expansion on the string 'str'. - * Chars that should not be expanded must be preceded with a backslash. - * Return a pointer to allocated memory containing the new string. - * Return NULL for failure. - * - * "orig" is the originally expanded string, copied to allocated memory. It - * should either be kept in orig_save or freed. When "mode" is WILD_NEXT or - * WILD_PREV "orig" should be NULL. - * - * Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode" - * is WILD_EXPAND_FREE or WILD_ALL. - * - * mode = WILD_FREE: just free previously expanded matches - * mode = WILD_EXPAND_FREE: normal expansion, do not keep matches - * mode = WILD_EXPAND_KEEP: normal expansion, keep matches - * mode = WILD_NEXT: use next match in multiple match, wrap to first - * mode = WILD_PREV: use previous match in multiple match, wrap to first - * mode = WILD_ALL: return all matches concatenated - * mode = WILD_LONGEST: return longest matched part - * mode = WILD_ALL_KEEP: get all matches, keep matches - * - * options = WILD_LIST_NOTFOUND: list entries without a match - * options = WILD_HOME_REPLACE: do home_replace() for buffer names - * options = WILD_USE_NL: Use '\n' for WILD_ALL - * options = WILD_NO_BEEP: Don't beep for multiple matches - * options = WILD_ADD_SLASH: add a slash after directory names - * options = WILD_KEEP_ALL: don't remove 'wildignore' entries - * options = WILD_SILENT: don't print warning messages - * options = WILD_ESCAPE: put backslash before special chars - * options = WILD_ICASE: ignore case for files - * - * The variables xp->xp_context and xp->xp_backslash must have been set! - */ -char_u * -ExpandOne ( - expand_T *xp, - char_u *str, - char_u *orig, /* allocated copy of original of expanded string */ - int options, - int mode -) +/// Do wildcard expansion on the string 'str'. +/// Chars that should not be expanded must be preceded with a backslash. +/// Return a pointer to allocated memory containing the new string. +/// Return NULL for failure. +/// +/// "orig" is the originally expanded string, copied to allocated memory. It +/// should either be kept in orig_save or freed. When "mode" is WILD_NEXT or +/// WILD_PREV "orig" should be NULL. +/// +/// Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode" +/// is WILD_EXPAND_FREE or WILD_ALL. +/// +/// mode = WILD_FREE: just free previously expanded matches +/// mode = WILD_EXPAND_FREE: normal expansion, do not keep matches +/// mode = WILD_EXPAND_KEEP: normal expansion, keep matches +/// mode = WILD_NEXT: use next match in multiple match, wrap to first +/// mode = WILD_PREV: use previous match in multiple match, wrap to first +/// mode = WILD_ALL: return all matches concatenated +/// mode = WILD_LONGEST: return longest matched part +/// mode = WILD_ALL_KEEP: get all matches, keep matches +/// +/// options = WILD_LIST_NOTFOUND: list entries without a match +/// options = WILD_HOME_REPLACE: do home_replace() for buffer names +/// options = WILD_USE_NL: Use '\n' for WILD_ALL +/// options = WILD_NO_BEEP: Don't beep for multiple matches +/// options = WILD_ADD_SLASH: add a slash after directory names +/// options = WILD_KEEP_ALL: don't remove 'wildignore' entries +/// options = WILD_SILENT: don't print warning messages +/// options = WILD_ESCAPE: put backslash before special chars +/// options = WILD_ICASE: ignore case for files +/// +/// The variables xp->xp_context and xp->xp_backslash must have been set! +/// +/// @param orig allocated copy of original of expanded string +char_u *ExpandOne(expand_T *xp, char_u *str, char_u *orig, int options, int mode) { - char_u *ss = NULL; + char_u *ss = NULL; static int findex; - static char_u *orig_save = NULL; /* kept value of orig */ + static char_u *orig_save = NULL; // kept value of orig int orig_saved = FALSE; int i; - int non_suf_match; /* number without matching suffix */ + int non_suf_match; // number without matching suffix /* * first handle the case of using an old match @@ -3814,27 +3891,31 @@ ExpandOne ( if (mode == WILD_NEXT || mode == WILD_PREV) { if (xp->xp_numfiles > 0) { if (mode == WILD_PREV) { - if (findex == -1) + if (findex == -1) { findex = xp->xp_numfiles; + } --findex; - } else /* mode == WILD_NEXT */ + } else { // mode == WILD_NEXT ++findex; + } /* * When wrapping around, return the original string, set findex to * -1. */ if (findex < 0) { - if (orig_save == NULL) + if (orig_save == NULL) { findex = xp->xp_numfiles - 1; - else + } else { findex = -1; + } } if (findex >= xp->xp_numfiles) { - if (orig_save == NULL) + if (orig_save == NULL) { findex = 0; - else + } else { findex = -1; + } } if (compl_match_array) { compl_selected = findex; @@ -3847,8 +3928,9 @@ ExpandOne ( return vim_strsave(orig_save); } return vim_strsave(xp->xp_files[findex]); - } else + } else { return NULL; + } } if (mode == WILD_CANCEL) { @@ -3858,7 +3940,7 @@ ExpandOne ( xp->xp_files[findex]); } - /* free old names */ + // free old names if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST) { FreeWild(xp->xp_numfiles, xp->xp_files); xp->xp_numfiles = -1; @@ -3866,8 +3948,9 @@ ExpandOne ( } findex = 0; - if (mode == WILD_FREE) /* only release file name */ + if (mode == WILD_FREE) { // only release file name return NULL; + } if (xp->xp_numfiles == -1 && mode != WILD_APPLY && mode != WILD_CANCEL) { xfree(orig_save); @@ -3878,20 +3961,22 @@ ExpandOne ( * Do the expansion. */ if (ExpandFromContext(xp, str, &xp->xp_numfiles, &xp->xp_files, - options) == FAIL) { + options) == FAIL) { #ifdef FNAME_ILLEGAL /* Illegal file name has been silently skipped. But when there * are wildcards, the real problem is that there was no match, * causing the pattern to be added, which has illegal characters. */ - if (!(options & WILD_SILENT) && (options & WILD_LIST_NOTFOUND)) + if (!(options & WILD_SILENT) && (options & WILD_LIST_NOTFOUND)) { EMSG2(_(e_nomatch2), str); + } #endif } else if (xp->xp_numfiles == 0) { - if (!(options & WILD_SILENT)) + if (!(options & WILD_SILENT)) { EMSG2(_(e_nomatch2), str); + } } else { - /* Escape the matches for use on the command line. */ + // Escape the matches for use on the command line. ExpandEscape(xp, str, xp->xp_numfiles, xp->xp_files, options); /* @@ -3899,10 +3984,11 @@ ExpandOne ( */ if (mode != WILD_ALL && mode != WILD_ALL_KEEP && mode != WILD_LONGEST) { - if (xp->xp_numfiles) + if (xp->xp_numfiles) { non_suf_match = xp->xp_numfiles; - else + } else { non_suf_match = 1; + } if ((xp->xp_context == EXPAND_FILES || xp->xp_context == EXPAND_DIRECTORIES) && xp->xp_numfiles > 1) { @@ -3912,9 +3998,11 @@ ExpandOne ( * expand_wildcards, only need to check the first two. */ non_suf_match = 0; - for (i = 0; i < 2; ++i) - if (match_suffix(xp->xp_files[i])) + for (i = 0; i < 2; ++i) { + if (match_suffix(xp->xp_files[i])) { ++non_suf_match; + } + } } if (non_suf_match != 1) { /* Can we ever get here unless it's while expanding @@ -3922,13 +4010,15 @@ ExpandOne ( * together. Don't really want to wait for this message * (and possibly have to hit return to continue!). */ - if (!(options & WILD_SILENT)) + if (!(options & WILD_SILENT)) { EMSG(_(e_toomany)); - else if (!(options & WILD_NO_BEEP)) + } else if (!(options & WILD_NO_BEEP)) { beep_flush(); + } } - if (!(non_suf_match != 1 && mode == WILD_EXPAND_FREE)) + if (!(non_suf_match != 1 && mode == WILD_EXPAND_FREE)) { ss = vim_strsave(xp->xp_files[0]); + } } } } @@ -3970,23 +4060,27 @@ ExpandOne ( // TODO(philix): use xstpcpy instead of strcat in a loop (ExpandOne) if (mode == WILD_ALL && xp->xp_numfiles > 0) { size_t len = 0; - for (i = 0; i < xp->xp_numfiles; ++i) + for (i = 0; i < xp->xp_numfiles; ++i) { len += STRLEN(xp->xp_files[i]) + 1; + } ss = xmalloc(len); *ss = NUL; for (i = 0; i < xp->xp_numfiles; ++i) { STRCAT(ss, xp->xp_files[i]); - if (i != xp->xp_numfiles - 1) + if (i != xp->xp_numfiles - 1) { STRCAT(ss, (options & WILD_USE_NL) ? "\n" : " "); + } } } - if (mode == WILD_EXPAND_FREE || mode == WILD_ALL) + if (mode == WILD_EXPAND_FREE || mode == WILD_ALL) { ExpandCleanup(xp); + } - /* Free "orig" if it wasn't stored in "orig_save". */ - if (!orig_saved) + // Free "orig" if it wasn't stored in "orig_save". + if (!orig_saved) { xfree(orig); + } return ss; } @@ -4016,13 +4110,14 @@ void ExpandCleanup(expand_T *xp) void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int options) { int i; - char_u *p; + char_u *p; /* * May change home directory back to "~" */ - if (options & WILD_HOME_REPLACE) + if (options & WILD_HOME_REPLACE) { tilde_replace(str, numfiles, files); + } if (options & WILD_ESCAPE) { if (xp->xp_context == EXPAND_FILES @@ -4035,7 +4130,7 @@ void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int o * and wildmatch characters, except '~'. */ for (i = 0; i < numfiles; ++i) { - /* for ":set path=" we need to escape spaces twice */ + // for ":set path=" we need to escape spaces twice if (xp->xp_backslash == XP_BS_THREE) { p = vim_strsave_escaped(files[i], (char_u *)" "); xfree(files[i]); @@ -4057,15 +4152,17 @@ void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int o /* If 'str' starts with "\~", replace "~" at start of * files[i] with "\~". */ - if (str[0] == '\\' && str[1] == '~' && files[i][0] == '~') + if (str[0] == '\\' && str[1] == '~' && files[i][0] == '~') { escape_fname(&files[i]); + } } xp->xp_backslash = XP_BS_NONE; /* If the first file starts with a '+' escape it. Otherwise it * could be seen as "+cmd". */ - if (*files[0] == '+') + if (*files[0] == '+') { escape_fname(&files[0]); + } } else if (xp->xp_context == EXPAND_TAGS) { /* * Insert a backslash before characters in a tag name that @@ -4087,12 +4184,11 @@ void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int o /// if true then it escapes for a shell command. /// /// @return [allocated] escaped file name. -char *vim_strsave_fnameescape(const char *const fname, - const bool shell FUNC_ATTR_UNUSED) +char *vim_strsave_fnameescape(const char *const fname, const bool shell FUNC_ATTR_UNUSED) FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL { #ifdef BACKSLASH_IN_FILENAME -#define PATH_ESC_CHARS " \t\n*?[{`%#'\"|!<" +# define PATH_ESC_CHARS " \t\n*?[{`%#'\"|!<" char_u buf[sizeof(PATH_ESC_CHARS)]; int j = 0; @@ -4106,10 +4202,10 @@ char *vim_strsave_fnameescape(const char *const fname, char *p = (char *)vim_strsave_escaped((const char_u *)fname, (const char_u *)buf); #else -#define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<") -#define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&") - char *p = (char *)vim_strsave_escaped( - (const char_u *)fname, (shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS)); +# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<") +# define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&") + char *p = + (char *)vim_strsave_escaped((const char_u *)fname, (shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS)); if (shell && csh_like_shell()) { // For csh and similar shells need to put two backslashes before '!'. // One is taken by Vim, one by the shell. @@ -4148,7 +4244,7 @@ static void escape_fname(char_u **pp) void tilde_replace(char_u *orig_pat, int num_files, char_u **files) { int i; - char_u *p; + char_u *p; if (orig_pat[0] == '~' && vim_ispathsep(orig_pat[1])) { for (i = 0; i < num_files; ++i) { @@ -4175,12 +4271,12 @@ static int showmatches(expand_T *xp, int wildmenu) #define L_SHOWFILE(m) (showtail \ ? sm_gettail(files_found[m], false) : files_found[m]) int num_files; - char_u **files_found; + char_u **files_found; int i, j, k; int maxlen; int lines; int columns; - char_u *p; + char_u *p; int lastlen; int attr; int showtail; @@ -4188,11 +4284,11 @@ static int showmatches(expand_T *xp, int wildmenu) if (xp->xp_numfiles == -1) { set_expand_context(xp); i = expand_cmdline(xp, ccline.cmdbuff, ccline.cmdpos, - &num_files, &files_found); + &num_files, &files_found); showtail = expand_showtail(xp); - if (i != EXPAND_OK) + if (i != EXPAND_OK) { return i; - + } } else { num_files = xp->xp_numfiles; files_found = xp->xp_files; @@ -4247,10 +4343,12 @@ static int showmatches(expand_T *xp, int wildmenu) || xp->xp_context == EXPAND_BUFFERS)) { home_replace(NULL, files_found[i], NameBuff, MAXPATHL, TRUE); j = vim_strsize(NameBuff); - } else + } else { j = vim_strsize(L_SHOWFILE(i)); - if (j > maxlen) + } + if (j > maxlen) { maxlen = j; + } } if (xp->xp_context == EXPAND_TAGS_LISTFILES) { @@ -4274,7 +4372,7 @@ static int showmatches(expand_T *xp, int wildmenu) MSG_PUTS_ATTR(_(" kind file\n"), HL_ATTR(HLF_T)); } - /* list the files line by line */ + // list the files line by line for (i = 0; i < lines; ++i) { lastlen = 999; for (k = i; k < num_files; k += lines) { @@ -4287,12 +4385,13 @@ static int showmatches(expand_T *xp, int wildmenu) msg_puts_long_attr(p + 2, HL_ATTR(HLF_D)); break; } - for (j = maxlen - lastlen; --j >= 0; ) + for (j = maxlen - lastlen; --j >= 0; ) { msg_putchar(' '); + } if (xp->xp_context == EXPAND_FILES || xp->xp_context == EXPAND_SHELLCMD || xp->xp_context == EXPAND_BUFFERS) { - /* highlight directories */ + // highlight directories if (xp->xp_numfiles != -1) { // Expansion was done before and special characters // were escaped, need to halve backslashes. Also @@ -4313,7 +4412,7 @@ static int showmatches(expand_T *xp, int wildmenu) p = L_SHOWFILE(k); } else { home_replace(NULL, files_found[k], NameBuff, MAXPATHL, - TRUE); + TRUE); p = NameBuff; } } else { @@ -4322,11 +4421,11 @@ static int showmatches(expand_T *xp, int wildmenu) } lastlen = msg_outtrans_attr(p, j ? attr : 0); } - if (msg_col > 0) { /* when not wrapped around */ + if (msg_col > 0) { // when not wrapped around msg_clr_eos(); msg_putchar('\n'); } - ui_flush(); /* show one line at a time */ + ui_flush(); // show one line at a time if (got_int) { got_int = FALSE; break; @@ -4337,11 +4436,12 @@ static int showmatches(expand_T *xp, int wildmenu) * we redraw the command below the lines that we have just listed * This is a bit tricky, but it saves a lot of screen updating. */ - cmdline_row = msg_row; /* will put it back later */ + cmdline_row = msg_row; // will put it back later } - if (xp->xp_numfiles == -1) + if (xp->xp_numfiles == -1) { FreeWild(num_files, files_found); + } return EXPAND_OK; } @@ -4352,8 +4452,8 @@ static int showmatches(expand_T *xp, int wildmenu) */ char_u *sm_gettail(char_u *s, bool eager) { - char_u *p; - char_u *t = s; + char_u *p; + char_u *t = s; int had_sep = FALSE; for (p = s; *p != NUL; ) { @@ -4383,26 +4483,29 @@ char_u *sm_gettail(char_u *s, bool eager) */ static int expand_showtail(expand_T *xp) { - char_u *s; - char_u *end; + char_u *s; + char_u *end; - /* When not completing file names a "/" may mean something different. */ + // When not completing file names a "/" may mean something different. if (xp->xp_context != EXPAND_FILES && xp->xp_context != EXPAND_SHELLCMD - && xp->xp_context != EXPAND_DIRECTORIES) + && xp->xp_context != EXPAND_DIRECTORIES) { return FALSE; + } end = path_tail(xp->xp_pattern); - if (end == xp->xp_pattern) /* there is no path separator */ + if (end == xp->xp_pattern) { // there is no path separator return FALSE; + } for (s = xp->xp_pattern; s < end; s++) { /* Skip escaped wildcards. Only when the backslash is not a path * separator, on DOS the '*' "path\*\file" must not be skipped. */ - if (rem_backslash(s)) + if (rem_backslash(s)) { ++s; - else if (vim_strchr((char_u *)"*?[", *s) != NULL) + } else if (vim_strchr((char_u *)"*?[", *s) != NULL) { return FALSE; + } } return TRUE; } @@ -4418,10 +4521,10 @@ static int expand_showtail(expand_T *xp) char_u *addstar(char_u *fname, size_t len, int context) FUNC_ATTR_NONNULL_RET { - char_u *retval; + char_u *retval; size_t i, j; size_t new_len; - char_u *tail; + char_u *tail; int ends_in_star; if (context != EXPAND_FILES @@ -4449,19 +4552,20 @@ char_u *addstar(char_u *fname, size_t len, int context) } else { new_len = len + 2; // +2 for '^' at start, NUL at end for (i = 0; i < len; i++) { - if (fname[i] == '*' || fname[i] == '~') + if (fname[i] == '*' || fname[i] == '~') { new_len++; /* '*' needs to be replaced by ".*" '~' needs to be replaced by "\~" */ - - /* Buffer names are like file names. "." should be literal */ - if (context == EXPAND_BUFFERS && fname[i] == '.') - new_len++; /* "." becomes "\." */ - + } + // Buffer names are like file names. "." should be literal + if (context == EXPAND_BUFFERS && fname[i] == '.') { + new_len++; // "." becomes "\." + } /* Custom expansion takes care of special things, match * backslashes literally (perhaps also for other types?) */ if ((context == EXPAND_USER_DEFINED - || context == EXPAND_USER_LIST) && fname[i] == '\\') - new_len++; /* '\' becomes "\\" */ + || context == EXPAND_USER_LIST) && fname[i] == '\\') { + new_len++; // '\' becomes "\\" + } } retval = xmalloc(new_len); { @@ -4473,22 +4577,30 @@ char_u *addstar(char_u *fname, size_t len, int context) if (context != EXPAND_USER_DEFINED && context != EXPAND_USER_LIST && fname[i] == '\\' - && ++i == len) + && ++i == len) { break; + } switch (fname[i]) { - case '*': retval[j++] = '.'; + case '*': + retval[j++] = '.'; break; - case '~': retval[j++] = '\\'; + case '~': + retval[j++] = '\\'; break; - case '?': retval[j] = '.'; + case '?': + retval[j] = '.'; continue; - case '.': if (context == EXPAND_BUFFERS) + case '.': + if (context == EXPAND_BUFFERS) { retval[j++] = '\\'; + } break; - case '\\': if (context == EXPAND_USER_DEFINED - || context == EXPAND_USER_LIST) + case '\\': + if (context == EXPAND_USER_DEFINED + || context == EXPAND_USER_LIST) { retval[j++] = '\\'; + } break; } retval[j] = fname[i]; @@ -4521,10 +4633,11 @@ char_u *addstar(char_u *fname, size_t len, int context) if ((*retval != '~' || tail != retval) && !ends_in_star && vim_strchr(tail, '$') == NULL - && vim_strchr(retval, '`') == NULL) + && vim_strchr(retval, '`') == NULL) { retval[len++] = '*'; - else if (len > 0 && retval[len - 1] == '$') + } else if (len > 0 && retval[len - 1] == '$') { --len; + } retval[len] = NUL; } return retval; @@ -4534,66 +4647,62 @@ char_u *addstar(char_u *fname, size_t len, int context) * Must parse the command line so far to work out what context we are in. * Completion can then be done based on that context. * This routine sets the variables: - * xp->xp_pattern The start of the pattern to be expanded within - * the command line (ends at the cursor). - * xp->xp_context The type of thing to expand. Will be one of: + * xp->xp_pattern The start of the pattern to be expanded within + * the command line (ends at the cursor). + * xp->xp_context The type of thing to expand. Will be one of: * - * EXPAND_UNSUCCESSFUL Used sometimes when there is something illegal on - * the command line, like an unknown command. Caller - * should beep. - * EXPAND_NOTHING Unrecognised context for completion, use char like - * a normal char, rather than for completion. eg - * :s/^I/ - * EXPAND_COMMANDS Cursor is still touching the command, so complete - * it. - * EXPAND_BUFFERS Complete file names for :buf and :sbuf commands. - * EXPAND_FILES After command with EX_XFILE set, or after setting - * with P_EXPAND set. eg :e ^I, :w>>^I - * EXPAND_DIRECTORIES In some cases this is used instead of the latter - * when we know only directories are of interest. eg - * :set dir=^I - * EXPAND_SHELLCMD After ":!cmd", ":r !cmd" or ":w !cmd". - * EXPAND_SETTINGS Complete variable names. eg :set d^I + * EXPAND_UNSUCCESSFUL Used sometimes when there is something illegal on + * the command line, like an unknown command. Caller + * should beep. + * EXPAND_NOTHING Unrecognised context for completion, use char like + * a normal char, rather than for completion. eg + * :s/^I/ + * EXPAND_COMMANDS Cursor is still touching the command, so complete + * it. + * EXPAND_BUFFERS Complete file names for :buf and :sbuf commands. + * EXPAND_FILES After command with EX_XFILE set, or after setting + * with P_EXPAND set. eg :e ^I, :w>>^I + * EXPAND_DIRECTORIES In some cases this is used instead of the latter + * when we know only directories are of interest. eg + * :set dir=^I + * EXPAND_SHELLCMD After ":!cmd", ":r !cmd" or ":w !cmd". + * EXPAND_SETTINGS Complete variable names. eg :set d^I * EXPAND_BOOL_SETTINGS Complete boolean variables only, eg :set no^I - * EXPAND_TAGS Complete tags from the files in p_tags. eg :ta a^I + * EXPAND_TAGS Complete tags from the files in p_tags. eg :ta a^I * EXPAND_TAGS_LISTFILES As above, but list filenames on ^D, after :tselect - * EXPAND_HELP Complete tags from the file 'helpfile'/tags - * EXPAND_EVENTS Complete event names - * EXPAND_SYNTAX Complete :syntax command arguments - * EXPAND_HIGHLIGHT Complete highlight (syntax) group names - * EXPAND_AUGROUP Complete autocommand group names - * EXPAND_USER_VARS Complete user defined variable names, eg :unlet a^I - * EXPAND_MAPPINGS Complete mapping and abbreviation names, - * eg :unmap a^I , :cunab x^I - * EXPAND_FUNCTIONS Complete internal or user defined function names, - * eg :call sub^I - * EXPAND_USER_FUNC Complete user defined function names, eg :delf F^I - * EXPAND_EXPRESSION Complete internal or user defined function/variable - * names in expressions, eg :while s^I - * EXPAND_ENV_VARS Complete environment variable names - * EXPAND_USER Complete user names + * EXPAND_HELP Complete tags from the file 'helpfile'/tags + * EXPAND_EVENTS Complete event names + * EXPAND_SYNTAX Complete :syntax command arguments + * EXPAND_HIGHLIGHT Complete highlight (syntax) group names + * EXPAND_AUGROUP Complete autocommand group names + * EXPAND_USER_VARS Complete user defined variable names, eg :unlet a^I + * EXPAND_MAPPINGS Complete mapping and abbreviation names, + * eg :unmap a^I , :cunab x^I + * EXPAND_FUNCTIONS Complete internal or user defined function names, + * eg :call sub^I + * EXPAND_USER_FUNC Complete user defined function names, eg :delf F^I + * EXPAND_EXPRESSION Complete internal or user defined function/variable + * names in expressions, eg :while s^I + * EXPAND_ENV_VARS Complete environment variable names + * EXPAND_USER Complete user names */ static void set_expand_context(expand_T *xp) { - /* only expansion for ':', '>' and '=' command-lines */ + // only expansion for ':', '>' and '=' command-lines if (ccline.cmdfirstc != ':' && ccline.cmdfirstc != '>' && ccline.cmdfirstc != '=' - && !ccline.input_fn - ) { + && !ccline.input_fn) { xp->xp_context = EXPAND_NOTHING; return; } set_cmd_context(xp, ccline.cmdbuff, ccline.cmdlen, ccline.cmdpos, true); } -void -set_cmd_context ( - expand_T *xp, - char_u *str, // start of command line - int len, // length of command line (excl. NUL) - int col, // position of cursor - int use_ccline // use ccline for info -) +/// @param str start of command line +/// @param len length of command line (excl. NUL) +/// @param col position of cursor +/// @param use_ccline use ccline for info +void set_cmd_context(expand_T *xp, char_u *str, int len, int col, int use_ccline) { char_u old_char = NUL; @@ -4601,8 +4710,9 @@ set_cmd_context ( * Avoid a UMR warning from Purify, only save the character if it has been * written before. */ - if (col < len) + if (col < len) { old_char = str[col]; + } str[col] = NUL; const char *nextcomm = (const char *)str; @@ -4627,35 +4737,31 @@ set_cmd_context ( str[col] = old_char; } -/* - * Expand the command line "str" from context "xp". - * "xp" must have been set by set_cmd_context(). - * xp->xp_pattern points into "str", to where the text that is to be expanded - * starts. - * Returns EXPAND_UNSUCCESSFUL when there is something illegal before the - * cursor. - * Returns EXPAND_NOTHING when there is nothing to expand, might insert the - * key that triggered expansion literally. - * Returns EXPAND_OK otherwise. - */ -int -expand_cmdline ( - expand_T *xp, - char_u *str, /* start of command line */ - int col, /* position of cursor */ - int *matchcount, /* return: nr of matches */ - char_u ***matches /* return: array of pointers to matches */ -) +/// Expand the command line "str" from context "xp". +/// "xp" must have been set by set_cmd_context(). +/// xp->xp_pattern points into "str", to where the text that is to be expanded +/// starts. +/// Returns EXPAND_UNSUCCESSFUL when there is something illegal before the +/// cursor. +/// Returns EXPAND_NOTHING when there is nothing to expand, might insert the +/// key that triggered expansion literally. +/// Returns EXPAND_OK otherwise. +/// +/// @param str start of command line +/// @param col position of cursor +/// @param matchcount return: nr of matches +/// @param matches return: array of pointers to matches +int expand_cmdline(expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches) { - char_u *file_str = NULL; + char_u *file_str = NULL; int options = WILD_ADD_SLASH|WILD_SILENT; if (xp->xp_context == EXPAND_UNSUCCESSFUL) { beep_flush(); - return EXPAND_UNSUCCESSFUL; /* Something illegal on command line */ + return EXPAND_UNSUCCESSFUL; // Something illegal on command line } if (xp->xp_context == EXPAND_NOTHING) { - /* Caller can use the character as a normal char instead */ + // Caller can use the character as a normal char instead return EXPAND_NOTHING; } @@ -4664,10 +4770,11 @@ expand_cmdline ( xp->xp_pattern_len = (size_t)((str + col) - xp->xp_pattern); file_str = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context); - if (p_wic) + if (p_wic) { options += WILD_ICASE; + } - /* find all files that match the description */ + // find all files that match the description if (ExpandFromContext(xp, file_str, matchcount, matches, options) == FAIL) { *matchcount = 0; *matches = NULL; @@ -4731,31 +4838,28 @@ static void cleanup_help_tags(int num_file, char_u **file) typedef char_u *(*ExpandFunc)(expand_T *, int); -/* - * Do the expansion based on xp->xp_context and "pat". - */ -static int -ExpandFromContext ( - expand_T *xp, - char_u *pat, - int *num_file, - char_u ***file, - int options // WILD_ flags -) +/// Do the expansion based on xp->xp_context and "pat". +/// +/// @param options WILD_ flags +static int ExpandFromContext(expand_T *xp, char_u *pat, int *num_file, char_u ***file, int options) { regmatch_T regmatch; int ret; int flags; - flags = EW_DIR; /* include directories */ - if (options & WILD_LIST_NOTFOUND) + flags = EW_DIR; // include directories + if (options & WILD_LIST_NOTFOUND) { flags |= EW_NOTFOUND; - if (options & WILD_ADD_SLASH) + } + if (options & WILD_ADD_SLASH) { flags |= EW_ADDSLASH; - if (options & WILD_KEEP_ALL) + } + if (options & WILD_KEEP_ALL) { flags |= EW_KEEPALL; - if (options & WILD_SILENT) + } + if (options & WILD_SILENT) { flags |= EW_SILENT; + } if (options & WILD_NOERROR) { flags |= EW_NOERROR; } @@ -4776,32 +4880,38 @@ ExpandFromContext ( if (xp->xp_backslash != XP_BS_NONE) { free_pat = TRUE; pat = vim_strsave(pat); - for (i = 0; pat[i]; ++i) + for (i = 0; pat[i]; ++i) { if (pat[i] == '\\') { if (xp->xp_backslash == XP_BS_THREE && pat[i + 1] == '\\' && pat[i + 2] == '\\' - && pat[i + 3] == ' ') + && pat[i + 3] == ' ') { STRMOVE(pat + i, pat + i + 3); + } if (xp->xp_backslash == XP_BS_ONE - && pat[i + 1] == ' ') + && pat[i + 1] == ' ') { STRMOVE(pat + i, pat + i + 1); + } } + } } - if (xp->xp_context == EXPAND_FILES) + if (xp->xp_context == EXPAND_FILES) { flags |= EW_FILE; - else if (xp->xp_context == EXPAND_FILES_IN_PATH) + } else if (xp->xp_context == EXPAND_FILES_IN_PATH) { flags |= (EW_FILE | EW_PATH); - else + } else { flags = (flags | EW_DIR) & ~EW_FILE; - if (options & WILD_ICASE) + } + if (options & WILD_ICASE) { flags |= EW_ICASE; + } - /* Expand wildcards, supporting %:h and the like. */ + // Expand wildcards, supporting %:h and the like. ret = expand_wildcards_eval(&pat, num_file, file, flags); - if (free_pat) + if (free_pat) { xfree(pat); + } #ifdef BACKSLASH_IN_FILENAME if (p_csl[0] != NUL && (options & WILD_IGNORE_COMPLETESLASH) == 0) { for (int i = 0; i < *num_file; i++) { @@ -4842,8 +4952,9 @@ ExpandFromContext ( ExpandOldSetting(num_file, file); return OK; } - if (xp->xp_context == EXPAND_BUFFERS) + if (xp->xp_context == EXPAND_BUFFERS) { return ExpandBufnames(pat, num_file, file, options); + } if (xp->xp_context == EXPAND_DIFF_BUFFERS) { return ExpandBufnames(pat, num_file, file, options | BUF_DIFF_FILTER); } @@ -4868,10 +4979,6 @@ ExpandFromContext ( char *directories[] = { "syntax", "indent", "ftplugin", NULL }; return ExpandRTDir(pat, DIP_LUA, num_file, file, directories); } - if (xp->xp_context == EXPAND_CHECKHEALTH) { - char *directories[] = { "autoload/health", NULL }; - return ExpandRTDir(pat, 0, num_file, file, directories); - } if (xp->xp_context == EXPAND_USER_LIST) { return ExpandUserList(xp, num_file, file); } @@ -4896,20 +5003,21 @@ ExpandFromContext ( } regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0); - if (regmatch.regprog == NULL) + if (regmatch.regprog == NULL) { return FAIL; + } - /* set ignore-case according to p_ic, p_scs and pat */ + // set ignore-case according to p_ic, p_scs and pat regmatch.rm_ic = ignorecase(pat); if (xp->xp_context == EXPAND_SETTINGS - || xp->xp_context == EXPAND_BOOL_SETTINGS) + || xp->xp_context == EXPAND_BOOL_SETTINGS) { ret = ExpandSettings(xp, ®match, num_file, file); - else if (xp->xp_context == EXPAND_MAPPINGS) + } else if (xp->xp_context == EXPAND_MAPPINGS) { ret = ExpandMappings(®match, num_file, file); - else if (xp->xp_context == EXPAND_USER_DEFINED) + } else if (xp->xp_context == EXPAND_USER_DEFINED) { ret = ExpandUserDefined(xp, ®match, num_file, file); - else { + } else { static struct expgen { int context; ExpandFunc func; @@ -4947,6 +5055,7 @@ ExpandFromContext ( { EXPAND_ENV_VARS, get_env_name, true, true }, { EXPAND_USER, get_users, true, false }, { EXPAND_ARGLIST, get_arglist_name, true, false }, + { EXPAND_CHECKHEALTH, get_healthcheck_names, true, false }, }; int i; @@ -4955,7 +5064,7 @@ ExpandFromContext ( * right function to do the expansion. */ ret = FAIL; - for (i = 0; i < (int)ARRAY_SIZE(tab); ++i) + for (i = 0; i < (int)ARRAY_SIZE(tab); ++i) { if (xp->xp_context == tab[i].context) { if (tab[i].ic) { regmatch.rm_ic = TRUE; @@ -4965,6 +5074,7 @@ ExpandFromContext ( ret = OK; break; } + } } vim_regfree(regmatch.regprog); @@ -4973,39 +5083,36 @@ ExpandFromContext ( return ret; } -/* - * Expand a list of names. - * - * Generic function for command line completion. It calls a function to - * obtain strings, one by one. The strings are matched against a regexp - * program. Matching strings are copied into an array, which is returned. - */ -static void ExpandGeneric( - expand_T *xp, - regmatch_T *regmatch, - int *num_file, - char_u ***file, - CompleteListItemGetter func, /* returns a string from the list */ - int escaped - ) +/// Expand a list of names. +/// +/// Generic function for command line completion. It calls a function to +/// obtain strings, one by one. The strings are matched against a regexp +/// program. Matching strings are copied into an array, which is returned. +/// +/// @param func returns a string from the list +static void ExpandGeneric(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file, + CompleteListItemGetter func, int escaped) { int i; size_t count = 0; - char_u *str; + char_u *str; // count the number of matching names for (i = 0;; ++i) { str = (*func)(xp, i); - if (str == NULL) // end of list + if (str == NULL) { // end of list break; - if (*str == NUL) // skip empty strings + } + if (*str == NUL) { // skip empty strings continue; + } if (vim_regexec(regmatch, str, (colnr_T)0)) { ++count; } } - if (count == 0) + if (count == 0) { return; + } assert(count < INT_MAX); *num_file = (int)count; *file = (char_u **)xmalloc(count * sizeof(char_u *)); @@ -5037,16 +5144,17 @@ static void ExpandGeneric( } } - /* Sort the results. Keep menu's in the specified order. */ + // Sort the results. Keep menu's in the specified order. if (xp->xp_context != EXPAND_MENUNAMES && xp->xp_context != EXPAND_MENUS) { if (xp->xp_context == EXPAND_EXPRESSION || xp->xp_context == EXPAND_FUNCTIONS - || xp->xp_context == EXPAND_USER_FUNC) - /* <SNR> functions should be sorted to the end. */ + || xp->xp_context == EXPAND_USER_FUNC) { + // <SNR> functions should be sorted to the end. qsort((void *)*file, (size_t)*num_file, sizeof(char_u *), - sort_func_compare); - else + sort_func_compare); + } else { sort_strings(*file, *num_file); + } } /* Reset the variables used for special highlight names expansion, so that @@ -5062,26 +5170,27 @@ static void ExpandGeneric( /// *file will either be set to NULL or point to /// allocated memory. /// @param flagsarg is a combination of EW_* flags. -static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, - int flagsarg) +static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, int flagsarg) FUNC_ATTR_NONNULL_ALL { - char_u *pat; + char_u *pat; int i; - char_u *path = NULL; + char_u *path = NULL; garray_T ga; char_u *buf = xmalloc(MAXPATHL); size_t l; - char_u *s, *e; + char_u *s, *e; int flags = flagsarg; int ret; bool did_curdir = false; // for ":set path=" and ":set tags=" halve backslashes for escaped space pat = vim_strsave(filepat); - for (i = 0; pat[i]; ++i) - if (pat[i] == '\\' && pat[i + 1] == ' ') + for (i = 0; pat[i]; ++i) { + if (pat[i] == '\\' && pat[i + 1] == ' ') { STRMOVE(pat + i, pat + i + 1); + } + } flags |= EW_FILE | EW_EXEC | EW_SHELLCMD; @@ -5139,7 +5248,7 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, l = STRLEN(buf); STRLCPY(buf + l, pat, MAXPATHL - l); - /* Expand matches in one directory of $PATH. */ + // Expand matches in one directory of $PATH. ret = expand_wildcards(1, &buf, num_file, file, flags); if (ret == OK) { ga_grow(&ga, *num_file); @@ -5166,8 +5275,9 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, xfree(*file); } } - if (*e != NUL) + if (*e != NUL) { ++e; + } } *file = ga.ga_data; *num_file = ga.ga_len; @@ -5182,8 +5292,8 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, /// Call "user_expand_func()" to invoke a user defined Vim script function and /// return the result (either a string, a List or NULL). -static void * call_user_expand_func(user_expand_func_T user_expand_func, - expand_T *xp, int *num_file, char_u ***file) +static void *call_user_expand_func(user_expand_func_T user_expand_func, expand_T *xp, int *num_file, + char_u ***file) FUNC_ATTR_NONNULL_ALL { char_u keep = 0; @@ -5192,8 +5302,9 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func, const sctx_T save_current_sctx = current_sctx; struct cmdline_info save_ccline; - if (xp->xp_arg == NULL || xp->xp_arg[0] == '\0' || xp->xp_line == NULL) + if (xp->xp_arg == NULL || xp->xp_arg[0] == '\0' || xp->xp_line == NULL) { return NULL; + } *num_file = 0; *file = NULL; @@ -5211,7 +5322,7 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func, args[1].vval.v_string = xp->xp_line; args[2].vval.v_number = xp->xp_col; - /* Save the cmdline, we don't know what the function may do. */ + // Save the cmdline, we don't know what the function may do. save_ccline = ccline; ccline.cmdbuff = NULL; ccline.cmdprompt = NULL; @@ -5234,11 +5345,11 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func, */ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file) { - char_u *e; - garray_T ga; + char_u *e; + garray_T ga; - char_u *const retstr = call_user_expand_func( - (user_expand_func_T)call_func_retstr, xp, num_file, file); + char_u *const retstr = call_user_expand_func((user_expand_func_T)call_func_retstr, xp, num_file, + file); if (retstr == NULL) { return FAIL; @@ -5247,13 +5358,14 @@ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file, ga_init(&ga, (int)sizeof(char *), 3); for (char_u *s = retstr; *s != NUL; s = e) { e = vim_strchr(s, '\n'); - if (e == NULL) + if (e == NULL) { e = s + STRLEN(s); + } const char_u keep = *e; *e = NUL; const bool skip = xp->xp_pattern[0] - && vim_regexec(regmatch, s, (colnr_T)0) == 0; + && vim_regexec(regmatch, s, (colnr_T)0) == 0; *e = keep; if (!skip) { GA_APPEND(char_u *, &ga, vim_strnsave(s, (size_t)(e - s))); @@ -5274,8 +5386,8 @@ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file, */ static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file) { - list_T *const retlist = call_user_expand_func( - (user_expand_func_T)call_func_retlist, xp, num_file, file); + list_T *const retlist = call_user_expand_func((user_expand_func_T)call_func_retlist, xp, num_file, + file); if (retlist == NULL) { return FAIL; } @@ -5289,8 +5401,7 @@ static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file) continue; // Skip non-string items and empty strings. } - GA_APPEND(char *, &ga, xstrdup( - (const char *)TV_LIST_ITEM_TV(li)->vval.v_string)); + GA_APPEND(char *, &ga, xstrdup((const char *)TV_LIST_ITEM_TV(li)->vval.v_string)); }); tv_list_unref(retlist); @@ -5308,8 +5419,7 @@ static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file) /// 'packpath'/pack/ * /opt/ * /{dirnames}/{pat}.vim /// When "flags" has DIP_LUA: search also performed for .lua files /// "dirnames" is an array with one or more directory names. -static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file, - char *dirnames[]) +static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file, char *dirnames[]) { *num_file = 0; *file = NULL; @@ -5403,8 +5513,9 @@ static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file, } } - if (GA_EMPTY(&ga)) + if (GA_EMPTY(&ga)) { return FAIL; + } /* Sort and remove duplicates which can happen when specifying multiple * directories in dirnames. */ @@ -5497,7 +5608,7 @@ void globpath(char_u *path, char_u *file, garray_T *ga, int expand_options) /********************************* -* Command line history stuff * +* Command line history stuff * *********************************/ /// Translate a history character to the associated type number @@ -5505,26 +5616,20 @@ static HistoryType hist_char2type(const int c) FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT { switch (c) { - case ':': { - return HIST_CMD; - } - case '=': { - return HIST_EXPR; - } - case '@': { - return HIST_INPUT; - } - case '>': { - return HIST_DEBUG; - } - case NUL: - case '/': - case '?': { - return HIST_SEARCH; - } - default: { - return HIST_INVALID; - } + case ':': + return HIST_CMD; + case '=': + return HIST_EXPR; + case '@': + return HIST_INPUT; + case '>': + return HIST_DEBUG; + case NUL: + case '/': + case '?': + return HIST_SEARCH; + default: + return HIST_INVALID; } // Silence -Wreturn-type return 0; @@ -5561,10 +5666,12 @@ static char_u *get_history_arg(expand_T *xp, int idx) compl[0] = (char_u)short_names[idx]; return compl; } - if (idx < short_names_count + history_name_count) + if (idx < short_names_count + history_name_count) { return (char_u *)history_names[idx - short_names_count]; - if (idx == short_names_count + history_name_count) + } + if (idx == short_names_count + history_name_count) { return (char_u *)"all"; + } return NULL; } @@ -5642,49 +5749,48 @@ static inline void clear_hist_entry(histentry_T *hisptr) memset(hisptr, 0, sizeof(*hisptr)); } -/* - * Check if command line 'str' is already in history. - * If 'move_to_front' is TRUE, matching entry is moved to end of history. - */ -static int -in_history ( - int type, - char_u *str, - int move_to_front, // Move the entry to the front if it exists - int sep -) +/// Check if command line 'str' is already in history. +/// If 'move_to_front' is TRUE, matching entry is moved to end of history. +/// +/// @param move_to_front Move the entry to the front if it exists +static int in_history(int type, char_u *str, int move_to_front, int sep) { int i; int last_i = -1; - char_u *p; + char_u *p; - if (hisidx[type] < 0) + if (hisidx[type] < 0) { return FALSE; + } i = hisidx[type]; do { - if (history[type][i].hisstr == NULL) + if (history[type][i].hisstr == NULL) { return FALSE; + } /* For search history, check that the separator character matches as * well. */ p = history[type][i].hisstr; if (STRCMP(str, p) == 0 && (type != HIST_SEARCH || sep == p[STRLEN(p) + 1])) { - if (!move_to_front) + if (!move_to_front) { return TRUE; + } last_i = i; break; } - if (--i < 0) + if (--i < 0) { i = hislen - 1; + } } while (i != hisidx[type]); if (last_i >= 0) { list_T *const list = history[type][i].additional_elements; str = history[type][i].hisstr; while (i != hisidx[type]) { - if (++i >= hislen) + if (++i >= hislen) { i = 0; + } history[type][last_i] = history[type][i]; last_i = i; } @@ -5710,8 +5816,7 @@ in_history ( /// /// @return Any value from HistoryType enum, including HIST_INVALID. May not /// return HIST_DEFAULT unless return_default is true. -HistoryType get_histtype(const char *const name, const size_t len, - const bool return_default) +HistoryType get_histtype(const char *const name, const size_t len, const bool return_default) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { // No argument: use current history. @@ -5732,7 +5837,7 @@ HistoryType get_histtype(const char *const name, const size_t len, return HIST_INVALID; } -static int last_maptick = -1; /* last seen maptick */ +static int last_maptick = -1; // last seen maptick /// Add the given string to the given history. If the string is already in the /// history then it is moved to the front. "histype" may be one of he HIST_ @@ -5749,8 +5854,9 @@ void add_to_history(int histype, char_u *new_entry, int in_map, int sep) } assert(histype != HIST_DEFAULT); - if (cmdmod.keeppatterns && histype == HIST_SEARCH) + if (cmdmod.keeppatterns && histype == HIST_SEARCH) { return; + } /* * Searches inside the same mapping overwrite each other, so that only @@ -5763,14 +5869,16 @@ void add_to_history(int histype, char_u *new_entry, int in_map, int sep) hisptr = &history[HIST_SEARCH][hisidx[HIST_SEARCH]]; hist_free_entry(hisptr); --hisnum[histype]; - if (--hisidx[HIST_SEARCH] < 0) + if (--hisidx[HIST_SEARCH] < 0) { hisidx[HIST_SEARCH] = hislen - 1; + } } last_maptick = -1; } if (!in_history(histype, new_entry, true, sep)) { - if (++hisidx[histype] == hislen) + if (++hisidx[histype] == hislen) { hisidx[histype] = 0; + } hisptr = &history[histype][hisidx[histype]]; hist_free_entry(hisptr); @@ -5782,8 +5890,9 @@ void add_to_history(int histype, char_u *new_entry, int in_map, int sep) hisptr->hisstr[len + 1] = (char_u)sep; hisptr->hisnum = ++hisnum[histype]; - if (histype == HIST_SEARCH && in_map) + if (histype == HIST_SEARCH && in_map) { last_maptick = maptick; + } } } @@ -5795,8 +5904,9 @@ void add_to_history(int histype, char_u *new_entry, int in_map, int sep) int get_history_idx(int histype) { if (hislen == 0 || histype < 0 || histype >= HIST_COUNT - || hisidx[histype] < 0) + || hisidx[histype] < 0) { return -1; + } return history[histype][hisidx[histype]].hisnum; } @@ -5831,8 +5941,9 @@ char_u *get_cmdline_str(void) } struct cmdline_info *p = get_ccline_ptr(); - if (p == NULL) + if (p == NULL) { return NULL; + } return vim_strnsave(p->cmdbuff, (size_t)p->cmdlen); } @@ -5846,8 +5957,9 @@ int get_cmdline_pos(void) { struct cmdline_info *p = get_ccline_ptr(); - if (p == NULL) + if (p == NULL) { return -1; + } return p->cmdpos; } @@ -5860,15 +5972,17 @@ int set_cmdline_pos(int pos) { struct cmdline_info *p = get_ccline_ptr(); - if (p == NULL) + if (p == NULL) { return 1; + } - /* The position is not set directly but after CTRL-\ e or CTRL-R = has - * changed the command line. */ - if (pos < 0) + // The position is not set directly but after CTRL-\ e or CTRL-R = has + // changed the command line. + if (pos < 0) { new_cmdpos = 0; - else + } else { new_cmdpos = pos; + } return 0; } @@ -5882,10 +5996,12 @@ int get_cmdline_type(void) { struct cmdline_info *p = get_ccline_ptr(); - if (p == NULL) + if (p == NULL) { return NUL; - if (p->cmdfirstc == NUL) + } + if (p->cmdfirstc == NUL) { return (p->input_fn) ? '@' : '-'; + } return p->cmdfirstc; } @@ -5902,26 +6018,32 @@ static int calc_hist_idx(int histype, int num) int wrapped = FALSE; if (hislen == 0 || histype < 0 || histype >= HIST_COUNT - || (i = hisidx[histype]) < 0 || num == 0) + || (i = hisidx[histype]) < 0 || num == 0) { return -1; + } hist = history[histype]; if (num > 0) { - while (hist[i].hisnum > num) + while (hist[i].hisnum > num) { if (--i < 0) { - if (wrapped) + if (wrapped) { break; + } i += hislen; wrapped = TRUE; } - if (hist[i].hisnum == num && hist[i].hisstr != NULL) + } + if (hist[i].hisnum == num && hist[i].hisstr != NULL) { return i; - } else if (-num <= hislen) { + } + } else if (-num <= hislen) { i += num + 1; - if (i < 0) + if (i < 0) { i += hislen; - if (hist[i].hisstr != NULL) + } + if (hist[i].hisstr != NULL) { return i; + } } return -1; } @@ -5933,10 +6055,11 @@ static int calc_hist_idx(int histype, int num) char_u *get_history_entry(int histype, int idx) { idx = calc_hist_idx(histype, idx); - if (idx >= 0) + if (idx >= 0) { return history[histype][idx].hisstr; - else + } else { return (char_u *)""; + } } /// Clear all entries in a history @@ -5973,7 +6096,7 @@ int del_history_entry(int histype, char_u *str) bool found = false; regmatch.regprog = NULL; - regmatch.rm_ic = FALSE; /* always match case */ + regmatch.rm_ic = FALSE; // always match case if (hislen != 0 && histype >= 0 && histype < HIST_COUNT @@ -5984,8 +6107,9 @@ int del_history_entry(int histype, char_u *str) i = last = idx; do { hisptr = &history[histype][i]; - if (hisptr->hisstr == NULL) + if (hisptr->hisstr == NULL) { break; + } if (vim_regexec(®match, hisptr->hisstr, (colnr_T)0)) { found = true; hist_free_entry(hisptr); @@ -5994,14 +6118,17 @@ int del_history_entry(int histype, char_u *str) history[histype][last] = *hisptr; clear_hist_entry(hisptr); } - if (--last < 0) + if (--last < 0) { last += hislen; + } } - if (--i < 0) + if (--i < 0) { i += hislen; + } } while (i != idx); - if (history[histype][idx].hisstr == NULL) + if (history[histype][idx].hisstr == NULL) { hisidx[histype] = -1; + } } vim_regfree(regmatch.regprog); return found; @@ -6016,16 +6143,18 @@ int del_history_idx(int histype, int idx) int i, j; i = calc_hist_idx(histype, idx); - if (i < 0) + if (i < 0) { return FALSE; + } idx = hisidx[histype]; hist_free_entry(&history[histype][i]); /* When deleting the last added search string in a mapping, reset * last_maptick, so that the last added search string isn't deleted again. */ - if (histype == HIST_SEARCH && maptick == last_maptick && i == idx) + if (histype == HIST_SEARCH && maptick == last_maptick && i == idx) { last_maptick = -1; + } while (i != idx) { j = (i + 1) % hislen; @@ -6089,8 +6218,8 @@ void ex_history(exarg_T *eap) int hisidx2 = -1; int idx; int i, j, k; - char_u *end; - char_u *arg = eap->arg; + char_u *end; + char_u *arg = eap->arg; if (hislen == 0) { MSG(_("'history' option is zero")); @@ -6100,8 +6229,9 @@ void ex_history(exarg_T *eap) if (!(ascii_isdigit(*arg) || *arg == '-' || *arg == ',')) { end = arg; while (ASCII_ISALPHA(*end) - || vim_strchr((char_u *)":=@>/?", *end) != NULL) + || vim_strchr((char_u *)":=@>/?", *end) != NULL) { end++; + } histype1 = get_histtype((const char *)arg, (size_t)(end - arg), false); if (histype1 == HIST_INVALID) { if (STRNICMP(arg, "all", end - arg) == 0) { @@ -6111,8 +6241,9 @@ void ex_history(exarg_T *eap) EMSG(_(e_trailing)); return; } - } else + } else { histype2 = histype1; + } } else { end = arg; } @@ -6130,14 +6261,17 @@ void ex_history(exarg_T *eap) hist = history[histype1]; j = hisidx1; k = hisidx2; - if (j < 0) + if (j < 0) { j = (-j > hislen) ? 0 : hist[(hislen+j+idx+1) % hislen].hisnum; - if (k < 0) + } + if (k < 0) { k = (-k > hislen) ? 0 : hist[(hislen+k+idx+1) % hislen].hisnum; - if (idx >= 0 && j <= k) + } + if (idx >= 0 && j <= k) { for (i = idx + 1; !got_int; ++i) { - if (i == hislen) + if (i == hislen) { i = 0; + } if (hist[i].hisstr != NULL && hist[i].hisnum >= j && hist[i].hisnum <= k) { msg_putchar('\n'); @@ -6152,9 +6286,11 @@ void ex_history(exarg_T *eap) msg_outtrans(IObuff); ui_flush(); } - if (i == idx) + if (i == idx) { break; + } } + } } } @@ -6163,24 +6299,18 @@ int hist_type2char(int type) FUNC_ATTR_CONST { switch (type) { - case HIST_CMD: { - return ':'; - } - case HIST_SEARCH: { - return '/'; - } - case HIST_EXPR: { - return '='; - } - case HIST_INPUT: { - return '@'; - } - case HIST_DEBUG: { - return '>'; - } - default: { - abort(); - } + case HIST_CMD: + return ':'; + case HIST_SEARCH: + return '/'; + case HIST_EXPR: + return '='; + case HIST_INPUT: + return '@'; + case HIST_DEBUG: + return '>'; + default: + abort(); } return NUL; } @@ -6194,10 +6324,10 @@ int hist_type2char(int type) static int open_cmdwin(void) { struct cmdline_info save_ccline; - bufref_T old_curbuf; - bufref_T bufref; - win_T *old_curwin = curwin; - win_T *wp; + bufref_T old_curbuf; + bufref_T bufref; + win_T *old_curwin = curwin; + win_T *wp; int i; linenr_T lnum; garray_T winsizes; @@ -6207,10 +6337,9 @@ static int open_cmdwin(void) bool save_exmode = exmode_active; int save_cmdmsg_rl = cmdmsg_rl; - /* Can't do this recursively. Can't do it when typing a password. */ + // Can't do this recursively. Can't do it when typing a password. if (cmdwin_type != 0 - || cmdline_star > 0 - ) { + || cmdline_star > 0) { beep_flush(); return K_IGNORE; } @@ -6272,8 +6401,9 @@ static int open_cmdwin(void) if (i >= 0) { lnum = 0; do { - if (++i == hislen) + if (++i == hislen) { i = 0; + } if (history[histtype][i].hisstr != NULL) { ml_append(lnum++, history[histtype][i].hisstr, (colnr_T)0, false); } @@ -6341,16 +6471,17 @@ static int open_cmdwin(void) exmode_active = save_exmode; - /* Safety check: The old window or buffer was deleted: It's a bug when - * this happens! */ + // Safety check: The old window or buffer was deleted: It's a bug when + // this happens! if (!win_valid(old_curwin) || !bufref_valid(&old_curbuf)) { cmdwin_result = Ctrl_C; EMSG(_("E199: Active window or buffer deleted")); } else { - /* autocmds may abort script processing */ - if (aborting() && cmdwin_result != K_IGNORE) + // autocmds may abort script processing + if (aborting() && cmdwin_result != K_IGNORE) { cmdwin_result = Ctrl_C; - /* Set the new command line from the cmdline buffer. */ + } + // Set the new command line from the cmdline buffer. xfree(ccline.cmdbuff); if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) { // :qa[!] typed const char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!"; @@ -6367,11 +6498,12 @@ static int open_cmdwin(void) stuffcharReadbuff(CAR); } } else if (cmdwin_result == Ctrl_C) { - /* :q or :close, don't execute any command - * and don't modify the cmd window. */ + // :q or :close, don't execute any command + // and don't modify the cmd window. ccline.cmdbuff = NULL; - } else + } else { ccline.cmdbuff = vim_strsave(get_cursor_line_ptr()); + } if (ccline.cmdbuff == NULL) { ccline.cmdbuff = vim_strsave((char_u *)""); ccline.cmdlen = 0; @@ -6382,8 +6514,9 @@ static int open_cmdwin(void) ccline.cmdlen = (int)STRLEN(ccline.cmdbuff); ccline.cmdbufflen = ccline.cmdlen + 1; ccline.cmdpos = curwin->w_cursor.col; - if (ccline.cmdpos > ccline.cmdlen) + if (ccline.cmdpos > ccline.cmdlen) { ccline.cmdpos = ccline.cmdlen; + } if (cmdwin_result == K_IGNORE) { ccline.cmdspos = cmd_screencol(ccline.cmdpos); redrawcmd(); @@ -6449,13 +6582,12 @@ char *script_get(exarg_T *const eap, size_t *const lenp) } const char *const end_pattern = ( - cmd[2] != NUL + cmd[2] != NUL ? (const char *)skipwhite((const char_u *)cmd + 2) : "."); for (;;) { - char *const theline = (char *)eap->getline( - eap->cstack->cs_looplevel > 0 ? -1 : - NUL, eap->cookie, 0, true); + char *const theline = (char *)eap->getline(eap->cstack->cs_looplevel > 0 ? -1 : + NUL, eap->cookie, 0, true); if (theline == NULL || strcmp(end_pattern, theline) == 0) { xfree(theline); @@ -6463,7 +6595,7 @@ char *script_get(exarg_T *const eap, size_t *const lenp) } if (!eap->skip) { - ga_concat(&ga, (const char_u *)theline); + ga_concat(&ga, theline); ga_append(&ga, '\n'); } xfree(theline); @@ -6497,8 +6629,8 @@ char *script_get(exarg_T *const eap, size_t *const lenp) /// /// @return Pointer used in next iteration or NULL to indicate that iteration /// was finished. -const void *hist_iter(const void *const iter, const uint8_t history_type, - const bool zero, histentry_T *const hist) +const void *hist_iter(const void *const iter, const uint8_t history_type, const bool zero, + histentry_T *const hist) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(4) { *hist = (histentry_T) { @@ -6509,7 +6641,7 @@ const void *hist_iter(const void *const iter, const uint8_t history_type, } histentry_T *const hstart = &(history[history_type][0]); histentry_T *const hlast = ( - &(history[history_type][hisidx[history_type]])); + &(history[history_type][hisidx[history_type]])); const histentry_T *const hend = &(history[history_type][hislen - 1]); histentry_T *hiter; if (iter == NULL) { @@ -6525,7 +6657,7 @@ const void *hist_iter(const void *const iter, const uint8_t history_type, } while (hfirst != hlast); hiter = hfirst; } else { - hiter = (histentry_T *) iter; + hiter = (histentry_T *)iter; } if (hiter == NULL) { return NULL; @@ -6538,7 +6670,7 @@ const void *hist_iter(const void *const iter, const uint8_t history_type, return NULL; } hiter++; - return (const void *) ((hiter > hend) ? hstart : hiter); + return (const void *)((hiter > hend) ? hstart : hiter); } /// Get array of history items diff --git a/src/nvim/ex_getln.h b/src/nvim/ex_getln.h index 3727aa5e62..fe2bf958b5 100644 --- a/src/nvim/ex_getln.h +++ b/src/nvim/ex_getln.h @@ -7,7 +7,7 @@ #include "nvim/os/time.h" #include "nvim/regexp_defs.h" -/* Values for nextwild() and ExpandOne(). See ExpandOne() for meaning. */ +// Values for nextwild() and ExpandOne(). See ExpandOne() for meaning. #define WILD_FREE 1 #define WILD_EXPAND_FREE 2 #define WILD_EXPAND_KEEP 3 diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c index 3038ed3947..0dfd7e1edd 100644 --- a/src/nvim/ex_session.c +++ b/src/nvim/ex_session.c @@ -8,13 +8,11 @@ // :mksession #include <assert.h> -#include <string.h> +#include <inttypes.h> #include <stdbool.h> #include <stdlib.h> -#include <inttypes.h> +#include <string.h> -#include "nvim/vim.h" -#include "nvim/globals.h" #include "nvim/ascii.h" #include "nvim/buffer.h" #include "nvim/cursor.h" @@ -28,6 +26,7 @@ #include "nvim/fileio.h" #include "nvim/fold.h" #include "nvim/getchar.h" +#include "nvim/globals.h" #include "nvim/keymap.h" #include "nvim/misc1.h" #include "nvim/move.h" @@ -36,6 +35,7 @@ #include "nvim/os/os.h" #include "nvim/os/time.h" #include "nvim/path.h" +#include "nvim/vim.h" #include "nvim/window.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -63,7 +63,7 @@ static int put_view_curpos(FILE *fd, const win_T *wp, char *spaces) static int ses_winsizes(FILE *fd, int restore_size, win_T *tab_firstwin) { int n = 0; - win_T *wp; + win_T *wp; if (restore_size && (ssop_flags & SSOP_WINSIZE)) { for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) { @@ -105,7 +105,7 @@ static int ses_winsizes(FILE *fd, int restore_size, win_T *tab_firstwin) // Returns FAIL when writing the commands to "fd" fails. static int ses_win_rec(FILE *fd, frame_T *fr) { - frame_T *frc; + frame_T *frc; int count = 0; if (fr->fr_layout != FR_LEAF) { @@ -149,7 +149,7 @@ static int ses_win_rec(FILE *fd, frame_T *fr) // Returns NULL when there none. static frame_T *ses_skipframe(frame_T *fr) { - frame_T *frc; + frame_T *frc; FOR_ALL_FRAMES(frc, fr) { if (ses_do_frame(frc)) { @@ -200,11 +200,10 @@ static int ses_do_win(win_T *wp) /// @param flagp /// /// @returns FAIL if writing fails. -static int ses_arglist(FILE *fd, char *cmd, garray_T *gap, int fullname, - unsigned *flagp) +static int ses_arglist(FILE *fd, char *cmd, garray_T *gap, int fullname, unsigned *flagp) { - char_u *buf = NULL; - char_u *s; + char_u *buf = NULL; + char_u *s; if (fprintf(fd, "%s\n%s\n", cmd, "%argdel") < 0) { return FAIL; @@ -297,17 +296,15 @@ static int ses_put_fname(FILE *fd, char_u *name, unsigned *flagp) return retval; } -// Write commands to "fd" to restore the view of a window. -// Caller must make sure 'scrolloff' is zero. -static int put_view( - FILE *fd, - win_T *wp, - int add_edit, // add ":edit" command to view - unsigned *flagp, // vop_flags or ssop_flags - int current_arg_idx // current argument index of the window, use -) // -1 if unknown +/// Write commands to "fd" to restore the view of a window. +/// Caller must make sure 'scrolloff' is zero. +/// +/// @param add_edit add ":edit" command to view +/// @param flagp vop_flags or ssop_flags +/// @param current_arg_idx current argument index of the window, use -1 if unknown +static int put_view(FILE *fd, win_T *wp, int add_edit, unsigned *flagp, int current_arg_idx) { - win_T *save_curwin; + win_T *save_curwin; int f; int do_cursor; int did_next = false; @@ -348,8 +345,8 @@ static int put_view( // Load the file. // if (wp->w_buffer->b_ffname != NULL - && (!bt_nofile(wp->w_buffer) || wp->w_buffer->terminal) - ) { + && (!bt_nofile(wp->w_buffer) || + wp->w_buffer->terminal)) { // Editing a file in this buffer: use ":edit file". // This may have side effects! (e.g., compressed or network file). // @@ -434,8 +431,8 @@ static int put_view( // if ((*flagp & SSOP_FOLDS) && wp->w_buffer->b_ffname != NULL - && (bt_normal(wp->w_buffer) || bt_help(wp->w_buffer)) - ) { + && (bt_normal(wp->w_buffer) || + bt_help(wp->w_buffer))) { if (put_folds(fd, wp) == FAIL) { return FAIL; } @@ -453,11 +450,11 @@ static int put_view( } } else if (fprintf(fd, "let s:l = %" PRIdLINENR " - ((%" PRIdLINENR - " * winheight(0) + %" PRId64 ") / %" PRId64 ")\n", + " * winheight(0) + %d) / %d)\n", wp->w_cursor.lnum, wp->w_cursor.lnum - wp->w_topline, - (int64_t)(wp->w_height_inner / 2), - (int64_t)wp->w_height_inner) < 0) { + (wp->w_height_inner / 2), + wp->w_height_inner) < 0) { return FAIL; } if (fprintf(fd, @@ -525,12 +522,12 @@ static int makeopens(FILE *fd, char_u *dirnow) int only_save_windows = true; int nr; int restore_size = true; - win_T *wp; - char_u *sname; - win_T *edited_win = NULL; + win_T *wp; + char_u *sname; + win_T *edited_win = NULL; int tabnr; - win_T *tab_firstwin; - frame_T *tab_topframe; + win_T *tab_firstwin; + frame_T *tab_topframe; int cur_arg_idx = 0; int next_arg_idx = 0; @@ -658,8 +655,7 @@ static int makeopens(FILE *fd, char_u *dirnow) if (ses_do_win(wp) && wp->w_buffer->b_ffname != NULL && !bt_help(wp->w_buffer) - && !bt_nofile(wp->w_buffer) - ) { + && !bt_nofile(wp->w_buffer)) { if (need_tabnext && put_line(fd, "tabnext") == FAIL) { return FAIL; } @@ -863,7 +859,7 @@ void ex_loadview(exarg_T *eap) { char *fname = get_view_file(*eap->arg); if (fname != NULL) { - if (do_source((char_u *)fname, false, DOSO_NONE) == FAIL) { + if (do_source(fname, false, DOSO_NONE) == FAIL) { EMSG2(_(e_notopen), fname); } xfree(fname); @@ -877,12 +873,12 @@ void ex_loadview(exarg_T *eap) /// - SSOP_SLASH: filenames are written with "/" slash void ex_mkrc(exarg_T *eap) { - FILE *fd; + FILE *fd; int failed = false; int view_session = false; // :mkview, :mksession int using_vdir = false; // using 'viewdir'? char *viewFile = NULL; - unsigned *flagp; + unsigned *flagp; if (eap->cmdidx == CMD_mksession || eap->cmdidx == CMD_mkview) { view_session = true; @@ -967,7 +963,7 @@ void ex_mkrc(exarg_T *eap) *dirnow = NUL; } if (*dirnow != NUL && (ssop_flags & SSOP_SESDIR)) { - if (vim_chdirfile((char_u *)fname) == OK) { + if (vim_chdirfile((char_u *)fname, kCdCauseOther) == OK) { shorten_fnames(true); } } else if (*dirnow != NUL diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index b4f22dbf33..dc73e34111 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -29,19 +29,20 @@ // code for redrawing the line with the deleted decoration. #include <assert.h> + #include "nvim/api/vim.h" -#include "nvim/vim.h" +#include "nvim/buffer.h" +#include "nvim/buffer_updates.h" #include "nvim/charset.h" -#include "nvim/extmark.h" #include "nvim/decoration.h" -#include "nvim/buffer_updates.h" -#include "nvim/memline.h" -#include "nvim/pos.h" +#include "nvim/extmark.h" #include "nvim/globals.h" -#include "nvim/map.h" #include "nvim/lib/kbtree.h" +#include "nvim/map.h" +#include "nvim/memline.h" +#include "nvim/pos.h" #include "nvim/undo.h" -#include "nvim/buffer.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "extmark.c.generated.h" @@ -55,16 +56,16 @@ static ExtmarkNs *buf_ns_ref(buf_T *buf, uint64_t ns_id, bool put) { /// Create or update an extmark /// /// must not be used during iteration! -/// @returns the mark id -uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t id, - int row, colnr_T col, int end_row, colnr_T end_col, - Decoration *decor, bool right_gravity, - bool end_right_gravity, ExtmarkOp op) +/// @returns the internal mark id +uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t *idp, int row, colnr_T col, int end_row, + colnr_T end_col, Decoration *decor, bool right_gravity, bool end_right_gravity, + ExtmarkOp op) { ExtmarkNs *ns = buf_ns_ref(buf, ns_id, true); assert(ns != NULL); mtpos_t old_pos; uint64_t mark = 0; + uint64_t id = idp ? *idp : 0; if (id == 0) { id = ns->free_id++; @@ -118,7 +119,11 @@ revised: if (decor) { decor_redraw(buf, row, end_row > -1 ? end_row : row, decor); } - return id; + + if (idp) { + *idp = id; + } + return mark; } static bool extmark_setraw(buf_T *buf, uint64_t mark, int row, colnr_T col) @@ -169,6 +174,10 @@ bool extmark_del(buf_T *buf, uint64_t ns_id, uint64_t id) decor_free(item.decor); } + if (mark == buf->b_virt_line_mark) { + clear_virt_lines(buf, pos.row); + } + map_del(uint64_t, uint64_t)(ns->map, id); map_del(uint64_t, ExtmarkItem)(buf->b_extmark_index, mark); @@ -178,9 +187,7 @@ bool extmark_del(buf_T *buf, uint64_t ns_id, uint64_t id) // Free extmarks in a ns between lines // if ns = 0, it means clear all namespaces -bool extmark_clear(buf_T *buf, uint64_t ns_id, - int l_row, colnr_T l_col, - int u_row, colnr_T u_col) +bool extmark_clear(buf_T *buf, uint64_t ns_id, int l_row, colnr_T l_col, int u_row, colnr_T u_col) { if (!map_size(buf->b_extmark_ns)) { return false; @@ -229,6 +236,9 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id, } uint64_t start_id = mark.id & ~MARKTREE_END_FLAG; + if (start_id == buf->b_virt_line_mark) { + clear_virt_lines(buf, mark.row); + } ExtmarkItem item = map_get(uint64_t, ExtmarkItem)(buf->b_extmark_index, start_id); @@ -281,10 +291,8 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id, // will be searched to the start, or end // dir can be set to control the order of the array // amount = amount of marks to find or -1 for all -ExtmarkInfoArray extmark_get(buf_T *buf, uint64_t ns_id, - int l_row, colnr_T l_col, - int u_row, colnr_T u_col, - int64_t amount, bool reverse) +ExtmarkInfoArray extmark_get(buf_T *buf, uint64_t ns_id, int l_row, colnr_T l_col, int u_row, + colnr_T u_col, int64_t amount, bool reverse) { ExtmarkInfoArray array = KV_INITIAL_VALUE; MarkTreeIter itr[1]; @@ -394,10 +402,9 @@ void extmark_free_all(buf_T *buf) // Save info for undo/redo of set marks -static void u_extmark_set(buf_T *buf, uint64_t mark, - int row, colnr_T col) +static void u_extmark_set(buf_T *buf, uint64_t mark, int row, colnr_T col) { - u_header_T *uhp = u_force_get_undo_header(buf); + u_header_T *uhp = u_force_get_undo_header(buf); if (!uhp) { return; } @@ -419,11 +426,9 @@ static void u_extmark_set(buf_T *buf, uint64_t mark, /// /// useful when we cannot simply reverse the operation. This will do nothing on /// redo, enforces correct position when undo. -void u_extmark_copy(buf_T *buf, - int l_row, colnr_T l_col, - int u_row, colnr_T u_col) +void u_extmark_copy(buf_T *buf, int l_row, colnr_T l_col, int u_row, colnr_T u_col) { - u_header_T *uhp = u_force_get_undo_header(buf); + u_header_T *uhp = u_force_get_undo_header(buf); if (!uhp) { return; } @@ -467,7 +472,6 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo) splice.new_row, splice.new_col, splice.new_byte, splice.old_row, splice.old_col, splice.old_byte, kExtmarkNoUndo); - } else { extmark_splice_impl(curbuf, splice.start_row, splice.start_col, splice.start_byte, @@ -475,14 +479,14 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo) splice.new_row, splice.new_col, splice.new_byte, kExtmarkNoUndo); } - // kExtmarkSavePos + // kExtmarkSavePos } else if (undo_info.type == kExtmarkSavePos) { ExtmarkSavePos pos = undo_info.data.savepos; if (undo) { if (pos.old_row >= 0) { extmark_setraw(curbuf, pos.mark, pos.old_row, pos.old_col); } - // Redo + // Redo } else { if (pos.row >= 0) { extmark_setraw(curbuf, pos.mark, pos.row, pos.col); @@ -504,15 +508,12 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo) kExtmarkNoUndo); } } + curbuf->b_virt_line_pos = -1; } // Adjust extmark row for inserted/deleted rows (columns stay fixed). -void extmark_adjust(buf_T *buf, - linenr_T line1, - linenr_T line2, - long amount, - long amount_after, +void extmark_adjust(buf_T *buf, linenr_T line1, linenr_T line2, long amount, long amount_after, ExtmarkOp undo) { if (curbuf_splice_pending) { @@ -537,7 +538,7 @@ void extmark_adjust(buf_T *buf, } if (new_row > 0) { new_byte = ml_find_line_or_offset(buf, line1+new_row, NULL, true) - - start_byte; + - start_byte; } extmark_splice_impl(buf, (int)line1-1, 0, start_byte, @@ -562,10 +563,8 @@ void extmark_adjust(buf_T *buf, // the end column of the new region. // @param new_byte Byte extent of the new region. // @param undo -void extmark_splice(buf_T *buf, - int start_row, colnr_T start_col, - int old_row, colnr_T old_col, bcount_t old_byte, - int new_row, colnr_T new_col, bcount_t new_byte, +void extmark_splice(buf_T *buf, int start_row, colnr_T start_col, int old_row, colnr_T old_col, + bcount_t old_byte, int new_row, colnr_T new_col, bcount_t new_byte, ExtmarkOp undo) { long offset = ml_find_line_or_offset(buf, start_row + 1, NULL, true); @@ -584,13 +583,12 @@ void extmark_splice(buf_T *buf, undo); } -void extmark_splice_impl(buf_T *buf, - int start_row, colnr_T start_col, bcount_t start_byte, - int old_row, colnr_T old_col, bcount_t old_byte, - int new_row, colnr_T new_col, bcount_t new_byte, - ExtmarkOp undo) +void extmark_splice_impl(buf_T *buf, int start_row, colnr_T start_col, bcount_t start_byte, + int old_row, colnr_T old_col, bcount_t old_byte, int new_row, + colnr_T new_col, bcount_t new_byte, ExtmarkOp undo) { - curbuf->deleted_bytes2 = 0; + buf->deleted_bytes2 = 0; + buf->b_virt_line_pos = -1; buf_updates_send_splice(buf, start_row, start_col, start_byte, old_row, old_col, old_byte, new_row, new_col, new_byte); @@ -612,7 +610,7 @@ void extmark_splice_impl(buf_T *buf, new_row, new_col); if (undo == kExtmarkUndo) { - u_header_T *uhp = u_force_get_undo_header(buf); + u_header_T *uhp = u_force_get_undo_header(buf); if (!uhp) { return; } @@ -621,7 +619,7 @@ void extmark_splice_impl(buf_T *buf, // TODO(bfredl): this is quite rudimentary. We merge small (within line) // inserts with each other and small deletes with each other. Add full // merge algorithm later. - if (old_row == 0 && new_row == 0 && kv_size(uhp->uh_extmark)) { + if (old_row == 0 && new_row == 0 && kv_size(uhp->uh_extmark)) { ExtmarkUndoObject *item = &kv_A(uhp->uh_extmark, kv_size(uhp->uh_extmark)-1); if (item->type == kExtmarkSplice) { @@ -669,24 +667,20 @@ void extmark_splice_impl(buf_T *buf, } } -void extmark_splice_cols(buf_T *buf, - int start_row, colnr_T start_col, - colnr_T old_col, colnr_T new_col, - ExtmarkOp undo) +void extmark_splice_cols(buf_T *buf, int start_row, colnr_T start_col, colnr_T old_col, + colnr_T new_col, ExtmarkOp undo) { extmark_splice(buf, start_row, start_col, 0, old_col, old_col, 0, new_col, new_col, undo); } -void extmark_move_region( - buf_T *buf, - int start_row, colnr_T start_col, bcount_t start_byte, - int extent_row, colnr_T extent_col, bcount_t extent_byte, - int new_row, colnr_T new_col, bcount_t new_byte, - ExtmarkOp undo) +void extmark_move_region(buf_T *buf, int start_row, colnr_T start_col, bcount_t start_byte, + int extent_row, colnr_T extent_col, bcount_t extent_byte, int new_row, + colnr_T new_col, bcount_t new_byte, ExtmarkOp undo) { - curbuf->deleted_bytes2 = 0; + buf->deleted_bytes2 = 0; + buf->b_virt_line_pos = -1; // TODO(bfredl): this is not synced to the buffer state inside the callback. // But unless we make the undo implementation smarter, this is not ensured // anyway. @@ -704,7 +698,7 @@ void extmark_move_region( if (undo == kExtmarkUndo) { - u_header_T *uhp = u_force_get_undo_header(buf); + u_header_T *uhp = u_force_get_undo_header(buf); if (!uhp) { return; } @@ -729,7 +723,7 @@ void extmark_move_region( uint64_t src2ns(Integer *src_id) { if (*src_id == 0) { - *src_id = (Integer)nvim_create_namespace((String)STRING_INIT); + *src_id = nvim_create_namespace((String)STRING_INIT); } if (*src_id < 0) { return UINT64_MAX; diff --git a/src/nvim/extmark.h b/src/nvim/extmark.h index 1bc42322a3..aee679a9c7 100644 --- a/src/nvim/extmark.h +++ b/src/nvim/extmark.h @@ -1,10 +1,10 @@ #ifndef NVIM_EXTMARK_H #define NVIM_EXTMARK_H -#include "nvim/pos.h" #include "nvim/buffer_defs.h" #include "nvim/extmark_defs.h" #include "nvim/marktree.h" +#include "nvim/pos.h" EXTERN int extmark_splice_pending INIT(= 0); diff --git a/src/nvim/extmark_defs.h b/src/nvim/extmark_defs.h index b5d91382ec..c0a4f4014f 100644 --- a/src/nvim/extmark_defs.h +++ b/src/nvim/extmark_defs.h @@ -1,11 +1,21 @@ #ifndef NVIM_EXTMARK_DEFS_H #define NVIM_EXTMARK_DEFS_H -#include "nvim/types.h" #include "nvim/lib/kvec.h" +#include "nvim/types.h" typedef struct Decoration Decoration; +typedef struct { + char *text; + int hl_id; +} VirtTextChunk; + +typedef kvec_t(VirtTextChunk) VirtText; +#define VIRTTEXT_EMPTY ((VirtText)KV_INITIAL_VALUE) +typedef kvec_t(VirtText) VirtLines; + + typedef struct { uint64_t ns_id; diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 8beba38509..fca62353d5 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -44,50 +44,51 @@ // functions. #include <assert.h> -#include <string.h> -#include <stdbool.h> #include <inttypes.h> #include <limits.h> +#include <stdbool.h> +#include <string.h> -#include "nvim/vim.h" -#include "nvim/eval.h" #include "nvim/ascii.h" -#include "nvim/file_search.h" #include "nvim/charset.h" +#include "nvim/eval.h" +#include "nvim/file_search.h" #include "nvim/fileio.h" +#include "nvim/globals.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" #include "nvim/option.h" +#include "nvim/os/fs_defs.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" #include "nvim/os_unix.h" #include "nvim/path.h" #include "nvim/strings.h" #include "nvim/tag.h" +#include "nvim/vim.h" #include "nvim/window.h" -#include "nvim/os/os.h" -#include "nvim/os/input.h" -#include "nvim/os/fs_defs.h" -static char_u *ff_expand_buffer = NULL; /* used for expanding filenames */ +static char_u *ff_expand_buffer = NULL; // used for expanding filenames /* * type for the directory search stack */ typedef struct ff_stack { - struct ff_stack *ffs_prev; + struct ff_stack *ffs_prev; /* the fix part (no wildcards) and the part containing the wildcards * of the search path */ - char_u *ffs_fix_path; - char_u *ffs_wc_path; + char_u *ffs_fix_path; + char_u *ffs_wc_path; /* files/dirs found in the above directory, matched by the first wildcard * of wc_part */ - char_u **ffs_filearray; + char_u **ffs_filearray; int ffs_filearray_size; - char_u ffs_filearray_cur; /* needed for partly handled dirs */ + char_u ffs_filearray_cur; // needed for partly handled dirs /* to store status of partly handled directories * 0: we work on this directory for the first time @@ -100,7 +101,7 @@ typedef struct ff_stack { */ int ffs_level; - /* Did we already expand '**' to an empty string? */ + // Did we already expand '**' to an empty string? int ffs_star_star_empty; } ff_stack_T; @@ -108,19 +109,19 @@ typedef struct ff_stack { * type for already visited directories or files. */ typedef struct ff_visited { - struct ff_visited *ffv_next; + struct ff_visited *ffv_next; /* Visited directories are different if the wildcard string are * different. So we have to save it. */ - char_u *ffv_wc_path; + char_u *ffv_wc_path; // use FileID for comparison (needed because of links), else use filename. bool file_id_valid; FileID file_id; /* The memory for this struct is allocated according to the length of * ffv_fname. */ - char_u ffv_fname[1]; /* actually longer */ + char_u ffv_fname[1]; // actually longer } ff_visited_T; /* @@ -138,13 +139,12 @@ typedef struct ff_visited { * visited lists. */ typedef struct ff_visited_list_hdr { - struct ff_visited_list_hdr *ffvl_next; - - /* the filename the attached visited list is for */ - char_u *ffvl_filename; + struct ff_visited_list_hdr *ffvl_next; - ff_visited_T *ffvl_visited_list; + // the filename the attached visited list is for + char_u *ffvl_filename; + ff_visited_T *ffvl_visited_list; } ff_visited_list_hdr_T; @@ -156,38 +156,38 @@ typedef struct ff_visited_list_hdr { /* * The search context: - * ffsc_stack_ptr: the stack for the dirs to search + * ffsc_stack_ptr: the stack for the dirs to search * ffsc_visited_list: the currently active visited list * ffsc_dir_visited_list: the currently active visited list for search dirs * ffsc_visited_lists_list: the list of all visited lists * ffsc_dir_visited_lists_list: the list of all visited lists for search dirs * ffsc_file_to_search: the file to search for - * ffsc_start_dir: the starting directory, if search path was relative - * ffsc_fix_path: the fix part of the given path (without wildcards) - * Needed for upward search. - * ffsc_wc_path: the part of the given path containing wildcards - * ffsc_level: how many levels of dirs to search downwards - * ffsc_stopdirs_v: array of stop directories for upward search - * ffsc_find_what: FINDFILE_BOTH, FINDFILE_DIR or FINDFILE_FILE - * ffsc_tagfile: searching for tags file, don't use 'suffixesadd' + * ffsc_start_dir: the starting directory, if search path was relative + * ffsc_fix_path: the fix part of the given path (without wildcards) + * Needed for upward search. + * ffsc_wc_path: the part of the given path containing wildcards + * ffsc_level: how many levels of dirs to search downwards + * ffsc_stopdirs_v: array of stop directories for upward search + * ffsc_find_what: FINDFILE_BOTH, FINDFILE_DIR or FINDFILE_FILE + * ffsc_tagfile: searching for tags file, don't use 'suffixesadd' */ typedef struct ff_search_ctx_T { - ff_stack_T *ffsc_stack_ptr; - ff_visited_list_hdr_T *ffsc_visited_list; - ff_visited_list_hdr_T *ffsc_dir_visited_list; - ff_visited_list_hdr_T *ffsc_visited_lists_list; - ff_visited_list_hdr_T *ffsc_dir_visited_lists_list; - char_u *ffsc_file_to_search; - char_u *ffsc_start_dir; - char_u *ffsc_fix_path; - char_u *ffsc_wc_path; + ff_stack_T *ffsc_stack_ptr; + ff_visited_list_hdr_T *ffsc_visited_list; + ff_visited_list_hdr_T *ffsc_dir_visited_list; + ff_visited_list_hdr_T *ffsc_visited_lists_list; + ff_visited_list_hdr_T *ffsc_dir_visited_lists_list; + char_u *ffsc_file_to_search; + char_u *ffsc_start_dir; + char_u *ffsc_fix_path; + char_u *ffsc_wc_path; int ffsc_level; - char_u **ffsc_stopdirs_v; + char_u **ffsc_stopdirs_v; int ffsc_find_what; int ffsc_tagfile; } ff_search_ctx_T; -/* locally needed functions */ +// locally needed functions #ifdef INCLUDE_GENERATED_DECLARATIONS # include "file_search.c.generated.h" @@ -195,104 +195,98 @@ typedef struct ff_search_ctx_T { static char_u e_pathtoolong[] = N_("E854: path too long for completion"); -/* - * Initialization routine for vim_findfile(). - * - * Returns the newly allocated search context or NULL if an error occurred. - * - * Don't forget to clean up by calling vim_findfile_cleanup() if you are done - * with the search context. - * - * Find the file 'filename' in the directory 'path'. - * The parameter 'path' may contain wildcards. If so only search 'level' - * directories deep. The parameter 'level' is the absolute maximum and is - * not related to restricts given to the '**' wildcard. If 'level' is 100 - * and you use '**200' vim_findfile() will stop after 100 levels. - * - * 'filename' cannot contain wildcards! It is used as-is, no backslashes to - * escape special characters. - * - * If 'stopdirs' is not NULL and nothing is found downward, the search is - * restarted on the next higher directory level. This is repeated until the - * start-directory of a search is contained in 'stopdirs'. 'stopdirs' has the - * format ";*<dirname>*\(;<dirname>\)*;\=$". - * - * If the 'path' is relative, the starting dir for the search is either VIM's - * current dir or if the path starts with "./" the current files dir. - * If the 'path' is absolute, the starting dir is that part of the path before - * the first wildcard. - * - * Upward search is only done on the starting dir. - * - * If 'free_visited' is TRUE the list of already visited files/directories is - * cleared. Set this to FALSE if you just want to search from another - * directory, but want to be sure that no directory from a previous search is - * searched again. This is useful if you search for a file at different places. - * The list of visited files/dirs can also be cleared with the function - * vim_findfile_free_visited(). - * - * Set the parameter 'find_what' to FINDFILE_DIR if you want to search for - * directories only, FINDFILE_FILE for files only, FINDFILE_BOTH for both. - * - * A search context returned by a previous call to vim_findfile_init() can be - * passed in the parameter "search_ctx_arg". This context is reused and - * reinitialized with the new parameters. The list of already visited - * directories from this context is only deleted if the parameter - * "free_visited" is true. Be aware that the passed "search_ctx_arg" is freed - * if the reinitialization fails. - * - * If you don't have a search context from a previous call "search_ctx_arg" - * must be NULL. - * - * This function silently ignores a few errors, vim_findfile() will have - * limited functionality then. - */ -void * -vim_findfile_init ( - char_u *path, - char_u *filename, - char_u *stopdirs, - int level, - int free_visited, - int find_what, - void *search_ctx_arg, - int tagfile, /* expanding names of tags files */ - char_u *rel_fname /* file name to use for "." */ -) +/// Initialization routine for vim_findfile(). +/// +/// Returns the newly allocated search context or NULL if an error occurred. +/// +/// Don't forget to clean up by calling vim_findfile_cleanup() if you are done +/// with the search context. +/// +/// Find the file 'filename' in the directory 'path'. +/// The parameter 'path' may contain wildcards. If so only search 'level' +/// directories deep. The parameter 'level' is the absolute maximum and is +/// not related to restricts given to the '**' wildcard. If 'level' is 100 +/// and you use '**200' vim_findfile() will stop after 100 levels. +/// +/// 'filename' cannot contain wildcards! It is used as-is, no backslashes to +/// escape special characters. +/// +/// If 'stopdirs' is not NULL and nothing is found downward, the search is +/// restarted on the next higher directory level. This is repeated until the +/// start-directory of a search is contained in 'stopdirs'. 'stopdirs' has the +/// format ";*<dirname>*\(;<dirname>\)*;\=$". +/// +/// If the 'path' is relative, the starting dir for the search is either VIM's +/// current dir or if the path starts with "./" the current files dir. +/// If the 'path' is absolute, the starting dir is that part of the path before +/// the first wildcard. +/// +/// Upward search is only done on the starting dir. +/// +/// If 'free_visited' is TRUE the list of already visited files/directories is +/// cleared. Set this to FALSE if you just want to search from another +/// directory, but want to be sure that no directory from a previous search is +/// searched again. This is useful if you search for a file at different places. +/// The list of visited files/dirs can also be cleared with the function +/// vim_findfile_free_visited(). +/// +/// Set the parameter 'find_what' to FINDFILE_DIR if you want to search for +/// directories only, FINDFILE_FILE for files only, FINDFILE_BOTH for both. +/// +/// A search context returned by a previous call to vim_findfile_init() can be +/// passed in the parameter "search_ctx_arg". This context is reused and +/// reinitialized with the new parameters. The list of already visited +/// directories from this context is only deleted if the parameter +/// "free_visited" is true. Be aware that the passed "search_ctx_arg" is freed +/// if the reinitialization fails. +/// +/// If you don't have a search context from a previous call "search_ctx_arg" +/// must be NULL. +/// +/// This function silently ignores a few errors, vim_findfile() will have +/// limited functionality then. +/// +/// @param tagfile expanding names of tags files +/// @param rel_fname file name to use for "." +void *vim_findfile_init(char_u *path, char_u *filename, char_u *stopdirs, int level, + int free_visited, int find_what, void *search_ctx_arg, int tagfile, + char_u *rel_fname) { - char_u *wc_part; - ff_stack_T *sptr; - ff_search_ctx_T *search_ctx; + char_u *wc_part; + ff_stack_T *sptr; + ff_search_ctx_T *search_ctx; /* If a search context is given by the caller, reuse it, else allocate a * new one. */ - if (search_ctx_arg != NULL) + if (search_ctx_arg != NULL) { search_ctx = search_ctx_arg; - else { + } else { search_ctx = xcalloc(1, sizeof(ff_search_ctx_T)); } search_ctx->ffsc_find_what = find_what; search_ctx->ffsc_tagfile = tagfile; - /* clear the search context, but NOT the visited lists */ + // clear the search context, but NOT the visited lists ff_clear(search_ctx); - /* clear visited list if wanted */ - if (free_visited == TRUE) + // clear visited list if wanted + if (free_visited == TRUE) { vim_findfile_free_visited(search_ctx); - else { + } else { /* Reuse old visited lists. Get the visited list for the given * filename. If no list for the current filename exists, creates a new * one. */ search_ctx->ffsc_visited_list = ff_get_visited_list(filename, - &search_ctx->ffsc_visited_lists_list); - if (search_ctx->ffsc_visited_list == NULL) + &search_ctx->ffsc_visited_lists_list); + if (search_ctx->ffsc_visited_list == NULL) { goto error_return; + } search_ctx->ffsc_dir_visited_list = ff_get_visited_list(filename, - &search_ctx->ffsc_dir_visited_lists_list); - if (search_ctx->ffsc_dir_visited_list == NULL) + &search_ctx->ffsc_dir_visited_lists_list); + if (search_ctx->ffsc_dir_visited_list == NULL) { goto error_return; + } } if (ff_expand_buffer == NULL) { @@ -308,16 +302,18 @@ vim_findfile_init ( size_t len = (size_t)(path_tail(rel_fname) - rel_fname); if (!vim_isAbsName(rel_fname) && len + 1 < MAXPATHL) { - /* Make the start dir an absolute path name. */ + // Make the start dir an absolute path name. STRLCPY(ff_expand_buffer, rel_fname, len + 1); search_ctx->ffsc_start_dir = (char_u *)FullName_save((char *)ff_expand_buffer, FALSE); - } else + } else { search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len); - if (*++path != NUL) + } + if (*++path != NUL) { ++path; + } } else if (*path == NUL || !vim_isAbsName(path)) { #ifdef BACKSLASH_IN_FILENAME - /* "c:dir" needs "c:" to be expanded, otherwise use current dir */ + // "c:dir" needs "c:" to be expanded, otherwise use current dir if (*path != NUL && path[1] == ':') { char_u drive[3]; @@ -332,8 +328,9 @@ vim_findfile_init ( path += 2; } else #endif - if (os_dirname(ff_expand_buffer, MAXPATHL) == FAIL) + if (os_dirname(ff_expand_buffer, MAXPATHL) == FAIL) { goto error_return; + } search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer); @@ -342,8 +339,9 @@ vim_findfile_init ( * directory (but not for "//machine/dir"). Only use the drive name. */ if ((*path == '/' || *path == '\\') && path[1] != path[0] - && search_ctx->ffsc_start_dir[1] == ':') + && search_ctx->ffsc_start_dir[1] == ':') { search_ctx->ffsc_start_dir[2] = NUL; + } #endif } @@ -357,21 +355,22 @@ vim_findfile_init ( * ff_path_in_stoplist() for details. */ if (stopdirs != NULL) { - char_u *walker = stopdirs; + char_u *walker = stopdirs; - while (*walker == ';') + while (*walker == ';') { walker++; + } size_t dircount = 1; search_ctx->ffsc_stopdirs_v = xmalloc(sizeof(char_u *)); do { - char_u *helper; - void *ptr; + char_u *helper; + void *ptr; helper = walker; ptr = xrealloc(search_ctx->ffsc_stopdirs_v, - (dircount + 1) * sizeof(char_u *)); + (dircount + 1) * sizeof(char_u *)); search_ctx->ffsc_stopdirs_v = ptr; walker = vim_strchr(walker, ';'); if (walker) { @@ -379,15 +378,15 @@ vim_findfile_init ( search_ctx->ffsc_stopdirs_v[dircount-1] = vim_strnsave(helper, (size_t)(walker - helper)); walker++; - } else + } else { /* this might be "", which means ascent till top * of directory tree. */ search_ctx->ffsc_stopdirs_v[dircount-1] = vim_strsave(helper); + } dircount++; - } while (walker != NULL); search_ctx->ffsc_stopdirs_v[dircount-1] = NULL; } @@ -402,9 +401,9 @@ vim_findfile_init ( if (wc_part != NULL) { int64_t llevel; int len; - char *errpt; + char *errpt; - /* save the fix part of the path */ + // save the fix part of the path assert(wc_part - path >= 0); search_ctx->ffsc_fix_path = vim_strnsave(path, (size_t)(wc_part - path)); @@ -428,27 +427,30 @@ vim_findfile_init ( ff_expand_buffer[len++] = *wc_part++; llevel = strtol((char *)wc_part, &errpt, 10); - if ((char_u *)errpt != wc_part && llevel > 0 && llevel < 255) + if ((char_u *)errpt != wc_part && llevel > 0 && llevel < 255) { ff_expand_buffer[len++] = (char_u)llevel; - else if ((char_u *)errpt != wc_part && llevel == 0) - /* restrict is 0 -> remove already added '**' */ + } else if ((char_u *)errpt != wc_part && llevel == 0) { + // restrict is 0 -> remove already added '**' len -= 2; - else + } else { ff_expand_buffer[len++] = FF_MAX_STAR_STAR_EXPAND; + } wc_part = (char_u *)errpt; if (*wc_part != NUL && !vim_ispathsep(*wc_part)) { EMSG2(_( - "E343: Invalid path: '**[number]' must be at the end of the path or be followed by '%s'."), - PATHSEPSTR); + "E343: Invalid path: '**[number]' must be at the end of the path or be followed by '%s'."), + PATHSEPSTR); goto error_return; } - } else + } else { ff_expand_buffer[len++] = *wc_part++; + } } ff_expand_buffer[len] = NUL; search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer); - } else + } else { search_ctx->ffsc_fix_path = vim_strsave(path); + } if (search_ctx->ffsc_start_dir == NULL) { /* store the fix part as startdir. @@ -458,7 +460,7 @@ vim_findfile_init ( search_ctx->ffsc_fix_path[0] = NUL; } - /* create an absolute path */ + // create an absolute path if (STRLEN(search_ctx->ffsc_start_dir) + STRLEN(search_ctx->ffsc_fix_path) + 3 >= MAXPATHL) { EMSG(_(e_pathtoolong)); @@ -505,8 +507,8 @@ vim_findfile_init ( } sptr = ff_create_stack_element(ff_expand_buffer, - search_ctx->ffsc_wc_path, - level, 0); + search_ctx->ffsc_wc_path, + level, 0); ff_push(search_ctx, sptr); search_ctx->ffsc_file_to_search = vim_strsave(filename); @@ -527,7 +529,7 @@ error_return: */ char_u *vim_findfile_stopdir(char_u *buf) { - char_u *r_ptr = buf; + char_u *r_ptr = buf; while (*r_ptr != NUL && *r_ptr != ';') { if (r_ptr[0] == '\\' && r_ptr[1] == ';') { @@ -541,8 +543,9 @@ char_u *vim_findfile_stopdir(char_u *buf) if (*r_ptr == ';') { *r_ptr = 0; r_ptr++; - } else if (*r_ptr == NUL) + } else if (*r_ptr == NUL) { r_ptr = NULL; + } return r_ptr; } @@ -551,8 +554,9 @@ char_u *vim_findfile_stopdir(char_u *buf) */ void vim_findfile_cleanup(void *ctx) { - if (ctx == NULL) + if (ctx == NULL) { return; + } vim_findfile_free_visited(ctx); ff_clear(ctx); @@ -573,17 +577,18 @@ void vim_findfile_cleanup(void *ctx) */ char_u *vim_findfile(void *search_ctx_arg) { - char_u *file_path; - char_u *rest_of_wildcards; - char_u *path_end = NULL; - ff_stack_T *stackp = NULL; + char_u *file_path; + char_u *rest_of_wildcards; + char_u *path_end = NULL; + ff_stack_T *stackp = NULL; size_t len; - char_u *p; - char_u *suf; + char_u *p; + char_u *suf; ff_search_ctx_T *search_ctx; - if (search_ctx_arg == NULL) + if (search_ctx_arg == NULL) { return NULL; + } search_ctx = (ff_search_ctx_T *)search_ctx_arg; @@ -593,24 +598,27 @@ char_u *vim_findfile(void *search_ctx_arg) */ file_path = xmalloc(MAXPATHL); - /* store the end of the start dir -- needed for upward search */ - if (search_ctx->ffsc_start_dir != NULL) + // store the end of the start dir -- needed for upward search + if (search_ctx->ffsc_start_dir != NULL) { path_end = &search_ctx->ffsc_start_dir[ - STRLEN(search_ctx->ffsc_start_dir)]; + STRLEN(search_ctx->ffsc_start_dir)]; + } - /* upward search loop */ + // upward search loop for (;; ) { - /* downward search loop */ + // downward search loop for (;; ) { - /* check if user user wants to stop the search*/ + // check if user user wants to stop the search os_breakcheck(); - if (got_int) + if (got_int) { break; + } - /* get directory to work on from stack */ + // get directory to work on from stack stackp = ff_pop(search_ctx); - if (stackp == NULL) + if (stackp == NULL) { break; + } /* * TODO: decide if we leave this test in @@ -633,10 +641,10 @@ char_u *vim_findfile(void *search_ctx_arg) */ if (stackp->ffs_filearray == NULL && ff_check_visited(&search_ctx->ffsc_dir_visited_list - ->ffvl_visited_list, - stackp->ffs_fix_path - , stackp->ffs_wc_path - ) == FAIL) { + ->ffvl_visited_list, + stackp->ffs_fix_path, + stackp->ffs_wc_path + ) == FAIL) { #ifdef FF_VERBOSE if (p_verbose >= 5) { verbose_enter_scroll(); @@ -659,7 +667,7 @@ char_u *vim_findfile(void *search_ctx_arg) } #endif - /* check depth */ + // check depth if (stackp->ffs_level <= 0) { ff_free_stack_element(stackp); continue; @@ -725,13 +733,14 @@ char_u *vim_findfile(void *search_ctx_arg) } if (*p == 0) { - /* remove '**<numb> from wildcards */ + // remove '**<numb> from wildcards STRMOVE(rest_of_wildcards, rest_of_wildcards + 3); - } else + } else { rest_of_wildcards += 3; + } if (stackp->ffs_star_star_empty == 0) { - /* if not done before, expand '**' to empty */ + // if not done before, expand '**' to empty stackp->ffs_star_star_empty = 1; dirptrs[1] = stackp->ffs_fix_path; } @@ -754,8 +763,9 @@ char_u *vim_findfile(void *search_ctx_arg) } file_path[len] = NUL; - if (vim_ispathsep(*rest_of_wildcards)) + if (vim_ispathsep(*rest_of_wildcards)) { rest_of_wildcards++; + } } /* @@ -766,23 +776,25 @@ char_u *vim_findfile(void *search_ctx_arg) stackp->ffs_filearray = xmalloc(sizeof(char *)); stackp->ffs_filearray[0] = vim_strsave(dirptrs[0]); stackp->ffs_filearray_size = 1; - } else + } else { /* Add EW_NOTWILD because the expanded path may contain * wildcard characters that are to be taken literally. * This is a bit of a hack. */ expand_wildcards((dirptrs[1] == NULL) ? 1 : 2, dirptrs, - &stackp->ffs_filearray_size, - &stackp->ffs_filearray, - EW_DIR|EW_ADDSLASH|EW_SILENT|EW_NOTWILD); + &stackp->ffs_filearray_size, + &stackp->ffs_filearray, + EW_DIR|EW_ADDSLASH|EW_SILENT|EW_NOTWILD); + } stackp->ffs_filearray_cur = 0; stackp->ffs_stage = 0; - } else + } else { rest_of_wildcards = &stackp->ffs_wc_path[ - STRLEN(stackp->ffs_wc_path)]; + STRLEN(stackp->ffs_wc_path)]; + } if (stackp->ffs_stage == 0) { - /* this is the first time we work on this directory */ + // this is the first time we work on this directory if (*rest_of_wildcards == NUL) { /* * We don't have further wildcards to expand, so we have to @@ -791,9 +803,9 @@ char_u *vim_findfile(void *search_ctx_arg) for (int i = stackp->ffs_filearray_cur; i < stackp->ffs_filearray_size; ++i) { if (!path_with_url((char *)stackp->ffs_filearray[i]) - && !os_isdir(stackp->ffs_filearray[i])) - continue; /* not a directory */ - + && !os_isdir(stackp->ffs_filearray[i])) { + continue; // not a directory + } // prepare the filename to be checked for existence below if (STRLEN(stackp->ffs_filearray[i]) + 1 + STRLEN(search_ctx->ffsc_file_to_search) >= MAXPATHL) { @@ -812,12 +824,13 @@ char_u *vim_findfile(void *search_ctx_arg) * from 'suffixesadd'. */ len = STRLEN(file_path); - if (search_ctx->ffsc_tagfile) + if (search_ctx->ffsc_tagfile) { suf = (char_u *)""; - else + } else { suf = curbuf->b_p_sua; + } for (;; ) { - /* if file exists and we didn't already find it */ + // if file exists and we didn't already find it if ((path_with_url((char *)file_path) || (os_path_exists(file_path) && (search_ctx->ffsc_find_what @@ -826,19 +839,17 @@ char_u *vim_findfile(void *search_ctx_arg) == FINDFILE_DIR) == os_isdir(file_path))))) #ifndef FF_VERBOSE - && (ff_check_visited( - &search_ctx->ffsc_visited_list->ffvl_visited_list, - file_path - , (char_u *)"" - ) == OK) + && (ff_check_visited(&search_ctx->ffsc_visited_list->ffvl_visited_list, + file_path, + (char_u *)"" + ) == OK) #endif ) { #ifdef FF_VERBOSE - if (ff_check_visited( - &search_ctx->ffsc_visited_list->ffvl_visited_list, - file_path - , (char_u *)"" - ) == FAIL) { + if (ff_check_visited(&search_ctx->ffsc_visited_list->ffvl_visited_list, + file_path, + (char_u *)"" + ) == FAIL) { if (p_verbose >= 5) { verbose_enter_scroll(); smsg("Already: %s", file_path); @@ -849,19 +860,21 @@ char_u *vim_findfile(void *search_ctx_arg) } #endif - /* push dir to examine rest of subdirs later */ + // push dir to examine rest of subdirs later assert(i < UCHAR_MAX - 1); stackp->ffs_filearray_cur = (char_u)(i + 1); ff_push(search_ctx, stackp); - if (!path_with_url((char *)file_path)) + if (!path_with_url((char *)file_path)) { simplify_filename(file_path); + } if (os_dirname(ff_expand_buffer, MAXPATHL) == OK) { p = path_shorten_fname(file_path, - ff_expand_buffer); - if (p != NULL) + ff_expand_buffer); + if (p != NULL) { STRMOVE(file_path, p); + } } #ifdef FF_VERBOSE if (p_verbose >= 5) { @@ -874,12 +887,13 @@ char_u *vim_findfile(void *search_ctx_arg) return file_path; } - /* Not found or found already, try next suffix. */ - if (*suf == NUL) + // Not found or found already, try next suffix. + if (*suf == NUL) { break; + } assert(MAXPATHL >= len); copy_option_part(&suf, file_path + len, - MAXPATHL - len, ","); + MAXPATHL - len, ","); } } } else { @@ -889,14 +903,13 @@ char_u *vim_findfile(void *search_ctx_arg) */ for (int i = stackp->ffs_filearray_cur; i < stackp->ffs_filearray_size; ++i) { - if (!os_isdir(stackp->ffs_filearray[i])) - continue; /* not a directory */ - + if (!os_isdir(stackp->ffs_filearray[i])) { + continue; // not a directory + } ff_push(search_ctx, - ff_create_stack_element( - stackp->ffs_filearray[i], - rest_of_wildcards, - stackp->ffs_level - 1, 0)); + ff_create_stack_element(stackp->ffs_filearray[i], + rest_of_wildcards, + stackp->ffs_level - 1, 0)); } } stackp->ffs_filearray_cur = 0; @@ -911,19 +924,20 @@ char_u *vim_findfile(void *search_ctx_arg) for (int i = stackp->ffs_filearray_cur; i < stackp->ffs_filearray_size; ++i) { if (fnamecmp(stackp->ffs_filearray[i], - stackp->ffs_fix_path) == 0) - continue; /* don't repush same directory */ - if (!os_isdir(stackp->ffs_filearray[i])) - continue; /* not a directory */ + stackp->ffs_fix_path) == 0) { + continue; // don't repush same directory + } + if (!os_isdir(stackp->ffs_filearray[i])) { + continue; // not a directory + } ff_push(search_ctx, - ff_create_stack_element(stackp->ffs_filearray[i], - stackp->ffs_wc_path, stackp->ffs_level - 1, 1)); + ff_create_stack_element(stackp->ffs_filearray[i], + stackp->ffs_wc_path, stackp->ffs_level - 1, 1)); } } - /* we are done with the current directory */ + // we are done with the current directory ff_free_stack_element(stackp); - } /* If we reached this, we didn't find anything downwards. @@ -931,26 +945,30 @@ char_u *vim_findfile(void *search_ctx_arg) */ if (search_ctx->ffsc_start_dir && search_ctx->ffsc_stopdirs_v != NULL && !got_int) { - ff_stack_T *sptr; + ff_stack_T *sptr; - /* is the last starting directory in the stop list? */ + // is the last starting directory in the stop list? if (ff_path_in_stoplist(search_ctx->ffsc_start_dir, - (int)(path_end - search_ctx->ffsc_start_dir), - search_ctx->ffsc_stopdirs_v) == TRUE) + (int)(path_end - search_ctx->ffsc_start_dir), + search_ctx->ffsc_stopdirs_v) == TRUE) { break; + } - /* cut of last dir */ + // cut of last dir while (path_end > search_ctx->ffsc_start_dir - && vim_ispathsep(*path_end)) + && vim_ispathsep(*path_end)) { path_end--; + } while (path_end > search_ctx->ffsc_start_dir - && !vim_ispathsep(path_end[-1])) + && !vim_ispathsep(path_end[-1])) { path_end--; + } *path_end = 0; path_end--; - if (*search_ctx->ffsc_start_dir == 0) + if (*search_ctx->ffsc_start_dir == 0) { break; + } if (STRLEN(search_ctx->ffsc_start_dir) + 1 + STRLEN(search_ctx->ffsc_fix_path) >= MAXPATHL) { @@ -962,12 +980,13 @@ char_u *vim_findfile(void *search_ctx_arg) } STRCAT(file_path, search_ctx->ffsc_fix_path); - /* create a new stack entry */ + // create a new stack entry sptr = ff_create_stack_element(file_path, - search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0); + search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0); ff_push(search_ctx, sptr); - } else + } else { break; + } } fail: @@ -983,8 +1002,9 @@ void vim_findfile_free_visited(void *search_ctx_arg) { ff_search_ctx_T *search_ctx; - if (search_ctx_arg == NULL) + if (search_ctx_arg == NULL) { return; + } search_ctx = (ff_search_ctx_T *)search_ctx_arg; vim_findfile_free_visited_list(&search_ctx->ffsc_visited_lists_list); @@ -1023,11 +1043,12 @@ static void ff_free_visited_list(ff_visited_T *vl) * Returns the already visited list for the given filename. If none is found it * allocates a new one. */ -static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, ff_visited_list_hdr_T **list_headp) +static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, + ff_visited_list_hdr_T **list_headp) { - ff_visited_list_hdr_T *retptr = NULL; + ff_visited_list_hdr_T *retptr = NULL; - /* check if a visited list for the given filename exists */ + // check if a visited list for the given filename exists if (*list_headp != NULL) { retptr = *list_headp; while (retptr != NULL) { @@ -1115,7 +1136,7 @@ static bool ff_wc_equal(char_u *s1, char_u *s2) */ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u *wc_path) { - ff_visited_T *vp; + ff_visited_T *vp; bool url = false; FileID file_id; @@ -1131,7 +1152,7 @@ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u * } } - /* check against list of already visited files */ + // check against list of already visited files for (vp = *visited_list; vp != NULL; vp = vp->ffv_next) { if ((url && fnamecmp(vp->ffv_fname, ff_expand_buffer) == 0) || (!url && vp->file_id_valid @@ -1158,10 +1179,11 @@ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u * STRCPY(vp->ffv_fname, ff_expand_buffer); } - if (wc_path != NULL) + if (wc_path != NULL) { vp->ffv_wc_path = vim_strsave(wc_path); - else + } else { vp->ffv_wc_path = NULL; + } vp->ffv_next = *visited_list; *visited_list = vp; @@ -1172,7 +1194,8 @@ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u * /* * create stack element from given path pieces */ -static ff_stack_T *ff_create_stack_element(char_u *fix_part, char_u *wc_part, int level, int star_star_empty) +static ff_stack_T *ff_create_stack_element(char_u *fix_part, char_u *wc_part, int level, + int star_star_empty) { ff_stack_T *new = xmalloc(sizeof(ff_stack_T)); @@ -1184,13 +1207,15 @@ static ff_stack_T *ff_create_stack_element(char_u *fix_part, char_u *wc_part, in new->ffs_level = level; new->ffs_star_star_empty = star_star_empty; - /* the following saves NULL pointer checks in vim_findfile */ - if (fix_part == NULL) + // the following saves NULL pointer checks in vim_findfile + if (fix_part == NULL) { fix_part = (char_u *)""; + } new->ffs_fix_path = vim_strsave(fix_part); - if (wc_part == NULL) + if (wc_part == NULL) { wc_part = (char_u *)""; + } new->ffs_wc_path = vim_strsave(wc_part); return new; @@ -1215,11 +1240,12 @@ static void ff_push(ff_search_ctx_T *search_ctx, ff_stack_T *stack_ptr) */ static ff_stack_T *ff_pop(ff_search_ctx_T *search_ctx) { - ff_stack_T *sptr; + ff_stack_T *sptr; sptr = search_ctx->ffsc_stack_ptr; - if (search_ctx->ffsc_stack_ptr != NULL) + if (search_ctx->ffsc_stack_ptr != NULL) { search_ctx->ffsc_stack_ptr = search_ctx->ffsc_stack_ptr->ffs_prev; + } return sptr; } @@ -1249,11 +1275,12 @@ static void ff_free_stack_element(ff_stack_T *const stack_ptr) */ static void ff_clear(ff_search_ctx_T *search_ctx) { - ff_stack_T *sptr; + ff_stack_T *sptr; - /* clear up stack */ - while ((sptr = ff_pop(search_ctx)) != NULL) + // clear up stack + while ((sptr = ff_pop(search_ctx)) != NULL) { ff_free_stack_element(sptr); + } xfree(search_ctx->ffsc_file_to_search); xfree(search_ctx->ffsc_start_dir); @@ -1271,7 +1298,7 @@ static void ff_clear(ff_search_ctx_T *search_ctx) } search_ctx->ffsc_stopdirs_v = NULL; - /* reset everything */ + // reset everything search_ctx->ffsc_file_to_search = NULL; search_ctx->ffsc_start_dir = NULL; search_ctx->ffsc_fix_path = NULL; @@ -1287,13 +1314,15 @@ static int ff_path_in_stoplist(char_u *path, int path_len, char_u **stopdirs_v) { int i = 0; - /* eat up trailing path separators, except the first */ - while (path_len > 1 && vim_ispathsep(path[path_len - 1])) + // eat up trailing path separators, except the first + while (path_len > 1 && vim_ispathsep(path[path_len - 1])) { path_len--; + } - /* if no path consider it as match */ - if (path_len == 0) + // if no path consider it as match + if (path_len == 0) { return TRUE; + } for (i = 0; stopdirs_v[i] != NULL; i++) { if ((int)STRLEN(stopdirs_v[i]) > path_len) { @@ -1302,49 +1331,46 @@ static int ff_path_in_stoplist(char_u *path, int path_len, char_u **stopdirs_v) * '/home/r' would also match '/home/rks' */ if (fnamencmp(stopdirs_v[i], path, path_len) == 0 - && vim_ispathsep(stopdirs_v[i][path_len])) + && vim_ispathsep(stopdirs_v[i][path_len])) { return TRUE; + } } else { - if (fnamecmp(stopdirs_v[i], path) == 0) + if (fnamecmp(stopdirs_v[i], path) == 0) { return TRUE; + } } } return FALSE; } -/* - * Find the file name "ptr[len]" in the path. Also finds directory names. - * - * On the first call set the parameter 'first' to TRUE to initialize - * the search. For repeating calls to FALSE. - * - * Repeating calls will return other files called 'ptr[len]' from the path. - * - * Only on the first call 'ptr' and 'len' are used. For repeating calls they - * don't need valid values. - * - * If nothing found on the first call the option FNAME_MESS will issue the - * message: - * 'Can't find file "<file>" in path' - * On repeating calls: - * 'No more file "<file>" found in path' - * - * options: - * FNAME_MESS give error message when not found - * - * Uses NameBuff[]! - * - * Returns an allocated string for the file name. NULL for error. - * - */ -char_u * -find_file_in_path ( - char_u *ptr, /* file name */ - size_t len, /* length of file name */ - int options, - int first, /* use count'th matching file name */ - char_u *rel_fname /* file name searching relative to */ -) +/// Find the file name "ptr[len]" in the path. Also finds directory names. +/// +/// On the first call set the parameter 'first' to TRUE to initialize +/// the search. For repeating calls to FALSE. +/// +/// Repeating calls will return other files called 'ptr[len]' from the path. +/// +/// Only on the first call 'ptr' and 'len' are used. For repeating calls they +/// don't need valid values. +/// +/// If nothing found on the first call the option FNAME_MESS will issue the +/// message: +/// 'Can't find file "<file>" in path' +/// On repeating calls: +/// 'No more file "<file>" found in path' +/// +/// options: +/// FNAME_MESS give error message when not found +/// +/// Uses NameBuff[]! +/// +/// @param ptr file name +/// @param len length of file name +/// @param first use count'th matching file name +/// @param rel_fname file name searching relative to +/// +/// @return an allocated string for the file name. NULL for error. +char_u *find_file_in_path(char_u *ptr, size_t len, int options, int first, char_u *rel_fname) { return find_file_in_path_option(ptr, len, options, first, (*curbuf->b_p_path == NUL @@ -1353,8 +1379,8 @@ find_file_in_path ( FINDFILE_BOTH, rel_fname, curbuf->b_p_sua); } -static char_u *ff_file_to_find = NULL; -static void *fdip_search_ctx = NULL; +static char_u *ff_file_to_find = NULL; +static void *fdip_search_ctx = NULL; #if defined(EXITFREE) void free_findfile(void) @@ -1366,46 +1392,41 @@ void free_findfile(void) #endif -/* - * Find the directory name "ptr[len]" in the path. - * - * options: - * FNAME_MESS give error message when not found - * FNAME_UNESC unescape backslashes - * - * Uses NameBuff[]! - * - * Returns an allocated string for the file name. NULL for error. - */ -char_u * -find_directory_in_path ( - char_u *ptr, /* file name */ - size_t len, /* length of file name */ - int options, - char_u *rel_fname /* file name searching relative to */ -) +/// Find the directory name "ptr[len]" in the path. +/// +/// options: +/// FNAME_MESS give error message when not found +/// FNAME_UNESC unescape backslashes +/// +/// Uses NameBuff[]! +/// +/// @param ptr file name +/// @param len length of file name +/// @param rel_fname file name searching relative to +/// +/// @return an allocated string for the file name. NULL for error. +char_u *find_directory_in_path(char_u *ptr, size_t len, int options, char_u *rel_fname) { return find_file_in_path_option(ptr, len, options, TRUE, p_cdpath, FINDFILE_DIR, rel_fname, (char_u *)""); } -char_u * -find_file_in_path_option ( - char_u *ptr, /* file name */ - size_t len, /* length of file name */ - int options, - int first, /* use count'th matching file name */ - char_u *path_option, /* p_path or p_cdpath */ - int find_what, /* FINDFILE_FILE, _DIR or _BOTH */ - char_u *rel_fname, /* file name we are looking relative to. */ - char_u *suffixes /* list of suffixes, 'suffixesadd' option */ -) +/// @param ptr file name +/// @param len length of file name +/// @param first use count'th matching file name +/// @param path_option p_path or p_cdpath +/// @param find_what FINDFILE_FILE, _DIR or _BOTH +/// @param rel_fname file name we are looking relative to. +/// @param suffixes list of suffixes, 'suffixesadd' option +char_u *find_file_in_path_option(char_u *ptr, size_t len, int options, int first, + char_u *path_option, int find_what, char_u *rel_fname, + char_u *suffixes) { - static char_u *dir; + static char_u *dir; static int did_findfile_init = FALSE; char_u save_char; - char_u *file_name = NULL; - char_u *buf = NULL; + char_u *file_name = NULL; + char_u *buf = NULL; int rel_to_curdir; if (rel_fname != NULL && path_with_url((const char *)rel_fname)) { @@ -1414,7 +1435,7 @@ find_file_in_path_option ( } if (first == TRUE) { - /* copy file name into NameBuff, expanding environment variables */ + // copy file name into NameBuff, expanding environment variables save_char = ptr[len]; ptr[len] = NUL; expand_env_esc(ptr, NameBuff, MAXPATHL, false, true, NULL); @@ -1485,11 +1506,12 @@ find_file_in_path_option ( && (find_what == FINDFILE_BOTH || ((find_what == FINDFILE_DIR) == os_isdir(NameBuff))))) { - file_name = vim_strsave(NameBuff); - goto theend; + file_name = vim_strsave(NameBuff); + goto theend; } - if (*buf == NUL) + if (*buf == NUL) { break; + } assert(MAXPATHL >= l); copy_option_part(&buf, NameBuff + l, MAXPATHL - l, ","); } @@ -1502,7 +1524,7 @@ find_file_in_path_option ( * Otherwise continue to find the next match. */ if (first == TRUE) { - /* vim_findfile_free_visited can handle a possible NULL pointer */ + // vim_findfile_free_visited can handle a possible NULL pointer vim_findfile_free_visited(fdip_search_ctx); dir = path_option; did_findfile_init = FALSE; @@ -1511,12 +1533,13 @@ find_file_in_path_option ( for (;; ) { if (did_findfile_init) { file_name = vim_findfile(fdip_search_ctx); - if (file_name != NULL) + if (file_name != NULL) { break; + } did_findfile_init = FALSE; } else { - char_u *r_ptr; + char_u *r_ptr; if (dir == NULL || *dir == NUL) { /* We searched all paths of the option, now we can @@ -1528,36 +1551,39 @@ find_file_in_path_option ( buf = xmalloc(MAXPATHL); - /* copy next path */ + // copy next path buf[0] = 0; copy_option_part(&dir, buf, MAXPATHL, " ,"); - /* get the stopdir string */ + // get the stopdir string r_ptr = vim_findfile_stopdir(buf); fdip_search_ctx = vim_findfile_init(buf, ff_file_to_find, - r_ptr, 100, FALSE, find_what, - fdip_search_ctx, FALSE, rel_fname); - if (fdip_search_ctx != NULL) + r_ptr, 100, FALSE, find_what, + fdip_search_ctx, FALSE, rel_fname); + if (fdip_search_ctx != NULL) { did_findfile_init = TRUE; + } xfree(buf); } } } if (file_name == NULL && (options & FNAME_MESS)) { if (first == TRUE) { - if (find_what == FINDFILE_DIR) + if (find_what == FINDFILE_DIR) { EMSG2(_("E344: Can't find directory \"%s\" in cdpath"), - ff_file_to_find); - else + ff_file_to_find); + } else { EMSG2(_("E345: Can't find file \"%s\" in path"), - ff_file_to_find); + ff_file_to_find); + } } else { - if (find_what == FINDFILE_DIR) + if (find_what == FINDFILE_DIR) { EMSG2(_("E346: No more directory \"%s\" found in cdpath"), - ff_file_to_find); - else + ff_file_to_find); + } else { EMSG2(_("E347: No more file \"%s\" found in path"), - ff_file_to_find); + ff_file_to_find); + } } } @@ -1565,7 +1591,7 @@ theend: return file_name; } -void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window) +void do_autocmd_dirchanged(char *new_dir, CdScope scope, CdCause cause) { static bool recursive = false; @@ -1581,29 +1607,44 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window) char buf[8]; switch (scope) { - case kCdScopeGlobal: { - snprintf(buf, sizeof(buf), "global"); - break; - } - case kCdScopeTab: { - snprintf(buf, sizeof(buf), "tab"); - break; - } - case kCdScopeWindow: { - snprintf(buf, sizeof(buf), "window"); - break; - } - case kCdScopeInvalid: { - // Should never happen. - abort(); - } + case kCdScopeGlobal: + snprintf(buf, sizeof(buf), "global"); + break; + case kCdScopeTabpage: + snprintf(buf, sizeof(buf), "tabpage"); + break; + case kCdScopeWindow: + snprintf(buf, sizeof(buf), "window"); + break; + case kCdScopeInvalid: + // Should never happen. + abort(); } +#ifdef BACKSLASH_IN_FILENAME + char new_dir_buf[MAXPATHL]; + STRCPY(new_dir_buf, new_dir); + slash_adjust(new_dir_buf); + new_dir = new_dir_buf; +#endif + tv_dict_add_str(dict, S_LEN("scope"), buf); // -V614 - tv_dict_add_str(dict, S_LEN("cwd"), new_dir); - tv_dict_add_bool(dict, S_LEN("changed_window"), changed_window); + tv_dict_add_str(dict, S_LEN("cwd"), new_dir); + tv_dict_add_bool(dict, S_LEN("changed_window"), cause == kCdCauseWindow); tv_dict_set_keys_readonly(dict); + switch (cause) { + case kCdCauseManual: + case kCdCauseWindow: + break; + case kCdCauseAuto: + snprintf(buf, sizeof(buf), "auto"); + break; + case kCdCauseOther: + // Should never happen. + abort(); + } + apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, (char_u *)new_dir, false, curbuf); @@ -1615,7 +1656,7 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window) /// Change to a file's directory. /// Caller must call shorten_fnames()! /// @return OK or FAIL -int vim_chdirfile(char_u *fname) +int vim_chdirfile(char_u *fname, CdCause cause) { char dir[MAXPATHL]; @@ -1626,30 +1667,27 @@ int vim_chdirfile(char_u *fname) NameBuff[0] = NUL; } - if (os_chdir(dir) != 0) { + if (os_chdir(dir) == 0) { + if (cause != kCdCauseOther && pathcmp(dir, (char *)NameBuff, -1) != 0) { + do_autocmd_dirchanged(dir, kCdScopeWindow, cause); + } + } else { return FAIL; } -#ifdef BACKSLASH_IN_FILENAME - slash_adjust((char_u *)dir); -#endif - if (!strequal(dir, (char *)NameBuff)) { - do_autocmd_dirchanged(dir, kCdScopeWindow, false); - } - return OK; } /// Change directory to "new_dir". Search 'cdpath' for relative directory names. int vim_chdir(char_u *new_dir) { - char_u *dir_name = find_directory_in_path(new_dir, STRLEN(new_dir), - FNAME_MESS, curbuf->b_ffname); + char *dir_name = (char *)find_directory_in_path(new_dir, STRLEN(new_dir), + FNAME_MESS, curbuf->b_ffname); if (dir_name == NULL) { return -1; } - int r = os_chdir((char *)dir_name); + int r = os_chdir(dir_name); xfree(dir_name); return r; } diff --git a/src/nvim/file_search.h b/src/nvim/file_search.h index b128029123..4d4e723922 100644 --- a/src/nvim/file_search.h +++ b/src/nvim/file_search.h @@ -1,15 +1,15 @@ #ifndef NVIM_FILE_SEARCH_H #define NVIM_FILE_SEARCH_H -#include <stdlib.h> // for size_t +#include <stdlib.h> // for size_t -#include "nvim/types.h" // for char_u -#include "nvim/globals.h" // for CdScope +#include "nvim/globals.h" // for CdScope +#include "nvim/types.h" // for char_u -/* Flags for find_file_*() functions. */ -#define FINDFILE_FILE 0 /* only files */ -#define FINDFILE_DIR 1 /* only directories */ -#define FINDFILE_BOTH 2 /* files and directories */ +// Flags for find_file_*() functions. +#define FINDFILE_FILE 0 // only files +#define FINDFILE_DIR 1 // only directories +#define FINDFILE_BOTH 2 // files and directories #ifdef INCLUDE_GENERATED_DECLARATIONS # include "file_search.h.generated.h" diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index b7dbda3d99..4a33d74011 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -65,7 +65,7 @@ // For compatibility with libuv < 1.20.0 (tested on 1.18.0) #ifndef UV_FS_COPYFILE_FICLONE -#define UV_FS_COPYFILE_FICLONE 0 +# define UV_FS_COPYFILE_FICLONE 0 #endif #define HAS_BW_FLAGS @@ -105,9 +105,9 @@ struct bw_info { int bw_conv_error; // set for conversion error linenr_T bw_conv_error_lnum; // first line with error or zero linenr_T bw_start_lnum; // line number at start of buffer -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV iconv_t bw_iconv_fd; // descriptor for iconv() or -1 -# endif +#endif }; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -233,11 +233,11 @@ int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_ski char_u *fenc_next = NULL; // next item in 'fencs' or NULL bool advance_fenc = false; long real_size = 0; -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV iconv_t iconv_fd = (iconv_t)-1; // descriptor for iconv() or -1 bool did_iconv = false; // true when iconv() failed and trying // 'charconvert' next -# endif +#endif bool converted = false; // true if conversion done bool notconverted = false; // true if conversion wanted but it wasn't possible char_u conv_rest[CONV_RESTLEN]; @@ -269,10 +269,10 @@ int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_ski } } - /* Remember the initial values of curbuf, curbuf->b_ffname and - * curbuf->b_fname to detect whether they are altered as a result of - * executing nasty autocommands. Also check if "fname" and "sfname" - * point to one of these values. */ + // Remember the initial values of curbuf, curbuf->b_ffname and + // curbuf->b_fname to detect whether they are altered as a result of + // executing nasty autocommands. Also check if "fname" and "sfname" + // point to one of these values. old_curbuf = curbuf; old_b_ffname = curbuf->b_ffname; old_b_fname = curbuf->b_fname; @@ -373,10 +373,10 @@ int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_ski if (perm >= 0 && !S_ISREG(perm) // not a regular file ... && !S_ISFIFO(perm) // ... or fifo && !S_ISSOCK(perm) // ... or socket -# ifdef OPEN_CHR_FILES +#ifdef OPEN_CHR_FILES && !(S_ISCHR(perm) && is_dev_fd_file(fname)) // ... or a character special file named /dev/fd/<n> -# endif +#endif ) { if (S_ISDIR(perm)) { filemess(curbuf, fname, (char_u *)_(msg_is_a_directory), 0); @@ -429,8 +429,8 @@ int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_ski curbuf->b_orig_mode = 0; } - /* Reset the "new file" flag. It will be set again below when the - * file doesn't exist. */ + // Reset the "new file" flag. It will be set again below when the + // file doesn't exist. curbuf->b_flags &= ~(BF_NEW | BF_NEW_W); } @@ -493,11 +493,11 @@ int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_ski } else { filemess(curbuf, sfname, (char_u *)( (fd == UV_EFBIG) ? _("[File too big]") : -# if defined(UNIX) && defined(EOVERFLOW) +#if defined(UNIX) && defined(EOVERFLOW) // libuv only returns -errno in Unix and in Windows open() does not // set EOVERFLOW (fd == -EOVERFLOW) ? _("[File too big]") : -# endif +#endif _("[Permission Denied]")), 0); curbuf->b_p_ro = TRUE; // must use "w!" now } @@ -514,8 +514,8 @@ int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_ski } if (set_options) { - /* Don't change 'eol' if reading from buffer as it will already be - * correctly set when reading stdin. */ + // Don't change 'eol' if reading from buffer as it will already be + // correctly set when reading stdin. if (!read_buffer) { curbuf->b_p_eol = TRUE; curbuf->b_start_eol = TRUE; @@ -768,13 +768,13 @@ retry: } } -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV if (iconv_fd != (iconv_t)-1) { // aborted conversion with iconv(), close the descriptor iconv_close(iconv_fd); iconv_fd = (iconv_t)-1; } -# endif +#endif if (advance_fenc) { /* @@ -816,8 +816,8 @@ retry: fio_flags = 0; converted = need_conversion(fenc); if (converted) { - /* "ucs-bom" means we need to check the first bytes of the file - * for a BOM. */ + // "ucs-bom" means we need to check the first bytes of the file + // for a BOM. if (STRCMP(fenc, ENC_UCSBOM) == 0) { fio_flags = FIO_UCSBOM; } else { @@ -833,13 +833,13 @@ retry: -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV // Try using iconv() if we can't convert internally. if (fio_flags == 0 && !did_iconv) { iconv_fd = (iconv_t)my_iconv_open((char_u *)"utf-8", fenc); } -# endif +#endif /* * Use the 'charconvert' expression when conversion is required @@ -847,13 +847,13 @@ retry: */ if (fio_flags == 0 && !read_stdin && !read_buffer && *p_ccv != NUL && !read_fifo -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV && iconv_fd == (iconv_t)-1 -# endif +#endif ) { -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV did_iconv = false; -# endif +#endif /* Skip conversion when it's already done (retry for wrong * "fileformat"). */ if (tmpname == NULL) { @@ -872,9 +872,9 @@ retry: } } else { if (fio_flags == 0 -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV && iconv_fd == (iconv_t)-1 -# endif +#endif ) { /* Conversion wanted but we can't. * Try the next conversion in 'fileencodings' */ @@ -949,22 +949,22 @@ retry: ptr = buffer + linerest; line_start = buffer; - /* May need room to translate into. - * For iconv() we don't really know the required space, use a - * factor ICONV_MULT. - * latin1 to utf-8: 1 byte becomes up to 2 bytes - * utf-16 to utf-8: 2 bytes become up to 3 bytes, 4 bytes - * become up to 4 bytes, size must be multiple of 2 - * ucs-2 to utf-8: 2 bytes become up to 3 bytes, size must be - * multiple of 2 - * ucs-4 to utf-8: 4 bytes become up to 6 bytes, size must be - * multiple of 4 */ + // May need room to translate into. + // For iconv() we don't really know the required space, use a + // factor ICONV_MULT. + // latin1 to utf-8: 1 byte becomes up to 2 bytes + // utf-16 to utf-8: 2 bytes become up to 3 bytes, 4 bytes + // become up to 4 bytes, size must be multiple of 2 + // ucs-2 to utf-8: 2 bytes become up to 3 bytes, size must be + // multiple of 2 + // ucs-4 to utf-8: 4 bytes become up to 6 bytes, size must be + // multiple of 4 real_size = (int)size; -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV if (iconv_fd != (iconv_t)-1) { size = size / ICONV_MULT; } else { -# endif +#endif if (fio_flags & FIO_LATIN1) { size = size / 2; } else if (fio_flags & (FIO_UCS2 | FIO_UTF16)) { @@ -974,9 +974,9 @@ retry: } else if (fio_flags == FIO_UCSBOM) { size = size / ICONV_MULT; // worst case } -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV } -# endif +#endif if (conv_restlen > 0) { // Insert unconverted bytes from previous line. memmove(ptr, conv_rest, conv_restlen); // -V614 @@ -1000,9 +1000,9 @@ retry: p = ml_get(read_buf_lnum) + read_buf_col; n = (int)STRLEN(p); if ((int)tlen + n + 1 > size) { - /* Filled up to "size", append partial line. - * Change NL to NUL to reverse the effect done - * below. */ + // Filled up to "size", append partial line. + // Change NL to NUL to reverse the effect done + // below. n = (int)(size - tlen); for (ni = 0; ni < n; ++ni) { if (p[ni] == NL) { @@ -1026,8 +1026,8 @@ retry: ptr[tlen++] = NL; read_buf_col = 0; if (++read_buf_lnum > from) { - /* When the last line didn't have an - * end-of-line don't add it now either. */ + // When the last line didn't have an + // end-of-line don't add it now either. if (!curbuf->b_p_eol) { --tlen; } @@ -1055,9 +1055,9 @@ retry: // When we did a conversion report an error. if (fio_flags != 0 -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV || iconv_fd != (iconv_t)-1 -# endif +#endif ) { if (can_retry) { goto rewind_retry; @@ -1081,9 +1081,9 @@ retry: * leave the UTF8 checking code to do it, as it * works slightly differently. */ if (bad_char_behavior != BAD_KEEP && (fio_flags != 0 -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV || iconv_fd != (iconv_t)-1 -# endif +#endif )) { while (conv_restlen > 0) { *(--ptr) = bad_char_behavior; @@ -1091,12 +1091,12 @@ retry: } } fio_flags = 0; // don't convert this -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV if (iconv_fd != (iconv_t)-1) { iconv_close(iconv_fd); iconv_fd = (iconv_t)-1; } -# endif +#endif } } } @@ -1165,7 +1165,7 @@ retry: break; } -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV if (iconv_fd != (iconv_t)-1) { /* * Attempt conversion of the read bytes to 'encoding' using @@ -1223,7 +1223,7 @@ retry: memmove(line_start, buffer, (size_t)linerest); size = ((char_u *)top - ptr); } -# endif +#endif if (fio_flags != 0) { unsigned int u8c; @@ -1279,8 +1279,8 @@ retry: } } - /* If there is a trailing incomplete sequence move it to - * conv_rest[]. */ + // If there is a trailing incomplete sequence move it to + // conv_rest[]. if (tail != NULL) { conv_restlen = (int)((ptr + size) - tail); memmove(conv_rest, tail, conv_restlen); @@ -1320,8 +1320,8 @@ retry: } } - /* found second word of double-word, get the first - * word and compute the resulting character */ + // found second word of double-word, get the first + // word and compute the resulting character if (fio_flags & FIO_ENDIAN_L) { u16c = (*--p << 8); u16c += *--p; @@ -1369,9 +1369,9 @@ retry: p -= len; u8c = utf_ptr2char(p); if (len == 0) { - /* Not a valid UTF-8 character, retry with - * another fenc when possible, otherwise just - * report the error. */ + // Not a valid UTF-8 character, retry with + // another fenc when possible, otherwise just + // report the error. if (can_retry) { goto rewind_retry; } @@ -1435,18 +1435,18 @@ retry: } } if (l == 1 || l > todo) { - /* Illegal byte. If we can try another encoding - * do that, unless at EOF where a truncated - * file is more likely than a conversion error. */ + // Illegal byte. If we can try another encoding + // do that, unless at EOF where a truncated + // file is more likely than a conversion error. if (can_retry && !incomplete_tail) { break; } -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV // When we did a conversion report an error. if (iconv_fd != (iconv_t)-1 && conv_error == 0) { conv_error = readfile_linenr(linecnt, ptr, p); } -# endif +#endif // Remember the first linenr with an illegal byte if (conv_error == 0 && illegal_byte == 0) { illegal_byte = readfile_linenr(linecnt, ptr, p); @@ -1469,17 +1469,17 @@ retry: // Detected a UTF-8 error. rewind_retry: // Retry reading with another conversion. -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV if (*p_ccv != NUL && iconv_fd != (iconv_t)-1) { // iconv() failed, try 'charconvert' did_iconv = true; } else { -# endif +#endif // use next item from 'fileencodings' advance_fenc = true; -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV } -# endif +#endif file_rewind = true; goto retry; } @@ -1700,11 +1700,11 @@ failed: if (fenc_alloced) { xfree(fenc); } -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV if (iconv_fd != (iconv_t)-1) { iconv_close(iconv_fd); } -# endif +#endif if (!read_buffer && !read_stdin) { close(fd); // errors are ignored @@ -1909,8 +1909,8 @@ failed: */ curbuf->b_no_eol_lnum = read_no_eol_lnum; - /* When reloading a buffer put the cursor at the first line that is - * different. */ + // When reloading a buffer put the cursor at the first line that is + // different. if (flags & READ_KEEP_UNDO) { u_find_first_changed(); } @@ -1929,8 +1929,8 @@ failed: int m = msg_scroll; int n = msg_scrolled; - /* Save the fileformat now, otherwise the buffer will be considered - * modified if the format/encoding was automatically detected. */ + // Save the fileformat now, otherwise the buffer will be considered + // modified if the format/encoding was automatically detected. if (set_options) { save_file_ff(curbuf); } @@ -2280,9 +2280,9 @@ int buf_write(buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_ write_info.bw_conv_error = FALSE; write_info.bw_conv_error_lnum = 0; write_info.bw_restlen = 0; -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV write_info.bw_iconv_fd = (iconv_t)-1; -# endif +#endif /* After writing a file changedtick changes but we don't want to display * the line. */ @@ -2690,7 +2690,7 @@ int buf_write(buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_ if (fd < 0) { // can't write in directory backup_copy = TRUE; } else { -# ifdef UNIX +#ifdef UNIX os_fchown(fd, file_info_old.stat.st_uid, file_info_old.stat.st_gid); if (!os_fileinfo((char *)IObuff, &file_info) || file_info.stat.st_uid != file_info_old.stat.st_uid @@ -2698,7 +2698,7 @@ int buf_write(buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_ || (long)file_info.stat.st_mode != perm) { backup_copy = TRUE; } -# endif +#endif /* Close the file before removing it, on MS-Windows we * can't delete an open file. */ close(fd); @@ -2711,7 +2711,7 @@ int buf_write(buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_ * Break symlinks and/or hardlinks if we've been asked to. */ if ((bkc & BKC_BREAKSYMLINK) || (bkc & BKC_BREAKHARDLINK)) { -# ifdef UNIX +#ifdef UNIX bool file_info_link_ok = os_fileinfo_link((char *)fname, &file_info); // Symlinks. @@ -2728,7 +2728,7 @@ int buf_write(buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_ || os_fileinfo_id_equal(&file_info, &file_info_old))) { backup_copy = FALSE; } -# endif +#endif } // make sure we have a valid backup extension to use @@ -3085,7 +3085,7 @@ nobackup: if (converted && wb_flags == 0) { -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV // Use iconv() conversion when conversion is needed and it's not done // internally. write_info.bw_iconv_fd = (iconv_t)my_iconv_open(fenc, (char_u *)"utf-8"); @@ -3098,7 +3098,7 @@ nobackup: } write_info.bw_first = TRUE; } else -# endif +#endif /* * When the file needs to be converted with 'charconvert' after @@ -3114,9 +3114,9 @@ nobackup: } } if (converted && wb_flags == 0 -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV && write_info.bw_iconv_fd == (iconv_t)-1 -# endif +#endif && wfname == fname) { if (!forceit) { SET_ERRMSG(_("E213: Cannot convert (add ! to write without conversion)")); @@ -3154,8 +3154,8 @@ nobackup: O_WRONLY | (append ? (forceit ? (O_APPEND | O_CREAT) : O_APPEND) - : (O_CREAT | O_TRUNC)) - , perm < 0 ? 0666 : (perm & 0777))) < 0) { + : (O_CREAT | O_TRUNC)), + perm < 0 ? 0666 : (perm & 0777))) < 0) { // A forced write will try to create a new file if the old one // is still readonly. This may also happen when the directory // is read-only. In that case the mch_remove() will fail. @@ -3644,12 +3644,12 @@ nofail: } xfree(fenc_tofree); xfree(write_info.bw_conv_buf); -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV if (write_info.bw_iconv_fd != (iconv_t)-1) { iconv_close(write_info.bw_iconv_fd); write_info.bw_iconv_fd = (iconv_t)-1; } -# endif +#endif #ifdef HAVE_ACL mch_free_acl(acl); #endif @@ -4034,7 +4034,7 @@ static int buf_write_bytes(struct bw_info *ip) } } -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV if (ip->bw_iconv_fd != (iconv_t)-1) { const char *from; size_t fromlen; @@ -4096,7 +4096,7 @@ static int buf_write_bytes(struct bw_info *ip) buf = ip->bw_conv_buf; len = (int)((char_u *)to - ip->bw_conv_buf); } -# endif +#endif } if (ip->bw_fd < 0) { @@ -4684,7 +4684,7 @@ int vim_rename(const char_u *from, const char_u *to) } STRCPY(tempname, from); for (n = 123; n < 99999; n++) { - char * tail = (char *)path_tail(tempname); + char *tail = (char *)path_tail(tempname); snprintf(tail, (MAXPATHL + 1) - (tail - (char *)tempname - 1), "%d", n); if (!os_path_exists(tempname)) { @@ -4804,15 +4804,15 @@ int check_timestamps(int focus) { int didit = 0; - /* Don't check timestamps while system() or another low-level function may - * cause us to lose and gain focus. */ + // Don't check timestamps while system() or another low-level function may + // cause us to lose and gain focus. if (no_check_timestamps > 0) { return FALSE; } - /* Avoid doing a check twice. The OK/Reload dialog can cause a focus - * event and we would keep on checking if the file is steadily growing. - * Do check again after typing something. */ + // Avoid doing a check twice. The OK/Reload dialog can cause a focus + // event and we would keep on checking if the file is steadily growing. + // Do check again after typing something. if (focus && did_check_timestamps) { need_check_timestamps = TRUE; return FALSE; @@ -5025,8 +5025,8 @@ int buf_check_timestamp(buf_T *buf) mesg = _("W16: Warning: Mode of file \"%s\" has changed since editing started"); mesg2 = _("See \":help W16\" for more info."); } else { - /* Only timestamp changed, store it to avoid a warning - * in check_mtime() later. */ + // Only timestamp changed, store it to avoid a warning + // in check_mtime() later. buf->b_mtime_read = buf->b_mtime; } } @@ -5538,8 +5538,8 @@ bool match_file_list(char_u *list, char_u *sfname, char_u *ffname) /// @param no_bslash Don't use a backward slash as pathsep /// /// @return NULL on failure. -char_u * file_pat_to_reg_pat(const char_u *pat, const char_u *pat_end, char *allow_dirs, - int no_bslash) +char_u *file_pat_to_reg_pat(const char_u *pat, const char_u *pat_end, char *allow_dirs, + int no_bslash) FUNC_ATTR_NONNULL_ARG(1) { const char_u *endp; @@ -5623,12 +5623,11 @@ char_u * file_pat_to_reg_pat(const char_u *pat, const char_u *pat_end, char *all } #ifdef BACKSLASH_IN_FILENAME if (!no_bslash) { - /* translate: - * "\x" to "\\x" e.g., "dir\file" - * "\*" to "\\.*" e.g., "dir\*.c" - * "\?" to "\\." e.g., "dir\??.c" - * "\+" to "\+" e.g., "fileX\+.c" - */ + // translate: + // "\x" to "\\x" e.g., "dir\file" + // "\*" to "\\.*" e.g., "dir\*.c" + // "\?" to "\\." e.g., "dir\??.c" + // "\+" to "\+" e.g., "fileX\+.c" if ((vim_isfilec(p[1]) || p[1] == '*' || p[1] == '?') && p[1] != '+') { reg_pat[i++] = '['; @@ -5642,16 +5641,15 @@ char_u * file_pat_to_reg_pat(const char_u *pat, const char_u *pat_end, char *all } } #endif - /* Undo escaping from ExpandEscape(): - * foo\?bar -> foo?bar - * foo\%bar -> foo%bar - * foo\,bar -> foo,bar - * foo\ bar -> foo bar - * Don't unescape \, * and others that are also special in a - * regexp. - * An escaped { must be unescaped since we use magic not - * verymagic. Use "\\\{n,m\}"" to get "\{n,m}". - */ + // Undo escaping from ExpandEscape(): + // foo\?bar -> foo?bar + // foo\%bar -> foo%bar + // foo\,bar -> foo,bar + // foo\ bar -> foo bar + // Don't unescape \, * and others that are also special in a + // regexp. + // An escaped { must be unescaped since we use magic not + // verymagic. Use "\\\{n,m\}"" to get "\{n,m}". if (*++p == '?' #ifdef BACKSLASH_IN_FILENAME && no_bslash diff --git a/src/nvim/fileio.h b/src/nvim/fileio.h index 71149bdcc1..9bfec44ef3 100644 --- a/src/nvim/fileio.h +++ b/src/nvim/fileio.h @@ -1,9 +1,9 @@ #ifndef NVIM_FILEIO_H #define NVIM_FILEIO_H +#include "nvim/autocmd.h" #include "nvim/buffer_defs.h" #include "nvim/os/os.h" -#include "nvim/autocmd.h" // Values for readfile() flags #define READ_NEW 0x01 // read a file into a new buffer diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 7a017702ee..e141f9bb62 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -224,8 +224,8 @@ bool hasFoldingWin(win_T *const win, const linenr_T lnum, linenr_T *const firstp break; } - /* Fold found, but it's open: Check nested folds. Line number is - * relative to containing fold. */ + // Fold found, but it's open: Check nested folds. Line number is + // relative to containing fold. gap = &fp->fd_nested; lnum_rel -= fp->fd_top; ++level; @@ -264,8 +264,8 @@ bool hasFoldingWin(win_T *const win, const linenr_T lnum, linenr_T *const firstp */ int foldLevel(linenr_T lnum) { - /* While updating the folds lines between invalid_top and invalid_bot have - * an undefined fold level. Otherwise update the folds first. */ + // While updating the folds lines between invalid_top and invalid_bot have + // an undefined fold level. Otherwise update the folds first. if (invalid_top == (linenr_T)0) { checkupdate(curwin); } else if (lnum == prev_lnum && prev_lnum_lvl >= 0) { @@ -492,9 +492,9 @@ static void newFoldLevelWin(win_T *wp) checkupdate(wp); if (wp->w_fold_manual) { - /* Set all flags for the first level of folds to FD_LEVEL. Following - * manual open/close will then change the flags to FD_OPEN or - * FD_CLOSED for those folds that don't use 'foldlevel'. */ + // Set all flags for the first level of folds to FD_LEVEL. Following + // manual open/close will then change the flags to FD_OPEN or + // FD_CLOSED for those folds that don't use 'foldlevel'. fp = (fold_T *)wp->w_folds.ga_data; for (int i = 0; i < wp->w_folds.ga_len; ++i) { fp[i].fd_flags = FD_LEVEL; @@ -904,8 +904,8 @@ int foldMoveTo(const bool updown, const int dir, const long count) break; } - /* When moving up, consider a fold above the cursor; when - * moving down consider a fold below the cursor. */ + // When moving up, consider a fold above the cursor; when + // moving down consider a fold below the cursor. if (dir == FORWARD) { if (fp - (fold_T *)gap->ga_data >= gap->ga_len) { break; @@ -1414,7 +1414,7 @@ static void deleteFoldEntry(win_T *const wp, garray_T *const gap, const int idx, */ void deleteFoldRecurse(buf_T *bp, garray_T *gap) { -# define DELETE_FOLD_NESTED(fd) deleteFoldRecurse(bp, &((fd)->fd_nested)) +#define DELETE_FOLD_NESTED(fd) deleteFoldRecurse(bp, &((fd)->fd_nested)) GA_DEEP_CLEAR(gap, fold_T, DELETE_FOLD_NESTED); } @@ -1424,13 +1424,13 @@ void deleteFoldRecurse(buf_T *bp, garray_T *gap) */ void foldMarkAdjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after) { - /* If deleting marks from line1 to line2, but not deleting all those - * lines, set line2 so that only deleted lines have their folds removed. */ + // If deleting marks from line1 to line2, but not deleting all those + // lines, set line2 so that only deleted lines have their folds removed. if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after) { line2 = line1 - amount_after - 1; } - /* If appending a line in Insert mode, it should be included in the fold - * just above the line. */ + // If appending a line in Insert mode, it should be included in the fold + // just above the line. if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) { line1--; } @@ -1449,8 +1449,8 @@ static void foldMarkAdjustRecurse(win_T *wp, garray_T *gap, linenr_T line1, line return; } - /* In Insert mode an inserted line at the top of a fold is considered part - * of the fold, otherwise it isn't. */ + // In Insert mode an inserted line at the top of a fold is considered part + // of the fold, otherwise it isn't. if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) { top = line1 + 1; } else { @@ -1580,8 +1580,8 @@ static bool check_closed(win_T *const wp, fold_T *const fp, bool *const use_leve { bool closed = false; - /* Check if this fold is closed. If the flag is FD_LEVEL this - * fold and all folds it contains depend on 'foldlevel'. */ + // Check if this fold is closed. If the flag is FD_LEVEL this + // fold and all folds it contains depend on 'foldlevel'. if (*use_levelp || fp->fd_flags == FD_LEVEL) { *use_levelp = true; if (level >= wp->w_p_fdl) { @@ -1838,8 +1838,7 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T foldin curbuf = wp->w_buffer; emsg_silent++; // handle exceptions, but don't display errors - text = eval_to_string_safe(wp->w_p_fdt, NULL, - was_set_insecurely(wp, (char_u *)"foldtext", OPT_LOCAL)); + text = eval_to_string_safe(wp->w_p_fdt, NULL, was_set_insecurely(wp, "foldtext", OPT_LOCAL)); emsg_silent--; if (text == NULL || did_emsg) { @@ -1875,7 +1874,7 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T foldin } } if (*p != NUL) { - p = (char_u *)transstr((const char *)text); + p = (char_u *)transstr((const char *)text, true); xfree(text); text = p; } @@ -2036,8 +2035,8 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) // Init marker variables to speed up foldlevelMarker(). parseMarker(wp); - /* Need to get the level of the line above top, it is used if there is - * no marker at the top. */ + // Need to get the level of the line above top, it is used if there is + // no marker at the top. if (top > 1) { // Get the fold level at top - 1. const int level = foldLevelWin(wp, top - 1); @@ -2047,9 +2046,9 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) fline.lvl = level; getlevel(&fline); - /* If a fold started here, we already had the level, if it stops - * here, we need to use lvl_next. Could also start and end a fold - * in the same line. */ + // If a fold started here, we already had the level, if it stops + // here, we need to use lvl_next. Could also start and end a fold + // in the same line. if (fline.lvl > level) { fline.lvl = level - (fline.lvl - fline.lvl_next); } else { @@ -2062,8 +2061,8 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) fline.lnum = top; if (foldmethodIsExpr(wp)) { getlevel = foldlevelExpr; - /* start one line back, because a "<1" may indicate the end of a - * fold in the topline */ + // start one line back, because a "<1" may indicate the end of a + // fold in the topline if (top > 1) { --fline.lnum; } @@ -2152,9 +2151,9 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) end = fp->fd_top + fp->fd_len - 1; } else if (getlevel == foldlevelSyntax && foldLevelWin(wp, fline.lnum) != fline.lvl) { - /* For "syntax" method: Compare the foldlevel that the syntax - * tells us to the foldlevel from the existing folds. If they - * don't match continue updating folds. */ + // For "syntax" method: Compare the foldlevel that the syntax + // tells us to the foldlevel from the existing folds. If they + // don't match continue updating folds. end = fline.lnum; } else { break; @@ -2186,9 +2185,9 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) changed_window_setting_win(wp); } - /* If we updated folds past "bot", need to redraw more lines. Don't do - * this in other situations, the changed lines will be redrawn anyway and - * this method can cause the whole window to be updated. */ + // If we updated folds past "bot", need to redraw more lines. Don't do + // this in other situations, the changed lines will be redrawn anyway and + // this method can cause the whole window to be updated. if (end != bot) { if (wp->w_redraw_top == 0 || wp->w_redraw_top > top) { wp->w_redraw_top = top; @@ -2273,10 +2272,10 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level, // Updating folds can be slow, check for CTRL-C. line_breakcheck(); - /* Set "lvl" to the level of line "flp->lnum". When flp->start is set - * and after the first line of the fold, set the level to zero to - * force the fold to end. Do the same when had_end is set: Previous - * line was marked as end of a fold. */ + // Set "lvl" to the level of line "flp->lnum". When flp->start is set + // and after the first line of the fold, set the level to zero to + // force the fold to end. Do the same when had_end is set: Previous + // line was marked as end of a fold. lvl = flp->lvl; if (lvl > MAX_LEVEL) { lvl = MAX_LEVEL; @@ -2287,12 +2286,11 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level, } if (flp->lnum > bot && !finish && fp != NULL) { - /* For "marker" and "syntax" methods: - * - If a change caused a nested fold to be removed, we need to - * delete it and continue at least until where it ended. - * - If a change caused a nested fold to be created, or this fold - * to continue below its original end, need to finish this fold. - */ + // For "marker" and "syntax" methods: + // - If a change caused a nested fold to be removed, we need to + // delete it and continue at least until where it ended. + // - If a change caused a nested fold to be created, or this fold + // to continue below its original end, need to finish this fold. if (getlevel != foldlevelMarker && getlevel != foldlevelExpr && getlevel != foldlevelSyntax) { @@ -2301,9 +2299,9 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level, i = 0; fp2 = fp; if (lvl >= level) { - /* Compute how deep the folds currently are, if it's deeper - * than "lvl" then some must be deleted, need to update - * at least one nested fold. */ + // Compute how deep the folds currently are, if it's deeper + // than "lvl" then some must be deleted, need to update + // at least one nested fold. ll = flp->lnum - fp->fd_top; while (foldFind(&fp2->fd_nested, ll, &fp2)) { ++i; @@ -2322,9 +2320,9 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level, } } - /* At the start of the first nested fold and at the end of the current - * fold: check if existing folds at this level, before the current - * one, need to be deleted or truncated. */ + // At the start of the first nested fold and at the end of the current + // fold: check if existing folds at this level, before the current + // one, need to be deleted or truncated. if (fp == NULL && (lvl != level || flp->lnum_save >= bot @@ -2357,10 +2355,10 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level, || (lvl >= level && fp->fd_top <= flp->lnum_save))))) { if (fp->fd_top + fp->fd_len + concat > firstlnum) { - /* Use existing fold for the new fold. If it starts - * before where we started looking, extend it. If it - * starts at another line, update nested folds to keep - * their position, compensating for the new fd_top. */ + // Use existing fold for the new fold. If it starts + // before where we started looking, extend it. If it + // starts at another line, update nested folds to keep + // their position, compensating for the new fd_top. if (fp->fd_top == firstlnum) { // We have found a fold beginning exactly where we want one. } else if (fp->fd_top >= startlnum) { @@ -2504,8 +2502,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level, bot = flp->lnum; } - /* Line numbers in the nested fold are relative to the start of - * this fold. */ + // Line numbers in the nested fold are relative to the start of + // this fold. flp->lnum = flp->lnum_save - fp->fd_top; flp->off += fp->fd_top; i = (int)(fp - (fold_T *)gap->ga_data); @@ -2548,8 +2546,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level, break; } - /* leave flp->lnum_save to lnum of the line that was used to get - * the level, flp->lnum to the lnum of the next line. */ + // leave flp->lnum_save to lnum of the line that was used to get + // the level, flp->lnum to the lnum of the next line. flp->lnum_save = flp->lnum; flp->lnum = ll; } @@ -2634,8 +2632,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level, deleteFoldEntry(flp->wp, gap, (int)(fp2 - (fold_T *)gap->ga_data), true); } - /* Need to redraw the lines we inspected, which might be further down than - * was asked for. */ + // Need to redraw the lines we inspected, which might be further down than + // was asked for. if (bot < flp->lnum - 1) { bot = flp->lnum - 1; } @@ -2948,8 +2946,8 @@ static void foldMerge(win_T *const wp, fold_T *fp1, garray_T *gap, fold_T *fp2) garray_T *gap1 = &fp1->fd_nested; garray_T *gap2 = &fp2->fd_nested; - /* If the last nested fold in fp1 touches the first nested fold in fp2, - * merge them recursively. */ + // If the last nested fold in fp1 touches the first nested fold in fp2, + // merge them recursively. if (foldFind(gap1, fp1->fd_len - 1L, &fp3) && foldFind(gap2, 0L, &fp4)) { foldMerge(wp, fp3, gap2, fp4); } @@ -2986,8 +2984,8 @@ static void foldlevelIndent(fline_T *flp) buf = flp->wp->w_buffer; s = skipwhite(ml_get_buf(buf, lnum, false)); - /* empty line or lines starting with a character in 'foldignore': level - * depends on surrounding lines */ + // empty line or lines starting with a character in 'foldignore': level + // depends on surrounding lines if (*s == NUL || vim_strchr(flp->wp->w_p_fdi, *s) != NULL) { // first and last line can't be undefined, use level 0 if (lnum == 1 || lnum == buf->b_ml.ml_line_count) { @@ -3090,8 +3088,8 @@ static void foldlevelExpr(fline_T *flp) // "-1", "0", "1", ..: set fold level default: if (n < 0) { - /* Use the current level for the next line, so that "a1" - * will work there. */ + // Use the current level for the next line, so that "a1" + // will work there. flp->lvl_next = flp->lvl; } else { flp->lvl_next = n; @@ -3100,8 +3098,8 @@ static void foldlevelExpr(fline_T *flp) break; } - /* If the level is unknown for the first or the last line in the file, use - * level 0. */ + // If the level is unknown for the first or the last line in the file, use + // level 0. if (flp->lvl < 0) { if (lnum <= 1) { flp->lvl = 0; diff --git a/src/nvim/fold.h b/src/nvim/fold.h index 37fab4da60..a96ea8a039 100644 --- a/src/nvim/fold.h +++ b/src/nvim/fold.h @@ -3,17 +3,17 @@ #include <stdio.h> -#include "nvim/pos.h" +#include "nvim/buffer_defs.h" #include "nvim/garray.h" +#include "nvim/pos.h" #include "nvim/types.h" -#include "nvim/buffer_defs.h" /* * Info used to pass info about a fold from the fold-detection code to the * code that displays the foldcolumn. */ typedef struct foldinfo { - linenr_T fi_lnum; /* line number where fold starts */ + linenr_T fi_lnum; // line number where fold starts int fi_level; /* level of the fold; when this is zero the other fields are invalid */ int fi_low_level; /* lowest fold level that starts in the same diff --git a/src/nvim/func_attr.h b/src/nvim/func_attr.h index e0b0610646..afbd87f2be 100644 --- a/src/nvim/func_attr.h +++ b/src/nvim/func_attr.h @@ -1,24 +1,24 @@ -// If DEFINE_FUNC_ATTRIBUTES macro is not defined then all function attributes +// If DEFINE_FUNC_ATTRIBUTES macro is not defined then all function attributes // are defined as empty values. // -// If DO_NOT_DEFINE_EMPTY_ATTRIBUTES then empty macros are not defined. Thus -// undefined DEFINE_FUNC_ATTRIBUTES and defined DO_NOT_DEFINE_EMPTY_ATTRIBUTES -// leaves file with untouched FUNC_ATTR_* macros. This variant is used for +// If DO_NOT_DEFINE_EMPTY_ATTRIBUTES then empty macros are not defined. Thus +// undefined DEFINE_FUNC_ATTRIBUTES and defined DO_NOT_DEFINE_EMPTY_ATTRIBUTES +// leaves file with untouched FUNC_ATTR_* macros. This variant is used for // scripts/gendeclarations.lua. // -// Empty macros are used for *.c files. (undefined DEFINE_FUNC_ATTRIBUTES and +// Empty macros are used for *.c files. (undefined DEFINE_FUNC_ATTRIBUTES and // undefined DO_NOT_DEFINE_EMPTY_ATTRIBUTES) // -// Macros defined as __attribute__((*)) are used by generated header files. -// (defined DEFINE_FUNC_ATTRIBUTES and undefined +// Macros defined as __attribute__((*)) are used by generated header files. +// (defined DEFINE_FUNC_ATTRIBUTES and undefined // DO_NOT_DEFINE_EMPTY_ATTRIBUTES) // -// Defined DEFINE_FUNC_ATTRIBUTES and defined DO_NOT_DEFINE_EMPTY_ATTRIBUTES is +// Defined DEFINE_FUNC_ATTRIBUTES and defined DO_NOT_DEFINE_EMPTY_ATTRIBUTES is // not used by anything. -// FUNC_ATTR_* macros should be in *.c files for declarations generator. If you -// define a function for which declaration is not generated by -// gendeclarations.lua (e.g. template hash implementation) then you should use +// FUNC_ATTR_* macros should be in *.c files for declarations generator. If you +// define a function for which declaration is not generated by +// gendeclarations.lua (e.g. template hash implementation) then you should use // REAL_FATTR_* macros. // gcc and clang expose their version as follows: @@ -134,10 +134,10 @@ # if NVIM_HAS_ATTRIBUTE(no_sanitize_undefined) # define REAL_FATTR_NO_SANITIZE_UNDEFINED \ - __attribute__((no_sanitize_undefined)) + __attribute__((no_sanitize_undefined)) # elif NVIM_HAS_ATTRIBUTE(no_sanitize) # define REAL_FATTR_NO_SANITIZE_UNDEFINED \ - __attribute__((no_sanitize("undefined"))) + __attribute__((no_sanitize("undefined"))) # endif # endif diff --git a/src/nvim/garray.c b/src/nvim/garray.c index 1cfc2b6176..7a3cc4a944 100644 --- a/src/nvim/garray.c +++ b/src/nvim/garray.c @@ -5,16 +5,16 @@ /// /// Functions for handling growing arrays. -#include <string.h> #include <inttypes.h> +#include <string.h> -#include "nvim/vim.h" #include "nvim/ascii.h" +#include "nvim/garray.h" #include "nvim/log.h" #include "nvim/memory.h" #include "nvim/path.h" -#include "nvim/garray.h" #include "nvim/strings.h" +#include "nvim/vim.h" // #include "nvim/globals.h" #include "nvim/memline.h" @@ -143,14 +143,14 @@ void ga_remove_duplicate_strings(garray_T *gap) /// @param sep /// /// @returns the concatenated strings -char_u *ga_concat_strings_sep(const garray_T *gap, const char *sep) +char *ga_concat_strings_sep(const garray_T *gap, const char *sep) FUNC_ATTR_NONNULL_RET { - const size_t nelem = (size_t) gap->ga_len; + const size_t nelem = (size_t)gap->ga_len; const char **strings = gap->ga_data; if (nelem == 0) { - return (char_u *) xstrdup(""); + return xstrdup(""); } size_t len = 0; @@ -169,7 +169,7 @@ char_u *ga_concat_strings_sep(const garray_T *gap, const char *sep) } strcpy(s, strings[nelem - 1]); - return (char_u *) ret; + return ret; } /// For a growing array that contains a list of strings: concatenate all the @@ -178,9 +178,9 @@ char_u *ga_concat_strings_sep(const garray_T *gap, const char *sep) /// @param gap /// /// @returns the concatenated strings -char_u* ga_concat_strings(const garray_T *gap) FUNC_ATTR_NONNULL_RET +char_u *ga_concat_strings(const garray_T *gap) FUNC_ATTR_NONNULL_RET { - return ga_concat_strings_sep(gap, ","); + return (char_u *)ga_concat_strings_sep(gap, ","); } /// Concatenate a string to a growarray which contains characters. @@ -192,13 +192,13 @@ char_u* ga_concat_strings(const garray_T *gap) FUNC_ATTR_NONNULL_RET /// /// @param gap /// @param s -void ga_concat(garray_T *gap, const char_u *restrict s) +void ga_concat(garray_T *gap, const char *restrict s) { if (s == NULL) { return; } - ga_concat_len(gap, (const char *restrict) s, strlen((char *) s)); + ga_concat_len(gap, s, STRLEN(s)); } /// Concatenate a string to a growarray which contains characters @@ -206,15 +206,14 @@ void ga_concat(garray_T *gap, const char_u *restrict s) /// @param[out] gap Growarray to modify. /// @param[in] s String to concatenate. /// @param[in] len String length. -void ga_concat_len(garray_T *const gap, const char *restrict s, - const size_t len) +void ga_concat_len(garray_T *const gap, const char *restrict s, const size_t len) FUNC_ATTR_NONNULL_ALL { if (len) { - ga_grow(gap, (int) len); + ga_grow(gap, (int)len); char *data = gap->ga_data; memcpy(data + gap->ga_len, s, len); - gap->ga_len += (int) len; + gap->ga_len += (int)len; } } diff --git a/src/nvim/garray.h b/src/nvim/garray.h index e2cbdd4eab..56bd5c9130 100644 --- a/src/nvim/garray.h +++ b/src/nvim/garray.h @@ -3,8 +3,8 @@ #include <stddef.h> // for size_t -#include "nvim/types.h" // for char_u #include "nvim/log.h" +#include "nvim/types.h" // for char_u /// Structure used for growing arrays. /// This is used to store information that only grows, is deleted all at @@ -68,6 +68,6 @@ static inline void *ga_append_via_ptr(garray_T *gap, size_t item_size) /// garray. /// /// @param gap the garray to be freed -#define GA_DEEP_CLEAR_PTR(gap) GA_DEEP_CLEAR(gap, void*, FREE_PTR_PTR) +#define GA_DEEP_CLEAR_PTR(gap) GA_DEEP_CLEAR(gap, void *, FREE_PTR_PTR) #endif // NVIM_GARRAY_H diff --git a/src/nvim/generators/c_grammar.lua b/src/nvim/generators/c_grammar.lua index c9ab0cf709..f35817c466 100644 --- a/src/nvim/generators/c_grammar.lua +++ b/src/nvim/generators/c_grammar.lua @@ -16,8 +16,9 @@ local ws = S(' \t') + nl local fill = ws ^ 0 local c_comment = P('//') * (not_nl ^ 0) local c_preproc = P('#') * (not_nl ^ 0) +local dllexport = P('DLLEXPORT') * (ws ^ 1) local typed_container = - (P('ArrayOf(') + P('DictionaryOf(')) * ((any - P(')')) ^ 1) * P(')') + (P('ArrayOf(') + P('DictionaryOf(') + P('Dict(')) * ((any - P(')')) ^ 1) * P(')') local c_id = ( typed_container + (letter * (alpha ^ 0)) @@ -33,6 +34,7 @@ local c_param = Ct(c_param_type * C(c_id)) local c_param_list = c_param * (fill * (P(',') * fill * c_param) ^ 0) local c_params = Ct(c_void + c_param_list) local c_proto = Ct( + (dllexport ^ -1) * Cg(c_type, 'return_type') * Cg(c_id, 'name') * fill * P('(') * fill * Cg(c_params, 'parameters') * fill * P(')') * Cg(Cc(false), 'fast') * diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 99d80cdebc..21f8c3855e 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -33,6 +33,10 @@ local function_names = {} local c_grammar = require('generators.c_grammar') +local function startswith(String,Start) + return string.sub(String,1,string.len(Start))==Start +end + -- read each input file, parse and append to the api metadata for i = 6, #arg do local full_path = arg[i] @@ -47,7 +51,8 @@ for i = 6, #arg do local tmp = c_grammar.grammar:match(input:read('*all')) for j = 1, #tmp do local fn = tmp[j] - if not fn.noexport then + local public = startswith(fn.name, "nvim_") or fn.deprecated_since + if public and not fn.noexport then functions[#functions + 1] = tmp[j] function_names[fn.name] = true if #fn.parameters ~= 0 and fn.parameters[1][2] == 'channel_id' then @@ -76,10 +81,6 @@ local function shallowcopy(orig) return copy end -local function startswith(String,Start) - return string.sub(String,1,string.len(Start))==Start -end - -- Export functions under older deprecated names. -- These will be removed eventually. local deprecated_aliases = require("api.dispatch_deprecated") @@ -108,9 +109,10 @@ for _,f in ipairs(shallowcopy(functions)) do f.lua = f.lua_only or not f.remote_only f.eval = (not f.lua_only) and (not f.remote_only) else + f.deprecated_since = tonumber(f.deprecated_since) + assert(f.deprecated_since == 1) f.remote = true f.since = 0 - f.deprecated_since = 1 end f.method = ismethod local newname = deprecated_aliases[f.name] @@ -152,6 +154,8 @@ for _,f in ipairs(functions) do for i,param in ipairs(f.parameters) do if param[1] == "DictionaryOf(LuaRef)" then param = {"Dictionary", param[2]} + elseif startswith(param[1], "Dict(") then + param = {"Dictionary", param[2]} end f_exported.parameters[i] = param end @@ -173,7 +177,10 @@ local output = io.open(dispatch_outputf, 'wb') local function real_type(type) local rv = type - if c_grammar.typed_container:match(rv) then + local rmatch = string.match(type, "Dict%(([_%w]+)%)") + if rmatch then + return "KeyDict_"..rmatch + elseif c_grammar.typed_container:match(rv) then if rv:match('Array') then rv = 'Array' else @@ -209,8 +216,9 @@ for i = 1, #functions do -- Declare/initialize variables that will hold converted arguments for j = 1, #fn.parameters do local param = fn.parameters[j] + local rt = real_type(param[1]) local converted = 'arg_'..j - output:write('\n '..param[1]..' '..converted..';') + output:write('\n '..rt..' '..converted..';') end output:write('\n') output:write('\n if (args.size != '..#fn.parameters..') {') @@ -225,7 +233,24 @@ for i = 1, #functions do param = fn.parameters[j] converted = 'arg_'..j local rt = real_type(param[1]) - if rt ~= 'Object' then + if rt == 'Object' then + output:write('\n '..converted..' = args.items['..(j - 1)..'];\n') + elseif rt:match('^KeyDict_') then + converted = '&' .. converted + output:write('\n if (args.items['..(j - 1)..'].type == kObjectTypeDictionary) {') --luacheck: ignore 631 + output:write('\n memset('..converted..', 0, sizeof(*'..converted..'));') -- TODO: neeeee + output:write('\n if (!api_dict_to_keydict('..converted..', '..rt..'_get_field, args.items['..(j - 1)..'].data.dictionary, error)) {') + output:write('\n goto cleanup;') + output:write('\n }') + output:write('\n } else if (args.items['..(j - 1)..'].type == kObjectTypeArray && args.items['..(j - 1)..'].data.array.size == 0) {') --luacheck: ignore 631 + output:write('\n memset('..converted..', 0, sizeof(*'..converted..'));') + + output:write('\n } else {') + output:write('\n api_set_error(error, kErrorTypeException, \ + "Wrong type for argument '..j..' when calling '..fn.name..', expecting '..param[1]..'");') + output:write('\n goto cleanup;') + output:write('\n }\n') + else if rt:match('^Buffer$') or rt:match('^Window$') or rt:match('^Tabpage$') then -- Buffer, Window, and Tabpage have a specific type, but are stored in integer output:write('\n if (args.items['.. @@ -257,10 +282,7 @@ for i = 1, #functions do "Wrong type for argument '..j..' when calling '..fn.name..', expecting '..param[1]..'");') output:write('\n goto cleanup;') output:write('\n }\n') - else - output:write('\n '..converted..' = args.items['..(j - 1)..'];\n') end - args[#args + 1] = converted end @@ -397,7 +419,7 @@ local function process_function(fn) if not fn.fast then write_shifted_output(output, string.format([[ - if (!nlua_is_deferred_safe(lstate)) { + if (!nlua_is_deferred_safe()) { return luaL_error(lstate, e_luv_api_disabled, "%s"); } ]], fn.name)) @@ -423,13 +445,24 @@ local function process_function(fn) if param[1] == "DictionaryOf(LuaRef)" then extra = "true, " end + local errshift = 0 + if string.match(param_type, '^KeyDict_') then + write_shifted_output(output, string.format([[ + %s %s = { 0 }; nlua_pop_keydict(lstate, &%s, %s_get_field, %s&err);]], param_type, cparam, cparam, param_type, extra)) + cparam = '&'..cparam + errshift = 1 -- free incomplete dict on error + else + write_shifted_output(output, string.format([[ + const %s %s = nlua_pop_%s(lstate, %s&err);]], param[1], cparam, param_type, extra)) + end + write_shifted_output(output, string.format([[ - const %s %s = nlua_pop_%s(lstate, %s&err); if (ERROR_SET(&err)) { goto exit_%u; } - ]], param[1], cparam, param_type, extra, #fn.parameters - j)) + + ]], #fn.parameters - j + errshift)) free_code[#free_code + 1] = ('api_free_%s(%s);'):format( lc_param_type, cparam) cparams = cparam .. ', ' .. cparams @@ -446,7 +479,7 @@ local function process_function(fn) for i = 1, #free_code do local rev_i = #free_code - i + 1 local code = free_code[rev_i] - if i == 1 then + if i == 1 and not string.match(real_type(fn.parameters[1][1]), '^KeyDict_') then free_at_exit_code = free_at_exit_code .. ('\n %s'):format(code) else free_at_exit_code = free_at_exit_code .. ('\n exit_%u:\n %s'):format( diff --git a/src/nvim/generators/gen_declarations.lua b/src/nvim/generators/gen_declarations.lua index 0782c8115d..c7d5a1a191 100755 --- a/src/nvim/generators/gen_declarations.lua +++ b/src/nvim/generators/gen_declarations.lua @@ -60,7 +60,7 @@ local right_word = concat( ) local word = branch( concat( - branch(lit('ArrayOf('), lit('DictionaryOf(')), -- typed container macro + branch(lit('ArrayOf('), lit('DictionaryOf('), lit('Dict(')), -- typed container macro one_or_more(any_character - lit(')')), lit(')') ), @@ -216,7 +216,16 @@ local footer = [[ #include "nvim/func_attr.h" ]] -local non_static = header +local non_static = header .. [[ +#ifndef DLLEXPORT +# ifdef WIN32 +# define DLLEXPORT __declspec(dllexport) +# else +# define DLLEXPORT +# endif +#endif +]] + local static = header local filepattern = '^#%a* (%d+) "([^"]-)/?([^"/]+)"' @@ -269,6 +278,7 @@ while init ~= nil do declaration = declaration:gsub(' $', '') declaration = declaration:gsub('^ ', '') declaration = declaration .. ';' + if os.getenv('NVIM_GEN_DECLARATIONS_LINE_NUMBERS') == '1' then declaration = declaration .. (' // %s/%s:%u'):format( curdir, curfile, declline) @@ -277,6 +287,7 @@ while init ~= nil do if declaration:sub(1, 6) == 'static' then static = static .. declaration else + declaration = 'DLLEXPORT ' .. declaration non_static = non_static .. declaration end declendpos = e diff --git a/src/nvim/generators/gen_keysets.lua b/src/nvim/generators/gen_keysets.lua new file mode 100644 index 0000000000..63ef202fe1 --- /dev/null +++ b/src/nvim/generators/gen_keysets.lua @@ -0,0 +1,67 @@ + +local nvimsrcdir = arg[1] +local shared_file = arg[2] +local funcs_file = arg[3] +local defs_file = arg[4] + +_G.vim = loadfile(shared_file)() + +if nvimsrcdir == '--help' then + print([[ +Usage: + lua gen_keyset.lua TODOFIXUPDATETHIS + +Will generate build/src/nvim/auto/keyset.generated.h with definition of functions +static const array. +]]) + os.exit(0) +end + + +package.path = nvimsrcdir .. '/?.lua;' .. package.path +local hashy = require'generators.hashy' + +local funcspipe = io.open(funcs_file, 'wb') +local defspipe = io.open(defs_file, 'wb') + +local keysets = require'api.keysets' + +for name, keys in pairs(keysets) do + local neworder, hashfun = hashy.hashy_hash(name, keys, function (idx) + return name.."_table["..idx.."].str" + end) + + defspipe:write("typedef struct {\n") + for _, key in ipairs(neworder) do + defspipe:write(" Object "..key..";\n") + end + defspipe:write("} KeyDict_"..name..";\n\n") + + defspipe:write("extern KeySetLink "..name.."_table[];\n") + + funcspipe:write("KeySetLink "..name.."_table[] = {\n") + for _, key in ipairs(neworder) do + funcspipe:write(' {"'..key..'", offsetof(KeyDict_'..name..", "..key..")},\n") + end + funcspipe:write(' {NULL, 0},\n') + funcspipe:write("};\n\n") + + funcspipe:write(hashfun) + + funcspipe:write([[ +Object *KeyDict_]]..name..[[_get_field(void *retval, const char *str, size_t len) +{ + int hash = ]]..name..[[_hash(str, len); + if (hash == -1) { + return NULL; + } + + return (Object *)((char *)retval + ]]..name..[[_table[hash].ptr_off); +} + +]]) + defspipe:write("#define api_free_keydict_"..name.."(x) api_free_keydict(x, "..name.."_table)\n") +end + +funcspipe:close() +defspipe:close() diff --git a/src/nvim/generators/hashy.lua b/src/nvim/generators/hashy.lua new file mode 100644 index 0000000000..fac24c810a --- /dev/null +++ b/src/nvim/generators/hashy.lua @@ -0,0 +1,122 @@ +-- HASHY McHASHFACE + +local M = {} +_G.d = M + + +local function setdefault(table, key) + local val = table[key] + if val == nil then + val = {} + table[key] = val + end + return val +end + +function M.build_pos_hash(strings) + local len_buckets = {} + local maxlen = 0 + for _,s in ipairs(strings) do + table.insert(setdefault(len_buckets, #s),s) + if #s > maxlen then maxlen = #s end + end + + local len_pos_buckets = {} + local worst_buck_size = 0 + + for len = 1,maxlen do + local strs = len_buckets[len] + if strs then + -- the best position so far generates `best_bucket` + -- with `minsize` worst case collisions + local bestpos, minsize, best_bucket = nil, #strs*2, nil + for pos = 1,len do + local try_bucket = {} + for _,str in ipairs(strs) do + local poschar = string.sub(str, pos, pos) + table.insert(setdefault(try_bucket, poschar), str) + end + local maxsize = 1 + for _,pos_strs in pairs(try_bucket) do + maxsize = math.max(maxsize, #pos_strs) + end + if maxsize < minsize then + bestpos = pos + minsize = maxsize + best_bucket = try_bucket + end + end + len_pos_buckets[len] = {bestpos, best_bucket} + worst_buck_size = math.max(worst_buck_size, minsize) + end + end + return len_pos_buckets, maxlen, worst_buck_size +end + +function M.switcher(put, tab, maxlen, worst_buck_size) + local neworder = {} + put " switch (len) {\n" + local bucky = worst_buck_size > 1 + for len = 1,maxlen do + local vals = tab[len] + if vals then + put(" case "..len..": ") + local pos, posbuck = unpack(vals) + local keys = vim.tbl_keys(posbuck) + if #keys > 1 then + table.sort(keys) + put("switch (str["..(pos-1).."]) {\n") + for _,c in ipairs(keys) do + local buck = posbuck[c] + local startidx = #neworder + vim.list_extend(neworder, buck) + local endidx = #neworder + put(" case '"..c.."': ") + put("low = "..startidx.."; ") + if bucky then put("high = "..endidx.."; ") end + put "break;\n" + end + put " default: break;\n" + put " }\n " + else + local startidx = #neworder + table.insert(neworder, posbuck[keys[1]][1]) + local endidx = #neworder + put("low = "..startidx.."; ") + if bucky then put("high = "..endidx.."; ") end + end + put " break;\n" + end + end + put " default: break;\n" + put " }\n" + return neworder +end + +function M.hashy_hash(name, strings, access) + local stats = {} + local put = function(str) table.insert(stats, str) end + local len_pos_buckets, maxlen, worst_buck_size = M.build_pos_hash(strings) + put("int "..name.."_hash(const char *str, size_t len)\n{\n") + if worst_buck_size > 1 then + put(" int low = 0, high = 0;\n") + else + put(" int low = -1;\n") + end + local neworder = M.switcher(put, len_pos_buckets, maxlen, worst_buck_size) + if worst_buck_size > 1 then + error [[ not implemented yet ]] -- TODO(bfredl) + else + put [[ + if (low < 0) { + return -1; + } + ]] + put("if(memcmp(str, "..access("low")..", len)) {\n return -1;\n }\n") + put " return low;\n" + put "}\n\n" + end + return neworder, table.concat(stats) +end + +return M diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 3bf9d92696..eb836b9005 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -11,22 +11,25 @@ */ #include <assert.h> +#include <inttypes.h> #include <stdbool.h> #include <string.h> -#include <inttypes.h> -#include "nvim/assert.h" -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/getchar.h" +#include "nvim/assert.h" #include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cursor.h" #include "nvim/edit.h" #include "nvim/eval.h" +#include "nvim/event/loop.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" +#include "nvim/ex_session.h" #include "nvim/func_attr.h" +#include "nvim/garray.h" +#include "nvim/getchar.h" +#include "nvim/keymap.h" #include "nvim/lua/executor.h" #include "nvim/main.h" #include "nvim/mbyte.h" @@ -34,24 +37,21 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/plines.h" -#include "nvim/keymap.h" -#include "nvim/garray.h" #include "nvim/move.h" #include "nvim/normal.h" #include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/os/fileio.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" +#include "nvim/plines.h" #include "nvim/regexp.h" #include "nvim/screen.h" -#include "nvim/ex_session.h" #include "nvim/state.h" #include "nvim/strings.h" #include "nvim/ui.h" #include "nvim/undo.h" -#include "nvim/event/loop.h" -#include "nvim/os/input.h" -#include "nvim/os/os.h" -#include "nvim/os/fileio.h" +#include "nvim/vim.h" /// Index in scriptin @@ -163,7 +163,7 @@ static size_t last_recorded_len = 0; // number of last recorded chars */ void free_buff(buffheader_T *buf) { - buffblock_T *p, *np; + buffblock_T *p, *np; for (p = buf->bh_first.b_next; p != NULL; p = np) { np = p->b_next; @@ -172,17 +172,15 @@ void free_buff(buffheader_T *buf) buf->bh_first.b_next = NULL; } -/* - * Return the contents of a buffer as a single string. - * K_SPECIAL and CSI in the returned string are escaped. - */ -static char_u *get_buffcont(buffheader_T *buffer, - int dozero // count == zero is not an error - ) +/// Return the contents of a buffer as a single string. +/// K_SPECIAL and CSI in the returned string are escaped. +/// +/// @param dozero count == zero is not an error +static char_u *get_buffcont(buffheader_T *buffer, int dozero) { size_t count = 0; - char_u *p = NULL; - char_u *p2; + char_u *p = NULL; + char_u *p2; // compute the total length of the string for (const buffblock_T *bp = buffer->bh_first.b_next; @@ -211,7 +209,7 @@ static char_u *get_buffcont(buffheader_T *buffer, */ char_u *get_recorded(void) { - char_u *p; + char_u *p; size_t len; p = get_buffcont(&recordbuff, TRUE); @@ -231,8 +229,9 @@ char_u *get_recorded(void) * When stopping recording from Insert mode with CTRL-O q, also remove the * CTRL-O. */ - if (len > 0 && restart_edit != 0 && p[len - 1] == Ctrl_O) + if (len > 0 && restart_edit != 0 && p[len - 1] == Ctrl_O) { p[len - 1] = NUL; + } return p; } @@ -253,8 +252,7 @@ char_u *get_inserted(void) /// @param[out] buf Buffer to add to. /// @param[in] s String to add. /// @param[in] slen String length or -1 for NUL-terminated string. -static void add_buff(buffheader_T *const buf, const char *const s, - ptrdiff_t slen) +static void add_buff(buffheader_T *const buf, const char *const s, ptrdiff_t slen) { if (slen < 0) { slen = (ptrdiff_t)strlen(s); @@ -295,7 +293,6 @@ static void add_buff(buffheader_T *const buf, const char *const s, buf->bh_curr->b_next = p; buf->bh_curr = p; } - return; } /* @@ -354,8 +351,9 @@ static int read_readbuffers(int advance) int c; c = read_readbuf(&readbuf1, advance); - if (c == NUL) + if (c == NUL) { c = read_readbuf(&readbuf2, advance); + } return c; } @@ -524,7 +522,7 @@ void restoreRedobuff(save_redo_T *save_redo) void AppendToRedobuff(const char *s) { if (!block_redo) { - add_buff(&redobuff, (const char *)s, -1L); + add_buff(&redobuff, s, -1L); } } @@ -583,8 +581,9 @@ void AppendToRedobuffLit(const char_u *str, int len) */ void AppendCharToRedobuff(int c) { - if (!block_redo) + if (!block_redo) { add_char_buff(&redobuff, c); + } } /* @@ -592,8 +591,9 @@ void AppendCharToRedobuff(int c) */ void AppendNumberToRedobuff(long n) { - if (!block_redo) + if (!block_redo) { add_num_buff(&redobuff, n); + } } /* @@ -865,10 +865,9 @@ void init_default_mappings(void) // If silent is true, cmd_silent is set when the characters are obtained. // // return FAIL for failure, OK otherwise -int ins_typebuf(char_u *str, int noremap, int offset, - bool nottyped, bool silent) +int ins_typebuf(char_u *str, int noremap, int offset, bool nottyped, bool silent) { - char_u *s1, *s2; + char_u *s1, *s2; int newlen; int addlen; int i; @@ -877,8 +876,9 @@ int ins_typebuf(char_u *str, int noremap, int offset, int nrm; init_typebuf(); - if (++typebuf.tb_change_cnt == 0) + if (++typebuf.tb_change_cnt == 0) { typebuf.tb_change_cnt = 1; + } addlen = (int)STRLEN(str); @@ -924,12 +924,13 @@ int ins_typebuf(char_u *str, int noremap, int offset, typebuf.tb_buf = s1; memmove(s2 + newoff, typebuf.tb_noremap + typebuf.tb_off, - (size_t)offset); + (size_t)offset); memmove(s2 + newoff + offset + addlen, - typebuf.tb_noremap + typebuf.tb_off + offset, - (size_t)(typebuf.tb_len - offset)); - if (typebuf.tb_noremap != noremapbuf_init) + typebuf.tb_noremap + typebuf.tb_off + offset, + (size_t)(typebuf.tb_len - offset)); + if (typebuf.tb_noremap != noremapbuf_init) { xfree(typebuf.tb_noremap); + } typebuf.tb_noremap = s2; typebuf.tb_off = newoff; @@ -948,26 +949,29 @@ int ins_typebuf(char_u *str, int noremap, int offset, /* * Adjust typebuf.tb_noremap[] for the new characters: * If noremap == REMAP_NONE or REMAP_SCRIPT: new characters are - * (sometimes) not remappable + * (sometimes) not remappable * If noremap == REMAP_YES: all the new characters are mappable * If noremap > 0: "noremap" characters are not remappable, the rest - * mappable + * mappable */ - if (noremap == REMAP_SKIP) + if (noremap == REMAP_SKIP) { nrm = 1; - else if (noremap < 0) + } else if (noremap < 0) { nrm = addlen; - else + } else { nrm = noremap; - for (i = 0; i < addlen; ++i) + } + for (i = 0; i < addlen; ++i) { typebuf.tb_noremap[typebuf.tb_off + i + offset] = - (char_u)((--nrm >= 0) ? val : RM_YES); + (char_u)((--nrm >= 0) ? val : RM_YES); + } /* tb_maplen and tb_silent only remember the length of mapped and/or * silent mappings at the start of the buffer, assuming that a mapped * sequence doesn't result in typed characters. */ - if (nottyped || typebuf.tb_maplen > offset) + if (nottyped || typebuf.tb_maplen > offset) { typebuf.tb_maplen += addlen; + } if (silent || typebuf.tb_silent > offset) { typebuf.tb_silent += addlen; cmd_silent = true; @@ -995,22 +999,32 @@ void ins_char_typebuf(int c) buf[3] = NUL; } else { buf[utf_char2bytes(c, buf)] = NUL; + char_u *p = buf; + while (*p) { + if ((uint8_t)(*p) == CSI || (uint8_t)(*p) == K_SPECIAL) { + bool is_csi = (uint8_t)(*p) == CSI; + memmove(p + 3, p + 1, STRLEN(p + 1) + 1); + *p++ = K_SPECIAL; + *p++ = is_csi ? KS_EXTRA : KS_SPECIAL; + *p++ = is_csi ? KE_CSI : KE_FILLER; + } else { + p++; + } + } } (void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent); } -/* - * Return TRUE if the typeahead buffer was changed (while waiting for a - * character to arrive). Happens when a message was received from a client or - * from feedkeys(). - * But check in a more generic way to avoid trouble: When "typebuf.tb_buf" - * changed it was reallocated and the old pointer can no longer be used. - * Or "typebuf.tb_off" may have been changed and we would overwrite characters - * that was just added. - */ -bool typebuf_changed( - int tb_change_cnt // old value of typebuf.tb_change_cnt -) +/// Return TRUE if the typeahead buffer was changed (while waiting for a +/// character to arrive). Happens when a message was received from a client or +/// from feedkeys(). +/// But check in a more generic way to avoid trouble: When "typebuf.tb_buf" +/// changed it was reallocated and the old pointer can no longer be used. +/// Or "typebuf.tb_off" may have been changed and we would overwrite characters +/// that was just added. +/// +/// @param tb_change_cnt old value of typebuf.tb_change_cnt +bool typebuf_changed(int tb_change_cnt) { return tb_change_cnt != 0 && (typebuf.tb_change_cnt != tb_change_cnt || typebuf_was_filled @@ -1051,8 +1065,9 @@ void del_typebuf(int len, int offset) * Easy case: Just increase typebuf.tb_off. */ if (offset == 0 && typebuf.tb_buflen - (typebuf.tb_off + len) - >= 3 * MAXMAPLEN + 3) + >= 3 * MAXMAPLEN + 3) { typebuf.tb_off += len; + } /* * Have to move the characters in typebuf.tb_buf[] and typebuf.tb_noremap[] */ @@ -1063,9 +1078,9 @@ void del_typebuf(int len, int offset) */ if (typebuf.tb_off > MAXMAPLEN) { memmove(typebuf.tb_buf + MAXMAPLEN, - typebuf.tb_buf + typebuf.tb_off, (size_t)offset); + typebuf.tb_buf + typebuf.tb_off, (size_t)offset); memmove(typebuf.tb_noremap + MAXMAPLEN, - typebuf.tb_noremap + typebuf.tb_off, (size_t)offset); + typebuf.tb_noremap + typebuf.tb_off, (size_t)offset); typebuf.tb_off = MAXMAPLEN; } // adjust typebuf.tb_buf (include the NUL at the end) @@ -1075,8 +1090,8 @@ void del_typebuf(int len, int offset) typebuf.tb_buf + i + len, (size_t)bytes); // adjust typebuf.tb_noremap[] memmove(typebuf.tb_noremap + typebuf.tb_off + offset, - typebuf.tb_noremap + i + len, - (size_t)(typebuf.tb_len - offset)); + typebuf.tb_noremap + i + len, + (size_t)(typebuf.tb_len - offset)); } if (typebuf.tb_maplen > offset) { // adjust tb_maplen @@ -1168,8 +1183,9 @@ static void gotchars(const char_u *chars, size_t len) void may_sync_undo(void) { if ((!(State & (INSERT + CMDLINE)) || arrow_used) - && scriptin[curscript] == NULL) + && scriptin[curscript] == NULL) { u_sync(false); + } } /* @@ -1185,8 +1201,9 @@ void alloc_typebuf(void) typebuf.tb_maplen = 0; typebuf.tb_silent = 0; typebuf.tb_no_abbr_cnt = 0; - if (++typebuf.tb_change_cnt == 0) + if (++typebuf.tb_change_cnt == 0) { typebuf.tb_change_cnt = 1; + } } /* @@ -1264,13 +1281,10 @@ void restore_typeahead(tasave_T *tp) readbuf2 = tp->save_readbuf2; } -/* - * Open a new script file for the ":source!" command. - */ -void openscript( - char_u *name, - bool directly // when true execute directly -) +/// Open a new script file for the ":source!" command. +/// +/// @param directly when true execute directly +void openscript(char_u *name, bool directly) { if (curscript + 1 == NSCRIPT) { EMSG(_(e_nesting)); @@ -1351,15 +1365,17 @@ static void closescript(void) file_free(scriptin[curscript], false); scriptin[curscript] = NULL; - if (curscript > 0) + if (curscript > 0) { --curscript; + } } #if defined(EXITFREE) void close_all_scripts(void) { - while (scriptin[0] != NULL) + while (scriptin[0] != NULL) { closescript(); + } } #endif @@ -1460,60 +1476,81 @@ int vgetc(void) continue; } c = TO_SPECIAL(c2, c); - } // a keypad or special function key was not mapped, use it like // its ASCII equivalent switch (c) { - case K_KPLUS: c = '+'; break; - case K_KMINUS: c = '-'; break; - case K_KDIVIDE: c = '/'; break; - case K_KMULTIPLY: c = '*'; break; - case K_KENTER: c = CAR; break; - case K_KPOINT: c = '.'; break; - case K_KCOMMA: c = ','; break; - case K_KEQUAL: c = '='; break; - case K_K0: c = '0'; break; - case K_K1: c = '1'; break; - case K_K2: c = '2'; break; - case K_K3: c = '3'; break; - case K_K4: c = '4'; break; - case K_K5: c = '5'; break; - case K_K6: c = '6'; break; - case K_K7: c = '7'; break; - case K_K8: c = '8'; break; - case K_K9: c = '9'; break; - - case K_XHOME: - case K_ZHOME: - if (mod_mask == MOD_MASK_SHIFT) { - c = K_S_HOME; - mod_mask = 0; - } else if (mod_mask == MOD_MASK_CTRL) { - c = K_C_HOME; - mod_mask = 0; - } else { - c = K_HOME; - } - break; - case K_XEND: - case K_ZEND: - if (mod_mask == MOD_MASK_SHIFT) { - c = K_S_END; - mod_mask = 0; - } else if (mod_mask == MOD_MASK_CTRL) { - c = K_C_END; - mod_mask = 0; - } else { - c = K_END; - } - break; + case K_KPLUS: + c = '+'; break; + case K_KMINUS: + c = '-'; break; + case K_KDIVIDE: + c = '/'; break; + case K_KMULTIPLY: + c = '*'; break; + case K_KENTER: + c = CAR; break; + case K_KPOINT: + c = '.'; break; + case K_KCOMMA: + c = ','; break; + case K_KEQUAL: + c = '='; break; + case K_K0: + c = '0'; break; + case K_K1: + c = '1'; break; + case K_K2: + c = '2'; break; + case K_K3: + c = '3'; break; + case K_K4: + c = '4'; break; + case K_K5: + c = '5'; break; + case K_K6: + c = '6'; break; + case K_K7: + c = '7'; break; + case K_K8: + c = '8'; break; + case K_K9: + c = '9'; break; + + case K_XHOME: + case K_ZHOME: + if (mod_mask == MOD_MASK_SHIFT) { + c = K_S_HOME; + mod_mask = 0; + } else if (mod_mask == MOD_MASK_CTRL) { + c = K_C_HOME; + mod_mask = 0; + } else { + c = K_HOME; + } + break; + case K_XEND: + case K_ZEND: + if (mod_mask == MOD_MASK_SHIFT) { + c = K_S_END; + mod_mask = 0; + } else if (mod_mask == MOD_MASK_CTRL) { + c = K_C_END; + mod_mask = 0; + } else { + c = K_END; + } + break; - case K_XUP: c = K_UP; break; - case K_XDOWN: c = K_DOWN; break; - case K_XLEFT: c = K_LEFT; break; - case K_XRIGHT: c = K_RIGHT; break; + case K_XUP: + c = K_UP; break; + case K_XDOWN: + c = K_DOWN; break; + case K_XLEFT: + c = K_LEFT; break; + case K_XRIGHT: + c = K_RIGHT; break; } // For a multi-byte character get all the bytes and return the @@ -1532,7 +1569,7 @@ int vgetc(void) // a CSI (0x9B), // of a K_SPECIAL - KS_EXTRA - KE_CSI, which is CSI too. c = vgetorpeek(true); - if (vgetorpeek(true) == (int)KE_CSI && c == KS_EXTRA) { + if (vgetorpeek(true) == KE_CSI && c == KS_EXTRA) { buf[i] = CSI; } } @@ -1547,9 +1584,9 @@ int vgetc(void) if (!no_mapping && KeyTyped && (mod_mask == MOD_MASK_ALT || mod_mask == MOD_MASK_META)) { mod_mask = 0; - stuffcharReadbuff(c); - u_sync(false); - c = ESC; + ins_char_typebuf(c); + ins_char_typebuf(ESC); + continue; } break; @@ -1608,8 +1645,9 @@ int plain_vgetc(void) */ int vpeekc(void) { - if (old_char != -1) + if (old_char != -1) { return old_char; + } return vgetorpeek(false); } @@ -1623,8 +1661,9 @@ int vpeekc_any(void) int c; c = vpeekc(); - if (c == NUL && typebuf.tb_len > 0) + if (c == NUL && typebuf.tb_len > 0) { c = ESC; + } return c; } @@ -1678,10 +1717,10 @@ static int vgetorpeek(bool advance) { int c, c1; int keylen; - char_u *s; - mapblock_T *mp; - mapblock_T *mp2; - mapblock_T *mp_match; + char_u *s; + mapblock_T *mp; + mapblock_T *mp2; + mapblock_T *mp_match; int mp_match_len = 0; bool timedout = false; // waited for more than 1 second // for mapping to complete @@ -1700,7 +1739,7 @@ static int vgetorpeek(bool advance) /* * This function doesn't work very well when called recursively. This may * happen though, because of: - * 1. The call to add_to_showcmd(). char_avail() is then used to check if + * 1. The call to add_to_showcmd(). char_avail() is then used to check if * there is a character available, which calls this function. In that * case we must return NUL, to indicate no character is available. * 2. A GUI callback function writes to the screen, causing a @@ -1709,16 +1748,17 @@ static int vgetorpeek(bool advance) * thus it should be OK. But don't get a key from the user then. */ if (vgetc_busy > 0 - && ex_normal_busy == 0 - ) + && ex_normal_busy == 0) { return NUL; + } local_State = get_real_state(); ++vgetc_busy; - if (advance) + if (advance) { KeyStuffed = FALSE; + } init_typebuf(); start_stuff(); @@ -1731,8 +1771,9 @@ static int vgetorpeek(bool advance) */ if (typeahead_char != 0) { c = typeahead_char; - if (advance) + if (advance) { typeahead_char = 0; + } } else { c = read_readbuffers(advance); } @@ -1802,7 +1843,7 @@ static int vgetorpeek(bool advance) * - typebuf.tb_buf[typebuf.tb_off] should not be remapped * - in insert or cmdline mode and 'paste' option set * - waiting for "hit return to continue" and CR or SPACE - * typed + * typed * - waiting for a char with --more-- * - in Ctrl-X mode, and we get a valid char for that mode */ @@ -1821,8 +1862,8 @@ static int vgetorpeek(bool advance) && State != CONFIRM && !((ctrl_x_mode_not_default() && vim_is_ctrl_x_key(c1)) || ((compl_cont_status & CONT_LOCAL) - && (c1 == Ctrl_N || c1 == Ctrl_P))) - ) { + && (c1 == Ctrl_N || + c1 == Ctrl_P)))) { if (c1 == K_SPECIAL) { nolmaplen = 2; } else { @@ -1864,14 +1905,16 @@ static int vgetorpeek(bool advance) // find the match length of this mapping for (mlen = 1; mlen < typebuf.tb_len; mlen++) { c2 = typebuf.tb_buf[typebuf.tb_off + mlen]; - if (nomap > 0) + if (nomap > 0) { --nomap; - else if (c2 == K_SPECIAL) + } else if (c2 == K_SPECIAL) { nomap = 2; - else + } else { LANGMAP_ADJUST(c2, TRUE); - if (mp->m_keys[mlen] != c2) + } + if (mp->m_keys[mlen] != c2) { break; + } } /* Don't allow mapping the first byte(s) of a @@ -1902,17 +1945,21 @@ static int vgetorpeek(bool advance) && (mp->m_keys[0] != K_SPECIAL || mp->m_keys[1] != KS_EXTRA || mp->m_keys[2] - != (int)KE_SNR)) + != KE_SNR)) { continue; + } /* * If one of the typed keys cannot be * remapped, skip the entry. */ - for (n = mlen; --n >= 0; ) - if (*s++ & (RM_NONE|RM_ABBR)) + for (n = mlen; --n >= 0; ) { + if (*s++ & (RM_NONE|RM_ABBR)) { break; - if (n >= 0) + } + } + if (n >= 0) { continue; + } if (keylen > typebuf.tb_len) { if (!timedout && !(mp_match != NULL @@ -2030,10 +2077,11 @@ static int vgetorpeek(bool advance) */ if (++mapdepth >= p_mmd) { EMSG(_("E223: recursive mapping")); - if (State & CMDLINE) + if (State & CMDLINE) { redrawcmdline(); - else + } else { setcursor(); + } flush_buffers(FLUSH_MINIMAL); mapdepth = 0; // for next one c = -1; @@ -2090,9 +2138,9 @@ static int vgetorpeek(bool advance) * If m_noremap is set, don't remap the whole 'to' * part. */ - if (s == NULL) + if (s == NULL) { i = FAIL; - else { + } else { int noremap; // If this is a LANGMAP mapping, then we didn't record the keys @@ -2101,20 +2149,22 @@ static int vgetorpeek(bool advance) gotchars(s, STRLEN(s)); } - if (save_m_noremap != REMAP_YES) + if (save_m_noremap != REMAP_YES) { noremap = save_m_noremap; - else if ( - STRNCMP(s, save_m_keys != NULL + } else if ( + STRNCMP(s, save_m_keys != NULL ? save_m_keys : mp->m_keys, - (size_t)keylen) - != 0) + (size_t)keylen) + != 0) { noremap = REMAP_YES; - else + } else { noremap = REMAP_SKIP; + } i = ins_typebuf(s, noremap, - 0, TRUE, cmd_silent || save_m_silent); - if (save_m_expr) + 0, TRUE, cmd_silent || save_m_silent); + if (save_m_expr) { xfree(s); + } } xfree(save_m_keys); xfree(save_m_str); @@ -2152,7 +2202,7 @@ static int vgetorpeek(bool advance) && (c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len, 3, 25L)) == 0) { colnr_T col = 0, vcol; - char_u *ptr; + char_u *ptr; if (mode_displayed) { unshowmode(true); @@ -2177,7 +2227,7 @@ static int vgetorpeek(bool advance) if (!ascii_iswhite(ptr[col])) { curwin->w_wcol = vcol; } - vcol += lbr_chartabsize(ptr, ptr + col, (colnr_T)vcol); + vcol += lbr_chartabsize(ptr, ptr + col, vcol); col += utfc_ptr2len(ptr + col); } curwin->w_wrow = curwin->w_cline_row @@ -2299,11 +2349,13 @@ static int vgetorpeek(bool advance) curwin->w_wcol = new_wcol; curwin->w_wrow = new_wrow; push_showcmd(); - if (typebuf.tb_len > SHOWCMD_COLS) + if (typebuf.tb_len > SHOWCMD_COLS) { i = typebuf.tb_len - SHOWCMD_COLS; - while (i < typebuf.tb_len) + } + while (i < typebuf.tb_len) { (void)add_to_showcmd(typebuf.tb_buf[typebuf.tb_off + i++]); + } curwin->w_wcol = old_wcol; curwin->w_wrow = old_wrow; } @@ -2346,8 +2398,9 @@ static int vgetorpeek(bool advance) typebuf.tb_buflen - typebuf.tb_off - typebuf.tb_len - 1, wait_time); - if (i != 0) + if (i != 0) { pop_showcmd(); + } if (c1 == 1) { if (State & INSERT) { edit_unputchar(); @@ -2383,8 +2436,8 @@ static int vgetorpeek(bool advance) /* * The "INSERT" message is taken care of here: - * if we return an ESC to exit insert mode, the message is deleted - * if we don't return an ESC but deleted the message before, redisplay it + * if we return an ESC to exit insert mode, the message is deleted + * if we don't return an ESC but deleted the message before, redisplay it */ if (advance && p_smd && msg_silent == 0 && (State & INSERT)) { if (c == ESC && !mode_deleted && !no_mapping && mode_displayed) { @@ -2418,34 +2471,30 @@ static int vgetorpeek(bool advance) return c; } -/* - * inchar() - get one character from - * 1. a scriptfile - * 2. the keyboard - * - * As much characters as we can get (up to 'maxlen') are put in "buf" and - * NUL terminated (buffer length must be 'maxlen' + 1). - * Minimum for "maxlen" is 3!!!! - * - * "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into - * it. When typebuf.tb_change_cnt changes (e.g., when a message is received - * from a remote client) "buf" can no longer be used. "tb_change_cnt" is 0 - * otherwise. - * - * If we got an interrupt all input is read until none is available. - * - * If wait_time == 0 there is no waiting for the char. - * If wait_time == n we wait for n msec for a character to arrive. - * If wait_time == -1 we wait forever for a character to arrive. - * - * Return the number of obtained characters. - * Return -1 when end of input script reached. - */ -int inchar( - char_u *buf, - int maxlen, - long wait_time // milli seconds -) +/// inchar() - get one character from +/// 1. a scriptfile +/// 2. the keyboard +/// +/// As much characters as we can get (up to 'maxlen') are put in "buf" and +/// NUL terminated (buffer length must be 'maxlen' + 1). +/// Minimum for "maxlen" is 3!!!! +/// +/// "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into +/// it. When typebuf.tb_change_cnt changes (e.g., when a message is received +/// from a remote client) "buf" can no longer be used. "tb_change_cnt" is 0 +/// otherwise. +/// +/// If we got an interrupt all input is read until none is available. +/// +/// If wait_time == 0 there is no waiting for the char. +/// If wait_time == n we wait for n msec for a character to arrive. +/// If wait_time == -1 we wait forever for a character to arrive. +/// +/// Return the number of obtained characters. +/// Return -1 when end of input script reached. +/// +/// @param wait_time milli seconds +int inchar(char_u *buf, int maxlen, long wait_time) { int len = 0; // Init for GCC. int retesc = false; // Return ESC with gotint. @@ -2551,10 +2600,10 @@ int fix_input_buffer(char_u *buf, int len) // Reading from script, need to process special bytes int i; - char_u *p = buf; + char_u *p = buf; // Two characters are special: NUL and K_SPECIAL. - // Replace NUL by K_SPECIAL KS_ZERO KE_FILLER + // Replace NUL by K_SPECIAL KS_ZERO KE_FILLER // Replace K_SPECIAL by K_SPECIAL KS_SPECIAL KE_FILLER // Replace CSI by K_SPECIAL KS_EXTRA KE_CSI for (i = len; --i >= 0; ++p) { @@ -2595,9 +2644,8 @@ int fix_input_buffer(char_u *buf, int len) /// @param[in] orig_rhs_len `strlen` of orig_rhs. /// @param[in] cpo_flags See param docs for @ref replace_termcodes. /// @param[out] mapargs MapArguments struct holding the replaced strings. -void set_maparg_lhs_rhs(const char_u *orig_lhs, const size_t orig_lhs_len, - const char_u *orig_rhs, const size_t orig_rhs_len, - int cpo_flags, MapArguments *mapargs) +void set_maparg_lhs_rhs(const char_u *orig_lhs, const size_t orig_lhs_len, const char_u *orig_rhs, + const size_t orig_rhs_len, int cpo_flags, MapArguments *mapargs) { char_u *lhs_buf = NULL; char_u *rhs_buf = NULL; @@ -2612,12 +2660,11 @@ void set_maparg_lhs_rhs(const char_u *orig_lhs, const size_t orig_lhs_len, char_u *replaced = replace_termcodes(orig_lhs, orig_lhs_len, &lhs_buf, true, true, true, cpo_flags); mapargs->lhs_len = STRLEN(replaced); - xstrlcpy((char *)mapargs->lhs, (char *)replaced, sizeof(mapargs->lhs)); + STRLCPY(mapargs->lhs, replaced, sizeof(mapargs->lhs)); mapargs->orig_rhs_len = orig_rhs_len; mapargs->orig_rhs = xcalloc(mapargs->orig_rhs_len + 1, sizeof(char_u)); - xstrlcpy((char *)mapargs->orig_rhs, (char *)orig_rhs, - mapargs->orig_rhs_len + 1); + STRLCPY(mapargs->orig_rhs, orig_rhs, mapargs->orig_rhs_len + 1); if (STRICMP(orig_rhs, "<nop>") == 0) { // "<Nop>" means nothing mapargs->rhs = xcalloc(1, sizeof(char_u)); // single null-char @@ -2629,7 +2676,7 @@ void set_maparg_lhs_rhs(const char_u *orig_lhs, const size_t orig_lhs_len, mapargs->rhs_len = STRLEN(replaced); mapargs->rhs_is_noop = false; mapargs->rhs = xcalloc(mapargs->rhs_len + 1, sizeof(char_u)); - xstrlcpy((char *)mapargs->rhs, (char *)replaced, mapargs->rhs_len + 1); + STRLCPY(mapargs->rhs, replaced, mapargs->rhs_len + 1); } xfree(lhs_buf); @@ -2737,7 +2784,7 @@ int str_to_mapargs(const char_u *strargs, bool is_unmap, MapArguments *mapargs) // (e.g. "<Space>" is longer than ' '), so first copy into a buffer. size_t orig_lhs_len = (size_t)(lhs_end - to_parse); char_u *lhs_to_replace = xcalloc(orig_lhs_len + 1, sizeof(char_u)); - xstrlcpy((char *)lhs_to_replace, (char *)to_parse, orig_lhs_len + 1); + STRLCPY(lhs_to_replace, to_parse, orig_lhs_len + 1); size_t orig_rhs_len = STRLEN(rhs_start); set_maparg_lhs_rhs(lhs_to_replace, orig_lhs_len, @@ -2764,11 +2811,10 @@ int str_to_mapargs(const char_u *strargs, bool is_unmap, MapArguments *mapargs) /// @param mode @see do_map /// @param is_abbrev @see do_map /// @param buf Target Buffer -int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, - buf_T *buf) +int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, buf_T *buf) { - mapblock_T *mp, **mpp; - char_u *p; + mapblock_T *mp, **mpp; + char_u *p; int n; int len = 0; // init for GCC int did_it = false; @@ -2777,8 +2823,8 @@ int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, int retval = 0; int hash; int new_hash; - mapblock_T **abbr_table; - mapblock_T **map_table; + mapblock_T **abbr_table; + mapblock_T **map_table; int noremap; map_table = maphash; @@ -2813,7 +2859,7 @@ int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, } char_u *lhs = (char_u *)&args->lhs; - char_u *rhs = (char_u *)args->rhs; + char_u *rhs = args->rhs; char_u *orig_rhs = args->orig_rhs; // check arguments and translate function keys @@ -3148,15 +3194,15 @@ int do_map(int maptype, char_u *arg, int mode, bool is_abbrev) MapArguments parsed_args; int result = str_to_mapargs(arg, maptype == 1, &parsed_args); switch (result) { - case 0: - break; - case 1: - // invalid arguments - goto free_and_return; - default: - assert(false && "Unknown return code from str_to_mapargs!"); - result = -1; - goto free_and_return; + case 0: + break; + case 1: + // invalid arguments + goto free_and_return; + default: + assert(false && "Unknown return code from str_to_mapargs!"); + result = -1; + goto free_and_return; } // switch result = buf_do_map(maptype, &parsed_args, mode, is_abbrev, curbuf); @@ -3173,7 +3219,7 @@ free_and_return: */ static void mapblock_free(mapblock_T **mpp) { - mapblock_T *mp; + mapblock_T *mp; mp = *mpp; xfree(mp->m_keys); @@ -3199,7 +3245,7 @@ static void validate_maphash(void) */ int get_map_mode(char_u **cmdp, bool forceit) { - char_u *p; + char_u *p; int modec; int mode; @@ -3253,21 +3299,19 @@ void map_clear_mode(char_u *cmdp, char_u *arg, int forceit, int abbr) mode = get_map_mode(&cmdp, forceit); map_clear_int(curbuf, mode, - local, - abbr); + local, + abbr); } -/* - * Clear all mappings in "mode". - */ -void map_clear_int( - buf_T *buf, // buffer for local mappings - int mode, // mode in which to delete - bool local, // true for buffer-local mappings - bool abbr // true for abbreviations -) +/// Clear all mappings in "mode". +/// +/// @param buf, buffer for local mappings +/// @param mode mode in which to delete +/// @param local true for buffer-local mappings +/// @param abbr true for abbreviations +void map_clear_int(buf_T *buf, int mode, bool local, bool abbr) { - mapblock_T *mp, **mpp; + mapblock_T *mp, **mpp; int hash; int new_hash; @@ -3284,10 +3328,11 @@ void map_clear_int( mpp = &first_abbr; } } else { - if (local) + if (local) { mpp = &buf->b_maphash[hash]; - else + } else { mpp = &maphash[hash]; + } } while (*mpp != NULL) { mp = *mpp; @@ -3365,10 +3410,8 @@ char *map_mode_to_chars(int mode) return (char *)mapmode.ga_data; } -static void showmap( - mapblock_T *mp, - bool local // true for buffer-local map -) +/// @param local true for buffer-local map +static void showmap(mapblock_T *mp, bool local) { size_t len = 1; @@ -3390,8 +3433,9 @@ static void showmap( xfree(mapchars); } - while (++len <= 3) + while (++len <= 3) { msg_putchar(' '); + } // Display the LHS. Get length of what we write. len = (size_t)msg_outtrans_special(mp->m_keys, true, 0); @@ -3408,10 +3452,11 @@ static void showmap( msg_putchar(' '); } - if (local) + if (local) { msg_putchar('@'); - else + } else { msg_putchar(' '); + } /* Use FALSE below if we only want things like <Up> to show up as such on * the rhs, and not M-x etc, TRUE gets both -- webb */ @@ -3441,8 +3486,7 @@ static void showmap( /// @param[in] abbr true if checking abbreviations in place of mappings. /// /// @return true if there is at least one mapping with given parameters. -bool map_to_exists(const char *const str, const char *const modechars, - const bool abbr) +bool map_to_exists(const char *const str, const char *const modechars, const bool abbr) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE { int mode = 0; @@ -3487,7 +3531,7 @@ bool map_to_exists(const char *const str, const char *const modechars, /// @return true if there is at least one mapping with given parameters. int map_to_exists_mode(const char *const rhs, const int mode, const bool abbr) { - mapblock_T *mp; + mapblock_T *mp; int hash; bool exp_buffer = false; @@ -3533,29 +3577,25 @@ static int expand_mapmodes = 0; static bool expand_isabbrev = false; static bool expand_buffer = false; -/* - * Work out what to complete when doing command line completion of mapping - * or abbreviation names. - */ -char_u *set_context_in_map_cmd( - expand_T *xp, - char_u *cmd, - char_u *arg, - bool forceit, // true if '!' given - bool isabbrev, // true if abbreviation - bool isunmap, // true if unmap/unabbrev command - cmdidx_T cmdidx -) +/// Work out what to complete when doing command line completion of mapping +/// or abbreviation names. +/// +/// @param forceit true if '!' given +/// @param isabbrev true if abbreviation +/// @param isunmap true if unmap/unabbrev command +char_u *set_context_in_map_cmd(expand_T *xp, char_u *cmd, char_u *arg, bool forceit, bool isabbrev, + bool isunmap, cmdidx_T cmdidx) { - if (forceit && cmdidx != CMD_map && cmdidx != CMD_unmap) + if (forceit && cmdidx != CMD_map && cmdidx != CMD_unmap) { xp->xp_context = EXPAND_NOTHING; - else { - if (isunmap) + } else { + if (isunmap) { expand_mapmodes = get_map_mode(&cmd, forceit || isabbrev); - else { + } else { expand_mapmodes = INSERT + CMDLINE; - if (!isabbrev) + if (!isabbrev) { expand_mapmodes += VISUAL + SELECTMODE + NORMAL + OP_PENDING; + } } expand_isabbrev = isabbrev; xp->xp_context = EXPAND_MAPPINGS; @@ -3603,11 +3643,11 @@ char_u *set_context_in_map_cmd( // Return OK if matches found, FAIL otherwise. int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file) { - mapblock_T *mp; + mapblock_T *mp; int hash; int count; int round; - char_u *p; + char_u *p; int i; validate_maphash(); @@ -3642,10 +3682,11 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file) } if (vim_regexec(regmatch, p, (colnr_T)0)) { - if (round == 1) + if (round == 1) { ++count; - else + } else { (*file)[count++] = vim_strsave(p); + } } } @@ -3655,17 +3696,18 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file) break; // for (hash) } mp = first_abbr; - } else if (expand_buffer) + } else if (expand_buffer) { mp = curbuf->b_maphash[hash]; - else + } else { mp = maphash[hash]; + } for (; mp; mp = mp->m_next) { if (mp->m_mode & expand_mapmodes) { p = translate_mapping(mp->m_keys, CPO_TO_CPO_FLAGS); if (p != NULL && vim_regexec(regmatch, p, (colnr_T)0)) { - if (round == 1) + if (round == 1) { ++count; - else { + } else { (*file)[count++] = p; p = NULL; } @@ -3685,9 +3727,9 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file) } // for (round) if (count > 1) { - char_u **ptr1; - char_u **ptr2; - char_u **ptr3; + char_u **ptr1; + char_u **ptr2; + char_u **ptr3; // Sort the matches sort_strings(*file, count); @@ -3698,9 +3740,9 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file) ptr3 = ptr1 + count; while (ptr2 < ptr3) { - if (STRCMP(*ptr1, *ptr2)) + if (STRCMP(*ptr1, *ptr2)) { *++ptr1 = *ptr2++; - else { + } else { xfree(*ptr2++); count--; } @@ -3732,10 +3774,10 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol) int len; int scol; // starting column of the abbr. int j; - char_u *s; + char_u *s; char_u tb[MB_MAXBYTES + 4]; - mapblock_T *mp; - mapblock_T *mp2; + mapblock_T *mp; + mapblock_T *mp2; int clen = 0; // length in characters bool is_id = true; @@ -3779,8 +3821,9 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol) scol = (int)(p - ptr); } - if (scol < mincol) + if (scol < mincol) { scol = mincol; + } if (scol < col) { // there is a word in front of the cursor ptr += scol; len = col - scol; @@ -3858,17 +3901,19 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol) // insert the last typed char (void)ins_typebuf(tb, 1, 0, true, mp->m_silent); } - if (mp->m_expr) + if (mp->m_expr) { s = eval_map_expr(mp->m_str, c); - else + } else { s = mp->m_str; + } if (s != NULL) { // insert the to string (void)ins_typebuf(s, mp->m_noremap, 0, true, mp->m_silent); // no abbrev. for these chars typebuf.tb_no_abbr_cnt += (int)STRLEN(s) + j + 1; - if (mp->m_expr) + if (mp->m_expr) { xfree(s); + } } tb[0] = Ctrl_H; @@ -3883,20 +3928,16 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol) return false; } -/* - * Evaluate the RHS of a mapping or abbreviations and take care of escaping - * special characters. - */ -static char_u * -eval_map_expr ( - char_u *str, - int c // NUL or typed character for abbreviation -) +/// Evaluate the RHS of a mapping or abbreviations and take care of escaping +/// special characters. +/// +/// @param c NUL or typed character for abbreviation +static char_u *eval_map_expr(char_u *str, int c) { - char_u *res; - char_u *p; - char_u *expr; - char_u *save_cmd; + char_u *res; + char_u *p; + char_u *expr; + char_u *save_cmd; pos_T save_cursor; int save_msg_col; int save_msg_row; @@ -3926,8 +3967,9 @@ eval_map_expr ( restore_cmdline_alloc(save_cmd); xfree(expr); - if (p == NULL) + if (p == NULL) { return NULL; + } // Escape CSI in the result to be able to use the string as typeahead. res = vim_strsave_escape_csi(p); xfree(p); @@ -3970,7 +4012,7 @@ char_u *vim_strsave_escape_csi(char_u *p) */ void vim_unescape_csi(char_u *p) { - char_u *s = p, *d = p; + char_u *s = p, *d = p; while (*s != NUL) { if (s[0] == K_SPECIAL && s[1] == KS_SPECIAL && s[2] == KE_FILLER) { @@ -3980,26 +4022,23 @@ void vim_unescape_csi(char_u *p) && s[1] == KS_EXTRA && s[2] == (int)KE_CSI) { *d++ = CSI; s += 3; - } else + } else { *d++ = *s++; + } } *d = NUL; } -/* - * Write map commands for the current mappings to an .exrc file. - * Return FAIL on error, OK otherwise. - */ -int -makemap( - FILE *fd, - buf_T *buf // buffer for local mappings or NULL -) +/// Write map commands for the current mappings to an .exrc file. +/// Return FAIL on error, OK otherwise. +/// +/// @param buf buffer for local mappings or NULL +int makemap(FILE *fd, buf_T *buf) { - mapblock_T *mp; + mapblock_T *mp; char_u c1, c2, c3; - char_u *p; - char *cmd; + char_u *p; + char *cmd; int abbr; int hash; bool did_cpo = false; @@ -4209,13 +4248,14 @@ makemap( // return FAIL for failure, OK otherwise int put_escstr(FILE *fd, char_u *strstart, int what) { - char_u *str = strstart; + char_u *str = strstart; int c; // :map xx <Nop> if (*str == NUL && what == 1) { - if (fprintf(fd, "<Nop>") < 0) + if (fprintf(fd, "<Nop>") < 0) { return FAIL; + } return OK; } @@ -4224,9 +4264,11 @@ int put_escstr(FILE *fd, char_u *strstart, int what) // K_SPECIAL and CSI bytes. const char *p = mb_unescape((const char **)&str); if (p != NULL) { - while (*p != NUL) - if (fputc(*p++, fd) < 0) + while (*p != NUL) { + if (fputc(*p++, fd) < 0) { return FAIL; + } + } --str; continue; } @@ -4261,11 +4303,13 @@ int put_escstr(FILE *fd, char_u *strstart, int what) */ if (c == NL) { if (what == 2) { - if (fprintf(fd, "\\\026\n") < 0) + if (fprintf(fd, "\\\026\n") < 0) { return FAIL; + } } else { - if (fprintf(fd, "<NL>") < 0) + if (fprintf(fd, "<NL>") < 0) { return FAIL; + } } continue; } @@ -4282,39 +4326,38 @@ int put_escstr(FILE *fd, char_u *strstart, int what) * A space in the lhs of a :map needs a CTRL-V. */ if (what == 2 && (ascii_iswhite(c) || c == '"' || c == '\\')) { - if (putc('\\', fd) < 0) + if (putc('\\', fd) < 0) { return FAIL; + } } else if (c < ' ' || c > '~' || c == '|' || (what == 0 && c == ' ') || (what == 1 && str == strstart && c == ' ') || (what != 2 && c == '<')) { - if (putc(Ctrl_V, fd) < 0) + if (putc(Ctrl_V, fd) < 0) { return FAIL; + } } - if (putc(c, fd) < 0) + if (putc(c, fd) < 0) { return FAIL; + } } return OK; } -/* - * Check the string "keys" against the lhs of all mappings. - * Return pointer to rhs of mapping (mapblock->m_str). - * NULL when no mapping found. - */ -char_u * -check_map ( - char_u *keys, - int mode, - int exact, // require exact match - int ign_mod, // ignore preceding modifier - int abbr, // do abbreviations - mapblock_T **mp_ptr, // return: pointer to mapblock or NULL - int *local_ptr // return: buffer-local mapping or NULL -) +/// Check the string "keys" against the lhs of all mappings. +/// Return pointer to rhs of mapping (mapblock->m_str). +/// NULL when no mapping found. +/// +/// @param exact require exact match +/// @param ign_mod ignore preceding modifier +/// @param abbr do abbreviations +/// @param mp_ptr return: pointer to mapblock or NULL +/// @param local_ptr return: buffer-local mapping or NULL +char_u *check_map(char_u *keys, int mode, int exact, int ign_mod, int abbr, mapblock_T **mp_ptr, + int *local_ptr) { int len, minlen; - mapblock_T *mp; + mapblock_T *mp; validate_maphash(); @@ -4349,10 +4392,12 @@ check_map ( } minlen = keylen < len ? keylen : len; if (STRNCMP(s, keys, minlen) == 0) { - if (mp_ptr != NULL) + if (mp_ptr != NULL) { *mp_ptr = mp; - if (local_ptr != NULL) + } + if (local_ptr != NULL) { *local_ptr = local; + } return mp->m_str; } } @@ -4374,8 +4419,8 @@ check_map ( /// @param nore If true, make a non-recursive mapping. void add_map(char_u *map, int mode, bool nore) { - char_u *s; - char_u *cpo_save = p_cpo; + char_u *s; + char_u *cpo_save = p_cpo; p_cpo = (char_u *)""; // Allow <> notation // Need to put string in allocated memory, because do_map() will modify it. @@ -4385,21 +4430,20 @@ void add_map(char_u *map, int mode, bool nore) p_cpo = cpo_save; } -// Translate an internal mapping/abbreviation representation into the -// corresponding external one recognized by :map/:abbrev commands. -// -// This function is called when expanding mappings/abbreviations on the -// command-line. -// -// It uses a growarray to build the translation string since the latter can be -// wider than the original description. The caller has to free the string -// afterwards. -// -// Returns NULL when there is a problem. -static char_u * translate_mapping ( - char_u *str, - int cpo_flags // Value of various flags present in &cpo -) +/// Translate an internal mapping/abbreviation representation into the +/// corresponding external one recognized by :map/:abbrev commands. +/// +/// This function is called when expanding mappings/abbreviations on the +/// command-line. +/// +/// It uses a growarray to build the translation string since the latter can be +/// wider than the original description. The caller has to free the string +/// afterwards. +/// +/// @param cpo_flags Value of various flags present in &cpo +/// +/// @return NULL when there is a problem. +static char_u *translate_mapping(char_u *str, int cpo_flags) { garray_T ga; ga_init(&ga, 1, 40); @@ -4425,7 +4469,7 @@ static char_u * translate_mapping ( str += 2; } if (IS_SPECIAL(c) || modifiers) { // special key - ga_concat(&ga, get_special_key_name(c, modifiers)); + ga_concat(&ga, (char *)get_special_key_name(c, modifiers)); continue; // for (str) } } @@ -4447,8 +4491,9 @@ static bool typebuf_match_len(const uint8_t *str, int *mlen) { int i; for (i = 0; i < typebuf.tb_len && str[i]; i++) { - if (str[i] != typebuf.tb_buf[typebuf.tb_off + i]) + if (str[i] != typebuf.tb_buf[typebuf.tb_off + i]) { break; + } } *mlen = i; return str[i] == NUL; // matched the whole string @@ -4469,7 +4514,7 @@ mapblock_T *get_maphash(int index, buf_T *buf) } /// Get command argument for <Cmd> key -char_u * getcmdkeycmd(int promptc, void *cookie, int indent, bool do_concat) +char_u *getcmdkeycmd(int promptc, void *cookie, int indent, bool do_concat) { garray_T line_ga; int c1 = -1, c2; @@ -4518,7 +4563,7 @@ char_u * getcmdkeycmd(int promptc, void *cookie, int indent, bool do_concat) aborted = true; } else if (IS_SPECIAL(c1)) { if (c1 == K_SNR) { - ga_concat(&line_ga, (char_u *)"<SNR>"); + ga_concat(&line_ga, "<SNR>"); } else { EMSG2(e_cmdmap_key, get_special_key_name(c1, cmod)); aborted = true; diff --git a/src/nvim/getchar.h b/src/nvim/getchar.h index f0b52079aa..4e9dd2eab7 100644 --- a/src/nvim/getchar.h +++ b/src/nvim/getchar.h @@ -1,10 +1,10 @@ #ifndef NVIM_GETCHAR_H #define NVIM_GETCHAR_H -#include "nvim/os/fileio.h" -#include "nvim/types.h" #include "nvim/buffer_defs.h" #include "nvim/ex_cmds_defs.h" +#include "nvim/os/fileio.h" +#include "nvim/types.h" #include "nvim/vim.h" /// Values for "noremap" argument of ins_typebuf() @@ -56,6 +56,8 @@ struct map_arguments { size_t orig_rhs_len; }; typedef struct map_arguments MapArguments; +#define MAP_ARGUMENTS_INIT { false, false, false, false, false, false, false, \ + { 0 }, 0, NULL, 0, false, NULL, 0 } #define KEYLEN_PART_KEY -1 // keylen value for incomplete key-code #define KEYLEN_PART_MAP -2 // keylen value for incomplete mapping diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 4d54907a75..d1f6e2dbd9 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -1,23 +1,23 @@ #ifndef NVIM_GLOBALS_H #define NVIM_GLOBALS_H -#include <stdbool.h> #include <inttypes.h> +#include <stdbool.h> -#include "nvim/macros.h" +#include "nvim/event/loop.h" #include "nvim/ex_eval.h" #include "nvim/iconv.h" +#include "nvim/macros.h" #include "nvim/mbyte.h" #include "nvim/menu.h" +#include "nvim/os/os_defs.h" #include "nvim/syntax_defs.h" #include "nvim/types.h" -#include "nvim/event/loop.h" -#include "nvim/os/os_defs.h" #define IOSIZE (1024+1) // file I/O and sprintf buffer size -# define MSG_BUF_LEN 480 // length of buffer for small messages -# define MSG_BUF_CLEN (MSG_BUF_LEN / 6) // cell length (worst case: utf-8 +#define MSG_BUF_LEN 480 // length of buffer for small messages +#define MSG_BUF_CLEN (MSG_BUF_LEN / 6) // cell length (worst case: utf-8 // takes 6 bytes for one cell) #ifdef WIN32 @@ -169,16 +169,16 @@ EXTERN bool compl_busy INIT(= false); // List of flags for method of completion. EXTERN int compl_cont_status INIT(= 0); -# define CONT_ADDING 1 // "normal" or "adding" expansion -# define CONT_INTRPT (2 + 4) // a ^X interrupted the current expansion - // it's set only iff N_ADDS is set -# define CONT_N_ADDS 4 // next ^X<> will add-new or expand-current -# define CONT_S_IPOS 8 // next ^X<> will set initial_pos? - // if so, word-wise-expansion will set SOL -# define CONT_SOL 16 // pattern includes start of line, just for - // word-wise expansion, not set for ^X^L -# define CONT_LOCAL 32 // for ctrl_x_mode 0, ^X^P/^X^N do a local - // expansion, (eg use complete=.) +#define CONT_ADDING 1 // "normal" or "adding" expansion +#define CONT_INTRPT (2 + 4) // a ^X interrupted the current expansion + // it's set only iff N_ADDS is set +#define CONT_N_ADDS 4 // next ^X<> will add-new or expand-current +#define CONT_S_IPOS 8 // next ^X<> will set initial_pos? + // if so, word-wise-expansion will set SOL +#define CONT_SOL 16 // pattern includes start of line, just for + // word-wise expansion, not set for ^X^L +#define CONT_LOCAL 32 // for ctrl_x_mode 0, ^X^P/^X^N do a local + // expansion, (eg use complete=.) EXTERN char_u *edit_submode INIT(= NULL); // msg for CTRL-X submode EXTERN char_u *edit_submode_pre INIT(= NULL); // prepended to edit_submode @@ -335,7 +335,7 @@ EXTERN int garbage_collect_at_exit INIT(= false); #define SID_WINLAYOUT -7 // changing window size #define SID_LUA -8 // for Lua scripts/chunks #define SID_API_CLIENT -9 // for API clients -#define SID_STR -10 // for sourcing a string +#define SID_STR -10 // for sourcing a string with no script item // Script CTX being sourced or was sourced to define the current function. EXTERN sctx_T current_sctx INIT(= { 0 COMMA 0 COMMA 0 }); @@ -363,7 +363,7 @@ EXTERN int t_colors INIT(= 256); // int value of T_CCO // a match within one line), search_match_endcol the column number of the // character just after the match in the last line. EXTERN bool highlight_match INIT(= false); // show search match pos -EXTERN linenr_T search_match_lines; // lines of of matched string +EXTERN linenr_T search_match_lines; // lines of matched string EXTERN colnr_T search_match_endcol; // col nr of match end EXTERN linenr_T search_first_line INIT(= 0); // for :{FIRST},{last}s/pat EXTERN linenr_T search_last_line INIT(= MAXLNUM); // for :{first},{LAST}s/pat @@ -405,7 +405,7 @@ EXTERN int mouse_dragging INIT(= 0); // extending Visual area with // mouse dragging // The root of the menu hierarchy. -EXTERN vimmenu_T *root_menu INIT(= NULL); +EXTERN vimmenu_T *root_menu INIT(= NULL); // While defining the system menu, sys_menu is true. This avoids // overruling of menus that the user already defined. EXTERN int sys_menu INIT(= false); @@ -417,48 +417,48 @@ EXTERN int updating_screen INIT(= 0); // All windows are linked in a list. firstwin points to the first entry, // lastwin to the last entry (can be the same as firstwin) and curwin to the // currently active window. -EXTERN win_T *firstwin; // first window -EXTERN win_T *lastwin; // last window -EXTERN win_T *prevwin INIT(= NULL); // previous window -# define ONE_WINDOW (firstwin == lastwin) -# define FOR_ALL_FRAMES(frp, first_frame) \ +EXTERN win_T *firstwin; // first window +EXTERN win_T *lastwin; // last window +EXTERN win_T *prevwin INIT(= NULL); // previous window +#define ONE_WINDOW (firstwin == lastwin) +#define FOR_ALL_FRAMES(frp, first_frame) \ for (frp = first_frame; frp != NULL; frp = frp->fr_next) // NOLINT // When using this macro "break" only breaks out of the inner loop. Use "goto" // to break out of the tabpage loop. -# define FOR_ALL_TAB_WINDOWS(tp, wp) \ +#define FOR_ALL_TAB_WINDOWS(tp, wp) \ FOR_ALL_TABS(tp) \ - FOR_ALL_WINDOWS_IN_TAB(wp, tp) + FOR_ALL_WINDOWS_IN_TAB(wp, tp) // -V:FOR_ALL_WINDOWS_IN_TAB:501 -# define FOR_ALL_WINDOWS_IN_TAB(wp, tp) \ +#define FOR_ALL_WINDOWS_IN_TAB(wp, tp) \ for (win_T *wp = ((tp) == curtab) \ ? firstwin : (tp)->tp_firstwin; wp != NULL; wp = wp->w_next) -EXTERN win_T *curwin; // currently active window +EXTERN win_T *curwin; // currently active window -EXTERN win_T *aucmd_win; // window used in aucmd_prepbuf() +EXTERN win_T *aucmd_win; // window used in aucmd_prepbuf() EXTERN int aucmd_win_used INIT(= false); // aucmd_win is being used // The window layout is kept in a tree of frames. topframe points to the top // of the tree. -EXTERN frame_T *topframe; // top of the window frame tree +EXTERN frame_T *topframe; // top of the window frame tree // Tab pages are alternative topframes. "first_tabpage" points to the first // one in the list, "curtab" is the current one. -EXTERN tabpage_T *first_tabpage; -EXTERN tabpage_T *lastused_tabpage; -EXTERN tabpage_T *curtab; +EXTERN tabpage_T *first_tabpage; +EXTERN tabpage_T *lastused_tabpage; +EXTERN tabpage_T *curtab; EXTERN bool redraw_tabline INIT(= false); // need to redraw tabline // Iterates over all tabs in the tab list -# define FOR_ALL_TABS(tp) for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next) +#define FOR_ALL_TABS(tp) for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next) // All buffers are linked in a list. 'firstbuf' points to the first entry, // 'lastbuf' to the last entry and 'curbuf' to the currently active buffer. EXTERN buf_T *firstbuf INIT(= NULL); // first buffer -EXTERN buf_T *lastbuf INIT(= NULL); // last buffer -EXTERN buf_T *curbuf INIT(= NULL); // currently active buffer +EXTERN buf_T *lastbuf INIT(= NULL); // last buffer +EXTERN buf_T *curbuf INIT(= NULL); // currently active buffer // Iterates over all buffers in the buffer list. #define FOR_ALL_BUFFERS(buf) \ @@ -593,16 +593,16 @@ EXTERN int inhibit_delete_count INIT(= 0); // These flags are set based upon 'fileencoding'. // The characters are internally stored as UTF-8 // to avoid trouble with NUL bytes. -# define DBCS_JPN 932 // japan -# define DBCS_JPNU 9932 // euc-jp -# define DBCS_KOR 949 // korea -# define DBCS_KORU 9949 // euc-kr -# define DBCS_CHS 936 // chinese -# define DBCS_CHSU 9936 // euc-cn -# define DBCS_CHT 950 // taiwan -# define DBCS_CHTU 9950 // euc-tw -# define DBCS_2BYTE 1 // 2byte- -# define DBCS_DEBUG -1 +#define DBCS_JPN 932 // japan +#define DBCS_JPNU 9932 // euc-jp +#define DBCS_KOR 949 // korea +#define DBCS_KORU 9949 // euc-kr +#define DBCS_CHS 936 // chinese +#define DBCS_CHSU 9936 // euc-cn +#define DBCS_CHT 950 // taiwan +#define DBCS_CHTU 9950 // euc-tw +#define DBCS_2BYTE 1 // 2byte- +#define DBCS_DEBUG -1 /// Encoding used when 'fencs' is set to "default" EXTERN char_u *fenc_default INIT(= NULL); @@ -669,12 +669,12 @@ EXTERN bool swap_exists_did_quit INIT(= false); EXTERN char_u IObuff[IOSIZE]; ///< Buffer for sprintf, I/O, etc. EXTERN char_u NameBuff[MAXPATHL]; ///< Buffer for expanding file names -EXTERN char_u msg_buf[MSG_BUF_LEN]; ///< Small buffer for messages +EXTERN char msg_buf[MSG_BUF_LEN]; ///< Small buffer for messages EXTERN char os_buf[ ///< Buffer for the os/ layer #if MAXPATHL > IOSIZE -MAXPATHL + MAXPATHL #else -IOSIZE + IOSIZE #endif ]; @@ -746,7 +746,7 @@ EXTERN bool g_tag_at_cursor INIT(= false); // whether the tag command comes EXTERN int replace_offset INIT(= 0); // offset for replace_push() -EXTERN char_u *escape_chars INIT(= (char_u *)" \t\\\"|"); +EXTERN char_u *escape_chars INIT(= (char_u *)" \t\\\"|"); // need backslash in cmd line EXTERN int keep_help_flag INIT(= false); // doing :ta from help file @@ -754,7 +754,7 @@ EXTERN int keep_help_flag INIT(= false); // doing :ta from help file // When a string option is NULL (which only happens in out-of-memory // situations), it is set to empty_option, to avoid having to check for NULL // everywhere. -EXTERN char_u *empty_option INIT(= (char_u *)""); +EXTERN char_u *empty_option INIT(= (char_u *)""); EXTERN bool redir_off INIT(= false); // no redirection for a moment EXTERN FILE *redir_fd INIT(= NULL); // message redirection file @@ -787,7 +787,7 @@ extern char_u *compiled_sys; // When a window has a local directory, the absolute path of the global // current directory is stored here (in allocated memory). If the current // directory is not a local directory, globaldir is NULL. -EXTERN char_u *globaldir INIT(= NULL); +EXTERN char_u *globaldir INIT(= NULL); // Whether 'keymodel' contains "stopsel" and "startsel". EXTERN bool km_stopsel INIT(= false); @@ -810,8 +810,8 @@ EXTERN linenr_T sub_nlines; // total number of lines changed EXTERN char_u wim_flags[4]; // whether titlestring and iconstring contains statusline syntax -# define STL_IN_ICON 1 -# define STL_IN_TITLE 2 +#define STL_IN_ICON 1 +#define STL_IN_TITLE 2 EXTERN int stl_syntax INIT(= 0); // don't use 'hlsearch' temporarily @@ -846,15 +846,16 @@ EXTERN linenr_T spell_redraw_lnum INIT(= 0); // The error messages that can be shared are included here. // Excluded are errors that are only used once and debugging messages. EXTERN char_u e_abort[] INIT(= N_("E470: Command aborted")); -EXTERN char_u e_afterinit[] INIT(= N_( - "E905: Cannot set this option after startup")); +EXTERN char_u e_afterinit[] INIT(= N_("E905: Cannot set this option after startup")); EXTERN char_u e_api_spawn_failed[] INIT(= N_("E903: Could not spawn API job")); EXTERN char_u e_argreq[] INIT(= N_("E471: Argument required")); EXTERN char_u e_backslash[] INIT(= N_("E10: \\ should be followed by /, ? or &")); -EXTERN char_u e_cmdwin[] INIT(= N_( - "E11: Invalid in command-line window; <CR> executes, CTRL-C quits")); -EXTERN char_u e_curdir[] INIT(= N_( - "E12: Command not allowed from exrc/vimrc in current dir or tag search")); +EXTERN char_u e_cmdwin[] INIT(= + N_( + "E11: Invalid in command-line window; <CR> executes, CTRL-C quits")); +EXTERN char_u e_curdir[] INIT(= + N_( + "E12: Command not allowed from exrc/vimrc in current dir or tag search")); EXTERN char_u e_endif[] INIT(= N_("E171: Missing :endif")); EXTERN char_u e_endtry[] INIT(= N_("E600: Missing :endtry")); EXTERN char_u e_endwhile[] INIT(= N_("E170: Missing :endwhile")); @@ -869,8 +870,7 @@ EXTERN char_u e_interr[] INIT(= N_("Interrupted")); EXTERN char_u e_invarg[] INIT(= N_("E474: Invalid argument")); EXTERN char_u e_invarg2[] INIT(= N_("E475: Invalid argument: %s")); EXTERN char_u e_invargval[] INIT(= N_("E475: Invalid value for argument %s")); -EXTERN char_u e_invargNval[] INIT(= N_( - "E475: Invalid value for argument %s: %s")); +EXTERN char_u e_invargNval[] INIT(= N_("E475: Invalid value for argument %s: %s")); EXTERN char_u e_duparg2[] INIT(= N_("E983: Duplicate argument: %s")); EXTERN char_u e_invexpr2[] INIT(= N_("E15: Invalid expression: %s")); EXTERN char_u e_invrange[] INIT(= N_("E16: Invalid range")); @@ -880,24 +880,21 @@ EXTERN char_u e_no_spell[] INIT(= N_("E756: Spell checking is not possible")); EXTERN char_u e_invchan[] INIT(= N_("E900: Invalid channel id")); EXTERN char_u e_invchanjob[] INIT(= N_("E900: Invalid channel id: not a job")); EXTERN char_u e_jobtblfull[] INIT(= N_("E901: Job table is full")); -EXTERN char_u e_jobspawn[] INIT(= N_( - "E903: Process failed to start: %s: \"%s\"")); +EXTERN char_u e_jobspawn[] INIT(= N_("E903: Process failed to start: %s: \"%s\"")); EXTERN char_u e_channotpty[] INIT(= N_("E904: channel is not a pty")); -EXTERN char_u e_stdiochan2[] INIT(= N_( - "E905: Couldn't open stdio channel: %s")); +EXTERN char_u e_stdiochan2[] INIT(= N_("E905: Couldn't open stdio channel: %s")); EXTERN char_u e_invstream[] INIT(= N_("E906: invalid stream for channel")); -EXTERN char_u e_invstreamrpc[] INIT(= N_( - "E906: invalid stream for rpc channel, use 'rpc'")); -EXTERN char_u e_streamkey[] INIT(= N_( - "E5210: dict key '%s' already set for buffered stream in channel %" - PRIu64)); +EXTERN char_u e_invstreamrpc[] INIT(= N_("E906: invalid stream for rpc channel, use 'rpc'")); +EXTERN char_u e_streamkey[] INIT(= + N_( + "E5210: dict key '%s' already set for buffered stream in channel %" + PRIu64)); EXTERN char_u e_libcall[] INIT(= N_("E364: Library call failed for \"%s()\"")); EXTERN char e_fsync[] INIT(= N_("E667: Fsync failed: %s")); EXTERN char_u e_mkdir[] INIT(= N_("E739: Cannot create directory %s: %s")); EXTERN char_u e_markinval[] INIT(= N_("E19: Mark has invalid line number")); EXTERN char_u e_marknotset[] INIT(= N_("E20: Mark not set")); -EXTERN char_u e_modifiable[] INIT(= N_( - "E21: Cannot make changes, 'modifiable' is off")); +EXTERN char_u e_modifiable[] INIT(= N_("E21: Cannot make changes, 'modifiable' is off")); EXTERN char_u e_nesting[] INIT(= N_("E22: Scripts nested too deep")); EXTERN char_u e_noalt[] INIT(= N_("E23: No alternate file")); EXTERN char_u e_noabbr[] INIT(= N_("E24: No such abbreviation")); @@ -909,8 +906,7 @@ EXTERN char_u e_nomap[] INIT(= N_("E31: No such mapping")); EXTERN char_u e_nomatch[] INIT(= N_("E479: No match")); EXTERN char_u e_nomatch2[] INIT(= N_("E480: No match: %s")); EXTERN char_u e_noname[] INIT(= N_("E32: No file name")); -EXTERN char_u e_nopresub[] INIT(= N_( - "E33: No previous substitute regular expression")); +EXTERN char_u e_nopresub[] INIT(= N_("E33: No previous substitute regular expression")); EXTERN char_u e_noprev[] INIT(= N_("E34: No previous command")); EXTERN char_u e_noprevre[] INIT(= N_("E35: No previous regular expression")); EXTERN char_u e_norange[] INIT(= N_("E481: No range allowed")); @@ -926,36 +922,30 @@ EXTERN char_u e_outofmem[] INIT(= N_("E41: Out of memory!")); EXTERN char_u e_patnotf[] INIT(= N_("Pattern not found")); EXTERN char_u e_patnotf2[] INIT(= N_("E486: Pattern not found: %s")); EXTERN char_u e_positive[] INIT(= N_("E487: Argument must be positive")); -EXTERN char_u e_prev_dir[] INIT(= N_( - "E459: Cannot go back to previous directory")); +EXTERN char_u e_prev_dir[] INIT(= N_("E459: Cannot go back to previous directory")); EXTERN char_u e_quickfix[] INIT(= N_("E42: No Errors")); EXTERN char_u e_loclist[] INIT(= N_("E776: No location list")); EXTERN char_u e_re_damg[] INIT(= N_("E43: Damaged match string")); EXTERN char_u e_re_corr[] INIT(= N_("E44: Corrupted regexp program")); -EXTERN char_u e_readonly[] INIT(= N_( - "E45: 'readonly' option is set (add ! to override)")); -EXTERN char_u e_readonlyvar[] INIT(= N_( - "E46: Cannot change read-only variable \"%.*s\"")); +EXTERN char_u e_readonly[] INIT(= N_("E45: 'readonly' option is set (add ! to override)")); +EXTERN char_u e_readonlyvar[] INIT(= N_("E46: Cannot change read-only variable \"%.*s\"")); EXTERN char_u e_stringreq[] INIT(= N_("E928: String required")); EXTERN char_u e_dictreq[] INIT(= N_("E715: Dictionary required")); EXTERN char_u e_blobidx[] INIT(= N_("E979: Blob index out of range: %" PRId64)); EXTERN char_u e_invalblob[] INIT(= N_("E978: Invalid operation for Blob")); -EXTERN char_u e_toomanyarg[] INIT(= N_( - "E118: Too many arguments for function: %s")); -EXTERN char_u e_dictkey[] INIT(= N_( - "E716: Key not present in Dictionary: \"%s\"")); +EXTERN char_u e_toomanyarg[] INIT(= N_("E118: Too many arguments for function: %s")); +EXTERN char_u e_dictkey[] INIT(= N_("E716: Key not present in Dictionary: \"%s\"")); EXTERN char_u e_listreq[] INIT(= N_("E714: List required")); EXTERN char_u e_listblobreq[] INIT(= N_("E897: List or Blob required")); -EXTERN char_u e_listdictarg[] INIT(= N_( - "E712: Argument of %s must be a List or Dictionary")); -EXTERN char_u e_listdictblobarg[] INIT(= N_( - "E896: Argument of %s must be a List, Dictionary or Blob")); +EXTERN char_u e_listdictarg[] INIT(= N_("E712: Argument of %s must be a List or Dictionary")); +EXTERN char_u e_listdictblobarg[] INIT(= + N_( + "E896: Argument of %s must be a List, Dictionary or Blob")); EXTERN char_u e_readerrf[] INIT(= N_("E47: Error while reading errorfile")); EXTERN char_u e_sandbox[] INIT(= N_("E48: Not allowed in sandbox")); EXTERN char_u e_secure[] INIT(= N_("E523: Not allowed here")); -EXTERN char_u e_screenmode[] INIT(= N_( - "E359: Screen mode setting not supported")); +EXTERN char_u e_screenmode[] INIT(= N_("E359: Screen mode setting not supported")); EXTERN char_u e_scroll[] INIT(= N_("E49: Invalid scroll size")); EXTERN char_u e_shellempty[] INIT(= N_("E91: 'shell' option is empty")); EXTERN char_u e_signdata[] INIT(= N_("E255: Couldn't read in sign data!")); @@ -969,57 +959,44 @@ EXTERN char_u e_trailing[] INIT(= N_("E488: Trailing characters")); EXTERN char_u e_trailing2[] INIT(= N_("E488: Trailing characters: %s")); EXTERN char_u e_umark[] INIT(= N_("E78: Unknown mark")); EXTERN char_u e_wildexpand[] INIT(= N_("E79: Cannot expand wildcards")); -EXTERN char_u e_winheight[] INIT(= N_( - "E591: 'winheight' cannot be smaller than 'winminheight'")); -EXTERN char_u e_winwidth[] INIT(= N_( - "E592: 'winwidth' cannot be smaller than 'winminwidth'")); +EXTERN char_u e_winheight[] INIT(= N_("E591: 'winheight' cannot be smaller than 'winminheight'")); +EXTERN char_u e_winwidth[] INIT(= N_("E592: 'winwidth' cannot be smaller than 'winminwidth'")); EXTERN char_u e_write[] INIT(= N_("E80: Error while writing")); EXTERN char_u e_zerocount[] INIT(= N_("E939: Positive count required")); -EXTERN char_u e_usingsid[] INIT(= N_( - "E81: Using <SID> not in a script context")); +EXTERN char_u e_usingsid[] INIT(= N_("E81: Using <SID> not in a script context")); EXTERN char_u e_missingparen[] INIT(= N_("E107: Missing parentheses: %s")); -EXTERN char_u e_maxmempat[] INIT(= N_( - "E363: pattern uses more memory than 'maxmempattern'")); +EXTERN char_u e_maxmempat[] INIT(= N_("E363: pattern uses more memory than 'maxmempattern'")); EXTERN char_u e_emptybuf[] INIT(= N_("E749: empty buffer")); EXTERN char_u e_nobufnr[] INIT(= N_("E86: Buffer %" PRId64 " does not exist")); -EXTERN char_u e_invalpat[] INIT(= N_( - "E682: Invalid search pattern or delimiter")); +EXTERN char_u e_invalpat[] INIT(= N_("E682: Invalid search pattern or delimiter")); EXTERN char_u e_bufloaded[] INIT(= N_("E139: File is loaded in another buffer")); EXTERN char_u e_notset[] INIT(= N_("E764: Option '%s' is not set")); EXTERN char_u e_invalidreg[] INIT(= N_("E850: Invalid register name")); -EXTERN char_u e_dirnotf[] INIT(= N_( - "E919: Directory not found in '%s': \"%s\"")); -EXTERN char_u e_au_recursive[] INIT(= N_( - "E952: Autocommand caused recursive behavior")); -EXTERN char_u e_autocmd_close[] INIT(= N_( - "E813: Cannot close autocmd window")); +EXTERN char_u e_dirnotf[] INIT(= N_("E919: Directory not found in '%s': \"%s\"")); +EXTERN char_u e_au_recursive[] INIT(= N_("E952: Autocommand caused recursive behavior")); +EXTERN char_u e_autocmd_close[] INIT(= N_("E813: Cannot close autocmd window")); EXTERN char_u e_unsupportedoption[] INIT(= N_("E519: Option not supported")); EXTERN char_u e_fnametoolong[] INIT(= N_("E856: Filename too long")); EXTERN char_u e_float_as_string[] INIT(= N_("E806: using Float as a String")); -EXTERN char_u e_autocmd_err[] INIT(=N_( - "E5500: autocmd has thrown an exception: %s")); -EXTERN char_u e_cmdmap_err[] INIT(=N_( - "E5520: <Cmd> mapping must end with <CR>")); -EXTERN char_u e_cmdmap_repeated[] INIT(=N_( - "E5521: <Cmd> mapping must end with <CR> before second <Cmd>")); -EXTERN char_u e_cmdmap_key[] INIT(=N_( - "E5522: <Cmd> mapping must not include %s key")); +EXTERN char_u e_autocmd_err[] INIT(=N_("E5500: autocmd has thrown an exception: %s")); +EXTERN char_u e_cmdmap_err[] INIT(=N_("E5520: <Cmd> mapping must end with <CR>")); +EXTERN char_u +e_cmdmap_repeated[] INIT(=N_("E5521: <Cmd> mapping must end with <CR> before second <Cmd>")); +EXTERN char_u e_cmdmap_key[] INIT(=N_("E5522: <Cmd> mapping must not include %s key")); -EXTERN char_u e_api_error[] INIT(=N_( - "E5555: API call: %s")); +EXTERN char_u e_api_error[] INIT(=N_("E5555: API call: %s")); -EXTERN char e_luv_api_disabled[] INIT(=N_( - "E5560: %s must not be called in a lua loop callback")); +EXTERN char e_luv_api_disabled[] INIT(=N_("E5560: %s must not be called in a lua loop callback")); EXTERN char_u e_floatonly[] INIT(=N_( - "E5601: Cannot close window, only floating window would remain")); -EXTERN char_u e_floatexchange[] INIT(=N_( - "E5602: Cannot exchange or rotate float")); + "E5601: Cannot close window, only floating window would remain")); +EXTERN char_u e_floatexchange[] INIT(=N_("E5602: Cannot exchange or rotate float")); -EXTERN char e_cannot_define_autocommands_for_all_events[] INIT(= N_( - "E1155: Cannot define autocommands for ALL events")); +EXTERN char e_cannot_define_autocommands_for_all_events[] INIT(= + N_( + "E1155: Cannot define autocommands for ALL events")); EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM")); EXTERN char bot_top_msg[] INIT(= N_("search hit BOTTOM, continuing at TOP")); @@ -1057,14 +1034,22 @@ typedef enum { /// directly, use `MIN_CD_SCOPE` and `MAX_CD_SCOPE` instead. typedef enum { kCdScopeInvalid = -1, - kCdScopeWindow, ///< Affects one window. - kCdScopeTab, ///< Affects one tab page. - kCdScopeGlobal, ///< Affects the entire Nvim instance. + kCdScopeWindow, ///< Affects one window. + kCdScopeTabpage, ///< Affects one tab page. + kCdScopeGlobal, ///< Affects the entire Nvim instance. } CdScope; #define MIN_CD_SCOPE kCdScopeWindow #define MAX_CD_SCOPE kCdScopeGlobal +/// What caused the current directory to change. +typedef enum { + kCdCauseOther = -1, + kCdCauseManual, ///< Using `:cd`, `:tcd`, `:lcd` or `chdir()`. + kCdCauseWindow, ///< Switching to another window. + kCdCauseAuto, ///< On 'autochdir'. +} CdCause; + // Only filled for Win32. EXTERN char windowsVersion[20] INIT(= { 0 }); diff --git a/src/nvim/grid_defs.h b/src/nvim/grid_defs.h index dee096214f..bf0a5d63a8 100644 --- a/src/nvim/grid_defs.h +++ b/src/nvim/grid_defs.h @@ -48,10 +48,10 @@ typedef struct ScreenGrid ScreenGrid; struct ScreenGrid { handle_T handle; - schar_T *chars; - sattr_T *attrs; + schar_T *chars; + sattr_T *attrs; unsigned *line_offset; - char_u *line_wraps; + char_u *line_wraps; // last column that was drawn (not cleared with the default background). // only used when "throttled" is set. Not allocated by grid_alloc! diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index 1b1735c991..0b828777f4 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -6,35 +6,35 @@ */ #include <assert.h> -#include <string.h> #include <inttypes.h> +#include <string.h> -#include "nvim/vim.h" #include "nvim/ascii.h" +#include "nvim/vim.h" #ifdef HAVE_LOCALE_H # include <locale.h> #endif -#include "nvim/hardcopy.h" #include "nvim/buffer.h" #include "nvim/charset.h" #include "nvim/eval.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_docmd.h" #include "nvim/fileio.h" +#include "nvim/garray.h" +#include "nvim/hardcopy.h" #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/message.h" -#include "nvim/garray.h" #include "nvim/option.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" #include "nvim/path.h" #include "nvim/screen.h" #include "nvim/strings.h" #include "nvim/syntax.h" #include "nvim/ui.h" #include "nvim/version.h" -#include "nvim/os/os.h" -#include "nvim/os/input.h" /* * To implement printing on a platform, the following functions must be @@ -98,20 +98,20 @@ static option_table_T printer_opts[OPT_PRINT_NUM_OPTIONS] = { - {"top", TRUE, 0, NULL, 0, FALSE}, - {"bottom", TRUE, 0, NULL, 0, FALSE}, - {"left", TRUE, 0, NULL, 0, FALSE}, - {"right", TRUE, 0, NULL, 0, FALSE}, - {"header", TRUE, 0, NULL, 0, FALSE}, - {"syntax", FALSE, 0, NULL, 0, FALSE}, - {"number", FALSE, 0, NULL, 0, FALSE}, - {"wrap", FALSE, 0, NULL, 0, FALSE}, - {"duplex", FALSE, 0, NULL, 0, FALSE}, - {"portrait", FALSE, 0, NULL, 0, FALSE}, - {"paper", FALSE, 0, NULL, 0, FALSE}, - {"collate", FALSE, 0, NULL, 0, FALSE}, - {"jobsplit", FALSE, 0, NULL, 0, FALSE}, - {"formfeed", FALSE, 0, NULL, 0, FALSE}, + { "top", TRUE, 0, NULL, 0, FALSE }, + { "bottom", TRUE, 0, NULL, 0, FALSE }, + { "left", TRUE, 0, NULL, 0, FALSE }, + { "right", TRUE, 0, NULL, 0, FALSE }, + { "header", TRUE, 0, NULL, 0, FALSE }, + { "syntax", FALSE, 0, NULL, 0, FALSE }, + { "number", FALSE, 0, NULL, 0, FALSE }, + { "wrap", FALSE, 0, NULL, 0, FALSE }, + { "duplex", FALSE, 0, NULL, 0, FALSE }, + { "portrait", FALSE, 0, NULL, 0, FALSE }, + { "paper", FALSE, 0, NULL, 0, FALSE }, + { "collate", FALSE, 0, NULL, 0, FALSE }, + { "jobsplit", FALSE, 0, NULL, 0, FALSE }, + { "formfeed", FALSE, 0, NULL, 0, FALSE }, } ; @@ -140,22 +140,22 @@ static uint32_t curr_bg; static uint32_t curr_fg; static int page_count; -# define OPT_MBFONT_USECOURIER 0 -# define OPT_MBFONT_ASCII 1 -# define OPT_MBFONT_REGULAR 2 -# define OPT_MBFONT_BOLD 3 -# define OPT_MBFONT_OBLIQUE 4 -# define OPT_MBFONT_BOLDOBLIQUE 5 -# define OPT_MBFONT_NUM_OPTIONS 6 +#define OPT_MBFONT_USECOURIER 0 +#define OPT_MBFONT_ASCII 1 +#define OPT_MBFONT_REGULAR 2 +#define OPT_MBFONT_BOLD 3 +#define OPT_MBFONT_OBLIQUE 4 +#define OPT_MBFONT_BOLDOBLIQUE 5 +#define OPT_MBFONT_NUM_OPTIONS 6 static option_table_T mbfont_opts[OPT_MBFONT_NUM_OPTIONS] = { - {"c", FALSE, 0, NULL, 0, FALSE}, - {"a", FALSE, 0, NULL, 0, FALSE}, - {"r", FALSE, 0, NULL, 0, FALSE}, - {"b", FALSE, 0, NULL, 0, FALSE}, - {"i", FALSE, 0, NULL, 0, FALSE}, - {"o", FALSE, 0, NULL, 0, FALSE}, + { "c", FALSE, 0, NULL, 0, FALSE }, + { "a", FALSE, 0, NULL, 0, FALSE }, + { "r", FALSE, 0, NULL, 0, FALSE }, + { "b", FALSE, 0, NULL, 0, FALSE }, + { "i", FALSE, 0, NULL, 0, FALSE }, + { "o", FALSE, 0, NULL, 0, FALSE }, }; /* @@ -183,31 +183,31 @@ struct prt_ps_font_S { int uline_width; int bbox_min_y; int bbox_max_y; - char *(ps_fontname[4]); + char *(ps_fontname[4]); }; /* Structures to map user named encoding and mapping to PS equivalents for * building CID font name */ struct prt_ps_encoding_S { - char *encoding; - char *cmap_encoding; + char *encoding; + char *cmap_encoding; int needs_charset; }; struct prt_ps_charset_S { - char *charset; - char *cmap_charset; + char *charset; + char *cmap_charset; int has_charset; }; // Collections of encodings and charsets for multi-byte printing struct prt_ps_mbfont_S { int num_encodings; - struct prt_ps_encoding_S *encodings; + struct prt_ps_encoding_S *encodings; int num_charsets; - struct prt_ps_charset_S *charsets; - char *ascii_enc; - char *defcs; + struct prt_ps_charset_S *charsets; + char *ascii_enc; + char *defcs; }; // Types of PS resource file currently used @@ -234,14 +234,14 @@ struct prt_ps_resource_S { }; struct prt_dsc_comment_S { - char *string; + char *string; int len; int type; }; struct prt_dsc_line_S { int type; - char_u *string; + char_u *string; int len; }; @@ -286,15 +286,14 @@ char_u *parse_printmbfont(void) * Returns an error message for an illegal option, NULL otherwise. * Only used for the printer at the moment... */ -static char_u *parse_list_options(char_u *option_str, option_table_T *table, - size_t table_size) +static char_u *parse_list_options(char_u *option_str, option_table_T *table, size_t table_size) { option_table_T *old_opts; - char_u *ret = NULL; - char_u *stringp; - char_u *colonp; - char_u *commap; - char_u *p; + char_u *ret = NULL; + char_u *stringp; + char_u *colonp; + char_u *commap; + char_u *p; size_t idx = 0; // init for GCC int len; @@ -317,14 +316,17 @@ static char_u *parse_list_options(char_u *option_str, option_table_T *table, break; } commap = vim_strchr(stringp, ','); - if (commap == NULL) + if (commap == NULL) { commap = option_str + STRLEN(option_str); + } len = (int)(colonp - stringp); - for (idx = 0; idx < table_size; ++idx) - if (STRNICMP(stringp, table[idx].name, len) == 0) + for (idx = 0; idx < table_size; ++idx) { + if (STRNICMP(stringp, table[idx].name, len) == 0) { break; + } + } if (idx == table_size) { ret = (char_u *)N_("E551: Illegal component"); @@ -347,8 +349,9 @@ static char_u *parse_list_options(char_u *option_str, option_table_T *table, table[idx].strlen = (int)(commap - p); stringp = commap; - if (*stringp == ',') + if (*stringp == ',') { ++stringp; + } } if (ret != NULL) { @@ -401,16 +404,18 @@ static void prt_get_attr(int hl_id, prt_text_attr_T *pattr, int modec) colorindex = atoi(color); } - if (colorindex >= 0 && colorindex < t_colors) + if (colorindex >= 0 && colorindex < t_colors) { fg_color = prt_get_term_color(colorindex); - else + } else { fg_color = PRCOLOR_BLACK; + } } - if (fg_color == PRCOLOR_WHITE) + if (fg_color == PRCOLOR_WHITE) { fg_color = PRCOLOR_BLACK; - else if (*p_bg == 'd') + } else if (*p_bg == 'd') { fg_color = darken_rgb(fg_color); + } pattr->fg_color = fg_color; pattr->bg_color = PRCOLOR_WHITE; @@ -432,8 +437,7 @@ static void prt_set_bg(uint32_t bg) } } -static void prt_set_font(const TriState bold, const TriState italic, - const TriState underline) +static void prt_set_font(const TriState bold, const TriState italic, const TriState underline) { if (curr_bold != bold || curr_italic != italic @@ -446,8 +450,8 @@ static void prt_set_font(const TriState bold, const TriState italic, } // Print the line number in the left margin. -static void prt_line_number(prt_settings_T *const psettings, - const int page_line, const linenr_T lnum) +static void prt_line_number(prt_settings_T *const psettings, const int page_line, + const linenr_T lnum) { prt_set_fg(psettings->number.fg_color); prt_set_bg(psettings->number.bg_color); @@ -504,18 +508,19 @@ int prt_get_unit(int idx) int i; static char *(units[4]) = PRT_UNIT_NAMES; - if (printer_opts[idx].present) - for (i = 0; i < 4; ++i) + if (printer_opts[idx].present) { + for (i = 0; i < 4; ++i) { if (STRNICMP(printer_opts[idx].string, units[i], 2) == 0) { u = i; break; } + } + } return u; } // Print the page header. -static void prt_header(prt_settings_T *const psettings, const int pagenum, - const linenr_T lnum) +static void prt_header(prt_settings_T *const psettings, const int pagenum, const linenr_T lnum) { int width = psettings->chars_per_line; @@ -546,10 +551,10 @@ static void prt_header(prt_settings_T *const psettings, const int pagenum, curwin->w_botline = lnum + 63; printer_page_num = pagenum; - use_sandbox = was_set_insecurely(curwin, (char_u *)"printheader", 0); + use_sandbox = was_set_insecurely(curwin, "printheader", 0); build_stl_str_hl(curwin, tbuf, (size_t)width + IOSIZE, - p_header, use_sandbox, - ' ', width, NULL, NULL); + p_header, use_sandbox, + ' ', width, NULL, NULL); // Reset line numbers curwin->w_cursor.lnum = tmp_lnum; @@ -616,17 +621,19 @@ void ex_hardcopy(exarg_T *eap) settings.has_color = TRUE; if (*eap->arg == '>') { - char_u *errormsg = NULL; + char_u *errormsg = NULL; // Expand things like "%.ps". if (expand_filename(eap, eap->cmdlinep, &errormsg) == FAIL) { - if (errormsg != NULL) + if (errormsg != NULL) { EMSG(errormsg); + } return; } settings.outfile = skipwhite(eap->arg + 1); - } else if (*eap->arg != NUL) + } else if (*eap->arg != NUL) { settings.arguments = eap->arg; + } /* * Initialise for printing. Ask the user for settings, unless forceit is @@ -636,24 +643,22 @@ void ex_hardcopy(exarg_T *eap) * PS.) */ if (mch_print_init(&settings, - curbuf->b_fname == NULL - ? (char_u *)buf_spname(curbuf) - : curbuf->b_sfname == NULL - ? curbuf->b_fname - : curbuf->b_sfname, - eap->forceit) == FAIL) + curbuf->b_fname == NULL ? buf_spname(curbuf) : curbuf->b_sfname == + NULL ? curbuf->b_fname : curbuf->b_sfname, eap->forceit) == FAIL) { return; + } settings.modec = 'c'; - if (!syntax_present(curwin)) + if (!syntax_present(curwin)) { settings.do_syntax = FALSE; - else if (printer_opts[OPT_PRINT_SYNTAX].present - && TOLOWER_ASC(printer_opts[OPT_PRINT_SYNTAX].string[0]) != 'a') + } else if (printer_opts[OPT_PRINT_SYNTAX].present + && TOLOWER_ASC(printer_opts[OPT_PRINT_SYNTAX].string[0]) != 'a') { settings.do_syntax = (TOLOWER_ASC(printer_opts[OPT_PRINT_SYNTAX].string[0]) == 'y'); - else + } else { settings.do_syntax = settings.has_color; + } // Set up printing attributes for line numbers settings.number.fg_color = PRCOLOR_BLACK; @@ -675,8 +680,9 @@ void ex_hardcopy(exarg_T *eap) /* * Estimate the total lines to be printed */ - for (lnum = eap->line1; lnum <= eap->line2; lnum++) + for (lnum = eap->line1; lnum <= eap->line2; lnum++) { bytes_to_print += STRLEN(skipwhite(ml_get(lnum))); + } if (bytes_to_print == 0) { MSG(_("No text to be printed")); goto print_fail_no_begin; @@ -697,8 +703,9 @@ void ex_hardcopy(exarg_T *eap) jobsplit = (printer_opts[OPT_PRINT_JOBSPLIT].present && TOLOWER_ASC(printer_opts[OPT_PRINT_JOBSPLIT].string[0]) == 'y'); - if (!mch_print_begin(&settings)) + if (!mch_print_begin(&settings)) { goto print_fail_no_begin; + } /* * Loop over collated copies: 1 2 3, 1 2 3, ... @@ -718,8 +725,9 @@ void ex_hardcopy(exarg_T *eap) if (jobsplit && collated_copies > 0) { // Splitting jobs: Stop a previous job and start a new one. mch_print_end(&settings); - if (!mch_print_begin(&settings)) + if (!mch_print_begin(&settings)) { goto print_fail_no_begin; + } } /* @@ -746,34 +754,38 @@ void ex_hardcopy(exarg_T *eap) // Check for interrupt character every page. os_breakcheck(); - if (got_int || settings.user_abort) + if (got_int || settings.user_abort) { goto print_fail; + } assert(prtpos.bytes_printed <= SIZE_MAX / 100); sprintf((char *)IObuff, _("Printing page %d (%zu%%)"), page_count + 1 + side, prtpos.bytes_printed * 100 / bytes_to_print); - if (!mch_print_begin_page(IObuff)) + if (!mch_print_begin_page(IObuff)) { goto print_fail; + } - if (settings.n_collated_copies > 1) + if (settings.n_collated_copies > 1) { sprintf((char *)IObuff + STRLEN(IObuff), - _(" Copy %d of %d"), - collated_copies + 1, - settings.n_collated_copies); + _(" Copy %d of %d"), + collated_copies + 1, + settings.n_collated_copies); + } prt_message(IObuff); /* * Output header if required */ - if (prt_header_height() > 0) + if (prt_header_height() > 0) { prt_header(&settings, page_count + 1 + side, - prtpos.file_line); + prtpos.file_line); + } for (page_line = 0; page_line < settings.lines_per_page; ++page_line) { prtpos.column = hardcopy_line(&settings, - page_line, &prtpos); + page_line, &prtpos); if (prtpos.column == 0) { // finished a file line prtpos.bytes_printed += @@ -803,19 +815,21 @@ void ex_hardcopy(exarg_T *eap) if (prtpos.file_line > eap->line2 && settings.duplex && side == 0 && uncollated_copies + 1 < settings.n_uncollated_copies) { - if (!mch_print_blank_page()) + if (!mch_print_blank_page()) { goto print_fail; + } } } - if (settings.duplex && prtpos.file_line <= eap->line2) + if (settings.duplex && prtpos.file_line <= eap->line2) { ++page_count; + } // Remember the position where the next page starts. page_prtpos = prtpos; } vim_snprintf((char *)IObuff, IOSIZE, _("Printed: %s"), - settings.jobname); + settings.jobname); prt_message(IObuff); } @@ -837,7 +851,7 @@ print_fail_no_begin: static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T *ppos) { colnr_T col; - char_u *line; + char_u *line; int need_break = FALSE; int outputlen; int tab_spaces; @@ -848,8 +862,9 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T if (ppos->column == 0 || ppos->ff) { print_pos = 0; tab_spaces = 0; - if (!ppos->ff && prt_use_number()) + if (!ppos->ff && prt_use_number()) { prt_line_number(psettings, page_line, ppos->file_line); + } ppos->ff = FALSE; } else { // left over from wrap halfway through a tab @@ -870,10 +885,11 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T // syntax highlighting stuff. if (psettings->do_syntax) { id = syn_get_id(curwin, ppos->file_line, col, 1, NULL, FALSE); - if (id > 0) + if (id > 0) { id = syn_get_final_id(id); - else + } else { id = 0; + } // Get the line again, a multi-line regexp may invalidate it. line = ml_get(ppos->file_line); @@ -900,8 +916,9 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T need_break = mch_print_text_out((char_u *)" ", 1); print_pos++; tab_spaces--; - if (need_break) + if (need_break) { break; + } } // Keep the TAB if we didn't finish it. if (need_break && tab_spaces > 0) { @@ -930,8 +947,9 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T && (line[col] == NUL || (printer_opts[OPT_PRINT_WRAP].present && TOLOWER_ASC(printer_opts[OPT_PRINT_WRAP].string[0]) - == 'n'))) + == 'n'))) { return 0; + } return col; } @@ -1000,7 +1018,7 @@ static struct prt_ps_font_S prt_ps_courier_font = 600, -100, 50, -250, 805, - {"Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique"} + { "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique" } }; // Generic font metrics for multi-byte fonts @@ -1009,7 +1027,7 @@ static struct prt_ps_font_S prt_ps_mb_font = 1000, -100, 50, -250, 805, - {NULL, NULL, NULL, NULL} + { NULL, NULL, NULL, NULL } }; // Pointer to current font set being used @@ -1027,25 +1045,25 @@ static struct prt_ps_font_S *prt_ps_font; // Japanese encodings and charsets static struct prt_ps_encoding_S j_encodings[] = { - {"iso-2022-jp", NULL, (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990| - CS_NEC)}, - {"euc-jp", "EUC", (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990)}, - {"sjis", "RKSJ", (CS_JIS_C_1978|CS_JIS_X_1983|CS_MSWINDOWS| - CS_KANJITALK6|CS_KANJITALK7)}, - {"cp932", "RKSJ", CS_JIS_X_1983}, - {"ucs-2", "UCS2", CS_JIS_X_1990}, - {"utf-8", "UTF8", CS_JIS_X_1990} + { "iso-2022-jp", NULL, (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990| + CS_NEC) }, + { "euc-jp", "EUC", (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990) }, + { "sjis", "RKSJ", (CS_JIS_C_1978|CS_JIS_X_1983|CS_MSWINDOWS| + CS_KANJITALK6|CS_KANJITALK7) }, + { "cp932", "RKSJ", CS_JIS_X_1983 }, + { "ucs-2", "UCS2", CS_JIS_X_1990 }, + { "utf-8", "UTF8", CS_JIS_X_1990 } }; static struct prt_ps_charset_S j_charsets[] = { - {"JIS_C_1978", "78", CS_JIS_C_1978}, - {"JIS_X_1983", NULL, CS_JIS_X_1983}, - {"JIS_X_1990", "Hojo", CS_JIS_X_1990}, - {"NEC", "Ext", CS_NEC}, - {"MSWINDOWS", "90ms", CS_MSWINDOWS}, - {"CP932", "90ms", CS_JIS_X_1983}, - {"KANJITALK6", "83pv", CS_KANJITALK6}, - {"KANJITALK7", "90pv", CS_KANJITALK7} + { "JIS_C_1978", "78", CS_JIS_C_1978 }, + { "JIS_X_1983", NULL, CS_JIS_X_1983 }, + { "JIS_X_1990", "Hojo", CS_JIS_X_1990 }, + { "NEC", "Ext", CS_NEC }, + { "MSWINDOWS", "90ms", CS_MSWINDOWS }, + { "CP932", "90ms", CS_JIS_X_1983 }, + { "KANJITALK6", "83pv", CS_KANJITALK6 }, + { "KANJITALK7", "90pv", CS_KANJITALK7 } }; #define CS_GB_2312_80 (0x01) @@ -1059,23 +1077,23 @@ static struct prt_ps_charset_S j_charsets[] = // Simplified Chinese encodings and charsets static struct prt_ps_encoding_S sc_encodings[] = { - {"iso-2022", NULL, (CS_GB_2312_80|CS_GBT_12345_90)}, - {"gb18030", NULL, CS_GBK2K}, - {"euc-cn", "EUC", (CS_GB_2312_80|CS_GBT_12345_90|CS_SC_MAC| - CS_GBT_90_MAC)}, - {"gbk", "EUC", CS_GBK}, - {"ucs-2", "UCS2", CS_SC_ISO10646}, - {"utf-8", "UTF8", CS_SC_ISO10646} + { "iso-2022", NULL, (CS_GB_2312_80|CS_GBT_12345_90) }, + { "gb18030", NULL, CS_GBK2K }, + { "euc-cn", "EUC", (CS_GB_2312_80|CS_GBT_12345_90|CS_SC_MAC| + CS_GBT_90_MAC) }, + { "gbk", "EUC", CS_GBK }, + { "ucs-2", "UCS2", CS_SC_ISO10646 }, + { "utf-8", "UTF8", CS_SC_ISO10646 } }; static struct prt_ps_charset_S sc_charsets[] = { - {"GB_2312-80", "GB", CS_GB_2312_80}, - {"GBT_12345-90","GBT", CS_GBT_12345_90}, - {"MAC", "GBpc", CS_SC_MAC}, - {"GBT-90_MAC", "GBTpc", CS_GBT_90_MAC}, - {"GBK", "GBK", CS_GBK}, - {"GB18030", "GBK2K", CS_GBK2K}, - {"ISO10646", "UniGB", CS_SC_ISO10646} + { "GB_2312-80", "GB", CS_GB_2312_80 }, + { "GBT_12345-90", "GBT", CS_GBT_12345_90 }, + { "MAC", "GBpc", CS_SC_MAC }, + { "GBT-90_MAC", "GBTpc", CS_GBT_90_MAC }, + { "GBK", "GBK", CS_GBK }, + { "GB18030", "GBK2K", CS_GBK2K }, + { "ISO10646", "UniGB", CS_SC_ISO10646 } }; #define CS_CNS_PLANE_1 (0x01) @@ -1095,33 +1113,33 @@ static struct prt_ps_charset_S sc_charsets[] = // Traditional Chinese encodings and charsets static struct prt_ps_encoding_S tc_encodings[] = { - {"iso-2022", NULL, (CS_CNS_PLANE_1|CS_CNS_PLANE_2)}, - {"euc-tw", "EUC", CS_CNS_PLANE_1_2}, - {"big5", "B5", (CS_B5|CS_ETEN|CS_HK_GCCS|CS_HK_SCS| - CS_HK_SCS_ETEN|CS_MTHKL|CS_MTHKS|CS_DLHKL| - CS_DLHKS)}, - {"cp950", "B5", CS_B5}, - {"ucs-2", "UCS2", CS_TC_ISO10646}, - {"utf-8", "UTF8", CS_TC_ISO10646}, - {"utf-16", "UTF16", CS_TC_ISO10646}, - {"utf-32", "UTF32", CS_TC_ISO10646} + { "iso-2022", NULL, (CS_CNS_PLANE_1|CS_CNS_PLANE_2) }, + { "euc-tw", "EUC", CS_CNS_PLANE_1_2 }, + { "big5", "B5", (CS_B5|CS_ETEN|CS_HK_GCCS|CS_HK_SCS| + CS_HK_SCS_ETEN|CS_MTHKL|CS_MTHKS|CS_DLHKL| + CS_DLHKS) }, + { "cp950", "B5", CS_B5 }, + { "ucs-2", "UCS2", CS_TC_ISO10646 }, + { "utf-8", "UTF8", CS_TC_ISO10646 }, + { "utf-16", "UTF16", CS_TC_ISO10646 }, + { "utf-32", "UTF32", CS_TC_ISO10646 } }; static struct prt_ps_charset_S tc_charsets[] = { - {"CNS_1992_1", "CNS1", CS_CNS_PLANE_1}, - {"CNS_1992_2", "CNS2", CS_CNS_PLANE_2}, - {"CNS_1993", "CNS", CS_CNS_PLANE_1_2}, - {"BIG5", NULL, CS_B5}, - {"CP950", NULL, CS_B5}, - {"ETEN", "ETen", CS_ETEN}, - {"HK_GCCS", "HKgccs", CS_HK_GCCS}, - {"SCS", "HKscs", CS_HK_SCS}, - {"SCS_ETEN", "ETHK", CS_HK_SCS_ETEN}, - {"MTHKL", "HKm471", CS_MTHKL}, - {"MTHKS", "HKm314", CS_MTHKS}, - {"DLHKL", "HKdla", CS_DLHKL}, - {"DLHKS", "HKdlb", CS_DLHKS}, - {"ISO10646", "UniCNS", CS_TC_ISO10646} + { "CNS_1992_1", "CNS1", CS_CNS_PLANE_1 }, + { "CNS_1992_2", "CNS2", CS_CNS_PLANE_2 }, + { "CNS_1993", "CNS", CS_CNS_PLANE_1_2 }, + { "BIG5", NULL, CS_B5 }, + { "CP950", NULL, CS_B5 }, + { "ETEN", "ETen", CS_ETEN }, + { "HK_GCCS", "HKgccs", CS_HK_GCCS }, + { "SCS", "HKscs", CS_HK_SCS }, + { "SCS_ETEN", "ETHK", CS_HK_SCS_ETEN }, + { "MTHKL", "HKm471", CS_MTHKL }, + { "MTHKS", "HKm314", CS_MTHKS }, + { "DLHKL", "HKdla", CS_DLHKL }, + { "DLHKS", "HKdlb", CS_DLHKS }, + { "ISO10646", "UniCNS", CS_TC_ISO10646 } }; #define CS_KR_X_1992 (0x01) @@ -1132,24 +1150,24 @@ static struct prt_ps_charset_S tc_charsets[] = // Korean encodings and charsets static struct prt_ps_encoding_S k_encodings[] = { - {"iso-2022-kr", NULL, CS_KR_X_1992}, - {"euc-kr", "EUC", (CS_KR_X_1992|CS_KR_MAC)}, - {"johab", "Johab", CS_KR_X_1992}, - {"cp1361", "Johab", CS_KR_X_1992}, - {"uhc", "UHC", CS_KR_X_1992_MS}, - {"cp949", "UHC", CS_KR_X_1992_MS}, - {"ucs-2", "UCS2", CS_KR_ISO10646}, - {"utf-8", "UTF8", CS_KR_ISO10646} + { "iso-2022-kr", NULL, CS_KR_X_1992 }, + { "euc-kr", "EUC", (CS_KR_X_1992|CS_KR_MAC) }, + { "johab", "Johab", CS_KR_X_1992 }, + { "cp1361", "Johab", CS_KR_X_1992 }, + { "uhc", "UHC", CS_KR_X_1992_MS }, + { "cp949", "UHC", CS_KR_X_1992_MS }, + { "ucs-2", "UCS2", CS_KR_ISO10646 }, + { "utf-8", "UTF8", CS_KR_ISO10646 } }; static struct prt_ps_charset_S k_charsets[] = { - {"KS_X_1992", "KSC", CS_KR_X_1992}, - {"CP1361", "KSC", CS_KR_X_1992}, - {"MAC", "KSCpc", CS_KR_MAC}, - {"MSWINDOWS", "KSCms", CS_KR_X_1992_MS}, - {"CP949", "KSCms", CS_KR_X_1992_MS}, - {"WANSUNG", "KSCms", CS_KR_X_1992_MS}, - {"ISO10646", "UniKS", CS_KR_ISO10646} + { "KS_X_1992", "KSC", CS_KR_X_1992 }, + { "CP1361", "KSC", CS_KR_X_1992 }, + { "MAC", "KSCpc", CS_KR_MAC }, + { "MSWINDOWS", "KSCms", CS_KR_X_1992_MS }, + { "CP949", "KSCms", CS_KR_X_1992_MS }, + { "WANSUNG", "KSCms", CS_KR_X_1992_MS }, + { "ISO10646", "UniKS", CS_KR_ISO10646 } }; static struct prt_ps_mbfont_S prt_ps_mbfonts[] = @@ -1196,7 +1214,7 @@ static struct prt_ps_mbfont_S prt_ps_mbfonts[] = * * VIM Prolog CIDProlog * 6.2 1.3 - * 7.0 1.4 1.0 + * 7.0 1.4 1.0 */ #define PRT_PROLOG_VERSION ((char_u *)"1.4") #define PRT_CID_PROLOG_VERSION ((char_u *)"1.0") @@ -1224,11 +1242,11 @@ static struct prt_ps_mbfont_S prt_ps_mbfonts[] = #define SIZEOF_CSTR(s) (sizeof(s) - 1) static struct prt_dsc_comment_S prt_dsc_table[] = { - {PRT_DSC_TITLE, SIZEOF_CSTR(PRT_DSC_TITLE), PRT_DSC_TITLE_TYPE}, - {PRT_DSC_VERSION, SIZEOF_CSTR(PRT_DSC_VERSION), - PRT_DSC_VERSION_TYPE}, - {PRT_DSC_ENDCOMMENTS, SIZEOF_CSTR(PRT_DSC_ENDCOMMENTS), - PRT_DSC_ENDCOMMENTS_TYPE} + { PRT_DSC_TITLE, SIZEOF_CSTR(PRT_DSC_TITLE), PRT_DSC_TITLE_TYPE }, + { PRT_DSC_VERSION, SIZEOF_CSTR(PRT_DSC_VERSION), + PRT_DSC_VERSION_TYPE }, + { PRT_DSC_ENDCOMMENTS, SIZEOF_CSTR(PRT_DSC_ENDCOMMENTS), + PRT_DSC_ENDCOMMENTS_TYPE } }; @@ -1359,14 +1377,15 @@ static void prt_write_boolean(int b) static void prt_def_font(char *new_name, char *encoding, int height, char *font) { vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), - "/_%s /VIM-%s /%s ref\n", new_name, encoding, font); + "/_%s /VIM-%s /%s ref\n", new_name, encoding, font); prt_write_file(prt_line_buffer); - if (prt_out_mbyte) + if (prt_out_mbyte) { sprintf((char *)prt_line_buffer, "/%s %d %f /_%s sffs\n", - new_name, height, 500./prt_ps_courier_font.wx, new_name); - else + new_name, height, 500./prt_ps_courier_font.wx, new_name); + } else { vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), - "/%s %d /_%s ffs\n", new_name, height, new_name); + "/%s %d /_%s ffs\n", new_name, height, new_name); + } prt_write_file(prt_line_buffer); } @@ -1376,10 +1395,10 @@ static void prt_def_font(char *new_name, char *encoding, int height, char *font) static void prt_def_cidfont(char *new_name, int height, char *cidfont) { vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), - "/_%s /%s[/%s] vim_composefont\n", new_name, prt_cmap, cidfont); + "/_%s /%s[/%s] vim_composefont\n", new_name, prt_cmap, cidfont); prt_write_file(prt_line_buffer); vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), - "/%s %d /_%s ffs\n", new_name, height, new_name); + "/%s %d /_%s ffs\n", new_name, height, new_name); prt_write_file(prt_line_buffer); } @@ -1389,7 +1408,7 @@ static void prt_def_cidfont(char *new_name, int height, char *cidfont) static void prt_dup_cidfont(char *original_name, char *new_name) { vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), - "/%s %s d\n", new_name, original_name); + "/%s %s d\n", new_name, original_name); prt_write_file(prt_line_buffer); } @@ -1402,10 +1421,12 @@ static void prt_real_bits(double real, int precision, int *pinteger, int *pfract { int integer = (int)real; double fraction = real - integer; - if (real < integer) + if (real < integer) { fraction = -fraction; - for (int i = 0; i < precision; i++) + } + for (int i = 0; i < precision; i++) { fraction *= 10.0; + } *pinteger = integer; *pfraction = (int)(fraction + 0.5); @@ -1447,7 +1468,7 @@ static void prt_write_real(double val, int prec) static void prt_def_var(char *name, double value, int prec) { vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), - "/%s ", name); + "/%s ", name); prt_write_file(prt_line_buffer); prt_write_real(value, prec); sprintf((char *)prt_line_buffer, "d\n"); @@ -1500,16 +1521,18 @@ static void prt_flush_buffer(void) prt_write_string("ul\n"); } // Draw the text - if (prt_out_mbyte) + if (prt_out_mbyte) { prt_write_string("<"); - else + } else { prt_write_string("("); + } assert(prt_ps_buffer.ga_len >= 0); prt_write_file_raw_len(prt_ps_buffer.ga_data, (size_t)prt_ps_buffer.ga_len); - if (prt_out_mbyte) + if (prt_out_mbyte) { prt_write_string(">"); - else + } else { prt_write_string(")"); + } // Add a moveto if need be and use the appropriate show procedure if (prt_do_moveto) { prt_write_real(prt_pos_x_moveto, 2); @@ -1529,15 +1552,16 @@ static void prt_resource_name(char_u *filename, void *cookie) { char_u *resource_filename = cookie; - if (STRLEN(filename) >= MAXPATHL) + if (STRLEN(filename) >= MAXPATHL) { *resource_filename = NUL; - else + } else { STRCPY(resource_filename, filename); + } } static int prt_find_resource(char *name, struct prt_ps_resource_S *resource) { - char_u *buffer; + char_u *buffer; int retval; buffer = xmallocz(MAXPATHL); @@ -1568,15 +1592,17 @@ static int prt_resfile_next_line(void) // Move to start of next line and then find end of line idx = prt_resfile.line_end + 1; while (idx < prt_resfile.len) { - if (prt_resfile.buffer[idx] != PSLF && prt_resfile.buffer[idx] != PSCR) + if (prt_resfile.buffer[idx] != PSLF && prt_resfile.buffer[idx] != PSCR) { break; + } idx++; } prt_resfile.line_start = idx; while (idx < prt_resfile.len) { - if (prt_resfile.buffer[idx] == PSLF || prt_resfile.buffer[idx] == PSCR) + if (prt_resfile.buffer[idx] == PSLF || prt_resfile.buffer[idx] == PSCR) { break; + } idx++; } prt_resfile.line_end = idx; @@ -1592,7 +1618,7 @@ static int prt_resfile_strncmp(int offset, const char *string, int len) return 1; } return STRNCMP(&prt_resfile.buffer[prt_resfile.line_start + offset], - string, len); + string, len); } static int prt_resfile_skip_nonws(int offset) @@ -1601,8 +1627,9 @@ static int prt_resfile_skip_nonws(int offset) idx = prt_resfile.line_start + offset; while (idx < prt_resfile.line_end) { - if (isspace(prt_resfile.buffer[idx])) + if (isspace(prt_resfile.buffer[idx])) { return idx - prt_resfile.line_start; + } idx++; } return -1; @@ -1614,8 +1641,9 @@ static int prt_resfile_skip_ws(int offset) idx = prt_resfile.line_start + offset; while (idx < prt_resfile.line_end) { - if (!isspace(prt_resfile.buffer[idx])) + if (!isspace(prt_resfile.buffer[idx])) { return idx - prt_resfile.line_start; + } idx++; } return -1; @@ -1685,10 +1713,10 @@ static bool prt_open_resource(struct prt_ps_resource_S *resource) // Parse first line to ensure valid resource file prt_resfile.len = (int)fread((char *)prt_resfile.buffer, sizeof(char_u), - PRT_FILE_BUFFER_LEN, fd_resource); + PRT_FILE_BUFFER_LEN, fd_resource); if (ferror(fd_resource)) { EMSG2(_("E457: Can't read PostScript resource file \"%s\""), - resource->filename); + resource->filename); fclose(fd_resource); return false; } @@ -1702,7 +1730,7 @@ static bool prt_open_resource(struct prt_ps_resource_S *resource) int offset = 0; if (prt_resfile_strncmp(offset, PRT_RESOURCE_HEADER, - (int)STRLEN(PRT_RESOURCE_HEADER)) != 0) { + (int)STRLEN(PRT_RESOURCE_HEADER)) != 0) { EMSG2(_("E618: file \"%s\" is not a PostScript resource file"), resource->filename); return false; @@ -1719,7 +1747,7 @@ static bool prt_open_resource(struct prt_ps_resource_S *resource) return false; } if (prt_resfile_strncmp(offset, PRT_RESOURCE_RESOURCE, - (int)STRLEN(PRT_RESOURCE_RESOURCE)) != 0) { + (int)STRLEN(PRT_RESOURCE_RESOURCE)) != 0) { EMSG2(_("E619: file \"%s\" is not a supported PostScript resource file"), resource->filename); return false; @@ -1786,8 +1814,7 @@ static bool prt_open_resource(struct prt_ps_resource_S *resource) return true; } -static bool prt_check_resource(const struct prt_ps_resource_S *resource, - const char_u *version) +static bool prt_check_resource(const struct prt_ps_resource_S *resource, const char_u *version) FUNC_ATTR_NONNULL_ALL { // Version number m.n should match, the revision number does not matter @@ -1809,14 +1836,14 @@ static void prt_dsc_start(void) static void prt_dsc_noarg(char *comment) { vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), - "%%%%%s\n", comment); + "%%%%%s\n", comment); prt_write_file(prt_line_buffer); } static void prt_dsc_textline(char *comment, char *text) { vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), - "%%%%%s: %s\n", comment, text); + "%%%%%s: %s\n", comment, text); prt_write_file(prt_line_buffer); } @@ -1824,7 +1851,7 @@ static void prt_dsc_text(char *comment, char *text) { // TODO(vim): - should scan 'text' for any chars needing escaping! vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), - "%%%%%s: (%s)\n", comment, text); + "%%%%%s: (%s)\n", comment, text); prt_write_file(prt_line_buffer); } @@ -1835,7 +1862,7 @@ static void prt_dsc_ints(char *comment, int count, int *ints) int i; vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), - "%%%%%s:", comment); + "%%%%%s:", comment); prt_write_file(prt_line_buffer); for (i = 0; i < count; i++) { @@ -1846,23 +1873,21 @@ static void prt_dsc_ints(char *comment, int count, int *ints) prt_write_string("\n"); } -static void prt_dsc_resources( - const char *comment, // if NULL add to previous - const char *type, - const char *string -) +/// @param comment if NULL add to previous +static void prt_dsc_resources(const char *comment, const char *type, const char *string) FUNC_ATTR_NONNULL_ARG(2, 3) { - if (comment != NULL) + if (comment != NULL) { vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), - "%%%%%s: %s", comment, type); - else + "%%%%%s: %s", comment, type); + } else { vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), - "%%%%+ %s", type); + "%%%%+ %s", type); + } prt_write_file(prt_line_buffer); vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), - " %s\n", string); + " %s\n", string); prt_write_file(prt_line_buffer); } @@ -1871,10 +1896,12 @@ static void prt_dsc_font_resource(char *resource, struct prt_ps_font_S *ps_font) int i; prt_dsc_resources(resource, "font", - ps_font->ps_fontname[PRT_PS_FONT_ROMAN]); - for (i = PRT_PS_FONT_BOLD; i <= PRT_PS_FONT_BOLDOBLIQUE; i++) - if (ps_font->ps_fontname[i] != NULL) + ps_font->ps_fontname[PRT_PS_FONT_ROMAN]); + for (i = PRT_PS_FONT_BOLD; i <= PRT_PS_FONT_BOLDOBLIQUE; i++) { + if (ps_font->ps_fontname[i] != NULL) { prt_dsc_resources(NULL, "font", ps_font->ps_fontname[i]); + } + } } static void prt_dsc_requirements(int duplex, int tumble, int collate, int color, int num_copies) @@ -1882,21 +1909,25 @@ static void prt_dsc_requirements(int duplex, int tumble, int collate, int color, /* Only output the comment if we need to. * Note: tumble is ignored if we are not duplexing */ - if (!(duplex || collate || color || (num_copies > 1))) + if (!(duplex || collate || color || (num_copies > 1))) { return; + } sprintf((char *)prt_line_buffer, "%%%%Requirements:"); prt_write_file(prt_line_buffer); if (duplex) { prt_write_string(" duplex"); - if (tumble) + if (tumble) { prt_write_string("(tumble)"); + } } - if (collate) + if (collate) { prt_write_string(" collate"); - if (color) + } + if (color) { prt_write_string(" color"); + } if (num_copies > 1) { prt_write_string(" numcopies("); // Note: no space wanted so don't use prt_write_int() @@ -1908,23 +1939,26 @@ static void prt_dsc_requirements(int duplex, int tumble, int collate, int color, prt_write_string("\n"); } -static void prt_dsc_docmedia(char *paper_name, double width, double height, double weight, char *colour, char *type) +static void prt_dsc_docmedia(char *paper_name, double width, double height, double weight, + char *colour, char *type) { vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), - "%%%%DocumentMedia: %s ", paper_name); + "%%%%DocumentMedia: %s ", paper_name); prt_write_file(prt_line_buffer); prt_write_real(width, 2); prt_write_real(height, 2); prt_write_real(weight, 2); - if (colour == NULL) + if (colour == NULL) { prt_write_string("()"); - else + } else { prt_write_string(colour); + } prt_write_string(" "); - if (type == NULL) + if (type == NULL) { prt_write_string("()"); - else + } else { prt_write_string(type); + } prt_write_string("\n"); } @@ -1938,8 +1972,9 @@ void mch_print_cleanup(void) * one style). */ for (i = PRT_PS_FONT_ROMAN; i <= PRT_PS_FONT_BOLDOBLIQUE; i++) { - if (prt_ps_mb_font.ps_fontname[i] != NULL) + if (prt_ps_mb_font.ps_fontname[i] != NULL) { xfree(prt_ps_mb_font.ps_fontname[i]); + } prt_ps_mb_font.ps_fontname[i] = NULL; } } @@ -1993,7 +2028,8 @@ static double to_device_units(int idx, double physsize, int def_number) /* * Calculate margins for given width and height from printoptions settings. */ -static void prt_page_margins(double width, double height, double *left, double *right, double *top, double *bottom) +static void prt_page_margins(double width, double height, double *left, double *right, double *top, + double *bottom) { *left = to_device_units(OPT_PRINT_LEFT, width, 10); *right = width - to_device_units(OPT_PRINT_RIGHT, width, 5); @@ -2015,11 +2051,13 @@ static int prt_get_cpl(void) /* If we are outputting multi-byte characters then line numbers will be * printed with half width characters */ - if (prt_out_mbyte) + if (prt_out_mbyte) { prt_number_width /= 2; + } prt_left_margin += prt_number_width; - } else + } else { prt_number_width = 0.0; + } return (int)((prt_right_margin - prt_left_margin) / prt_char_width); } @@ -2044,11 +2082,11 @@ static int prt_get_lpp(void) * case where the font height can exceed the line height. */ prt_bgcol_offset = PRT_PS_FONT_TO_USER(prt_line_height, - prt_ps_font->bbox_min_y); + prt_ps_font->bbox_min_y); if ((prt_ps_font->bbox_max_y - prt_ps_font->bbox_min_y) < 1000.0) { prt_bgcol_offset -= PRT_PS_FONT_TO_USER(prt_line_height, - (1000.0 - (prt_ps_font->bbox_max_y - - prt_ps_font->bbox_min_y)) / 2); + (1000.0 - (prt_ps_font->bbox_max_y - + prt_ps_font->bbox_min_y)) / 2); } // Get height for topmost line based on background rect offset. @@ -2063,11 +2101,12 @@ static int prt_get_lpp(void) return lpp - prt_header_height(); } -static int prt_match_encoding(char *p_encoding, struct prt_ps_mbfont_S *p_cmap, struct prt_ps_encoding_S **pp_mbenc) +static int prt_match_encoding(char *p_encoding, struct prt_ps_mbfont_S *p_cmap, + struct prt_ps_encoding_S **pp_mbenc) { int mbenc; int enc_len; - struct prt_ps_encoding_S *p_mbenc; + struct prt_ps_encoding_S *p_mbenc; *pp_mbenc = NULL; // Look for recognised encoding @@ -2083,7 +2122,8 @@ static int prt_match_encoding(char *p_encoding, struct prt_ps_mbfont_S *p_cmap, return FALSE; } -static int prt_match_charset(char *p_charset, struct prt_ps_mbfont_S *p_cmap, struct prt_ps_charset_S **pp_mbchar) +static int prt_match_charset(char *p_charset, struct prt_ps_mbfont_S *p_cmap, + struct prt_ps_charset_S **pp_mbchar) { int mbchar; int char_len; @@ -2108,24 +2148,25 @@ static int prt_match_charset(char *p_charset, struct prt_ps_mbfont_S *p_cmap, st int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) { int i; - char *paper_name; + char *paper_name; int paper_strlen; int fontsize; - char_u *p; + char_u *p; int props; int cmap = 0; - char_u *p_encoding; + char_u *p_encoding; struct prt_ps_encoding_S *p_mbenc; struct prt_ps_encoding_S *p_mbenc_first; - struct prt_ps_charset_S *p_mbchar = NULL; + struct prt_ps_charset_S *p_mbchar = NULL; /* * Set up font and encoding. */ p_encoding = enc_skip(p_penc); - if (*p_encoding == NUL) + if (*p_encoding == NUL) { p_encoding = enc_skip(p_enc); + } /* Look for a multi-byte font that matches the encoding and character set. * Only look if multi-byte character set is defined, or using multi-byte @@ -2136,16 +2177,18 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) if (!(props & ENC_8BIT) && ((*p_pmcs != NUL) || !(props & ENC_UNICODE))) { p_mbenc_first = NULL; int effective_cmap = 0; - for (cmap = 0; cmap < (int)ARRAY_SIZE(prt_ps_mbfonts); cmap++) + for (cmap = 0; cmap < (int)ARRAY_SIZE(prt_ps_mbfonts); cmap++) { if (prt_match_encoding((char *)p_encoding, &prt_ps_mbfonts[cmap], &p_mbenc)) { if (p_mbenc_first == NULL) { p_mbenc_first = p_mbenc; effective_cmap = cmap; } - if (prt_match_charset((char *)p_pmcs, &prt_ps_mbfonts[cmap], &p_mbchar)) + if (prt_match_charset((char *)p_pmcs, &prt_ps_mbfonts[cmap], &p_mbchar)) { break; + } } + } // Use first encoding matched if no charset matched if (p_mbenc_first != NULL && p_mbchar == NULL) { @@ -2205,7 +2248,6 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) prt_build_cid_fontname(PRT_PS_FONT_BOLD, mbfont_opts[OPT_MBFONT_BOLD].string, mbfont_opts[OPT_MBFONT_BOLD].strlen); - } if (mbfont_opts[OPT_MBFONT_OBLIQUE].present) { prt_build_cid_fontname(PRT_PS_FONT_OBLIQUE, @@ -2221,8 +2263,8 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) // Check if need to use Courier for ASCII code range, and if so pick up // the encoding to use prt_use_courier = ( - mbfont_opts[OPT_MBFONT_USECOURIER].present - && (TOLOWER_ASC(mbfont_opts[OPT_MBFONT_USECOURIER].string[0]) == 'y')); + mbfont_opts[OPT_MBFONT_USECOURIER].present + && (TOLOWER_ASC(mbfont_opts[OPT_MBFONT_USECOURIER].string[0]) == 'y')); if (prt_use_courier) { // Use national ASCII variant unless ASCII wanted if (mbfont_opts[OPT_MBFONT_ASCII].present @@ -2252,13 +2294,16 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) paper_name = "A4"; paper_strlen = 2; } - for (i = 0; i < (int)PRT_MEDIASIZE_LEN; ++i) + for (i = 0; i < (int)PRT_MEDIASIZE_LEN; ++i) { if (STRLEN(prt_mediasize[i].name) == (unsigned)paper_strlen && STRNICMP(prt_mediasize[i].name, paper_name, - paper_strlen) == 0) + paper_strlen) == 0) { break; - if (i == PRT_MEDIASIZE_LEN) + } + } + if (i == PRT_MEDIASIZE_LEN) { i = 0; + } prt_media = i; /* @@ -2280,7 +2325,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) // needs to be done before the cpl and lpp are calculated. double left, right, top, bottom; prt_page_margins(prt_page_width, prt_page_height, &left, &right, &top, - &bottom); + &bottom); prt_left_margin = left; prt_right_margin = right; prt_top_margin = top; @@ -2290,9 +2335,11 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) * Set up the font size. */ fontsize = PRT_PS_DEFAULT_FONTSIZE; - for (p = p_pfn; (p = vim_strchr(p, ':')) != NULL; ++p) - if (p[1] == 'h' && ascii_isdigit(p[2])) + for (p = p_pfn; (p = vim_strchr(p, ':')) != NULL; ++p) { + if (p[1] == 'h' && ascii_isdigit(p[2])) { fontsize = atoi((char *)p + 2); + } + } prt_font_metrics(fontsize); /* @@ -2340,8 +2387,9 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) prt_duplex = FALSE; psettings->duplex = 0; } else if (STRNICMP(printer_opts[OPT_PRINT_DUPLEX].string, "short", 5) - == 0) + == 0) { prt_tumble = TRUE; + } } // For now user abort not supported @@ -2369,8 +2417,9 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) } prt_bufsiz = psettings->chars_per_line; - if (prt_out_mbyte) + if (prt_out_mbyte) { prt_bufsiz *= 2; + } ga_init(&prt_ps_buffer, (int)sizeof(char), prt_bufsiz); prt_page_num = 0; @@ -2389,7 +2438,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) static int prt_add_resource(struct prt_ps_resource_S *resource) { - FILE* fd_resource; + FILE *fd_resource; char_u resource_buffer[512]; size_t bytes_read; @@ -2403,7 +2452,7 @@ static int prt_add_resource(struct prt_ps_resource_S *resource) case PRT_RESOURCE_TYPE_ENCODING: case PRT_RESOURCE_TYPE_CMAP: prt_dsc_resources("BeginResource", prt_resource_types[resource->type], - (char *)resource->title); + (char *)resource->title); break; default: return FALSE; @@ -2413,15 +2462,16 @@ static int prt_add_resource(struct prt_ps_resource_S *resource) for (;; ) { bytes_read = fread((char *)resource_buffer, sizeof(char_u), - sizeof(resource_buffer), fd_resource); + sizeof(resource_buffer), fd_resource); if (ferror(fd_resource)) { EMSG2(_("E457: Can't read PostScript resource file \"%s\""), - resource->filename); + resource->filename); fclose(fd_resource); return FALSE; } - if (bytes_read == 0) + if (bytes_read == 0) { break; + } prt_write_file_raw_len(resource_buffer, bytes_read); if (prt_file_error) { fclose(fd_resource); @@ -2447,8 +2497,8 @@ int mch_print_begin(prt_settings_T *psettings) struct prt_ps_resource_S res_prolog; struct prt_ps_resource_S res_encoding; char buffer[256]; - char_u *p_encoding; - char_u *p; + char_u *p_encoding; + char_u *p; struct prt_ps_resource_S res_cidfont; struct prt_ps_resource_S res_cmap; int retval = FALSE; @@ -2468,8 +2518,9 @@ int mch_print_begin(prt_settings_T *psettings) char *p_time = os_ctime(ctime_buf, sizeof(ctime_buf)); // Note: os_ctime() adds a \n so we have to remove it :-( p = vim_strchr((char_u *)p_time, '\n'); - if (p != NULL) + if (p != NULL) { *p = NUL; + } prt_dsc_textline("CreationDate", p_time); prt_dsc_textline("DocumentData", "Clean8Bit"); prt_dsc_textline("Orientation", "Portrait"); @@ -2479,8 +2530,8 @@ int mch_print_begin(prt_settings_T *psettings) * user coordinate system! We have to recalculate right and bottom * coordinates based on the font metrics for the bbox to be accurate. */ prt_page_margins(prt_mediasize[prt_media].width, - prt_mediasize[prt_media].height, - &left, &right, &top, &bottom); + prt_mediasize[prt_media].height, + &left, &right, &top, &bottom); bbox[0] = (int)left; if (prt_portrait) { /* In portrait printing the fixed point is the top left corner so we @@ -2515,9 +2566,10 @@ int mch_print_begin(prt_settings_T *psettings) } if (prt_out_mbyte) { prt_dsc_font_resource((prt_use_courier ? NULL - : "DocumentNeededResources"), &prt_ps_mb_font); - if (!prt_custom_cmap) + : "DocumentNeededResources"), &prt_ps_mb_font); + if (!prt_custom_cmap) { prt_dsc_resources(NULL, "cmap", prt_cmap); + } } // Search for external resources VIM supplies @@ -2525,20 +2577,24 @@ int mch_print_begin(prt_settings_T *psettings) EMSG(_("E456: Can't find PostScript resource file \"prolog.ps\"")); return FALSE; } - if (!prt_open_resource(&res_prolog)) + if (!prt_open_resource(&res_prolog)) { return FALSE; - if (!prt_check_resource(&res_prolog, PRT_PROLOG_VERSION)) + } + if (!prt_check_resource(&res_prolog, PRT_PROLOG_VERSION)) { return FALSE; + } if (prt_out_mbyte) { // Look for required version of multi-byte printing procset if (!prt_find_resource("cidfont", &res_cidfont)) { EMSG(_("E456: Can't find PostScript resource file \"cidfont.ps\"")); return FALSE; } - if (!prt_open_resource(&res_cidfont)) + if (!prt_open_resource(&res_cidfont)) { return FALSE; - if (!prt_check_resource(&res_cidfont, PRT_CID_PROLOG_VERSION)) + } + if (!prt_check_resource(&res_cidfont, PRT_CID_PROLOG_VERSION)) { return FALSE; + } } /* Find an encoding to use for printing. @@ -2562,28 +2618,31 @@ int mch_print_begin(prt_settings_T *psettings) p_encoding = (char_u *)"latin1"; if (!prt_find_resource((char *)p_encoding, &res_encoding)) { EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""), - p_encoding); + p_encoding); return FALSE; } } } - if (!prt_open_resource(&res_encoding)) + if (!prt_open_resource(&res_encoding)) { return FALSE; + } /* For the moment there are no checks on encoding resource files to * perform */ } else { p_encoding = enc_skip(p_penc); - if (*p_encoding == NUL) + if (*p_encoding == NUL) { p_encoding = enc_skip(p_enc); + } if (prt_use_courier) { // Include ASCII range encoding vector if (!prt_find_resource(prt_ascii_encoding, &res_encoding)) { EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""), - prt_ascii_encoding); + prt_ascii_encoding); return FALSE; } - if (!prt_open_resource(&res_encoding)) + if (!prt_open_resource(&res_encoding)) { return FALSE; + } /* For the moment there are no checks on encoding resource files to * perform */ } @@ -2604,11 +2663,12 @@ int mch_print_begin(prt_settings_T *psettings) // Find user supplied CMap if (!prt_find_resource(prt_cmap, &res_cmap)) { EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""), - prt_cmap); + prt_cmap); return FALSE; } - if (!prt_open_resource(&res_cmap)) + if (!prt_open_resource(&res_cmap)) { return FALSE; + } } // List resources supplied @@ -2636,8 +2696,8 @@ int mch_print_begin(prt_settings_T *psettings) prt_dsc_resources(NULL, "encoding", buffer); } prt_dsc_requirements(prt_duplex, prt_tumble, prt_collate, - psettings->do_syntax - , prt_num_copies); + psettings->do_syntax, + prt_num_copies); prt_dsc_noarg("EndComments"); /* @@ -2651,9 +2711,10 @@ int mch_print_begin(prt_settings_T *psettings) } if (prt_out_mbyte) { prt_dsc_font_resource((prt_use_courier ? NULL : "PageResources"), - &prt_ps_mb_font); - if (!prt_custom_cmap) + &prt_ps_mb_font); + if (!prt_custom_cmap) { prt_dsc_resources(NULL, "cmap", prt_cmap); + } } // Paper will be used for all pages @@ -2680,11 +2741,13 @@ int mch_print_begin(prt_settings_T *psettings) } } - if (!prt_out_mbyte || prt_use_courier) + if (!prt_out_mbyte || prt_use_courier) { /* There will be only one Roman font encoding to be included in the PS * file. */ - if (!prt_add_resource(&res_encoding)) + if (!prt_add_resource(&res_encoding)) { return FALSE; + } + } prt_dsc_noarg("EndProlog"); @@ -2710,44 +2773,47 @@ int mch_print_begin(prt_settings_T *psettings) if (!prt_out_mbyte || prt_use_courier) { /* When using Courier for ASCII range when printing multi-byte, need to * pick up ASCII encoding to use with it. */ - if (prt_use_courier) + if (prt_use_courier) { p_encoding = (char_u *)prt_ascii_encoding; + } prt_dsc_resources("IncludeResource", "font", - prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]); + prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]); prt_def_font("F0", (char *)p_encoding, (int)prt_line_height, - prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]); + prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]); prt_dsc_resources("IncludeResource", "font", - prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]); + prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]); prt_def_font("F1", (char *)p_encoding, (int)prt_line_height, - prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]); + prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]); prt_dsc_resources("IncludeResource", "font", - prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]); + prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]); prt_def_font("F2", (char *)p_encoding, (int)prt_line_height, - prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]); + prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]); prt_dsc_resources("IncludeResource", "font", - prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]); + prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]); prt_def_font("F3", (char *)p_encoding, (int)prt_line_height, - prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]); + prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]); } if (prt_out_mbyte) { - /* Define the CID fonts to be used in the job. Typically CJKV fonts do + /* Define the CID fonts to be used in the job. Typically CJKV fonts do * not have an italic form being a western style, so where no font is * defined for these faces VIM falls back to an existing face. * Note: if using Courier for the ASCII range then the printout will * have bold/italic/bolditalic regardless of the setting of printmbfont. */ prt_dsc_resources("IncludeResource", "font", - prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]); - if (!prt_custom_cmap) + prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]); + if (!prt_custom_cmap) { prt_dsc_resources("IncludeResource", "cmap", prt_cmap); + } prt_def_cidfont("CF0", (int)prt_line_height, - prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]); + prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]); if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD] != NULL) { prt_dsc_resources("IncludeResource", "font", - prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]); - if (!prt_custom_cmap) + prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]); + if (!prt_custom_cmap) { prt_dsc_resources("IncludeResource", "cmap", prt_cmap); + } prt_def_cidfont("CF1", (int)prt_line_height, prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]); } else { @@ -2756,9 +2822,10 @@ int mch_print_begin(prt_settings_T *psettings) } if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE] != NULL) { prt_dsc_resources("IncludeResource", "font", - prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]); - if (!prt_custom_cmap) + prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]); + if (!prt_custom_cmap) { prt_dsc_resources("IncludeResource", "cmap", prt_cmap); + } prt_def_cidfont("CF2", (int)prt_line_height, prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]); } else { @@ -2767,9 +2834,10 @@ int mch_print_begin(prt_settings_T *psettings) } if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE] != NULL) { prt_dsc_resources("IncludeResource", "font", - prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]); - if (!prt_custom_cmap) + prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]); + if (!prt_custom_cmap) { prt_dsc_resources("IncludeResource", "cmap", prt_cmap); + } prt_def_cidfont("CF3", (int)prt_line_height, prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]); } else { @@ -2780,9 +2848,9 @@ int mch_print_begin(prt_settings_T *psettings) // Misc constant vars used for underlining and background rects prt_def_var("UO", PRT_PS_FONT_TO_USER(prt_line_height, - prt_ps_font->uline_offset), 2); + prt_ps_font->uline_offset), 2); prt_def_var("UW", PRT_PS_FONT_TO_USER(prt_line_height, - prt_ps_font->uline_width), 2); + prt_ps_font->uline_width), 2); prt_def_var("BO", prt_bgcol_offset, 2); prt_dsc_noarg("EndSetup"); @@ -2818,7 +2886,7 @@ void mch_print_end(prt_settings_T *psettings) prt_message((char_u *)_("Sending to printer...")); // Not printing to a file: use 'printexpr' to print the file. - if (eval_printexpr((char *) prt_ps_file_name, (char *) psettings->arguments) + if (eval_printexpr((char *)prt_ps_file_name, (char *)psettings->arguments) == FAIL) { EMSG(_("E365: Failed to print PostScript file")); } else { @@ -2853,10 +2921,11 @@ int mch_print_begin_page(char_u *str) prt_write_string("sv\n0 g\n"); prt_in_ascii = !prt_out_mbyte; - if (prt_out_mbyte) + if (prt_out_mbyte) { prt_write_string("CF0 sf\n"); - else + } else { prt_write_string("F0 sf\n"); + } prt_fgcol = PRCOLOR_BLACK; prt_bgcol = PRCOLOR_WHITE; prt_font = PRT_PS_FONT_ROMAN; @@ -2983,9 +3052,9 @@ int mch_print_text_out(char_u *const textp, size_t len) b = prt_fgcol & 0xff; prt_write_real(r / 255.0, 3); - if (r == g && g == b) + if (r == g && g == b) { prt_write_string("g\n"); - else { + } else { prt_write_real(g / 255.0, 3); prt_write_real(b / 255.0, 3); prt_write_string("r\n"); @@ -3003,8 +3072,9 @@ int mch_print_text_out(char_u *const textp, size_t len) } prt_need_bgcol = false; - if (prt_need_underline) + if (prt_need_underline) { prt_do_underline = prt_underline; + } prt_need_underline = false; prt_attribute_change = false; @@ -3042,14 +3112,22 @@ int mch_print_text_out(char_u *const textp, size_t len) */ ga_append(&prt_ps_buffer, '\\'); switch (ch) { - case BS: ga_append(&prt_ps_buffer, 'b'); break; - case TAB: ga_append(&prt_ps_buffer, 't'); break; - case NL: ga_append(&prt_ps_buffer, 'n'); break; - case FF: ga_append(&prt_ps_buffer, 'f'); break; - case CAR: ga_append(&prt_ps_buffer, 'r'); break; - case '(': ga_append(&prt_ps_buffer, '('); break; - case ')': ga_append(&prt_ps_buffer, ')'); break; - case '\\': ga_append(&prt_ps_buffer, '\\'); break; + case BS: + ga_append(&prt_ps_buffer, 'b'); break; + case TAB: + ga_append(&prt_ps_buffer, 't'); break; + case NL: + ga_append(&prt_ps_buffer, 'n'); break; + case FF: + ga_append(&prt_ps_buffer, 'f'); break; + case CAR: + ga_append(&prt_ps_buffer, 'r'); break; + case '(': + ga_append(&prt_ps_buffer, '('); break; + case ')': + ga_append(&prt_ps_buffer, ')'); break; + case '\\': + ga_append(&prt_ps_buffer, '\\'); break; default: sprintf((char *)ch_buff, "%03o", (unsigned int)ch); @@ -3058,8 +3136,9 @@ int mch_print_text_out(char_u *const textp, size_t len) ga_append(&prt_ps_buffer, (char)ch_buff[2]); break; } - } else + } else { ga_append(&prt_ps_buffer, (char)ch); + } } // Need to free any translated characters @@ -3071,7 +3150,7 @@ int mch_print_text_out(char_u *const textp, size_t len) // The downside of fp - use relative error on right margin check const double next_pos = prt_pos_x + prt_char_width; const bool need_break = (next_pos > prt_right_margin) - && ((next_pos - prt_right_margin) > (prt_right_margin * 1e-5)); + && ((next_pos - prt_right_margin) > (prt_right_margin * 1e-5)); if (need_break) { prt_flush_buffer(); @@ -3080,15 +3159,16 @@ int mch_print_text_out(char_u *const textp, size_t len) return need_break; } -void mch_print_set_font(const TriState iBold, const TriState iItalic, - const TriState iUnderline) +void mch_print_set_font(const TriState iBold, const TriState iItalic, const TriState iUnderline) { int font = 0; - if (iBold) + if (iBold) { font |= 0x01; - if (iItalic) + } + if (iItalic) { font |= 0x02; + } if (font != prt_font) { prt_font = font; diff --git a/src/nvim/hardcopy.h b/src/nvim/hardcopy.h index c6a3321b08..eba769d342 100644 --- a/src/nvim/hardcopy.h +++ b/src/nvim/hardcopy.h @@ -4,9 +4,9 @@ #include <stdint.h> #include <stdlib.h> // for size_t +#include "nvim/ex_cmds_defs.h" // for exarg_T #include "nvim/globals.h" // for TriState #include "nvim/types.h" // for char_u -#include "nvim/ex_cmds_defs.h" // for exarg_T /* * Structure to hold printing color and font attributes. @@ -34,19 +34,19 @@ typedef struct { int modec; int do_syntax; int user_abort; - char_u *jobname; - char_u *outfile; - char_u *arguments; + char_u *jobname; + char_u *outfile; + char_u *arguments; } prt_settings_T; /* * Generic option table item, only used for printer at the moment. */ typedef struct { - const char *name; + const char *name; int hasnum; int number; - char_u *string; /* points into option string */ + char_u *string; // points into option string int strlen; int present; } option_table_T; @@ -67,13 +67,13 @@ typedef struct { #define OPT_PRINT_FORMFEED 13 #define OPT_PRINT_NUM_OPTIONS 14 -/* For prt_get_unit(). */ +// For prt_get_unit(). #define PRT_UNIT_NONE -1 #define PRT_UNIT_PERC 0 #define PRT_UNIT_INCH 1 #define PRT_UNIT_MM 2 #define PRT_UNIT_POINT 3 -#define PRT_UNIT_NAMES {"pc", "in", "mm", "pt"} +#define PRT_UNIT_NAMES { "pc", "in", "mm", "pt" } #define PRINT_NUMBER_WIDTH 8 diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c index 526bc284a4..a8e5de839a 100644 --- a/src/nvim/hashtab.c +++ b/src/nvim/hashtab.c @@ -22,15 +22,15 @@ /// memory). #include <assert.h> +#include <inttypes.h> #include <stdbool.h> #include <string.h> -#include <inttypes.h> -#include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/hashtab.h" -#include "nvim/message.h" #include "nvim/memory.h" +#include "nvim/message.h" +#include "nvim/vim.h" // Magic value for algorithm that walks through the array. #define PERTURB_SHIFT 5 @@ -102,8 +102,7 @@ hashitem_T *hash_find(const hashtab_T *const ht, const char_u *const key) /// /// @warning Returned pointer becomes invalid as soon as the hash table /// is changed in any way. -hashitem_T *hash_find_len(const hashtab_T *const ht, const char *const key, - const size_t len) +hashitem_T *hash_find_len(const hashtab_T *const ht, const char *const key, const size_t len) { return hash_lookup(ht, key, len, hash_hash_len(key, len)); } @@ -119,8 +118,7 @@ hashitem_T *hash_find_len(const hashtab_T *const ht, const char *const key, /// used for that key. /// WARNING: Returned pointer becomes invalid as soon as the hash table /// is changed in any way. -hashitem_T *hash_lookup(const hashtab_T *const ht, - const char *const key, const size_t key_len, +hashitem_T *hash_lookup(const hashtab_T *const ht, const char *const key, const size_t key_len, const hash_T hash) { #ifdef HT_DEBUG @@ -336,7 +334,7 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems) bool newarray_is_small = newsize == HT_INIT_SIZE; bool keep_smallarray = newarray_is_small - && ht->ht_array == ht->ht_smallarray; + && ht->ht_array == ht->ht_smallarray; // Make sure that oldarray and newarray do not overlap, // so that copying is possible. @@ -387,7 +385,7 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems) } #define HASH_CYCLE_BODY(hash, p) \ - hash = hash * 101 + *p++ + hash = hash * 101 + *p++ /// Get the hash number for a key. /// diff --git a/src/nvim/hashtab.h b/src/nvim/hashtab.h index c82a6cc121..7740a3e431 100644 --- a/src/nvim/hashtab.h +++ b/src/nvim/hashtab.h @@ -77,18 +77,18 @@ typedef struct hashtable_S { /// @param hi Name of the variable with current hashtab entry. /// @param code Cycle body. #define HASHTAB_ITER(ht, hi, code) \ - do { \ - hashtab_T *const hi##ht_ = (ht); \ - size_t hi##todo_ = hi##ht_->ht_used; \ - for (hashitem_T *hi = hi##ht_->ht_array; hi##todo_; hi++) { \ - if (!HASHITEM_EMPTY(hi)) { \ - hi##todo_--; \ - { \ - code \ - } \ + do { \ + hashtab_T *const hi##ht_ = (ht); \ + size_t hi##todo_ = hi##ht_->ht_used; \ + for (hashitem_T *hi = hi##ht_->ht_array; hi##todo_; hi++) { \ + if (!HASHITEM_EMPTY(hi)) { \ + hi##todo_--; \ + { \ + code \ } \ } \ - } while (0) + } \ + } while (0) #ifdef INCLUDE_GENERATED_DECLARATIONS # include "hashtab.h.generated.h" diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c index 7341ac9393..737e668e81 100644 --- a/src/nvim/highlight.c +++ b/src/nvim/highlight.c @@ -3,9 +3,11 @@ // highlight.c: low level code for UI and syntax highlighting -#include "nvim/vim.h" +#include "nvim/api/private/defs.h" +#include "nvim/api/private/helpers.h" #include "nvim/highlight.h" #include "nvim/highlight_defs.h" +#include "nvim/lua/executor.h" #include "nvim/map.h" #include "nvim/message.h" #include "nvim/option.h" @@ -13,9 +15,7 @@ #include "nvim/screen.h" #include "nvim/syntax.h" #include "nvim/ui.h" -#include "nvim/api/private/defs.h" -#include "nvim/api/private/helpers.h" -#include "nvim/lua/executor.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "highlight.c.generated.h" @@ -306,7 +306,7 @@ void update_window_hl(win_T *wp, bool invalid) // syntax group! It needs at least 10 layers of special casing! Noooooo! // // haha, theme engine go brrr - int normality = syn_check_group((const char_u *)S_LEN("Normal")); + int normality = syn_check_group(S_LEN("Normal")); int ns_attr = ns_get_hl(-1, normality, false, false); if (ns_attr > 0) { // TODO(bfredl): hantera NormalNC and so on @@ -361,19 +361,19 @@ void update_window_hl(win_T *wp, bool invalid) int hl_get_underline(void) { return get_attr_entry((HlEntry){ - .attr = (HlAttrs){ - .cterm_ae_attr = (int16_t)HL_UNDERLINE, - .cterm_fg_color = 0, - .cterm_bg_color = 0, - .rgb_ae_attr = (int16_t)HL_UNDERLINE, - .rgb_fg_color = -1, - .rgb_bg_color = -1, - .rgb_sp_color = -1, - .hl_blend = -1, - }, - .kind = kHlUI, - .id1 = 0, - .id2 = 0, + .attr = (HlAttrs){ + .cterm_ae_attr = (int16_t)HL_UNDERLINE, + .cterm_fg_color = 0, + .cterm_bg_color = 0, + .rgb_ae_attr = (int16_t)HL_UNDERLINE, + .rgb_fg_color = -1, + .rgb_bg_color = -1, + .rgb_sp_color = -1, + .hl_blend = -1, + }, + .kind = kHlUI, + .id1 = 0, + .id2 = 0, }); } @@ -648,23 +648,23 @@ static int hl_cterm2rgb_color(int nr) }; static char_u ansi_table[16][4] = { // R G B idx - { 0, 0, 0, 1 } , // black - { 224, 0, 0, 2 } , // dark red - { 0, 224, 0, 3 } , // dark green - { 224, 224, 0, 4 } , // dark yellow / brown - { 0, 0, 224, 5 } , // dark blue - { 224, 0, 224, 6 } , // dark magenta - { 0, 224, 224, 7 } , // dark cyan - { 224, 224, 224, 8 } , // light grey - - { 128, 128, 128, 9 } , // dark grey - { 255, 64, 64, 10 } , // light red - { 64, 255, 64, 11 } , // light green - { 255, 255, 64, 12 } , // yellow - { 64, 64, 255, 13 } , // light blue - { 255, 64, 255, 14 } , // light magenta - { 64, 255, 255, 15 } , // light cyan - { 255, 255, 255, 16 } , // white + { 0, 0, 0, 1 }, // black + { 224, 0, 0, 2 }, // dark red + { 0, 224, 0, 3 }, // dark green + { 224, 224, 0, 4 }, // dark yellow / brown + { 0, 0, 224, 5 }, // dark blue + { 224, 0, 224, 6 }, // dark magenta + { 0, 224, 224, 7 }, // dark cyan + { 224, 224, 224, 8 }, // light grey + + { 128, 128, 128, 9 }, // dark grey + { 255, 64, 64, 10 }, // light red + { 64, 255, 64, 11 }, // light green + { 255, 255, 64, 12 }, // yellow + { 64, 64, 255, 13 }, // light blue + { 255, 64, 255, 14 }, // light magenta + { 64, 255, 255, 15 }, // light cyan + { 255, 255, 255, 16 }, // white }; int r = 0; @@ -790,7 +790,7 @@ Dictionary hlattrs2dict(HlAttrs ae, bool use_rgb) } if (ae.hl_blend > -1) { - PUT(hl, "blend", INTEGER_OBJ(ae.hl_blend)); + PUT(hl, "blend", INTEGER_OBJ(ae.hl_blend)); } return hl; @@ -847,7 +847,7 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err) err)) { cterm_mask |= flags[m].flag; } - break; + break; } } } @@ -890,7 +890,7 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err) } else if (link_id && strequal(key, "link")) { if (val.type == kObjectTypeString) { String str = val.data.string; - *link_id = syn_check_group((const char_u *)str.data, (int)str.size); + *link_id = syn_check_group(str.data, (int)str.size); } else if (val.type == kObjectTypeInteger) { // TODO(bfredl): validate range? *link_id = (int)val.data.integer; @@ -915,9 +915,9 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err) hlattrs.rgb_fg_color = fg; hlattrs.rgb_sp_color = sp; hlattrs.cterm_bg_color = - ctermbg == -1 ? cterm_normal_bg_color : ctermbg + 1; + ctermbg == -1 ? cterm_normal_bg_color : ctermbg + 1; hlattrs.cterm_fg_color = - ctermfg == -1 ? cterm_normal_fg_color : ctermfg + 1; + ctermfg == -1 ? cterm_normal_fg_color : ctermfg + 1; hlattrs.cterm_ae_attr = cterm_mask; } else { hlattrs.cterm_ae_attr = cterm_mask; @@ -945,34 +945,34 @@ static void hl_inspect_impl(Array *arr, int attr) HlEntry e = kv_A(attr_entries, attr); switch (e.kind) { - case kHlSyntax: - PUT(item, "kind", STRING_OBJ(cstr_to_string("syntax"))); - PUT(item, "hi_name", - STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id1)))); - break; - - case kHlUI: - PUT(item, "kind", STRING_OBJ(cstr_to_string("ui"))); - const char *ui_name = (e.id1 == -1) ? "Normal" : hlf_names[e.id1]; - PUT(item, "ui_name", STRING_OBJ(cstr_to_string(ui_name))); - PUT(item, "hi_name", - STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id2)))); - break; - - case kHlTerminal: - PUT(item, "kind", STRING_OBJ(cstr_to_string("term"))); - break; - - case kHlCombine: - case kHlBlend: - case kHlBlendThrough: - // attribute combination is associative, so flatten to an array - hl_inspect_impl(arr, e.id1); - hl_inspect_impl(arr, e.id2); - return; - - case kHlUnknown: - return; + case kHlSyntax: + PUT(item, "kind", STRING_OBJ(cstr_to_string("syntax"))); + PUT(item, "hi_name", + STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id1)))); + break; + + case kHlUI: + PUT(item, "kind", STRING_OBJ(cstr_to_string("ui"))); + const char *ui_name = (e.id1 == -1) ? "Normal" : hlf_names[e.id1]; + PUT(item, "ui_name", STRING_OBJ(cstr_to_string(ui_name))); + PUT(item, "hi_name", + STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id2)))); + break; + + case kHlTerminal: + PUT(item, "kind", STRING_OBJ(cstr_to_string("term"))); + break; + + case kHlCombine: + case kHlBlend: + case kHlBlendThrough: + // attribute combination is associative, so flatten to an array + hl_inspect_impl(arr, e.id1); + hl_inspect_impl(arr, e.id2); + return; + + case kHlUnknown: + return; } PUT(item, "id", INTEGER_OBJ(attr)); ADD(*arr, DICTIONARY_OBJ(item)); diff --git a/src/nvim/highlight.h b/src/nvim/highlight.h index a237ddbc34..ae63f83d65 100644 --- a/src/nvim/highlight.h +++ b/src/nvim/highlight.h @@ -2,15 +2,16 @@ #define NVIM_HIGHLIGHT_H #include <stdbool.h> -#include "nvim/highlight_defs.h" + #include "nvim/api/private/defs.h" +#include "nvim/highlight_defs.h" #include "nvim/ui.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "highlight.h.generated.h" #endif -# define HL_SET_DEFAULT_COLORS(rgb_fg, rgb_bg, rgb_sp) \ +#define HL_SET_DEFAULT_COLORS(rgb_fg, rgb_bg, rgb_sp) \ do { \ bool dark_ = (*p_bg == 'd'); \ rgb_fg = rgb_fg != -1 ? rgb_fg : (dark_ ? 0xFFFFFF : 0x000000); \ diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h index a0e8bad11f..12f2b62313 100644 --- a/src/nvim/highlight_defs.h +++ b/src/nvim/highlight_defs.h @@ -49,62 +49,61 @@ typedef struct attr_entry { /// Values for index in highlight_attr[]. /// When making changes, also update hlf_names below! typedef enum { - HLF_8 = 0 // Meta & special keys listed with ":map", text that is + HLF_8 = 0, // Meta & special keys listed with ":map", text that is // displayed different from what it is - , HLF_EOB // after the last line in the buffer - , HLF_TERM // terminal cursor focused - , HLF_TERMNC // terminal cursor unfocused - , HLF_AT // @ characters at end of screen, characters that - // don't really exist in the text - , HLF_D // directories in CTRL-D listing - , HLF_E // error messages - , HLF_I // incremental search - , HLF_L // last search string - , HLF_M // "--More--" message - , HLF_CM // Mode (e.g., "-- INSERT --") - , HLF_N // line number for ":number" and ":#" commands - , HLF_LNA // LineNrAbove - , HLF_LNB // LineNrBelow - , HLF_CLN // current line number when 'cursorline' is set - , HLF_R // return to continue message and yes/no questions - , HLF_S // status lines - , HLF_SNC // status lines of not-current windows - , HLF_C // column to separate vertically split windows - , HLF_T // Titles for output from ":set all", ":autocmd" etc. - , HLF_V // Visual mode - , HLF_VNC // Visual mode, autoselecting and not clipboard owner - , HLF_W // warning messages - , HLF_WM // Wildmenu highlight - , HLF_FL // Folded line - , HLF_FC // Fold column - , HLF_ADD // Added diff line - , HLF_CHD // Changed diff line - , HLF_DED // Deleted diff line - , HLF_TXD // Text Changed in diff line - , HLF_SC // Sign column - , HLF_CONCEAL // Concealed text - , HLF_SPB // SpellBad - , HLF_SPC // SpellCap - , HLF_SPR // SpellRare - , HLF_SPL // SpellLocal - , HLF_PNI // popup menu normal item - , HLF_PSI // popup menu selected item - , HLF_PSB // popup menu scrollbar - , HLF_PST // popup menu scrollbar thumb - , HLF_TP // tabpage line - , HLF_TPS // tabpage line selected - , HLF_TPF // tabpage line filler - , HLF_CUC // 'cursorcolumn' - , HLF_CUL // 'cursorline' - , HLF_MC // 'colorcolumn' - , HLF_QFL // selected quickfix line - , HLF_0 // Whitespace - , HLF_INACTIVE // NormalNC: Normal text in non-current windows - , HLF_MSGSEP // message separator line - , HLF_NFLOAT // Floating window - , HLF_MSG // Message area - , HLF_BORDER // Floating window border - , HLF_COUNT // MUST be the last one + HLF_EOB, // after the last line in the buffer + HLF_TERM, // terminal cursor focused + HLF_TERMNC, // terminal cursor unfocused + HLF_AT, // @ characters at end of screen, characters that don't really exist in the text + HLF_D, // directories in CTRL-D listing + HLF_E, // error messages + HLF_I, // incremental search + HLF_L, // last search string + HLF_M, // "--More--" message + HLF_CM, // Mode (e.g., "-- INSERT --") + HLF_N, // line number for ":number" and ":#" commands + HLF_LNA, // LineNrAbove + HLF_LNB, // LineNrBelow + HLF_CLN, // current line number when 'cursorline' is set + HLF_R, // return to continue message and yes/no questions + HLF_S, // status lines + HLF_SNC, // status lines of not-current windows + HLF_C, // column to separate vertically split windows + HLF_T, // Titles for output from ":set all", ":autocmd" etc. + HLF_V, // Visual mode + HLF_VNC, // Visual mode, autoselecting and not clipboard owner + HLF_W, // warning messages + HLF_WM, // Wildmenu highlight + HLF_FL, // Folded line + HLF_FC, // Fold column + HLF_ADD, // Added diff line + HLF_CHD, // Changed diff line + HLF_DED, // Deleted diff line + HLF_TXD, // Text Changed in diff line + HLF_SC, // Sign column + HLF_CONCEAL, // Concealed text + HLF_SPB, // SpellBad + HLF_SPC, // SpellCap + HLF_SPR, // SpellRare + HLF_SPL, // SpellLocal + HLF_PNI, // popup menu normal item + HLF_PSI, // popup menu selected item + HLF_PSB, // popup menu scrollbar + HLF_PST, // popup menu scrollbar thumb + HLF_TP, // tabpage line + HLF_TPS, // tabpage line selected + HLF_TPF, // tabpage line filler + HLF_CUC, // 'cursorcolumn' + HLF_CUL, // 'cursorline' + HLF_MC, // 'colorcolumn' + HLF_QFL, // selected quickfix line + HLF_0, // Whitespace + HLF_INACTIVE, // NormalNC: Normal text in non-current windows + HLF_MSGSEP, // message separator line + HLF_NFLOAT, // Floating window + HLF_MSG, // Message area + HLF_BORDER, // Floating window border + HLF_COUNT // MUST be the last one } hlf_T; EXTERN const char *hlf_names[] INIT(= { diff --git a/src/nvim/iconv.h b/src/nvim/iconv.h index a7c9ad4040..509f83c415 100644 --- a/src/nvim/iconv.h +++ b/src/nvim/iconv.h @@ -4,17 +4,17 @@ #include "auto/config.h" #ifdef HAVE_ICONV -# include <errno.h> -# include <iconv.h> +# include <errno.h> +# include <iconv.h> // define some missing constants if necessary -# ifndef EILSEQ -# define EILSEQ 123 -# endif -# define ICONV_ERRNO errno -# define ICONV_E2BIG E2BIG -# define ICONV_EINVAL EINVAL -# define ICONV_EILSEQ EILSEQ +# ifndef EILSEQ +# define EILSEQ 123 +# endif +# define ICONV_ERRNO errno +# define ICONV_E2BIG E2BIG +# define ICONV_EINVAL EINVAL +# define ICONV_EILSEQ EILSEQ #endif #endif // NVIM_ICONV_H diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index 31615e744a..d731e79473 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -9,31 +9,29 @@ * might be a few lines of code that look similar to what Nvi has. */ -#include <stdbool.h> - #include <assert.h> #include <errno.h> -#include <inttypes.h> #include <fcntl.h> +#include <inttypes.h> +#include <stdbool.h> +#include <sys/stat.h> +#include <sys/types.h> -#include "nvim/buffer.h" #include "nvim/ascii.h" -#include "nvim/if_cscope.h" +#include "nvim/buffer.h" #include "nvim/charset.h" +#include "nvim/event/stream.h" #include "nvim/fileio.h" -#include "nvim/message.h" +#include "nvim/if_cscope.h" #include "nvim/memory.h" +#include "nvim/message.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" #include "nvim/os/time.h" #include "nvim/path.h" #include "nvim/quickfix.h" #include "nvim/strings.h" #include "nvim/tag.h" -#include "nvim/os/os.h" -#include "nvim/os/input.h" -#include "nvim/event/stream.h" - -#include <sys/types.h> -#include <sys/stat.h> #if defined(UNIX) # include <sys/wait.h> #endif @@ -43,7 +41,7 @@ # include "if_cscope.c.generated.h" #endif -static csinfo_T * csinfo = NULL; +static csinfo_T *csinfo = NULL; static size_t csinfo_size = 0; // number of items allocated in csinfo[] static int eap_arg_len; // length of eap->arg, set in cs_lookup_cmd() @@ -90,19 +88,20 @@ char_u *get_cscope_name(expand_T *xp, int idx) // Complete with sub-commands of ":cscope": // add, find, help, kill, reset, show return (char_u *)cs_cmds[idx].name; - case EXP_SCSCOPE_SUBCMD: - { + case EXP_SCSCOPE_SUBCMD: { // Complete with sub-commands of ":scscope": same sub-commands as // ":cscope" but skip commands which don't support split windows int i; - for (i = 0, current_idx = 0; cs_cmds[i].name != NULL; i++) - if (cs_cmds[i].cansplit) - if (current_idx++ == idx) + for (i = 0, current_idx = 0; cs_cmds[i].name != NULL; i++) { + if (cs_cmds[i].cansplit) { + if (current_idx++ == idx) { break; + } + } + } return (char_u *)cs_cmds[i].name; } - case EXP_CSCOPE_FIND: - { + case EXP_CSCOPE_FIND: { const char *query_type[] = { "a", "c", "d", "e", "f", "g", "i", "s", "t", NULL @@ -114,8 +113,7 @@ char_u *get_cscope_name(expand_T *xp, int idx) // redundant. return (char_u *)query_type[idx]; } - case EXP_CSCOPE_KILL: - { + case EXP_CSCOPE_KILL: { static char connection[5]; // ":cscope kill" accepts connection numbers or partial names of @@ -124,8 +122,9 @@ char_u *get_cscope_name(expand_T *xp, int idx) // connections. size_t i; for (i = 0, current_idx = 0; i < csinfo_size; i++) { - if (csinfo[i].fname == NULL) + if (csinfo[i].fname == NULL) { continue; + } if (current_idx++ == idx) { vim_snprintf(connection, sizeof(connection), "%zu", i); return (char_u *)connection; @@ -172,11 +171,9 @@ void set_context_in_cscope_cmd(expand_T *xp, const char *arg, cmdidx_T cmdidx) /// Find the command, print help if invalid, and then call the corresponding /// command function. -static void -do_cscope_general( - exarg_T *eap, - int make_split // whether to split window -) +/// +/// @param make_split whether to split window +static void do_cscope_general(exarg_T *eap, int make_split) { cscmd_T *cmdp; @@ -187,8 +184,7 @@ do_cscope_general( if (make_split) { if (!cmdp->cansplit) { - (void)MSG_PUTS(_( - "This cscope command does not support splitting the window.\n")); + (void)MSG_PUTS(_("This cscope command does not support splitting the window.\n")); return; } postponed_split = -1; @@ -228,14 +224,16 @@ void ex_cstag(exarg_T *eap) case 0: if (cs_check_for_connections()) { ret = cs_find_common("g", (char *)(eap->arg), eap->forceit, FALSE, - FALSE, *eap->cmdlinep); + FALSE, *eap->cmdlinep); if (ret == FALSE) { cs_free_tags(); - if (msg_col) + if (msg_col) { msg_putchar('\n'); + } - if (cs_check_for_tags()) + if (cs_check_for_tags()) { ret = do_tag(eap->arg, DT_JUMP, 0, eap->forceit, FALSE); + } } } else if (cs_check_for_tags()) { ret = do_tag(eap->arg, DT_JUMP, 0, eap->forceit, FALSE); @@ -245,21 +243,24 @@ void ex_cstag(exarg_T *eap) if (cs_check_for_tags()) { ret = do_tag(eap->arg, DT_JUMP, 0, eap->forceit, FALSE); if (ret == FALSE) { - if (msg_col) + if (msg_col) { msg_putchar('\n'); + } if (cs_check_for_connections()) { ret = cs_find_common("g", (char *)(eap->arg), eap->forceit, - FALSE, FALSE, *eap->cmdlinep); - if (ret == FALSE) + FALSE, FALSE, *eap->cmdlinep); + if (ret == FALSE) { cs_free_tags(); + } } } } else if (cs_check_for_connections()) { ret = cs_find_common("g", (char *)(eap->arg), eap->forceit, FALSE, - FALSE, *eap->cmdlinep); - if (ret == FALSE) + FALSE, *eap->cmdlinep); + if (ret == FALSE) { cs_free_tags(); + } } break; default: @@ -306,29 +307,29 @@ void cs_print_tags(void) /* * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function * - * Checks for the existence of a |cscope| connection. If no - * parameters are specified, then the function returns: + * Checks for the existence of a |cscope| connection. If no + * parameters are specified, then the function returns: * - * 0, if cscope was not available (not compiled in), or if there - * are no cscope connections; or - * 1, if there is at least one cscope connection. + * 0, if cscope was not available (not compiled in), or if there + * are no cscope connections; or + * 1, if there is at least one cscope connection. * - * If parameters are specified, then the value of {num} - * determines how existence of a cscope connection is checked: + * If parameters are specified, then the value of {num} + * determines how existence of a cscope connection is checked: * - * {num} Description of existence check - * ----- ------------------------------ - * 0 Same as no parameters (e.g., "cscope_connection()"). - * 1 Ignore {prepend}, and use partial string matches for - * {dbpath}. - * 2 Ignore {prepend}, and use exact string matches for - * {dbpath}. - * 3 Use {prepend}, use partial string matches for both - * {dbpath} and {prepend}. - * 4 Use {prepend}, use exact string matches for both - * {dbpath} and {prepend}. + * {num} Description of existence check + * ----- ------------------------------ + * 0 Same as no parameters (e.g., "cscope_connection()"). + * 1 Ignore {prepend}, and use partial string matches for + * {dbpath}. + * 2 Ignore {prepend}, and use exact string matches for + * {dbpath}. + * 3 Use {prepend}, use partial string matches for both + * {dbpath} and {prepend}. + * 4 Use {prepend}, use exact string matches for both + * {dbpath} and {prepend}. * - * Note: All string comparisons are case sensitive! + * Note: All string comparisons are case sensitive! */ bool cs_connection(int num, char_u *dbpath, char_u *ppath) { @@ -393,8 +394,9 @@ static int cs_add(exarg_T *eap) cs_usage_msg(Add); return CSCOPE_FAILURE; } - if ((ppath = strtok((char *)NULL, (const char *)" ")) != NULL) + if ((ppath = strtok((char *)NULL, (const char *)" ")) != NULL) { flags = strtok((char *)NULL, (const char *)" "); + } return cs_add_common(fname, ppath, flags); } @@ -413,18 +415,16 @@ static void cs_stat_emsg(char *fname) /// The common routine to add a new cscope connection. Called by /// cs_add() and cs_reset(). I really don't like to do this, but this /// routine uses a number of goto statements. -static int -cs_add_common( - char *arg1, // filename - may contain environment variables - char *arg2, // prepend path - may contain environment variables - char *flags -) +/// +/// @param arg1 filename - may contain environment variables +/// @param arg2 prepend path - may contain environment variables +static int cs_add_common(char *arg1, char *arg2, char *flags) { - char *fname = NULL; - char *fname2 = NULL; - char *ppath = NULL; + char *fname = NULL; + char *fname2 = NULL; + char *ppath = NULL; size_t usedlen = 0; - char_u *fbuf = NULL; + char_u *fbuf = NULL; // get the filename (arg1), expand it, and try to stat it fname = xmalloc(MAXPATHL + 1); @@ -443,8 +443,9 @@ cs_add_common( bool file_info_ok = os_fileinfo(fname, &file_info); if (!file_info_ok) { staterr: - if (p_csverbose) + if (p_csverbose) { cs_stat_emsg(fname); + } goto add_err; } @@ -465,31 +466,32 @@ staterr: while (fname[strlen(fname)-1] == '/' ) { fname[strlen(fname)-1] = '\0'; - if (fname[0] == '\0') + if (fname[0] == '\0') { break; + } } - if (fname[0] == '\0') + if (fname[0] == '\0') { (void)sprintf(fname2, "/%s", CSCOPE_DBFILE); - else + } else { (void)sprintf(fname2, "%s/%s", fname, CSCOPE_DBFILE); + } file_info_ok = os_fileinfo(fname2, &file_info); if (!file_info_ok) { - if (p_csverbose) + if (p_csverbose) { cs_stat_emsg(fname2); + } goto add_err; } i = cs_insert_filelist(fname2, ppath, flags, &file_info); - } - else if (S_ISREG(file_info.stat.st_mode) || S_ISLNK(file_info.stat.st_mode)) - { + } else if (S_ISREG(file_info.stat.st_mode) || S_ISLNK(file_info.stat.st_mode)) { i = cs_insert_filelist(fname, ppath, flags, &file_info); } else { - if (p_csverbose) - (void)EMSG2( - _("E564: %s is not a directory or a valid cscope database"), - fname); + if (p_csverbose) { + (void)EMSG2(_("E564: %s is not a directory or a valid cscope database"), + fname); + } goto add_err; } @@ -538,15 +540,15 @@ static size_t cs_cnt_connections(void) size_t cnt = 0; for (size_t i = 0; i < csinfo_size; i++) { - if (csinfo[i].fname != NULL) + if (csinfo[i].fname != NULL) { cnt++; + } } return cnt; } -static void cs_reading_emsg( - size_t idx // connection index -) +/// @param idx connection index +static void cs_reading_emsg(size_t idx) { EMSGU(_("E262: error reading cscope connection %" PRIu64), idx); } @@ -582,7 +584,7 @@ static int cs_cnt_matches(size_t idx) // Accept "\S*cscope: X lines", also matches "mlcscope". // Bail out for the "Unable to search" error. if (strstr((const char *)buf, "Unable to search database") != NULL) { - break; + break; } if ((stok = strtok(buf, (const char *)" ")) == NULL) { continue; @@ -591,18 +593,21 @@ static int cs_cnt_matches(size_t idx) continue; } - if ((stok = strtok(NULL, (const char *)" ")) == NULL) + if ((stok = strtok(NULL, (const char *)" ")) == NULL) { continue; + } nlines = atoi(stok); if (nlines < 0) { nlines = 0; break; } - if ((stok = strtok(NULL, (const char *)" ")) == NULL) + if ((stok = strtok(NULL, (const char *)" ")) == NULL) { continue; - if (strncmp((const char *)stok, "lines", 5)) + } + if (strncmp((const char *)stok, "lines", 5)) { continue; + } break; } @@ -620,31 +625,40 @@ static char *cs_create_cmd(char *csoption, char *pattern) char *pat; switch (csoption[0]) { - case '0': case 's': + case '0': + case 's': search = 0; break; - case '1': case 'g': + case '1': + case 'g': search = 1; break; - case '2': case 'd': + case '2': + case 'd': search = 2; break; - case '3': case 'c': + case '3': + case 'c': search = 3; break; - case '4': case 't': + case '4': + case 't': search = 4; break; - case '6': case 'e': + case '6': + case 'e': search = 6; break; - case '7': case 'f': + case '7': + case 'f': search = 7; break; - case '8': case 'i': + case '8': + case 'i': search = 8; break; - case '9': case 'a': + case '9': + case 'a': search = 9; break; default: @@ -656,9 +670,11 @@ static char *cs_create_cmd(char *csoption, char *pattern) // Skip white space before the patter, except for text and pattern search, // they may want to use the leading white space. pat = pattern; - if (search != 4 && search != 6) - while (ascii_iswhite(*pat)) + if (search != 4 && search != 6) { + while (ascii_iswhite(*pat)) { ++pat; + } + } cmd = xmalloc(strlen(pat) + 2); @@ -675,7 +691,7 @@ static int cs_create_connection(size_t i) #ifdef UNIX int to_cs[2], from_cs[2]; #endif - char *prog, *cmd, *ppath = NULL; + char *prog, *cmd, *ppath = NULL; #if defined(UNIX) /* @@ -686,14 +702,18 @@ static int cs_create_connection(size_t i) if (pipe(to_cs) < 0 || pipe(from_cs) < 0) { (void)EMSG(_("E566: Could not create cscope pipes")); err_closing: - if (to_cs[0] != -1) + if (to_cs[0] != -1) { (void)close(to_cs[0]); - if (to_cs[1] != -1) + } + if (to_cs[1] != -1) { (void)close(to_cs[1]); - if (from_cs[0] != -1) + } + if (from_cs[0] != -1) { (void)close(from_cs[0]); - if (from_cs[1] != -1) + } + if (from_cs[1] != -1) { (void)close(from_cs[1]); + } return CSCOPE_FAILURE; } @@ -759,8 +779,9 @@ err_closing: len += strlen(ppath); } - if (csinfo[i].flags) + if (csinfo[i].flags) { len += strlen(csinfo[i].flags); + } cmd = xmalloc(len); @@ -779,10 +800,10 @@ err_closing: (void)strcat(cmd, " "); (void)strcat(cmd, csinfo[i].flags); } -# ifdef UNIX +#ifdef UNIX // on Win32 we still need prog xfree(prog); -# endif +#endif xfree(ppath); #if defined(UNIX) @@ -791,12 +812,14 @@ err_closing: # if defined(HAVE_SETSID) (void)setsid(); # else - if (setpgid(0, 0) == -1) + if (setpgid(0, 0) == -1) { PERROR(_("cs_create_connection setpgid failed")); + } # endif # endif - if (execl("/bin/sh", "sh", "-c", cmd, (char *)NULL) == -1) + if (execl("/bin/sh", "sh", "-c", cmd, (char *)NULL) == -1) { PERROR(_("cs_create_connection exec failed")); + } exit(127); // NOTREACHED @@ -827,7 +850,7 @@ err_closing: si.hStdError = stdout_wr; si.hStdInput = stdin_rd; created = CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, - NULL, NULL, &si, &pi); + NULL, NULL, &si, &pi); xfree(prog); xfree(cmd); @@ -888,9 +911,11 @@ static int cs_find(exarg_T *eap) * Let's replace the NULs written by strtok() with spaces - we need the * spaces to correctly display the quickfix/location list window's title. */ - for (int i = 0; i < eap_arg_len; ++i) - if (NUL == eap->arg[i]) + for (int i = 0; i < eap_arg_len; ++i) { + if (NUL == eap->arg[i]) { eap->arg[i] = ' '; + } + } return cs_find_common(opt, pat, eap->forceit, true, eap->cmdidx == CMD_lcscope, *eap->cmdlinep); @@ -898,8 +923,8 @@ static int cs_find(exarg_T *eap) /// Common code for cscope find, shared by cs_find() and ex_cstag(). -static int cs_find_common(char *opt, char *pat, int forceit, int verbose, - int use_ll, char_u *cmdline) +static int cs_find_common(char *opt, char *pat, int forceit, int verbose, int use_ll, + char_u *cmdline) { char *cmd; int *nummatches; @@ -966,8 +991,9 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, // create the actual command to send to cscope cmd = cs_create_cmd(opt, pat); - if (cmd == NULL) + if (cmd == NULL) { return FALSE; + } nummatches = xmalloc(sizeof(int) * csinfo_size); @@ -978,8 +1004,9 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, } totmatches = 0; for (size_t i = 0; i < csinfo_size; i++) { - if (csinfo[i].fname == NULL || csinfo[i].to_fp == NULL) + if (csinfo[i].fname == NULL || csinfo[i].to_fp == NULL) { continue; + } // send cmd to cscope (void)fprintf(csinfo[i].to_fp, "%s\n", cmd); @@ -987,11 +1014,13 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, nummatches[i] = cs_cnt_matches(i); - if (nummatches[i] > -1) + if (nummatches[i] > -1) { totmatches += (size_t)nummatches[i]; + } - if (nummatches[i] == 0) + if (nummatches[i] == 0) { (void)cs_read_prompt(i); + } } xfree(cmd); @@ -1014,10 +1043,10 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, if (qfpos != NULL && *qfpos != '0') { // Fill error list. - FILE *f; - char_u *tmp = vim_tempname(); - qf_info_T *qi = NULL; - win_T *wp = NULL; + FILE *f; + char_u *tmp = vim_tempname(); + qf_info_T *qi = NULL; + win_T *wp = NULL; f = os_fopen((char *)tmp, "w"); if (f == NULL) { @@ -1039,14 +1068,15 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, } apply_autocmds(EVENT_QUICKFIXCMDPOST, (char_u *)"cscope", - curbuf->b_fname, TRUE, curbuf); - if (use_ll) + curbuf->b_fname, TRUE, curbuf); + if (use_ll) { /* * In the location list window, use the displayed location * list. Otherwise, use the location list for the window. */ qi = (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL) ? wp->w_llist_ref : wp->w_llist; + } qf_jump(qi, 0, 0, forceit); } } @@ -1059,11 +1089,11 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, size_t matched = 0; // read output - cs_fill_results((char *)pat, totmatches, nummatches, &matches, - &contexts, &matched); + cs_fill_results(pat, totmatches, nummatches, &matches, &contexts, &matched); xfree(nummatches); - if (matches == NULL) + if (matches == NULL) { return FALSE; + } (void)cs_manage_matches(matches, contexts, matched, Store); @@ -1086,10 +1116,10 @@ static int cs_help(exarg_T *eap) space_cnt = 0; } (void)smsg(_("%-5s: %s%*s (Usage: %s)"), - cmdp->name, - help, space_cnt, " ", - cmdp->usage); - if (strcmp(cmdp->name, "find") == 0) + cmdp->name, + help, space_cnt, " ", + cmdp->usage); + if (strcmp(cmdp->name, "find") == 0) { MSG_PUTS(_("\n" " a: Find assignments to this symbol\n" " c: Find functions calling this function\n" @@ -1100,6 +1130,7 @@ static int cs_help(exarg_T *eap) " i: Find files #including this file\n" " s: Find this C symbol\n" " t: Find this text string\n")); + } cmdp++; } @@ -1121,8 +1152,7 @@ static void clear_csinfo(size_t i) } /// Insert a new cscope database filename into the filelist. -static int cs_insert_filelist(char *fname, char *ppath, char *flags, - FileInfo *file_info) +static int cs_insert_filelist(char *fname, char *ppath, char *flags, FileInfo *file_info) { size_t i = 0; bool empty_found = false; @@ -1130,8 +1160,9 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags, for (size_t j = 0; j < csinfo_size; j++) { if (csinfo[j].fname != NULL && os_fileid_equal_fileinfo(&(csinfo[j].file_id), file_info)) { - if (p_csverbose) + if (p_csverbose) { (void)EMSG(_("E568: duplicate cscope database not added")); + } return CSCOPE_FAILURE; } @@ -1154,8 +1185,9 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags, csinfo_size *= 2; csinfo = xrealloc(csinfo, sizeof(csinfo_T)*csinfo_size); } - for (size_t j = csinfo_size/2; j < csinfo_size; j++) + for (size_t j = csinfo_size/2; j < csinfo_size; j++) { clear_csinfo(j); + } } csinfo[i].fname = xmalloc(strlen(fname) + 1); @@ -1165,14 +1197,16 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags, if (ppath != NULL) { csinfo[i].ppath = xmalloc(strlen(ppath) + 1); (void)strcpy(csinfo[i].ppath, (const char *)ppath); - } else + } else { csinfo[i].ppath = NULL; + } if (flags != NULL) { csinfo[i].flags = xmalloc(strlen(flags) + 1); (void)strcpy(csinfo[i].flags, (const char *)flags); - } else + } else { csinfo[i].flags = NULL; + } os_fileinfo_id(file_info, &(csinfo[i].file_id)); assert(i <= INT_MAX); @@ -1181,25 +1215,28 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags, /// Find cscope command in command table. -static cscmd_T * cs_lookup_cmd(exarg_T *eap) +static cscmd_T *cs_lookup_cmd(exarg_T *eap) { cscmd_T *cmdp; char *stok; size_t len; - if (eap->arg == NULL) + if (eap->arg == NULL) { return NULL; + } // Store length of eap->arg before it gets modified by strtok(). eap_arg_len = (int)STRLEN(eap->arg); - if ((stok = strtok((char *)(eap->arg), (const char *)" ")) == NULL) + if ((stok = strtok((char *)(eap->arg), (const char *)" ")) == NULL) { return NULL; + } len = strlen(stok); for (cmdp = cs_cmds; cmdp->name != NULL; ++cmdp) { - if (strncmp((const char *)(stok), cmdp->name, len) == 0) + if (strncmp((const char *)(stok), cmdp->name, len) == 0) { return cmdp; + } } return NULL; } @@ -1224,21 +1261,23 @@ static int cs_kill(exarg_T *eap) || (strlen(stok) < 3 && stok[0] == '-' && ascii_isdigit((int)(stok[1])))) { num = atoi(stok); - if (num == -1) + if (num == -1) { killall = true; - else if (num >= 0) { + } else if (num >= 0) { i = (size_t)num; } else { // All negative values besides -1 are invalid. - if (p_csverbose) + if (p_csverbose) { (void)EMSG2(_("E261: cscope connection %s not found"), stok); + } return CSCOPE_FAILURE; } } else { // Else it must be part of a name. We will try to find a match // within all the names in the csinfo data structure for (i = 0; i < csinfo_size; i++) { - if (csinfo[i].fname != NULL && strstr(csinfo[i].fname, stok)) + if (csinfo[i].fname != NULL && strstr(csinfo[i].fname, stok)) { break; + } } } @@ -1250,11 +1289,12 @@ static int cs_kill(exarg_T *eap) } else { if (killall) { for (i = 0; i < csinfo_size; i++) { - if (csinfo[i].fname) + if (csinfo[i].fname) { cs_kill_execute(i, csinfo[i].fname); + } } } else { - cs_kill_execute((size_t)i, stok); + cs_kill_execute(i, stok); } } @@ -1263,10 +1303,10 @@ static int cs_kill(exarg_T *eap) /// Actually kills a specific cscope connection. -static void cs_kill_execute( - size_t i, // cscope table index - char *cname // cscope database name -) +/// +/// @param i cscope table index +/// @param cname cscope database name +static void cs_kill_execute(size_t i, char *cname) { if (p_csverbose) { msg_clr_eos(); @@ -1293,8 +1333,7 @@ static void cs_kill_execute( /// Besides, even if this particular case didn't happen, the search pattern /// would still have to be modified to escape all the special regular expression /// characters to comply with ctags formatting. -static char *cs_make_vim_style_matches(char *fname, char *slno, char *search, - char *tagstr) +static char *cs_make_vim_style_matches(char *fname, char *slno, char *search, char *tagstr) { // vim style is ctags: // @@ -1339,8 +1378,7 @@ static char *cs_make_vim_style_matches(char *fname, char *slno, char *search, /// Free: frees up everything and resets /// /// Print: prints the tags -static char *cs_manage_matches(char **matches, char **contexts, - size_t totmatches, mcmd_e cmd) +static char *cs_manage_matches(char **matches, char **contexts, size_t totmatches, mcmd_e cmd) { static char **mp = NULL; static char **cp = NULL; @@ -1352,16 +1390,18 @@ static char *cs_manage_matches(char **matches, char **contexts, case Store: assert(matches != NULL); assert(totmatches > 0); - if (mp != NULL || cp != NULL) + if (mp != NULL || cp != NULL) { (void)cs_manage_matches(NULL, NULL, 0, Free); + } mp = matches; cp = contexts; cnt = totmatches; next = 0; break; case Get: - if (next >= cnt) + if (next >= cnt) { return NULL; + } p = mp[next]; next++; @@ -1370,8 +1410,9 @@ static char *cs_manage_matches(char **matches, char **contexts, if (mp != NULL) { while (cnt--) { xfree(mp[cnt]); - if (cp != NULL) + if (cp != NULL) { xfree(cp[cnt]); + } } xfree(mp); xfree(cp); @@ -1396,8 +1437,8 @@ static char *cs_manage_matches(char **matches, char **contexts, /// Parse cscope output. -static char *cs_parse_results(size_t cnumber, char *buf, int bufsize, - char **context, char **linenumber, char **search) +static char *cs_parse_results(size_t cnumber, char *buf, int bufsize, char **context, + char **linenumber, char **search) { int ch; char *p; @@ -1421,8 +1462,9 @@ retry: // If the line's too long for the buffer, discard it. if ((p = strchr(buf, '\n')) == NULL) { - while ((ch = getc(csinfo[cnumber].fr_fp)) != EOF && ch != '\n') + while ((ch = getc(csinfo[cnumber].fr_fp)) != EOF && ch != '\n') { ; + } return NULL; } *p = '\0'; @@ -1430,14 +1472,18 @@ retry: /* * cscope output is in the following format: * - * <filename> <context> <line number> <pattern> + * <filename> <context> <line number> <pattern> */ - if ((name = strtok((char *)buf, (const char *)" ")) == NULL) + char *saveptr = NULL; + if ((name = os_strtok(buf, (const char *)" ", &saveptr)) == NULL) { return NULL; - if ((*context = strtok(NULL, (const char *)" ")) == NULL) + } + if ((*context = os_strtok(NULL, (const char *)" ", &saveptr)) == NULL) { return NULL; - if ((*linenumber = strtok(NULL, (const char *)" ")) == NULL) + } + if ((*linenumber = os_strtok(NULL, (const char *)" ", &saveptr)) == NULL) { return NULL; + } *search = *linenumber + strlen(*linenumber) + 1; // +1 to skip \0 // --- nvi --- @@ -1463,25 +1509,29 @@ static void cs_file_results(FILE *f, int *nummatches_a) char *buf = xmalloc(CSREAD_BUFSIZE); for (size_t i = 0; i < csinfo_size; i++) { - if (nummatches_a[i] < 1) + if (nummatches_a[i] < 1) { continue; + } for (int j = 0; j < nummatches_a[i]; j++) { if ((fullname = cs_parse_results(i, buf, CSREAD_BUFSIZE, &cntx, - &slno, &search)) == NULL) + &slno, &search)) == NULL) { continue; + } context = xmalloc(strlen(cntx) + 5); - if (strcmp(cntx, "<global>")==0) + if (strcmp(cntx, "<global>")==0) { strcpy(context, "<<global>>"); - else + } else { sprintf(context, "<<%s>>", cntx); + } - if (search == NULL) + if (search == NULL) { fprintf(f, "%s\t%s\t%s\n", fullname, slno, context); - else + } else { fprintf(f, "%s\t%s\t%s %s\n", fullname, slno, context, search); + } xfree(context); xfree(fullname); @@ -1495,9 +1545,8 @@ static void cs_file_results(FILE *f, int *nummatches_a) /// Get parsed cscope output and calls cs_make_vim_style_matches to convert /// into ctags format. /// When there are no matches sets "*matches_p" to NULL. -static void cs_fill_results(char *tagstr, size_t totmatches, int *nummatches_a, - char ***matches_p, char ***cntxts_p, - size_t *matched) +static void cs_fill_results(char *tagstr, size_t totmatches, int *nummatches_a, char ***matches_p, + char ***cntxts_p, size_t *matched) { char *buf; char *search, *slno; @@ -1510,26 +1559,28 @@ static void cs_fill_results(char *tagstr, size_t totmatches, int *nummatches_a, assert(totmatches > 0); buf = xmalloc(CSREAD_BUFSIZE); - matches = xmalloc(sizeof(char *) * (size_t)totmatches); - cntxts = xmalloc(sizeof(char *) * (size_t)totmatches); + matches = xmalloc(sizeof(char *) * totmatches); + cntxts = xmalloc(sizeof(char *) * totmatches); for (size_t i = 0; i < csinfo_size; i++) { - if (nummatches_a[i] < 1) + if (nummatches_a[i] < 1) { continue; + } for (int j = 0; j < nummatches_a[i]; j++) { if ((fullname = cs_parse_results(i, buf, CSREAD_BUFSIZE, &cntx, - &slno, &search)) == NULL) + &slno, &search)) == NULL) { continue; + } matches[totsofar] = cs_make_vim_style_matches(fullname, slno, search, tagstr); xfree(fullname); - if (strcmp(cntx, "<global>") == 0) + if (strcmp(cntx, "<global>") == 0) { cntxts[totsofar] = NULL; - else { + } else { cntxts[totsofar] = xstrdup(cntx); } @@ -1691,9 +1742,9 @@ static void cs_print_tags_priv(char **matches, char **cntxts, static int cs_read_prompt(size_t i) { int ch; - char *buf = NULL; // buffer for possible error message from cscope + char *buf = NULL; // buffer for possible error message from cscope size_t bufpos = 0; - char *cs_emsg = _("E609: Cscope error: %s"); + char *cs_emsg = _("E609: Cscope error: %s"); size_t cs_emsg_len = strlen(cs_emsg); static char *eprompt = "Press the RETURN key to continue:"; size_t epromptlen = strlen(eprompt); @@ -1886,10 +1937,12 @@ static void cs_release_csp(size_t i, bool freefnpp) } #endif - if (csinfo[i].fr_fp != NULL) + if (csinfo[i].fr_fp != NULL) { (void)fclose(csinfo[i].fr_fp); - if (csinfo[i].to_fp != NULL) + } + if (csinfo[i].to_fp != NULL) { (void)fclose(csinfo[i].to_fp); + } if (freefnpp) { xfree(csinfo[i].fname); @@ -1904,11 +1957,12 @@ static void cs_release_csp(size_t i, bool freefnpp) /// Calls cs_kill on all cscope connections then reinits. static int cs_reset(exarg_T *eap) { - char **dblist = NULL, **pplist = NULL, **fllist = NULL; + char **dblist = NULL, **pplist = NULL, **fllist = NULL; char buf[25]; // for snprintf " (#%zu)" - if (csinfo_size == 0) + if (csinfo_size == 0) { return CSCOPE_SUCCESS; + } // malloc our db and ppath list dblist = xmalloc(csinfo_size * sizeof(char *)); @@ -1919,8 +1973,9 @@ static int cs_reset(exarg_T *eap) dblist[i] = csinfo[i].fname; pplist[i] = csinfo[i].ppath; fllist[i] = csinfo[i].flags; - if (csinfo[i].fname != NULL) + if (csinfo[i].fname != NULL) { cs_release_csp(i, FALSE); + } } // rebuild the cscope connection list @@ -1959,8 +2014,8 @@ static int cs_reset(exarg_T *eap) /// Contrast this with my development system (Digital Unix), which does. static char *cs_resolve_file(size_t i, char *name) { - char *fullname; - char_u *csdir = NULL; + char *fullname; + char_u *csdir = NULL; /* * Ppath is freed when we destroy the cscope connection. @@ -1975,8 +2030,8 @@ static char *cs_resolve_file(size_t i, char *name) // path in path resolution. csdir = xmalloc(MAXPATHL); STRLCPY(csdir, csinfo[i].fname, - path_tail((char_u *)csinfo[i].fname) - - (char_u *)csinfo[i].fname + 1); + path_tail((char_u *)csinfo[i].fname) + - (char_u *)csinfo[i].fname + 1); len += STRLEN(csdir); } @@ -1985,8 +2040,7 @@ static char *cs_resolve_file(size_t i, char *name) // happens, you are screwed up and need to fix how you're using cscope. if (csinfo[i].ppath != NULL && (strncmp(name, csinfo[i].ppath, strlen(csinfo[i].ppath)) != 0) - && (name[0] != '/') - ) { + && (name[0] != '/')) { fullname = xmalloc(len); (void)sprintf(fullname, "%s/%s", csinfo[i].ppath, name); } else if (csdir != NULL && csinfo[i].fname != NULL && *csdir != NUL) { @@ -2005,15 +2059,15 @@ static char *cs_resolve_file(size_t i, char *name) /// Show all cscope connections. static int cs_show(exarg_T *eap) { - if (cs_cnt_connections() == 0) + if (cs_cnt_connections() == 0) { MSG_PUTS(_("no cscope connections\n")); - else { - MSG_PUTS_ATTR( - _(" # pid database name prepend path\n"), - HL_ATTR(HLF_T)); + } else { + MSG_PUTS_ATTR(_(" # pid database name prepend path\n"), + HL_ATTR(HLF_T)); for (size_t i = 0; i < csinfo_size; i++) { - if (csinfo[i].fname == NULL) + if (csinfo[i].fname == NULL) { continue; + } if (csinfo[i].ppath != NULL) { (void)smsg("%2zu %-5" PRId64 " %-34s %-32s", i, @@ -2033,8 +2087,9 @@ static int cs_show(exarg_T *eap) /// Only called when VIM exits to quit any cscope sessions. void cs_end(void) { - for (size_t i = 0; i < csinfo_size; i++) + for (size_t i = 0; i < csinfo_size; i++) { cs_release_csp(i, true); + } xfree(csinfo); csinfo_size = 0; } diff --git a/src/nvim/if_cscope.h b/src/nvim/if_cscope.h index e20462576a..8dbc78943f 100644 --- a/src/nvim/if_cscope.h +++ b/src/nvim/if_cscope.h @@ -1,8 +1,8 @@ #ifndef NVIM_IF_CSCOPE_H #define NVIM_IF_CSCOPE_H -#include "nvim/types.h" // for char_u and expand_T -#include "nvim/ex_cmds_defs.h" // for exarg_T +#include "nvim/ex_cmds_defs.h" // for exarg_T +#include "nvim/types.h" // for char_u and expand_T #ifdef INCLUDE_GENERATED_DECLARATIONS # include "if_cscope.h.generated.h" diff --git a/src/nvim/if_cscope_defs.h b/src/nvim/if_cscope_defs.h index d2d8b0fb62..182cbc28e1 100644 --- a/src/nvim/if_cscope_defs.h +++ b/src/nvim/if_cscope_defs.h @@ -13,9 +13,9 @@ # include <sys/types.h> // pid_t #endif -#include "nvim/os/os_defs.h" -#include "nvim/os/fs_defs.h" #include "nvim/ex_cmds_defs.h" +#include "nvim/os/fs_defs.h" +#include "nvim/os/os_defs.h" #define CSCOPE_SUCCESS 0 #define CSCOPE_FAILURE -1 @@ -26,30 +26,30 @@ // See ":help cscope-find" for the possible queries. typedef struct { - char * name; + char *name; int (*func)(exarg_T *eap); - char * help; - char * usage; + char *help; + char *usage; int cansplit; // if supports splitting window } cscmd_T; typedef struct csi { - char * fname; // cscope db name - char * ppath; // path to prepend (the -P option) - char * flags; // additional cscope flags/options (e.g, -p2) + char *fname; // cscope db name + char *ppath; // path to prepend (the -P option) + char *flags; // additional cscope flags/options (e.g, -p2) #if defined(UNIX) pid_t pid; // PID of the connected cscope process #else - DWORD pid; // PID of the connected cscope process - HANDLE hProc; // cscope process handle - DWORD nVolume; // Volume serial number, instead of st_dev - DWORD nIndexHigh; // st_ino has no meaning on Windows - DWORD nIndexLow; + DWORD pid; // PID of the connected cscope process + HANDLE hProc; // cscope process handle + DWORD nVolume; // Volume serial number, instead of st_dev + DWORD nIndexHigh; // st_ino has no meaning on Windows + DWORD nIndexLow; #endif FileID file_id; - FILE * fr_fp; // from cscope: FILE. - FILE * to_fp; // to cscope: FILE. + FILE *fr_fp; // from cscope: FILE. + FILE *to_fp; // to cscope: FILE. } csinfo_T; typedef enum { Add, Find, Help, Kill, Reset, Show } csid_e; diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 609598b678..f49aff6643 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -7,13 +7,14 @@ #include "nvim/ascii.h" #include "nvim/assert.h" +#include "nvim/buffer.h" #include "nvim/change.h" -#include "nvim/indent.h" -#include "nvim/eval.h" #include "nvim/charset.h" #include "nvim/cursor.h" -#include "nvim/mark.h" +#include "nvim/eval.h" #include "nvim/extmark.h" +#include "nvim/indent.h" +#include "nvim/mark.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/misc1.h" @@ -25,7 +26,6 @@ #include "nvim/search.h" #include "nvim/strings.h" #include "nvim/undo.h" -#include "nvim/buffer.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -444,8 +444,8 @@ int get_breakindent_win(win_T *wp, char_u *line) int bri = 0; // window width minus window margin space, i.e. what rests for text const int eff_wwidth = wp->w_width_inner - - ((wp->w_p_nu || wp->w_p_rnu) - && (vim_strchr(p_cpo, CPO_NUMCOL) == NULL) + - ((wp->w_p_nu || wp->w_p_rnu) + && (vim_strchr(p_cpo, CPO_NUMCOL) == NULL) ? number_width(wp) + 1 : 0); // used cached indent, unless pointer or 'tabstop' changed @@ -510,7 +510,7 @@ int get_breakindent_win(win_T *wp, char_u *line) // the line. int inindent(int extra) { - char_u *ptr; + char_u *ptr; colnr_T col; for (col = 0, ptr = get_cursor_line_ptr(); ascii_iswhite(*ptr); ++col) { @@ -533,15 +533,14 @@ int get_expr_indent(void) colnr_T save_curswant; int save_set_curswant; int save_State; - int use_sandbox = was_set_insecurely( - curwin, (char_u *)"indentexpr", OPT_LOCAL); + int use_sandbox = was_set_insecurely(curwin, "indentexpr", OPT_LOCAL); // Save and restore cursor position and curswant, in case it was changed // * via :normal commands. save_pos = curwin->w_cursor; save_curswant = curwin->w_curswant; save_set_curswant = curwin->w_set_curswant; - set_vim_var_nr(VV_LNUM, (varnumber_T) curwin->w_cursor.lnum); + set_vim_var_nr(VV_LNUM, (varnumber_T)curwin->w_cursor.lnum); if (use_sandbox) { sandbox++; @@ -722,11 +721,11 @@ int get_lisp_indent(void) quotecount = 0; if (vi_lisp || ((*that != '"') && (*that != '\'') - && (*that != '#') && ((*that < '0') || (*that > '9')))) { + && (*that != '#') && ((*that < '0') || (*that > '9')))) { while (*that && (!ascii_iswhite(*that) || quotecount || parencount) && (!((*that == '(' || *that == '[') - && !quotecount && !parencount && vi_lisp))) { + && !quotecount && !parencount && vi_lisp))) { if (*that == '"') { quotecount = !quotecount; } diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c index 25c27743f3..3e3e07e9d6 100644 --- a/src/nvim/indent_c.c +++ b/src/nvim/indent_c.c @@ -1,6 +1,8 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +// uncrustify:off + #include <assert.h> #include <inttypes.h> diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c index c6966ff9fa..b724d82f7c 100644 --- a/src/nvim/keymap.c +++ b/src/nvim/keymap.c @@ -5,16 +5,16 @@ #include <inttypes.h> #include <limits.h> -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/keymap.h" #include "nvim/charset.h" -#include "nvim/memory.h" #include "nvim/edit.h" #include "nvim/eval.h" +#include "nvim/keymap.h" +#include "nvim/memory.h" #include "nvim/message.h" -#include "nvim/strings.h" #include "nvim/mouse.h" +#include "nvim/strings.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "keymap.c.generated.h" @@ -51,48 +51,48 @@ static const struct modmasktable { static char_u modifier_keys_table[] = { - /* mod mask with modifier without modifier */ - MOD_MASK_SHIFT, '&', '9', '@', '1', /* begin */ - MOD_MASK_SHIFT, '&', '0', '@', '2', /* cancel */ - MOD_MASK_SHIFT, '*', '1', '@', '4', /* command */ - MOD_MASK_SHIFT, '*', '2', '@', '5', /* copy */ - MOD_MASK_SHIFT, '*', '3', '@', '6', /* create */ - MOD_MASK_SHIFT, '*', '4', 'k', 'D', /* delete char */ - MOD_MASK_SHIFT, '*', '5', 'k', 'L', /* delete line */ - MOD_MASK_SHIFT, '*', '7', '@', '7', /* end */ - MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_END, '@', '7', /* end */ - MOD_MASK_SHIFT, '*', '9', '@', '9', /* exit */ - MOD_MASK_SHIFT, '*', '0', '@', '0', /* find */ - MOD_MASK_SHIFT, '#', '1', '%', '1', /* help */ - MOD_MASK_SHIFT, '#', '2', 'k', 'h', /* home */ - MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_HOME, 'k', 'h', /* home */ - MOD_MASK_SHIFT, '#', '3', 'k', 'I', /* insert */ - MOD_MASK_SHIFT, '#', '4', 'k', 'l', /* left arrow */ - MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_LEFT, 'k', 'l', /* left arrow */ - MOD_MASK_SHIFT, '%', 'a', '%', '3', /* message */ - MOD_MASK_SHIFT, '%', 'b', '%', '4', /* move */ - MOD_MASK_SHIFT, '%', 'c', '%', '5', /* next */ - MOD_MASK_SHIFT, '%', 'd', '%', '7', /* options */ - MOD_MASK_SHIFT, '%', 'e', '%', '8', /* previous */ - MOD_MASK_SHIFT, '%', 'f', '%', '9', /* print */ - MOD_MASK_SHIFT, '%', 'g', '%', '0', /* redo */ - MOD_MASK_SHIFT, '%', 'h', '&', '3', /* replace */ - MOD_MASK_SHIFT, '%', 'i', 'k', 'r', /* right arr. */ - MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_RIGHT, 'k', 'r', /* right arr. */ - MOD_MASK_SHIFT, '%', 'j', '&', '5', /* resume */ - MOD_MASK_SHIFT, '!', '1', '&', '6', /* save */ - MOD_MASK_SHIFT, '!', '2', '&', '7', /* suspend */ - MOD_MASK_SHIFT, '!', '3', '&', '8', /* undo */ - MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_UP, 'k', 'u', /* up arrow */ - MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_DOWN, 'k', 'd', /* down arrow */ - - /* vt100 F1 */ + // mod mask with modifier without modifier + MOD_MASK_SHIFT, '&', '9', '@', '1', // begin + MOD_MASK_SHIFT, '&', '0', '@', '2', // cancel + MOD_MASK_SHIFT, '*', '1', '@', '4', // command + MOD_MASK_SHIFT, '*', '2', '@', '5', // copy + MOD_MASK_SHIFT, '*', '3', '@', '6', // create + MOD_MASK_SHIFT, '*', '4', 'k', 'D', // delete char + MOD_MASK_SHIFT, '*', '5', 'k', 'L', // delete line + MOD_MASK_SHIFT, '*', '7', '@', '7', // end + MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_END, '@', '7', // end + MOD_MASK_SHIFT, '*', '9', '@', '9', // exit + MOD_MASK_SHIFT, '*', '0', '@', '0', // find + MOD_MASK_SHIFT, '#', '1', '%', '1', // help + MOD_MASK_SHIFT, '#', '2', 'k', 'h', // home + MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_HOME, 'k', 'h', // home + MOD_MASK_SHIFT, '#', '3', 'k', 'I', // insert + MOD_MASK_SHIFT, '#', '4', 'k', 'l', // left arrow + MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_LEFT, 'k', 'l', // left arrow + MOD_MASK_SHIFT, '%', 'a', '%', '3', // message + MOD_MASK_SHIFT, '%', 'b', '%', '4', // move + MOD_MASK_SHIFT, '%', 'c', '%', '5', // next + MOD_MASK_SHIFT, '%', 'd', '%', '7', // options + MOD_MASK_SHIFT, '%', 'e', '%', '8', // previous + MOD_MASK_SHIFT, '%', 'f', '%', '9', // print + MOD_MASK_SHIFT, '%', 'g', '%', '0', // redo + MOD_MASK_SHIFT, '%', 'h', '&', '3', // replace + MOD_MASK_SHIFT, '%', 'i', 'k', 'r', // right arr. + MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_RIGHT, 'k', 'r', // right arr. + MOD_MASK_SHIFT, '%', 'j', '&', '5', // resume + MOD_MASK_SHIFT, '!', '1', '&', '6', // save + MOD_MASK_SHIFT, '!', '2', '&', '7', // suspend + MOD_MASK_SHIFT, '!', '3', '&', '8', // undo + MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_UP, 'k', 'u', // up arrow + MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_DOWN, 'k', 'd', // down arrow + + // vt100 F1 MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF1, KS_EXTRA, (int)KE_XF1, MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF2, KS_EXTRA, (int)KE_XF2, MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF3, KS_EXTRA, (int)KE_XF3, MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF4, KS_EXTRA, (int)KE_XF4, - MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F1, 'k', '1', /* F1 */ + MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F1, 'k', '1', // F1 MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F2, 'k', '2', MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F3, 'k', '3', MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F4, 'k', '4', @@ -101,7 +101,7 @@ static char_u modifier_keys_table[] = MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F7, 'k', '7', MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F8, 'k', '8', MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F9, 'k', '9', - MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F10, 'k', ';', /* F10 */ + MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F10, 'k', ';', // F10 MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F11, 'F', '1', MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F12, 'F', '2', @@ -133,7 +133,7 @@ static char_u modifier_keys_table[] = MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F36, 'F', 'Q', MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F37, 'F', 'R', - /* TAB pseudo code*/ + // TAB pseudo code MOD_MASK_SHIFT, 'k', 'B', KS_EXTRA, (int)KE_TAB, NUL @@ -397,22 +397,38 @@ int handle_x_keys(const int key) FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT { switch (key) { - case K_XUP: return K_UP; - case K_XDOWN: return K_DOWN; - case K_XLEFT: return K_LEFT; - case K_XRIGHT: return K_RIGHT; - case K_XHOME: return K_HOME; - case K_ZHOME: return K_HOME; - case K_XEND: return K_END; - case K_ZEND: return K_END; - case K_XF1: return K_F1; - case K_XF2: return K_F2; - case K_XF3: return K_F3; - case K_XF4: return K_F4; - case K_S_XF1: return K_S_F1; - case K_S_XF2: return K_S_F2; - case K_S_XF3: return K_S_F3; - case K_S_XF4: return K_S_F4; + case K_XUP: + return K_UP; + case K_XDOWN: + return K_DOWN; + case K_XLEFT: + return K_LEFT; + case K_XRIGHT: + return K_RIGHT; + case K_XHOME: + return K_HOME; + case K_ZHOME: + return K_HOME; + case K_XEND: + return K_END; + case K_ZEND: + return K_END; + case K_XF1: + return K_F1; + case K_XF2: + return K_F2; + case K_XF3: + return K_F3; + case K_XF4: + return K_F4; + case K_S_XF1: + return K_S_F1; + case K_S_XF2: + return K_S_F2; + case K_S_XF3: + return K_S_F3; + case K_S_XF4: + return K_S_F4; } return key; } @@ -427,31 +443,33 @@ char_u *get_special_key_name(int c, int modifiers) int i, idx; int table_idx; - char_u *s; + char_u *s; string[0] = '<'; idx = 1; - /* Key that stands for a normal character. */ - if (IS_SPECIAL(c) && KEY2TERMCAP0(c) == KS_KEY) + // Key that stands for a normal character. + if (IS_SPECIAL(c) && KEY2TERMCAP0(c) == KS_KEY) { c = KEY2TERMCAP1(c); + } /* * Translate shifted special keys into unshifted keys and set modifier. * Same for CTRL and ALT modifiers. */ if (IS_SPECIAL(c)) { - for (i = 0; modifier_keys_table[i] != 0; i += MOD_KEYS_ENTRY_SIZE) - if ( KEY2TERMCAP0(c) == (int)modifier_keys_table[i + 1] - && (int)KEY2TERMCAP1(c) == (int)modifier_keys_table[i + 2]) { + for (i = 0; modifier_keys_table[i] != 0; i += MOD_KEYS_ENTRY_SIZE) { + if (KEY2TERMCAP0(c) == (int)modifier_keys_table[i + 1] + && (int)KEY2TERMCAP1(c) == (int)modifier_keys_table[i + 2]) { modifiers |= modifier_keys_table[i]; c = TERMCAP2KEY(modifier_keys_table[i + 3], - modifier_keys_table[i + 4]); + modifier_keys_table[i + 4]); break; } + } } - /* try to find the key in the special key table */ + // try to find the key in the special key table table_idx = find_special_key_in_table(c); /* @@ -459,14 +477,13 @@ char_u *get_special_key_name(int c, int modifiers) * extract modifiers. */ if (c > 0 - && (*mb_char2len)(c) == 1 - ) { + && (*mb_char2len)(c) == 1) { if (table_idx < 0 && (!vim_isprintc(c) || (c & 0x7f) == ' ') && (c & 0x80)) { c &= 0x7f; modifiers |= MOD_MASK_ALT; - /* try again, to find the un-alted key in the special key table */ + // try again, to find the un-alted key in the special key table table_idx = find_special_key_in_table(c); } if (table_idx < 0 && !vim_isprintc(c) && c < ' ') { @@ -475,15 +492,16 @@ char_u *get_special_key_name(int c, int modifiers) } } - /* translate the modifier into a string */ - for (i = 0; mod_mask_table[i].name != 'A'; i++) + // translate the modifier into a string + for (i = 0; mod_mask_table[i].name != 'A'; i++) { if ((modifiers & mod_mask_table[i].mod_mask) == mod_mask_table[i].mod_flag) { string[idx++] = mod_mask_table[i].name; string[idx++] = (char_u)'-'; } + } - if (table_idx < 0) { /* unknown special key, may output t_xx */ + if (table_idx < 0) { // unknown special key, may output t_xx if (IS_SPECIAL(c)) { string[idx++] = 't'; string[idx++] = '_'; @@ -497,16 +515,17 @@ char_u *get_special_key_name(int c, int modifiers) string[idx++] = (char_u)c; } else { s = transchar(c); - while (*s) + while (*s) { string[idx++] = *s++; + } } } } else { // use name of special key size_t len = STRLEN(key_names_table[table_idx].name); if ((int)len + idx + 2 <= MAX_KEY_NAME_LEN) { - STRCPY(string + idx, key_names_table[table_idx].name); - idx += (int)len; + STRCPY(string + idx, key_names_table[table_idx].name); + idx += (int)len; } } string[idx++] = '>'; @@ -525,9 +544,8 @@ char_u *get_special_key_name(int c, int modifiers) /// @param[in] in_string Inside a double quoted string /// /// @return Number of characters added to dst, zero for no match. -unsigned int trans_special(const char_u **srcp, const size_t src_len, - char_u *const dst, const bool keycode, - const bool in_string) +unsigned int trans_special(const char_u **srcp, const size_t src_len, char_u *const dst, + const bool keycode, const bool in_string) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { int modifiers = 0; @@ -582,9 +600,8 @@ unsigned int special_to_buf(int key, int modifiers, bool keycode, char_u *dst) /// @param[in] in_string In string, double quote is escaped /// /// @return Key and modifiers or 0 if there is no match. -int find_special_key(const char_u **srcp, const size_t src_len, int *const modp, - const bool keycode, const bool keep_x_key, - const bool in_string) +int find_special_key(const char_u **srcp, const size_t src_len, int *const modp, const bool keycode, + const bool keep_x_key, const bool in_string) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { const char_u *last_dash; @@ -641,7 +658,7 @@ int find_special_key(const char_u **srcp, const size_t src_len, int *const modp, if (bp <= end && *bp == '>') { // found matching '>' end_of_name = bp + 1; - /* Which modifiers are given? */ + // Which modifiers are given? modifiers = 0x0; for (bp = src + 1; bp < last_dash; bp++) { if (*bp != '-') { @@ -795,13 +812,14 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag) { int i; - for (i = 0; mouse_table[i].pseudo_code; i++) + for (i = 0; mouse_table[i].pseudo_code; i++) { if (code == mouse_table[i].pseudo_code) { *is_click = mouse_table[i].is_click; *is_drag = mouse_table[i].is_drag; return mouse_table[i].button; } - return 0; /* Shouldn't get here */ + } + return 0; // Shouldn't get here } /// Replace any terminal code strings with the equivalent internal @@ -829,9 +847,8 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag) /// @return Pointer to an allocated memory in case of success, "from" in case of /// failure. In case of success returned pointer is also saved to /// "bufp". -char_u *replace_termcodes(const char_u *from, const size_t from_len, - char_u **bufp, const bool from_part, const bool do_lt, - const bool special, int cpo_flags) +char_u *replace_termcodes(const char_u *from, const size_t from_len, char_u **bufp, + const bool from_part, const bool do_lt, const bool special, int cpo_flags) FUNC_ATTR_NONNULL_ALL { ssize_t i; @@ -841,7 +858,7 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len, const char_u *src; const char_u *const end = from + from_len - 1; int do_backslash; // backslash is a special character - char_u *result; // buffer for resulting string + char_u *result; // buffer for resulting string do_backslash = !(cpo_flags&FLAG_CPO_BSLASH); @@ -897,7 +914,7 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len, } if (special) { - char_u *p, *s, len; + char_u *p, *s, len; // Replace <Leader> by the value of "mapleader". // Replace <LocalLeader> by the value of "maplocalleader". diff --git a/src/nvim/keymap.h b/src/nvim/keymap.h index 9fc44f6f84..663a7a12ec 100644 --- a/src/nvim/keymap.h +++ b/src/nvim/keymap.h @@ -41,31 +41,31 @@ /* * NUL cannot be in the input string, therefore it is replaced by - * K_SPECIAL KS_ZERO KE_FILLER + * K_SPECIAL KS_ZERO KE_FILLER */ #define KS_ZERO 255 /* * K_SPECIAL cannot be in the input string, therefore it is replaced by - * K_SPECIAL KS_SPECIAL KE_FILLER + * K_SPECIAL KS_SPECIAL KE_FILLER */ #define KS_SPECIAL 254 /* * KS_EXTRA is used for keys that have no termcap name - * K_SPECIAL KS_EXTRA KE_xxx + * K_SPECIAL KS_EXTRA KE_xxx */ #define KS_EXTRA 253 /* * KS_MODIFIER is used when a modifier is given for a (special) key - * K_SPECIAL KS_MODIFIER bitmask + * K_SPECIAL KS_MODIFIER bitmask */ #define KS_MODIFIER 252 /* * These are used for the GUI - * K_SPECIAL KS_xxx KE_FILLER + * K_SPECIAL KS_xxx KE_FILLER */ #define KS_MOUSE 251 #define KS_MENU 250 @@ -122,130 +122,130 @@ // // Entries must be in the range 0x02-0x7f (see comment at K_SPECIAL). enum key_extra { - KE_NAME = 3 // name of this terminal entry - - , KE_S_UP = 4 // shift-up - , KE_S_DOWN = 5 // shift-down - - , KE_S_F1 = 6 // shifted function keys - , KE_S_F2 = 7 - , KE_S_F3 = 8 - , KE_S_F4 = 9 - , KE_S_F5 = 10 - , KE_S_F6 = 11 - , KE_S_F7 = 12 - , KE_S_F8 = 13 - , KE_S_F9 = 14 - , KE_S_F10 = 15 - - , KE_S_F11 = 16 - , KE_S_F12 = 17 - , KE_S_F13 = 18 - , KE_S_F14 = 19 - , KE_S_F15 = 20 - , KE_S_F16 = 21 - , KE_S_F17 = 22 - , KE_S_F18 = 23 - , KE_S_F19 = 24 - , KE_S_F20 = 25 - - , KE_S_F21 = 26 - , KE_S_F22 = 27 - , KE_S_F23 = 28 - , KE_S_F24 = 29 - , KE_S_F25 = 30 - , KE_S_F26 = 31 - , KE_S_F27 = 32 - , KE_S_F28 = 33 - , KE_S_F29 = 34 - , KE_S_F30 = 35 - - , KE_S_F31 = 36 - , KE_S_F32 = 37 - , KE_S_F33 = 38 - , KE_S_F34 = 39 - , KE_S_F35 = 40 - , KE_S_F36 = 41 - , KE_S_F37 = 42 - - , KE_MOUSE = 43 // mouse event start + KE_NAME = 3, // name of this terminal entry + + KE_S_UP = 4, // shift-up + KE_S_DOWN = 5, // shift-down + + KE_S_F1 = 6, // shifted function keys + KE_S_F2 = 7, + KE_S_F3 = 8, + KE_S_F4 = 9, + KE_S_F5 = 10, + KE_S_F6 = 11, + KE_S_F7 = 12, + KE_S_F8 = 13, + KE_S_F9 = 14, + KE_S_F10 = 15, + + KE_S_F11 = 16, + KE_S_F12 = 17, + KE_S_F13 = 18, + KE_S_F14 = 19, + KE_S_F15 = 20, + KE_S_F16 = 21, + KE_S_F17 = 22, + KE_S_F18 = 23, + KE_S_F19 = 24, + KE_S_F20 = 25, + + KE_S_F21 = 26, + KE_S_F22 = 27, + KE_S_F23 = 28, + KE_S_F24 = 29, + KE_S_F25 = 30, + KE_S_F26 = 31, + KE_S_F27 = 32, + KE_S_F28 = 33, + KE_S_F29 = 34, + KE_S_F30 = 35, + + KE_S_F31 = 36, + KE_S_F32 = 37, + KE_S_F33 = 38, + KE_S_F34 = 39, + KE_S_F35 = 40, + KE_S_F36 = 41, + KE_S_F37 = 42, + + KE_MOUSE = 43, // mouse event start // Symbols for pseudo keys which are translated from the real key symbols // above. - , KE_LEFTMOUSE = 44 // Left mouse button click - , KE_LEFTDRAG = 45 // Drag with left mouse button down - , KE_LEFTRELEASE = 46 // Left mouse button release - , KE_MIDDLEMOUSE = 47 // Middle mouse button click - , KE_MIDDLEDRAG = 48 // Drag with middle mouse button down - , KE_MIDDLERELEASE = 49 // Middle mouse button release - , KE_RIGHTMOUSE = 50 // Right mouse button click - , KE_RIGHTDRAG = 51 // Drag with right mouse button down - , KE_RIGHTRELEASE = 52 // Right mouse button release + KE_LEFTMOUSE = 44, // Left mouse button click + KE_LEFTDRAG = 45, // Drag with left mouse button down + KE_LEFTRELEASE = 46, // Left mouse button release + KE_MIDDLEMOUSE = 47, // Middle mouse button click + KE_MIDDLEDRAG = 48, // Drag with middle mouse button down + KE_MIDDLERELEASE = 49, // Middle mouse button release + KE_RIGHTMOUSE = 50, // Right mouse button click + KE_RIGHTDRAG = 51, // Drag with right mouse button down + KE_RIGHTRELEASE = 52, // Right mouse button release - , KE_IGNORE = 53 // Ignored mouse drag/release + KE_IGNORE = 53, // Ignored mouse drag/release - , KE_TAB = 54 // unshifted TAB key - , KE_S_TAB_OLD = 55 // shifted TAB key (no longer used) + KE_TAB = 54, // unshifted TAB key + KE_S_TAB_OLD = 55, // shifted TAB key (no longer used) // , KE_SNIFF_UNUSED = 56 // obsolete - , KE_XF1 = 57 // extra vt100 function keys for xterm - , KE_XF2 = 58 - , KE_XF3 = 59 - , KE_XF4 = 60 - , KE_XEND = 61 // extra (vt100) end key for xterm - , KE_ZEND = 62 // extra (vt100) end key for xterm - , KE_XHOME = 63 // extra (vt100) home key for xterm - , KE_ZHOME = 64 // extra (vt100) home key for xterm - , KE_XUP = 65 // extra vt100 cursor keys for xterm - , KE_XDOWN = 66 - , KE_XLEFT = 67 - , KE_XRIGHT = 68 - - , KE_LEFTMOUSE_NM = 69 // non-mappable Left mouse button click - , KE_LEFTRELEASE_NM = 70 // non-mappable left mouse button release - - , KE_S_XF1 = 71 // vt100 shifted function keys for xterm - , KE_S_XF2 = 72 - , KE_S_XF3 = 73 - , KE_S_XF4 = 74 + KE_XF1 = 57, // extra vt100 function keys for xterm + KE_XF2 = 58, + KE_XF3 = 59, + KE_XF4 = 60, + KE_XEND = 61, // extra (vt100) end key for xterm + KE_ZEND = 62, // extra (vt100) end key for xterm + KE_XHOME = 63, // extra (vt100) home key for xterm + KE_ZHOME = 64, // extra (vt100) home key for xterm + KE_XUP = 65, // extra vt100 cursor keys for xterm + KE_XDOWN = 66, + KE_XLEFT = 67, + KE_XRIGHT = 68, + + KE_LEFTMOUSE_NM = 69, // non-mappable Left mouse button click + KE_LEFTRELEASE_NM = 70, // non-mappable left mouse button release + + KE_S_XF1 = 71, // vt100 shifted function keys for xterm + KE_S_XF2 = 72, + KE_S_XF3 = 73, + KE_S_XF4 = 74, // NOTE: The scroll wheel events are inverted: i.e. UP is the same as // moving the actual scroll wheel down, LEFT is the same as moving the // scroll wheel right. - , KE_MOUSEDOWN = 75 // scroll wheel pseudo-button Down - , KE_MOUSEUP = 76 // scroll wheel pseudo-button Up - , KE_MOUSELEFT = 77 // scroll wheel pseudo-button Left - , KE_MOUSERIGHT = 78 // scroll wheel pseudo-button Right - - , KE_KINS = 79 // keypad Insert key - , KE_KDEL = 80 // keypad Delete key - - , KE_CSI = 81 // CSI typed directly - , KE_SNR = 82 // <SNR> - , KE_PLUG = 83 // <Plug> - , KE_CMDWIN = 84 // open command-line window from Command-line Mode - - , KE_C_LEFT = 85 // control-left - , KE_C_RIGHT = 86 // control-right - , KE_C_HOME = 87 // control-home - , KE_C_END = 88 // control-end - - , KE_X1MOUSE = 89 // X1/X2 mouse-buttons - , KE_X1DRAG = 90 - , KE_X1RELEASE = 91 - , KE_X2MOUSE = 92 - , KE_X2DRAG = 93 - , KE_X2RELEASE = 94 - - , KE_DROP = 95 // DnD data is available + KE_MOUSEDOWN = 75, // scroll wheel pseudo-button Down + KE_MOUSEUP = 76, // scroll wheel pseudo-button Up + KE_MOUSELEFT = 77, // scroll wheel pseudo-button Left + KE_MOUSERIGHT = 78, // scroll wheel pseudo-button Right + + KE_KINS = 79, // keypad Insert key + KE_KDEL = 80, // keypad Delete key + + KE_CSI = 81, // CSI typed directly + KE_SNR = 82, // <SNR> + KE_PLUG = 83, // <Plug> + KE_CMDWIN = 84, // open command-line window from Command-line Mode + + KE_C_LEFT = 85, // control-left + KE_C_RIGHT = 86, // control-right + KE_C_HOME = 87, // control-home + KE_C_END = 88, // control-end + + KE_X1MOUSE = 89, // X1/X2 mouse-buttons + KE_X1DRAG = 90, + KE_X1RELEASE = 91, + KE_X2MOUSE = 92, + KE_X2DRAG = 93, + KE_X2RELEASE = 94, + + KE_DROP = 95, // DnD data is available // , KE_CURSORHOLD = 96 // CursorHold event - , KE_NOP = 97 // no-op: does nothing + KE_NOP = 97, // no-op: does nothing // , KE_FOCUSGAINED = 98 // focus gained // , KE_FOCUSLOST = 99 // focus lost - , KE_MOUSEMOVE = 100 // mouse moved with no button down + KE_MOUSEMOVE = 100, // mouse moved with no button down // , KE_CANCEL = 101 // return from vgetc - , KE_EVENT = 102 // event - , KE_COMMAND = 104 // <Cmd> special key + KE_EVENT = 102, // event + KE_COMMAND = 104 // <Cmd> special key }; /* diff --git a/src/nvim/lib/kbtree.h b/src/nvim/lib/kbtree.h index bef37f8ba9..e2a4e9edea 100644 --- a/src/nvim/lib/kbtree.h +++ b/src/nvim/lib/kbtree.h @@ -34,386 +34,419 @@ #ifndef NVIM_LIB_KBTREE_H #define NVIM_LIB_KBTREE_H +#include <assert.h> +#include <stdint.h> #include <stdlib.h> #include <string.h> -#include <stdint.h> -#include <assert.h> #include "nvim/memory.h" #define KB_MAX_DEPTH 64 -#define __KB_KEY(type, x) (x->key) -#define __KB_PTR(btr, x) (x->ptr) +#define __KB_KEY(type, x) (x->key) +#define __KB_PTR(btr, x) (x->ptr) -#define __KB_TREE_T(name,key_t,T) \ - typedef struct kbnode_##name##_s kbnode_##name##_t; \ - struct kbnode_##name##_s { \ - int32_t n; \ - bool is_internal; \ - key_t key[2*T-1]; \ - kbnode_##name##_t *ptr[]; \ - } ; \ +#define __KB_TREE_T(name, key_t, T) \ + typedef struct kbnode_##name##_s kbnode_##name##_t; \ + struct kbnode_##name##_s { \ + int32_t n; \ + bool is_internal; \ + key_t key[2*T-1]; \ + kbnode_##name##_t *ptr[]; \ + } ; \ \ - typedef struct { \ - kbnode_##name##_t *root; \ - int n_keys, n_nodes; \ - } kbtree_##name##_t; \ + typedef struct { \ + kbnode_##name##_t *root; \ + int n_keys, n_nodes; \ + } kbtree_##name##_t; \ \ - typedef struct { \ - kbnode_##name##_t *x; \ - int i; \ - } kbpos_##name##_t; \ - typedef struct { \ - kbpos_##name##_t stack[KB_MAX_DEPTH], *p; \ - } kbitr_##name##_t; \ + typedef struct { \ + kbnode_##name##_t *x; \ + int i; \ + } kbpos_##name##_t; \ + typedef struct { \ + kbpos_##name##_t stack[KB_MAX_DEPTH], *p; \ + } kbitr_##name##_t; \ -#define __kb_destroy(kbnode_t,b) do { \ - int i; \ - unsigned int max = 8; \ - kbnode_t *x, **top, **stack = 0; \ - if (b->root) { \ - top = stack = (kbnode_t**)xcalloc(max, sizeof(kbnode_t*)); \ - *top++ = (b)->root; \ - while (top != stack) { \ - x = *--top; \ - if (x->is_internal == 0) { XFREE_CLEAR(x); continue; } \ - for (i = 0; i <= x->n; ++i) \ - if (__KB_PTR(b, x)[i]) { \ - if (top - stack == (int)max) { \ - max <<= 1; \ - stack = (kbnode_t**)xrealloc(stack, max * sizeof(kbnode_t*)); \ - top = stack + (max>>1); \ - } \ - *top++ = __KB_PTR(b, x)[i]; \ - } \ - XFREE_CLEAR(x); \ - } \ - } \ - XFREE_CLEAR(stack); \ - } while (0) +#define __kb_destroy(kbnode_t, b) do { \ + int i; \ + unsigned int max = 8; \ + kbnode_t *x, **top, **stack = 0; \ + if (b->root) { \ + top = stack = (kbnode_t **)xcalloc(max, sizeof(kbnode_t *)); \ + *top++ = (b)->root; \ + while (top != stack) { \ + x = *--top; \ + if (x->is_internal == 0) { XFREE_CLEAR(x); continue; } \ + for (i = 0; i <= x->n; ++i) \ + if (__KB_PTR(b, x)[i]) { \ + if (top - stack == (int)max) { \ + max <<= 1; \ + stack = (kbnode_t **)xrealloc(stack, max * sizeof(kbnode_t *)); \ + top = stack + (max>>1); \ + } \ + *top++ = __KB_PTR(b, x)[i]; \ + } \ + XFREE_CLEAR(x); \ + } \ + } \ + XFREE_CLEAR(stack); \ +} while (0) -#define __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \ - static inline int __kb_getp_aux_##name(const kbnode_t * __restrict x, key_t * __restrict k, int *r) \ - { \ - int tr, *rr, begin = 0, end = x->n; \ - if (x->n == 0) return -1; \ - rr = r? r : &tr; \ - while (begin < end) { \ - int mid = (begin + end) >> 1; \ - if (__cmp(__KB_KEY(key_t, x)[mid], *k) < 0) begin = mid + 1; \ - else end = mid; \ - } \ - if (begin == x->n) { *rr = 1; return x->n - 1; } \ - if ((*rr = __cmp(*k, __KB_KEY(key_t, x)[begin])) < 0) --begin; \ - return begin; \ - } +#define __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \ + static inline int __kb_getp_aux_##name(const kbnode_t * __restrict x, key_t * __restrict k, \ + int *r) \ + { \ + int tr, *rr, begin = 0, end = x->n; \ + if (x->n == 0) return -1; \ + rr = r? r : &tr; \ + while (begin < end) { \ + int mid = (begin + end) >> 1; \ + if (__cmp(__KB_KEY(key_t, x)[mid], *k) < 0) begin = mid + 1; \ + else end = mid; \ + } \ + if (begin == x->n) { *rr = 1; return x->n - 1; } \ + if ((*rr = __cmp(*k, __KB_KEY(key_t, x)[begin])) < 0) --begin; \ + return begin; \ + } -#define __KB_GET(name, key_t, kbnode_t) \ - static key_t *kb_getp_##name(kbtree_##name##_t *b, key_t * __restrict k) \ - { \ - if (!b->root) { \ - return 0; \ - } \ - int i, r = 0; \ - kbnode_t *x = b->root; \ - while (x) { \ - i = __kb_getp_aux_##name(x, k, &r); \ - if (i >= 0 && r == 0) return &__KB_KEY(key_t, x)[i]; \ - if (x->is_internal == 0) return 0; \ - x = __KB_PTR(b, x)[i + 1]; \ - } \ - return 0; \ - } \ - static inline key_t *kb_get_##name(kbtree_##name##_t *b, key_t k) \ - { \ - return kb_getp_##name(b, &k); \ - } +#define __KB_GET(name, key_t, kbnode_t) \ + static key_t *kb_getp_##name(kbtree_##name##_t *b, key_t * __restrict k) \ + { \ + if (!b->root) { \ + return 0; \ + } \ + int i, r = 0; \ + kbnode_t *x = b->root; \ + while (x) { \ + i = __kb_getp_aux_##name(x, k, &r); \ + if (i >= 0 && r == 0) return &__KB_KEY(key_t, x)[i]; \ + if (x->is_internal == 0) return 0; \ + x = __KB_PTR(b, x)[i + 1]; \ + } \ + return 0; \ + } \ + static inline key_t *kb_get_##name(kbtree_##name##_t *b, key_t k) \ + { \ + return kb_getp_##name(b, &k); \ + } -#define __KB_INTERVAL(name, key_t, kbnode_t) \ - static inline void kb_intervalp_##name(kbtree_##name##_t *b, key_t * __restrict k, key_t **lower, key_t **upper) \ - { \ - if (!b->root) { \ - return; \ - } \ - int i, r = 0; \ - kbnode_t *x = b->root; \ - *lower = *upper = 0; \ - while (x) { \ - i = __kb_getp_aux_##name(x, k, &r); \ - if (i >= 0 && r == 0) { \ - *lower = *upper = &__KB_KEY(key_t, x)[i]; \ - return; \ - } \ - if (i >= 0) *lower = &__KB_KEY(key_t, x)[i]; \ - if (i < x->n - 1) *upper = &__KB_KEY(key_t, x)[i + 1]; \ - if (x->is_internal == 0) return; \ - x = __KB_PTR(b, x)[i + 1]; \ - } \ - } \ - static inline void kb_interval_##name(kbtree_##name##_t *b, key_t k, key_t **lower, key_t **upper) \ - { \ - kb_intervalp_##name(b, &k, lower, upper); \ - } +#define __KB_INTERVAL(name, key_t, kbnode_t) \ + static inline void kb_intervalp_##name(kbtree_##name##_t *b, key_t * __restrict k, key_t **lower, \ + key_t **upper) \ + { \ + if (!b->root) { \ + return; \ + } \ + int i, r = 0; \ + kbnode_t *x = b->root; \ + *lower = *upper = 0; \ + while (x) { \ + i = __kb_getp_aux_##name(x, k, &r); \ + if (i >= 0 && r == 0) { \ + *lower = *upper = &__KB_KEY(key_t, x)[i]; \ + return; \ + } \ + if (i >= 0) *lower = &__KB_KEY(key_t, x)[i]; \ + if (i < x->n - 1) *upper = &__KB_KEY(key_t, x)[i + 1]; \ + if (x->is_internal == 0) return; \ + x = __KB_PTR(b, x)[i + 1]; \ + } \ + } \ + static inline void kb_interval_##name(kbtree_##name##_t *b, key_t k, key_t **lower, key_t **upper) \ + { \ + kb_intervalp_##name(b, &k, lower, upper); \ + } -#define __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \ - /* x must be an internal node */ \ - static inline void __kb_split_##name(kbtree_##name##_t *b, kbnode_t *x, int i, kbnode_t *y) \ - { \ - kbnode_t *z; \ - z = (kbnode_t*)xcalloc(1, y->is_internal? ILEN : sizeof(kbnode_##name##_t)); \ - ++b->n_nodes; \ - z->is_internal = y->is_internal; \ - z->n = T - 1; \ - memcpy(__KB_KEY(key_t, z), &__KB_KEY(key_t, y)[T], sizeof(key_t) * (T - 1)); \ - if (y->is_internal) memcpy(__KB_PTR(b, z), &__KB_PTR(b, y)[T], sizeof(void*) * T); \ - y->n = T - 1; \ - memmove(&__KB_PTR(b, x)[i + 2], &__KB_PTR(b, x)[i + 1], sizeof(void*) * (unsigned int)(x->n - i)); \ - __KB_PTR(b, x)[i + 1] = z; \ - memmove(&__KB_KEY(key_t, x)[i + 1], &__KB_KEY(key_t, x)[i], sizeof(key_t) * (unsigned int)(x->n - i)); \ - __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[T - 1]; \ - ++x->n; \ - } \ - static inline key_t *__kb_putp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k) \ - { \ - int i = x->n - 1; \ - key_t *ret; \ - if (x->is_internal == 0) { \ - i = __kb_getp_aux_##name(x, k, 0); \ - if (i != x->n - 1) \ - memmove(&__KB_KEY(key_t, x)[i + 2], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \ - ret = &__KB_KEY(key_t, x)[i + 1]; \ - *ret = *k; \ - ++x->n; \ - } else { \ - i = __kb_getp_aux_##name(x, k, 0) + 1; \ - if (__KB_PTR(b, x)[i]->n == 2 * T - 1) { \ - __kb_split_##name(b, x, i, __KB_PTR(b, x)[i]); \ - if (__cmp(*k, __KB_KEY(key_t, x)[i]) > 0) ++i; \ - } \ - ret = __kb_putp_aux_##name(b, __KB_PTR(b, x)[i], k); \ - } \ - return ret; \ - } \ - static inline key_t *kb_putp_##name(kbtree_##name##_t *b, key_t * __restrict k) \ - { \ - if (!b->root) { \ - b->root = (kbnode_t*)xcalloc(1, ILEN); \ - ++b->n_nodes; \ - } \ - kbnode_t *r, *s; \ - ++b->n_keys; \ - r = b->root; \ - if (r->n == 2 * T - 1) { \ - ++b->n_nodes; \ - s = (kbnode_t*)xcalloc(1, ILEN); \ - b->root = s; s->is_internal = 1; s->n = 0; \ - __KB_PTR(b, s)[0] = r; \ - __kb_split_##name(b, s, 0, r); \ - r = s; \ - } \ - return __kb_putp_aux_##name(b, r, k); \ - } \ - static inline void kb_put_##name(kbtree_##name##_t *b, key_t k) \ - { \ - kb_putp_##name(b, &k); \ - } +#define __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \ + /* x must be an internal node */ \ + static inline void __kb_split_##name(kbtree_##name##_t *b, kbnode_t *x, int i, kbnode_t *y) \ + { \ + kbnode_t *z; \ + z = (kbnode_t *)xcalloc(1, y->is_internal? ILEN : sizeof(kbnode_##name##_t)); \ + ++b->n_nodes; \ + z->is_internal = y->is_internal; \ + z->n = T - 1; \ + memcpy(__KB_KEY(key_t, z), &__KB_KEY(key_t, y)[T], sizeof(key_t) * (T - 1)); \ + if (y->is_internal) memcpy(__KB_PTR(b, z), &__KB_PTR(b, y)[T], sizeof(void *) * T); \ + y->n = T - 1; \ + memmove(&__KB_PTR(b, x)[i + 2], &__KB_PTR(b, \ + x)[i + 1], sizeof(void *) * (unsigned int)(x->n - i)); \ + __KB_PTR(b, x)[i + 1] = z; \ + memmove(&__KB_KEY(key_t, x)[i + 1], &__KB_KEY(key_t, x)[i], \ + sizeof(key_t) * (unsigned int)(x->n - i)); \ + __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[T - 1]; \ + ++x->n; \ + } \ + static inline key_t *__kb_putp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k) \ + { \ + int i = x->n - 1; \ + key_t *ret; \ + if (x->is_internal == 0) { \ + i = __kb_getp_aux_##name(x, k, 0); \ + if (i != x->n - 1) \ + memmove(&__KB_KEY(key_t, x)[i + 2], &__KB_KEY(key_t, \ + x)[i + 1], \ + (unsigned int)(x->n - i - 1) * sizeof(key_t)); \ + ret = &__KB_KEY(key_t, x)[i + 1]; \ + *ret = *k; \ + ++x->n; \ + } else { \ + i = __kb_getp_aux_##name(x, k, 0) + 1; \ + if (__KB_PTR(b, x)[i]->n == 2 * T - 1) { \ + __kb_split_##name(b, x, i, __KB_PTR(b, x)[i]); \ + if (__cmp(*k, __KB_KEY(key_t, x)[i]) > 0) ++i; \ + } \ + ret = __kb_putp_aux_##name(b, __KB_PTR(b, x)[i], k); \ + } \ + return ret; \ + } \ + static inline key_t *kb_putp_##name(kbtree_##name##_t *b, key_t * __restrict k) \ + { \ + if (!b->root) { \ + b->root = (kbnode_t *)xcalloc(1, ILEN); \ + ++b->n_nodes; \ + } \ + kbnode_t *r, *s; \ + ++b->n_keys; \ + r = b->root; \ + if (r->n == 2 * T - 1) { \ + ++b->n_nodes; \ + s = (kbnode_t *)xcalloc(1, ILEN); \ + b->root = s; s->is_internal = 1; s->n = 0; \ + __KB_PTR(b, s)[0] = r; \ + __kb_split_##name(b, s, 0, r); \ + r = s; \ + } \ + return __kb_putp_aux_##name(b, r, k); \ + } \ + static inline void kb_put_##name(kbtree_##name##_t *b, key_t k) \ + { \ + kb_putp_##name(b, &k); \ + } -#define __KB_DEL(name, key_t, kbnode_t, T) \ - static inline key_t __kb_delp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k, int s) \ - { \ - int yn, zn, i, r = 0; \ - kbnode_t *xp, *y, *z; \ - key_t kp; \ - if (x == 0) return *k; \ - if (s) { /* s can only be 0, 1 or 2 */ \ - r = x->is_internal == 0? 0 : s == 1? 1 : -1; \ - i = s == 1? x->n - 1 : -1; \ - } else i = __kb_getp_aux_##name(x, k, &r); \ - if (x->is_internal == 0) { \ - if (s == 2) ++i; \ - kp = __KB_KEY(key_t, x)[i]; \ - memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \ - --x->n; \ - return kp; \ - } \ - if (r == 0) { \ - if ((yn = __KB_PTR(b, x)[i]->n) >= T) { \ - xp = __KB_PTR(b, x)[i]; \ - kp = __KB_KEY(key_t, x)[i]; \ - __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 1); \ - return kp; \ - } else if ((zn = __KB_PTR(b, x)[i + 1]->n) >= T) { \ - xp = __KB_PTR(b, x)[i + 1]; \ - kp = __KB_KEY(key_t, x)[i]; \ - __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 2); \ - return kp; \ - } else if (yn == T - 1 && zn == T - 1) { \ - y = __KB_PTR(b, x)[i]; z = __KB_PTR(b, x)[i + 1]; \ - __KB_KEY(key_t, y)[y->n++] = *k; \ - memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, z), (unsigned int)z->n * sizeof(key_t)); \ - if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, z), (unsigned int)(z->n + 1) * sizeof(void*)); \ - y->n += z->n; \ - memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \ - memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, x)[i + 2], (unsigned int)(x->n - i - 1) * sizeof(void*)); \ - --x->n; \ - XFREE_CLEAR(z); \ - return __kb_delp_aux_##name(b, y, k, s); \ - } \ - } \ - ++i; \ - if ((xp = __KB_PTR(b, x)[i])->n == T - 1) { \ - if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n >= T) { \ - memmove(&__KB_KEY(key_t, xp)[1], __KB_KEY(key_t, xp), (unsigned int)xp->n * sizeof(key_t)); \ - if (xp->is_internal) memmove(&__KB_PTR(b, xp)[1], __KB_PTR(b, xp), (unsigned int)(xp->n + 1) * sizeof(void*)); \ - __KB_KEY(key_t, xp)[0] = __KB_KEY(key_t, x)[i - 1]; \ - __KB_KEY(key_t, x)[i - 1] = __KB_KEY(key_t, y)[y->n - 1]; \ - if (xp->is_internal) __KB_PTR(b, xp)[0] = __KB_PTR(b, y)[y->n]; \ - --y->n; ++xp->n; \ - } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n >= T) { \ - __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \ - __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[0]; \ - if (xp->is_internal) __KB_PTR(b, xp)[xp->n] = __KB_PTR(b, y)[0]; \ - --y->n; \ - memmove(__KB_KEY(key_t, y), &__KB_KEY(key_t, y)[1], (unsigned int)y->n * sizeof(key_t)); \ - if (y->is_internal) memmove(__KB_PTR(b, y), &__KB_PTR(b, y)[1], (unsigned int)(y->n + 1) * sizeof(void*)); \ - } else if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n == T - 1) { \ - __KB_KEY(key_t, y)[y->n++] = __KB_KEY(key_t, x)[i - 1]; \ - memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, xp), (unsigned int)xp->n * sizeof(key_t)); \ - if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, xp), (unsigned int)(xp->n + 1) * sizeof(void*)); \ - y->n += xp->n; \ - memmove(&__KB_KEY(key_t, x)[i - 1], &__KB_KEY(key_t, x)[i], (unsigned int)(x->n - i) * sizeof(key_t)); \ - memmove(&__KB_PTR(b, x)[i], &__KB_PTR(b, x)[i + 1], (unsigned int)(x->n - i) * sizeof(void*)); \ - --x->n; \ - XFREE_CLEAR(xp); \ - xp = y; \ - } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n == T - 1) { \ - __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \ - memmove(&__KB_KEY(key_t, xp)[xp->n], __KB_KEY(key_t, y), (unsigned int)y->n * sizeof(key_t)); \ - if (xp->is_internal) memmove(&__KB_PTR(b, xp)[xp->n], __KB_PTR(b, y), (unsigned int)(y->n + 1) * sizeof(void*)); \ - xp->n += y->n; \ - memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \ - memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, x)[i + 2], (unsigned int)(x->n - i - 1) * sizeof(void*)); \ - --x->n; \ - XFREE_CLEAR(y); \ - } \ - } \ - return __kb_delp_aux_##name(b, xp, k, s); \ - } \ - static inline key_t kb_delp_##name(kbtree_##name##_t *b, key_t * __restrict k) \ - { \ - kbnode_t *x; \ - key_t ret; \ - ret = __kb_delp_aux_##name(b, b->root, k, 0); \ - --b->n_keys; \ - if (b->root->n == 0 && b->root->is_internal) { \ - --b->n_nodes; \ - x = b->root; \ - b->root = __KB_PTR(b, x)[0]; \ - XFREE_CLEAR(x); \ - } \ - return ret; \ - } \ - static inline key_t kb_del_##name(kbtree_##name##_t *b, key_t k) \ - { \ - return kb_delp_##name(b, &k); \ - } +#define __KB_DEL(name, key_t, kbnode_t, T) \ + static inline key_t __kb_delp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k, \ + int s) \ + { \ + int yn, zn, i, r = 0; \ + kbnode_t *xp, *y, *z; \ + key_t kp; \ + if (x == 0) return *k; \ + if (s) { /* s can only be 0, 1 or 2 */ \ + r = x->is_internal == 0? 0 : s == 1? 1 : -1; \ + i = s == 1? x->n - 1 : -1; \ + } else i = __kb_getp_aux_##name(x, k, &r); \ + if (x->is_internal == 0) { \ + if (s == 2) ++i; \ + kp = __KB_KEY(key_t, x)[i]; \ + memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, \ + x)[i + 1], \ + (unsigned int)(x->n - i - 1) * sizeof(key_t)); \ + --x->n; \ + return kp; \ + } \ + if (r == 0) { \ + if ((yn = __KB_PTR(b, x)[i]->n) >= T) { \ + xp = __KB_PTR(b, x)[i]; \ + kp = __KB_KEY(key_t, x)[i]; \ + __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 1); \ + return kp; \ + } else if ((zn = __KB_PTR(b, x)[i + 1]->n) >= T) { \ + xp = __KB_PTR(b, x)[i + 1]; \ + kp = __KB_KEY(key_t, x)[i]; \ + __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 2); \ + return kp; \ + } else if (yn == T - 1 && zn == T - 1) { \ + y = __KB_PTR(b, x)[i]; z = __KB_PTR(b, x)[i + 1]; \ + __KB_KEY(key_t, y)[y->n++] = *k; \ + memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, z), (unsigned int)z->n * sizeof(key_t)); \ + if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, \ + z), \ + (unsigned int)(z->n + 1) * sizeof(void *)); \ + y->n += z->n; \ + memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, \ + x)[i + 1], \ + (unsigned int)(x->n - i - 1) * sizeof(key_t)); \ + memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, \ + x)[i + 2], \ + (unsigned int)(x->n - i - 1) * sizeof(void *)); \ + --x->n; \ + XFREE_CLEAR(z); \ + return __kb_delp_aux_##name(b, y, k, s); \ + } \ + } \ + ++i; \ + if ((xp = __KB_PTR(b, x)[i])->n == T - 1) { \ + if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n >= T) { \ + memmove(&__KB_KEY(key_t, xp)[1], __KB_KEY(key_t, xp), (unsigned int)xp->n * sizeof(key_t)); \ + if (xp->is_internal) memmove(&__KB_PTR(b, xp)[1], __KB_PTR(b, \ + xp), \ + (unsigned int)(xp->n + 1) * sizeof(void *)); \ + __KB_KEY(key_t, xp)[0] = __KB_KEY(key_t, x)[i - 1]; \ + __KB_KEY(key_t, x)[i - 1] = __KB_KEY(key_t, y)[y->n - 1]; \ + if (xp->is_internal) __KB_PTR(b, xp)[0] = __KB_PTR(b, y)[y->n]; \ + --y->n; ++xp->n; \ + } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n >= T) { \ + __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \ + __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[0]; \ + if (xp->is_internal) __KB_PTR(b, xp)[xp->n] = __KB_PTR(b, y)[0]; \ + --y->n; \ + memmove(__KB_KEY(key_t, y), &__KB_KEY(key_t, y)[1], (unsigned int)y->n * sizeof(key_t)); \ + if (y->is_internal) memmove(__KB_PTR(b, y), &__KB_PTR(b, \ + y)[1], \ + (unsigned int)(y->n + 1) * sizeof(void *)); \ + } else if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n == T - 1) { \ + __KB_KEY(key_t, y)[y->n++] = __KB_KEY(key_t, x)[i - 1]; \ + memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, xp), \ + (unsigned int)xp->n * sizeof(key_t)); \ + if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, \ + xp), \ + (unsigned int)(xp->n + 1) * sizeof(void *)); \ + y->n += xp->n; \ + memmove(&__KB_KEY(key_t, x)[i - 1], &__KB_KEY(key_t, \ + x)[i], \ + (unsigned int)(x->n - i) * sizeof(key_t)); \ + memmove(&__KB_PTR(b, x)[i], &__KB_PTR(b, \ + x)[i + 1], (unsigned int)(x->n - i) * sizeof(void *)); \ + --x->n; \ + XFREE_CLEAR(xp); \ + xp = y; \ + } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n == T - 1) { \ + __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \ + memmove(&__KB_KEY(key_t, xp)[xp->n], __KB_KEY(key_t, y), \ + (unsigned int)y->n * sizeof(key_t)); \ + if (xp->is_internal) memmove(&__KB_PTR(b, xp)[xp->n], __KB_PTR(b, y), \ + (unsigned int)(y->n + 1) * sizeof(void *)); \ + xp->n += y->n; \ + memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, \ + x)[i + 1], \ + (unsigned int)(x->n - i - 1) * sizeof(key_t)); \ + memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, \ + x)[i + 2], \ + (unsigned int)(x->n - i - 1) * sizeof(void *)); \ + --x->n; \ + XFREE_CLEAR(y); \ + } \ + } \ + return __kb_delp_aux_##name(b, xp, k, s); \ + } \ + static inline key_t kb_delp_##name(kbtree_##name##_t *b, key_t * __restrict k) \ + { \ + kbnode_t *x; \ + key_t ret; \ + ret = __kb_delp_aux_##name(b, b->root, k, 0); \ + --b->n_keys; \ + if (b->root->n == 0 && b->root->is_internal) { \ + --b->n_nodes; \ + x = b->root; \ + b->root = __KB_PTR(b, x)[0]; \ + XFREE_CLEAR(x); \ + } \ + return ret; \ + } \ + static inline key_t kb_del_##name(kbtree_##name##_t *b, key_t k) \ + { \ + return kb_delp_##name(b, &k); \ + } #define __KB_ITR(name, key_t, kbnode_t) \ - static inline void kb_itr_first_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ - { \ - itr->p = NULL; \ - if (b->n_keys == 0) return; \ - itr->p = itr->stack; \ - itr->p->x = b->root; itr->p->i = 0; \ - while (itr->p->x->is_internal && __KB_PTR(b, itr->p->x)[0] != 0) { \ - kbnode_t *x = itr->p->x; \ - ++itr->p; \ - itr->p->x = __KB_PTR(b, x)[0]; itr->p->i = 0; \ - } \ - } \ - static inline int kb_itr_next_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ - { \ - if (itr->p == NULL) return 0; \ - for (;;) { \ - ++itr->p->i; \ - assert(itr->p->i <= 21); \ - while (itr->p->x && itr->p->i <= itr->p->x->n) { \ - itr->p[1].i = 0; \ - itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \ - ++itr->p; \ - } \ - if (itr->p == itr->stack) { \ - itr->p = NULL; \ - return 0; \ - } \ - --itr->p; \ - if (itr->p->x && itr->p->i < itr->p->x->n) return 1; \ - } \ - } \ - static inline int kb_itr_prev_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ - { \ - if (itr->p == NULL) return 0; \ - for (;;) { \ - while (itr->p->x && itr->p->i >= 0) { \ - itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \ - itr->p[1].i = itr->p[1].x ? itr->p[1].x->n : -1; \ - ++itr->p; \ - } \ - if (itr->p == itr->stack) { \ - itr->p = NULL; \ - return 0; \ - } \ - --itr->p; \ - --itr->p->i; \ - if (itr->p->x && itr->p->i >= 0) return 1; \ - } \ - } \ - static inline int kb_itr_getp_##name(kbtree_##name##_t *b, key_t * __restrict k, kbitr_##name##_t *itr) \ - { \ - if (b->n_keys == 0) { \ + static inline void kb_itr_first_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ + { \ + itr->p = NULL; \ + if (b->n_keys == 0) return; \ + itr->p = itr->stack; \ + itr->p->x = b->root; itr->p->i = 0; \ + while (itr->p->x->is_internal && __KB_PTR(b, itr->p->x)[0] != 0) { \ + kbnode_t *x = itr->p->x; \ + ++itr->p; \ + itr->p->x = __KB_PTR(b, x)[0]; itr->p->i = 0; \ + } \ + } \ + static inline int kb_itr_next_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ + { \ + if (itr->p == NULL) return 0; \ + for (;;) { \ + ++itr->p->i; \ + assert(itr->p->i <= 21); \ + while (itr->p->x && itr->p->i <= itr->p->x->n) { \ + itr->p[1].i = 0; \ + itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \ + ++itr->p; \ + } \ + if (itr->p == itr->stack) { \ + itr->p = NULL; \ + return 0; \ + } \ + --itr->p; \ + if (itr->p->x && itr->p->i < itr->p->x->n) return 1; \ + } \ + } \ + static inline int kb_itr_prev_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ + { \ + if (itr->p == NULL) return 0; \ + for (;;) { \ + while (itr->p->x && itr->p->i >= 0) { \ + itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \ + itr->p[1].i = itr->p[1].x ? itr->p[1].x->n : -1; \ + ++itr->p; \ + } \ + if (itr->p == itr->stack) { \ itr->p = NULL; \ return 0; \ - } \ - int i, r = 0; \ - itr->p = itr->stack; \ - itr->p->x = b->root; \ - while (itr->p->x) { \ - i = __kb_getp_aux_##name(itr->p->x, k, &r); \ - itr->p->i = i; \ - if (i >= 0 && r == 0) return 1; \ - ++itr->p->i; \ - assert(itr->p->i <= 21); \ - itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[i + 1] : 0; \ - ++itr->p; \ - } \ - itr->p->i = 0; \ - return 0; \ - } \ - static inline int kb_itr_get_##name(kbtree_##name##_t *b, key_t k, kbitr_##name##_t *itr) \ - { \ - return kb_itr_getp_##name(b,&k,itr); \ - } \ - static inline void kb_del_itr_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ - { \ - key_t k = kb_itr_key(itr); \ - kb_delp_##name(b, &k); \ - kb_itr_getp_##name(b, &k, itr); \ - } + } \ + --itr->p; \ + --itr->p->i; \ + if (itr->p->x && itr->p->i >= 0) return 1; \ + } \ + } \ + static inline int kb_itr_getp_##name(kbtree_##name##_t *b, key_t * __restrict k, \ + kbitr_##name##_t *itr) \ + { \ + if (b->n_keys == 0) { \ + itr->p = NULL; \ + return 0; \ + } \ + int i, r = 0; \ + itr->p = itr->stack; \ + itr->p->x = b->root; \ + while (itr->p->x) { \ + i = __kb_getp_aux_##name(itr->p->x, k, &r); \ + itr->p->i = i; \ + if (i >= 0 && r == 0) return 1; \ + ++itr->p->i; \ + assert(itr->p->i <= 21); \ + itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[i + 1] : 0; \ + ++itr->p; \ + } \ + itr->p->i = 0; \ + return 0; \ + } \ + static inline int kb_itr_get_##name(kbtree_##name##_t *b, key_t k, kbitr_##name##_t *itr) \ + { \ + return kb_itr_getp_##name(b, &k, itr); \ + } \ + static inline void kb_del_itr_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ + { \ + key_t k = kb_itr_key(itr); \ + kb_delp_##name(b, &k); \ + kb_itr_getp_##name(b, &k, itr); \ + } #define KBTREE_INIT(name, key_t, __cmp, T) \ - KBTREE_INIT_IMPL(name, key_t, kbnode_##name##_t, __cmp, T, (sizeof(kbnode_##name##_t)+(2*T)*sizeof(void *))) + KBTREE_INIT_IMPL(name, key_t, kbnode_##name##_t, __cmp, T, \ + (sizeof(kbnode_##name##_t)+(2*T)*sizeof(void *))) -#define KBTREE_INIT_IMPL(name, key_t, kbnode_t, __cmp, T, ILEN) \ - __KB_TREE_T(name, key_t, T) \ - __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \ - __KB_GET(name, key_t, kbnode_t) \ - __KB_INTERVAL(name, key_t, kbnode_t) \ - __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \ - __KB_DEL(name, key_t, kbnode_t, T) \ - __KB_ITR(name, key_t, kbnode_t) +#define KBTREE_INIT_IMPL(name, key_t, kbnode_t, __cmp, T, ILEN) \ + __KB_TREE_T(name, key_t, T) \ + __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \ + __KB_GET(name, key_t, kbnode_t) \ + __KB_INTERVAL(name, key_t, kbnode_t) \ + __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \ + __KB_DEL(name, key_t, kbnode_t, T) \ + __KB_ITR(name, key_t, kbnode_t) #define KB_DEFAULT_SIZE 512 diff --git a/src/nvim/lib/khash.h b/src/nvim/lib/khash.h index c999511543..dd87415144 100644 --- a/src/nvim/lib/khash.h +++ b/src/nvim/lib/khash.h @@ -21,14 +21,14 @@ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ + */ /* - Example: + Example: -#include "nvim/khash.h" -KHASH_MAP_INIT_INT(32, char) -int main() { + #include "nvim/khash.h" + KHASH_MAP_INIT_INT(32, char) + int main() { int ret, is_missing; khiter_t k; khash_t(32) *h = kh_init(32); @@ -42,99 +42,98 @@ int main() { if (kh_exist(h, k)) kh_value(h, k) = 1; kh_destroy(32, h); return 0; -} -*/ + } + */ /* - 2013-05-02 (0.2.8): + 2013-05-02 (0.2.8): - * Use quadratic probing. When the capacity is power of 2, stepping function - i*(i+1)/2 guarantees to traverse each bucket. It is better than double - hashing on cache performance and is more robust than linear probing. + * Use quadratic probing. When the capacity is power of 2, stepping function + i*(i+1)/2 guarantees to traverse each bucket. It is better than double + hashing on cache performance and is more robust than linear probing. - In theory, double hashing should be more robust than quadratic probing. - However, my implementation is probably not for large hash tables, because - the second hash function is closely tied to the first hash function, - which reduce the effectiveness of double hashing. + In theory, double hashing should be more robust than quadratic probing. + However, my implementation is probably not for large hash tables, because + the second hash function is closely tied to the first hash function, + which reduce the effectiveness of double hashing. - Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php + Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php - 2011-12-29 (0.2.7): + 2011-12-29 (0.2.7): - * Minor code clean up; no actual effect. + * Minor code clean up; no actual effect. - 2011-09-16 (0.2.6): + 2011-09-16 (0.2.6): - * The capacity is a power of 2. This seems to dramatically improve the - speed for simple keys. Thank Zilong Tan for the suggestion. Reference: + * The capacity is a power of 2. This seems to dramatically improve the + speed for simple keys. Thank Zilong Tan for the suggestion. Reference: - - http://code.google.com/p/ulib/ - - http://nothings.org/computer/judy/ + - http://code.google.com/p/ulib/ + - http://nothings.org/computer/judy/ - * Allow to optionally use linear probing which usually has better - performance for random input. Double hashing is still the default as it - is more robust to certain non-random input. + * Allow to optionally use linear probing which usually has better + performance for random input. Double hashing is still the default as it + is more robust to certain non-random input. - * Added Wang's integer hash function (not used by default). This hash - function is more robust to certain non-random input. + * Added Wang's integer hash function (not used by default). This hash + function is more robust to certain non-random input. - 2011-02-14 (0.2.5): + 2011-02-14 (0.2.5): - * Allow to declare global functions. + * Allow to declare global functions. - 2009-09-26 (0.2.4): + 2009-09-26 (0.2.4): - * Improve portability + * Improve portability - 2008-09-19 (0.2.3): + 2008-09-19 (0.2.3): - * Corrected the example - * Improved interfaces + * Corrected the example + * Improved interfaces - 2008-09-11 (0.2.2): + 2008-09-11 (0.2.2): - * Improved speed a little in kh_put() + * Improved speed a little in kh_put() - 2008-09-10 (0.2.1): + 2008-09-10 (0.2.1): - * Added kh_clear() - * Fixed a compiling error + * Added kh_clear() + * Fixed a compiling error - 2008-09-02 (0.2.0): + 2008-09-02 (0.2.0): - * Changed to token concatenation which increases flexibility. + * Changed to token concatenation which increases flexibility. - 2008-08-31 (0.1.2): + 2008-08-31 (0.1.2): - * Fixed a bug in kh_get(), which has not been tested previously. + * Fixed a bug in kh_get(), which has not been tested previously. - 2008-08-31 (0.1.1): + 2008-08-31 (0.1.1): - * Added destructor -*/ + * Added destructor + */ #ifndef NVIM_LIB_KHASH_H #define NVIM_LIB_KHASH_H /*! - @header + @header - Generic hash table library. + Generic hash table library. */ #define AC_VERSION_KHASH_H "0.2.8" -#include <stdlib.h> -#include <string.h> #include <limits.h> #include <stdint.h> - -#include "nvim/memory.h" +#include <stdlib.h> +#include <string.h> #include "nvim/func_attr.h" +#include "nvim/memory.h" -/* compiler specific configuration */ +// compiler specific configuration #if UINT_MAX == 0xffffffffu typedef unsigned int khint32_t; @@ -149,9 +148,9 @@ typedef unsigned long long khint64_t; #endif #ifdef _MSC_VER -#define kh_inline __inline +# define kh_inline __inline #else -#define kh_inline inline +# define kh_inline inline #endif typedef khint32_t khint_t; @@ -168,31 +167,32 @@ typedef khint_t khiter_t; #define __ac_fsize(m) ((m) < 16? 1 : (m)>>4) #ifndef kroundup32 -#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +# define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, \ + ++(x)) #endif #ifndef kcalloc -#define kcalloc(N,Z) xcalloc(N,Z) +# define kcalloc(N, Z) xcalloc(N, Z) #endif #ifndef kmalloc -#define kmalloc(Z) xmalloc(Z) +# define kmalloc(Z) xmalloc(Z) #endif #ifndef krealloc -#define krealloc(P,Z) xrealloc(P,Z) +# define krealloc(P, Z) xrealloc(P, Z) #endif #ifndef kfree -#define kfree(P) XFREE_CLEAR(P) +# define kfree(P) XFREE_CLEAR(P) #endif #define __ac_HASH_UPPER 0.77 #define __KHASH_TYPE(name, khkey_t, khval_t) \ - typedef struct { \ - khint_t n_buckets, size, n_occupied, upper_bound; \ - khint32_t *flags; \ - khkey_t *keys; \ - khval_t *vals; \ - } kh_##name##_t; + typedef struct { \ + khint_t n_buckets, size, n_occupied, upper_bound; \ + khint32_t *flags; \ + khkey_t *keys; \ + khval_t *vals; \ + } kh_##name##_t; #define __KHASH_PROTOTYPES(name, khkey_t, khval_t) \ extern kh_##name##_t *kh_init_##name(void); \ @@ -207,12 +207,12 @@ typedef khint_t khiter_t; #define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, \ __hash_equal) \ SCOPE kh_##name##_t *kh_init_##name(void) \ - REAL_FATTR_UNUSED; \ + REAL_FATTR_UNUSED; \ SCOPE kh_##name##_t *kh_init_##name(void) { \ - return (kh_##name##_t*)kcalloc(1, sizeof(kh_##name##_t)); \ + return (kh_##name##_t *)kcalloc(1, sizeof(kh_##name##_t)); \ } \ SCOPE void kh_dealloc_##name(kh_##name##_t *h) \ - REAL_FATTR_UNUSED; \ + REAL_FATTR_UNUSED; \ SCOPE void kh_dealloc_##name(kh_##name##_t *h) \ { \ kfree(h->keys); \ @@ -220,7 +220,7 @@ typedef khint_t khiter_t; kfree(h->vals); \ } \ SCOPE void kh_destroy_##name(kh_##name##_t *h) \ - REAL_FATTR_UNUSED; \ + REAL_FATTR_UNUSED; \ SCOPE void kh_destroy_##name(kh_##name##_t *h) \ { \ if (h) { \ @@ -229,7 +229,7 @@ typedef khint_t khiter_t; } \ } \ SCOPE void kh_clear_##name(kh_##name##_t *h) \ - REAL_FATTR_UNUSED; \ + REAL_FATTR_UNUSED; \ SCOPE void kh_clear_##name(kh_##name##_t *h) \ { \ if (h && h->flags) { \ @@ -238,7 +238,7 @@ typedef khint_t khiter_t; } \ } \ SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \ - REAL_FATTR_UNUSED; \ + REAL_FATTR_UNUSED; \ SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \ { \ if (h->n_buckets) { \ @@ -259,10 +259,10 @@ typedef khint_t khiter_t; } \ } \ SCOPE void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ - REAL_FATTR_UNUSED; \ + REAL_FATTR_UNUSED; \ SCOPE void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ - { /* This function uses 0.25*n_buckets bytes of working space instead of */ \ - /* [sizeof(key_t+val_t)+.25]*n_buckets. */ \ + { /* This function uses 0.25*n_buckets bytes of working space instead of */ \ + /* [sizeof(key_t+val_t)+.25]*n_buckets. */ \ khint32_t *new_flags = 0; \ khint_t j = 1; \ { \ @@ -273,24 +273,23 @@ typedef khint_t khiter_t; /* requested size is too small */ \ if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) { \ j = 0; \ - } else { /* hash table size to be changed (shrink or expand); rehash */ \ - new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) \ - * sizeof(khint32_t)); \ + } else { /* hash table size to be changed (shrink or expand); rehash */ \ + new_flags = (khint32_t *)kmalloc(__ac_fsize(new_n_buckets) \ + * sizeof(khint32_t)); \ memset(new_flags, 0xaa, \ __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ - if (h->n_buckets < new_n_buckets) { /* expand */ \ - khkey_t *new_keys = (khkey_t*)krealloc( \ - (void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ + if (h->n_buckets < new_n_buckets) { /* expand */ \ + khkey_t *new_keys = (khkey_t *)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ h->keys = new_keys; \ if (kh_is_map) { \ - khval_t *new_vals = (khval_t*)krealloc( \ - (void *)h->vals, new_n_buckets * sizeof(khval_t)); \ + khval_t *new_vals = \ + (khval_t *)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ h->vals = new_vals; \ } \ - } /* otherwise shrink */ \ + } /* otherwise shrink */ \ } \ } \ - if (j) { /* rehashing is needed */ \ + if (j) { /* rehashing is needed */ \ for (j = 0; j != h->n_buckets; ++j) { \ if (__ac_iseither(h->flags, j) == 0) { \ khkey_t key = h->keys[j]; \ @@ -324,7 +323,7 @@ typedef khint_t khiter_t; } \ /* mark it as deleted in the old hash table */ \ __ac_set_isdel_true(h->flags, i); \ - } else { /* write the element and jump out of the loop */ \ + } else { /* write the element and jump out of the loop */ \ h->keys[i] = key; \ if (kh_is_map) { \ h->vals[i] = val; \ @@ -334,15 +333,15 @@ typedef khint_t khiter_t; } \ } \ } \ - if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \ - h->keys = (khkey_t*)krealloc((void *)h->keys, \ - new_n_buckets * sizeof(khkey_t)); \ + if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \ + h->keys = (khkey_t *)krealloc((void *)h->keys, \ + new_n_buckets * sizeof(khkey_t)); \ if (kh_is_map) { \ - h->vals = (khval_t*)krealloc((void *)h->vals, \ - new_n_buckets * sizeof(khval_t)); \ + h->vals = (khval_t *)krealloc((void *)h->vals, \ + new_n_buckets * sizeof(khval_t)); \ } \ } \ - kfree(h->flags); /* free the working space */ \ + kfree(h->flags); /* free the working space */ \ h->flags = new_flags; \ h->n_buckets = new_n_buckets; \ h->n_occupied = h->size; \ @@ -350,25 +349,25 @@ typedef khint_t khiter_t; } \ } \ SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \ - REAL_FATTR_UNUSED; \ + REAL_FATTR_UNUSED; \ SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \ { \ khint_t x; \ - if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \ + if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \ if (h->n_buckets > (h->size << 1)) { \ - kh_resize_##name(h, h->n_buckets - 1); /* clear "deleted" elements */ \ + kh_resize_##name(h, h->n_buckets - 1); /* clear "deleted" elements */ \ } else { \ - kh_resize_##name(h, h->n_buckets + 1); /* expand the hash table */ \ + kh_resize_##name(h, h->n_buckets + 1); /* expand the hash table */ \ } \ - } /* TODO: implement automatically shrinking; */ \ - /* resize() already support shrinking */ \ + } /* TODO: implement automatically shrinking; */ \ + /* resize() already support shrinking */ \ { \ khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \ x = site = h->n_buckets; \ k = __hash_func(key); \ i = k & mask; \ if (__ac_isempty(h->flags, i)) { \ - x = i; /* for speed up */ \ + x = i; /* for speed up */ \ } else { \ last = i; \ while (!__ac_isempty(h->flags, i) \ @@ -392,24 +391,24 @@ typedef khint_t khiter_t; } \ } \ } \ - if (__ac_isempty(h->flags, x)) { /* not present at all */ \ + if (__ac_isempty(h->flags, x)) { /* not present at all */ \ h->keys[x] = key; \ __ac_set_isboth_false(h->flags, x); \ h->size++; \ h->n_occupied++; \ *ret = 1; \ - } else if (__ac_isdel(h->flags, x)) { /* deleted */ \ + } else if (__ac_isdel(h->flags, x)) { /* deleted */ \ h->keys[x] = key; \ __ac_set_isboth_false(h->flags, x); \ h->size++; \ *ret = 2; \ } else { \ - *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \ + *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \ } \ return x; \ } \ SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \ - REAL_FATTR_UNUSED; \ + REAL_FATTR_UNUSED; \ SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \ { \ if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \ @@ -418,240 +417,242 @@ typedef khint_t khiter_t; } \ } -#define KHASH_DECLARE(name, khkey_t, khval_t) \ - __KHASH_TYPE(name, khkey_t, khval_t) \ - __KHASH_PROTOTYPES(name, khkey_t, khval_t) +#define KHASH_DECLARE(name, khkey_t, khval_t) \ + __KHASH_TYPE(name, khkey_t, khval_t) \ + __KHASH_PROTOTYPES(name, khkey_t, khval_t) #define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ - __KHASH_TYPE(name, khkey_t, khval_t) \ - __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) + __KHASH_TYPE(name, khkey_t, khval_t) \ + __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) #define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ - KHASH_INIT2(name, static kh_inline, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) + KHASH_INIT2(name, static kh_inline, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) -/* --- BEGIN OF HASH FUNCTIONS --- */ +// --- BEGIN OF HASH FUNCTIONS --- /*! @function - @abstract Integer hash function - @param key The integer [khint32_t] - @return The hash value [khint_t] + @abstract Integer hash function + @param key The integer [khint32_t] + @return The hash value [khint_t] */ #define kh_int_hash_func(key) (khint32_t)(key) /*! @function - @abstract Integer comparison function + @abstract Integer comparison function */ #define kh_int_hash_equal(a, b) ((a) == (b)) /*! @function - @abstract 64-bit integer hash function - @param key The integer [khint64_t] - @return The hash value [khint_t] + @abstract 64-bit integer hash function + @param key The integer [khint64_t] + @return The hash value [khint_t] */ #define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11) /*! @function - @abstract 64-bit integer comparison function + @abstract 64-bit integer comparison function */ #define kh_int64_hash_equal(a, b) ((a) == (b)) /*! @function - @abstract const char* hash function - @param s Pointer to a null terminated string - @return The hash value + @abstract const char* hash function + @param s Pointer to a null terminated string + @return The hash value */ static kh_inline khint_t __ac_X31_hash_string(const char *s) { - khint_t h = (khint_t)*s; - if (h) for (++s ; *s; ++s) h = (h << 5) - h + (uint8_t)*s; - return h; + khint_t h = (khint_t)*s; + if (h) { + for (++s ; *s; ++s) { h = (h << 5) - h + (uint8_t)*s; } + } + return h; } /*! @function - @abstract Another interface to const char* hash function - @param key Pointer to a null terminated string [const char*] - @return The hash value [khint_t] + @abstract Another interface to const char* hash function + @param key Pointer to a null terminated string [const char*] + @return The hash value [khint_t] */ #define kh_str_hash_func(key) __ac_X31_hash_string(key) /*! @function - @abstract Const char* comparison function + @abstract Const char* comparison function */ #define kh_str_hash_equal(a, b) (strcmp(a, b) == 0) static kh_inline khint_t __ac_Wang_hash(khint_t key) { - key += ~(key << 15); - key ^= (key >> 10); - key += (key << 3); - key ^= (key >> 6); - key += ~(key << 11); - key ^= (key >> 16); - return key; + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key; } #define kh_int_hash_func2(k) __ac_Wang_hash((khint_t)key) -/* --- END OF HASH FUNCTIONS --- */ +// --- END OF HASH FUNCTIONS --- -/* Other convenient macros... */ +// Other convenient macros... /*! - @abstract Type of the hash table. - @param name Name of the hash table [symbol] + @abstract Type of the hash table. + @param name Name of the hash table [symbol] */ #define khash_t(name) kh_##name##_t /*! @function - @abstract Initiate a hash table. - @param name Name of the hash table [symbol] - @return Pointer to the hash table [khash_t(name)*] + @abstract Initiate a hash table. + @param name Name of the hash table [symbol] + @return Pointer to the hash table [khash_t(name)*] */ #define kh_init(name) kh_init_##name() /*! @function - @abstract Destroy a hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] + @abstract Destroy a hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] */ #define kh_destroy(name, h) kh_destroy_##name(h) /*! @function - @abstract Free memory referenced directly inside a hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] + @abstract Free memory referenced directly inside a hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] */ #define kh_dealloc(name, h) kh_dealloc_##name(h) /*! @function - @abstract Reset a hash table without deallocating memory. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] + @abstract Reset a hash table without deallocating memory. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] */ #define kh_clear(name, h) kh_clear_##name(h) /*! @function - @abstract Resize a hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - @param s New size [khint_t] + @abstract Resize a hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param s New size [khint_t] */ #define kh_resize(name, h, s) kh_resize_##name(h, s) /*! @function - @abstract Insert a key to the hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - @param k Key [type of keys] - @param r Extra return code: -1 if the operation failed; + @abstract Insert a key to the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Key [type of keys] + @param r Extra return code: -1 if the operation failed; 0 if the key is present in the hash table; 1 if the bucket is empty (never used); 2 if the element in the bucket has been deleted [int*] - @return Iterator to the inserted element [khint_t] + @return Iterator to the inserted element [khint_t] */ #define kh_put(name, h, k, r) kh_put_##name(h, k, r) /*! @function - @abstract Retrieve a key from the hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - @param k Key [type of keys] - @return Iterator to the found element, or kh_end(h) if the element is absent [khint_t] + @abstract Retrieve a key from the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Key [type of keys] + @return Iterator to the found element, or kh_end(h) if the element is absent [khint_t] */ #define kh_get(name, h, k) kh_get_##name(h, k) /*! @function - @abstract Remove a key from the hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - @param k Iterator to the element to be deleted [khint_t] + @abstract Remove a key from the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Iterator to the element to be deleted [khint_t] */ #define kh_del(name, h, k) kh_del_##name(h, k) /*! @function - @abstract Test whether a bucket contains data. - @param h Pointer to the hash table [khash_t(name)*] - @param x Iterator to the bucket [khint_t] - @return 1 if containing data; 0 otherwise [int] + @abstract Test whether a bucket contains data. + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return 1 if containing data; 0 otherwise [int] */ #define kh_exist(h, x) (!__ac_iseither((h)->flags, (x))) /*! @function - @abstract Get key given an iterator - @param h Pointer to the hash table [khash_t(name)*] - @param x Iterator to the bucket [khint_t] - @return Key [type of keys] + @abstract Get key given an iterator + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return Key [type of keys] */ #define kh_key(h, x) ((h)->keys[x]) /*! @function - @abstract Get value given an iterator - @param h Pointer to the hash table [khash_t(name)*] - @param x Iterator to the bucket [khint_t] - @return Value [type of values] - @discussion For hash sets, calling this results in segfault. + @abstract Get value given an iterator + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return Value [type of values] + @discussion For hash sets, calling this results in segfault. */ #define kh_val(h, x) ((h)->vals[x]) /*! @function - @abstract Alias of kh_val() + @abstract Alias of kh_val() */ #define kh_value(h, x) ((h)->vals[x]) /*! @function - @abstract Get the start iterator - @param h Pointer to the hash table [khash_t(name)*] - @return The start iterator [khint_t] + @abstract Get the start iterator + @param h Pointer to the hash table [khash_t(name)*] + @return The start iterator [khint_t] */ #define kh_begin(h) (khint_t)(0) /*! @function - @abstract Get the end iterator - @param h Pointer to the hash table [khash_t(name)*] - @return The end iterator [khint_t] + @abstract Get the end iterator + @param h Pointer to the hash table [khash_t(name)*] + @return The end iterator [khint_t] */ #define kh_end(h) ((h)->n_buckets) /*! @function - @abstract Get the number of elements in the hash table - @param h Pointer to the hash table [khash_t(name)*] - @return Number of elements in the hash table [khint_t] + @abstract Get the number of elements in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @return Number of elements in the hash table [khint_t] */ #define kh_size(h) ((h)->size) /*! @function - @abstract Get the number of buckets in the hash table - @param h Pointer to the hash table [khash_t(name)*] - @return Number of buckets in the hash table [khint_t] + @abstract Get the number of buckets in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @return Number of buckets in the hash table [khint_t] */ #define kh_n_buckets(h) ((h)->n_buckets) /*! @function - @abstract Iterate over the entries in the hash table - @param h Pointer to the hash table [khash_t(name)*] - @param kvar Variable to which key will be assigned - @param vvar Variable to which value will be assigned - @param code Block of code to execute + @abstract Iterate over the entries in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @param kvar Variable to which key will be assigned + @param vvar Variable to which value will be assigned + @param code Block of code to execute */ -#define kh_foreach(h, kvar, vvar, code) { khint_t __i; \ - for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ - if (!kh_exist(h,__i)) continue; \ - (kvar) = kh_key(h,__i); \ - (vvar) = kh_val(h,__i); \ - code; \ - } } +#define kh_foreach(h, kvar, vvar, code) { khint_t __i; \ + for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ + if (!kh_exist(h, __i)) continue; \ + (kvar) = kh_key(h, __i); \ + (vvar) = kh_val(h, __i); \ + code; \ + } } /*! @function - @abstract Iterate over the values in the hash table - @param h Pointer to the hash table [khash_t(name)*] - @param vvar Variable to which value will be assigned - @param code Block of code to execute + @abstract Iterate over the values in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @param vvar Variable to which value will be assigned + @param code Block of code to execute */ -#define kh_foreach_value(h, vvar, code) { khint_t __i; \ - for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ - if (!kh_exist(h,__i)) continue; \ - (vvar) = kh_val(h,__i); \ - code; \ - } } +#define kh_foreach_value(h, vvar, code) { khint_t __i; \ + for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ + if (!kh_exist(h, __i)) continue; \ + (vvar) = kh_val(h, __i); \ + code; \ + } } /*! @function - @abstract Iterate over the keys in the hash table - @param h Pointer to the hash table [khash_t(name)*] - @param kvar Variable to which value will be assigned - @param code Block of code to execute + @abstract Iterate over the keys in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @param kvar Variable to which value will be assigned + @param code Block of code to execute */ #define kh_foreach_key(h, kvar, code) \ { \ @@ -665,57 +666,57 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key) } \ } -/* More conenient interfaces */ +// More conenient interfaces /*! @function - @abstract Instantiate a hash set containing integer keys - @param name Name of the hash table [symbol] + @abstract Instantiate a hash set containing integer keys + @param name Name of the hash table [symbol] */ -#define KHASH_SET_INIT_INT(name) \ - KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal) +#define KHASH_SET_INIT_INT(name) \ + KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal) /*! @function - @abstract Instantiate a hash map containing integer keys - @param name Name of the hash table [symbol] - @param khval_t Type of values [type] + @abstract Instantiate a hash map containing integer keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] */ -#define KHASH_MAP_INIT_INT(name, khval_t) \ - KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal) +#define KHASH_MAP_INIT_INT(name, khval_t) \ + KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal) /*! @function - @abstract Instantiate a hash map containing 64-bit integer keys - @param name Name of the hash table [symbol] + @abstract Instantiate a hash map containing 64-bit integer keys + @param name Name of the hash table [symbol] */ -#define KHASH_SET_INIT_INT64(name) \ - KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal) +#define KHASH_SET_INIT_INT64(name) \ + KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal) /*! @function - @abstract Instantiate a hash map containing 64-bit integer keys - @param name Name of the hash table [symbol] - @param khval_t Type of values [type] + @abstract Instantiate a hash map containing 64-bit integer keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] */ -#define KHASH_MAP_INIT_INT64(name, khval_t) \ - KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal) +#define KHASH_MAP_INIT_INT64(name, khval_t) \ + KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal) typedef const char *kh_cstr_t; /*! @function - @abstract Instantiate a hash map containing const char* keys - @param name Name of the hash table [symbol] + @abstract Instantiate a hash map containing const char* keys + @param name Name of the hash table [symbol] */ -#define KHASH_SET_INIT_STR(name) \ - KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal) +#define KHASH_SET_INIT_STR(name) \ + KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal) /*! @function - @abstract Instantiate a hash map containing const char* keys - @param name Name of the hash table [symbol] - @param khval_t Type of values [type] + @abstract Instantiate a hash map containing const char* keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] */ #define KHASH_MAP_INIT_STR(name, khval_t) \ KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal) /*! @function - @abstract Return a literal for an empty hash table. - @param name Name of the hash table [symbol] + @abstract Return a literal for an empty hash table. + @param name Name of the hash table [symbol] */ #define KHASH_EMPTY_TABLE(name) \ ((kh_##name##_t) { \ diff --git a/src/nvim/lib/klist.h b/src/nvim/lib/klist.h index b80f4be3c2..c8489e298b 100644 --- a/src/nvim/lib/klist.h +++ b/src/nvim/lib/klist.h @@ -21,50 +21,50 @@ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ + */ #ifndef _AC_KLIST_H #define _AC_KLIST_H -#include <stdlib.h> #include <assert.h> +#include <stdlib.h> -#include "nvim/memory.h" #include "nvim/func_attr.h" +#include "nvim/memory.h" #define KMEMPOOL_INIT(name, kmptype_t, kmpfree_f) \ - typedef struct { \ - size_t cnt, n, max; \ - kmptype_t **buf; \ - } kmp_##name##_t; \ - static inline kmp_##name##_t *kmp_init_##name(void) { \ - return xcalloc(1, sizeof(kmp_##name##_t)); \ + typedef struct { \ + size_t cnt, n, max; \ + kmptype_t **buf; \ + } kmp_##name##_t; \ + static inline kmp_##name##_t *kmp_init_##name(void) { \ + return xcalloc(1, sizeof(kmp_##name##_t)); \ + } \ + static inline void kmp_destroy_##name(kmp_##name##_t *mp) \ + REAL_FATTR_UNUSED; \ + static inline void kmp_destroy_##name(kmp_##name##_t *mp) { \ + size_t k; \ + for (k = 0; k < mp->n; k++) { \ + kmpfree_f(mp->buf[k]); XFREE_CLEAR(mp->buf[k]); \ } \ - static inline void kmp_destroy_##name(kmp_##name##_t *mp) \ - REAL_FATTR_UNUSED; \ - static inline void kmp_destroy_##name(kmp_##name##_t *mp) { \ - size_t k; \ - for (k = 0; k < mp->n; k++) { \ - kmpfree_f(mp->buf[k]); XFREE_CLEAR(mp->buf[k]); \ - } \ - XFREE_CLEAR(mp->buf); XFREE_CLEAR(mp); \ + XFREE_CLEAR(mp->buf); XFREE_CLEAR(mp); \ + } \ + static inline kmptype_t *kmp_alloc_##name(kmp_##name##_t *mp) { \ + mp->cnt++; \ + if (mp->n == 0) { \ + return xcalloc(1, sizeof(kmptype_t)); \ } \ - static inline kmptype_t *kmp_alloc_##name(kmp_##name##_t *mp) { \ - mp->cnt++; \ - if (mp->n == 0) { \ - return xcalloc(1, sizeof(kmptype_t)); \ - } \ - return mp->buf[--mp->n]; \ + return mp->buf[--mp->n]; \ + } \ + static inline void kmp_free_##name(kmp_##name##_t *mp, kmptype_t *p) { \ + mp->cnt--; \ + if (mp->n == mp->max) { \ + mp->max = mp->max ? (mp->max << 1) : 16; \ + mp->buf = xrealloc(mp->buf, sizeof(kmptype_t *) * mp->max); \ } \ - static inline void kmp_free_##name(kmp_##name##_t *mp, kmptype_t *p) { \ - mp->cnt--; \ - if (mp->n == mp->max) { \ - mp->max = mp->max ? (mp->max << 1) : 16; \ - mp->buf = xrealloc(mp->buf, sizeof(kmptype_t *) * mp->max); \ - } \ - mp->buf[mp->n++] = p; \ - } + mp->buf[mp->n++] = p; \ + } #define kmempool_t(name) kmp_##name##_t #define kmp_init(name) kmp_init_##name() @@ -73,55 +73,55 @@ #define kmp_free(name, mp, p) kmp_free_##name(mp, p) #define KLIST_INIT(name, kltype_t, kmpfree_t) \ - struct __kl1_##name { \ - kltype_t data; \ - struct __kl1_##name *next; \ - }; \ - typedef struct __kl1_##name kl1_##name; \ - KMEMPOOL_INIT(name, kl1_##name, kmpfree_t) \ - typedef struct { \ - kl1_##name *head, *tail; \ - kmp_##name##_t *mp; \ - size_t size; \ - } kl_##name##_t; \ - static inline kl_##name##_t *kl_init_##name(void) { \ - kl_##name##_t *kl = xcalloc(1, sizeof(kl_##name##_t)); \ - kl->mp = kmp_init(name); \ - kl->head = kl->tail = kmp_alloc(name, kl->mp); \ - kl->head->next = 0; \ - return kl; \ - } \ - static inline void kl_destroy_##name(kl_##name##_t *kl) \ - REAL_FATTR_UNUSED; \ - static inline void kl_destroy_##name(kl_##name##_t *kl) { \ - kl1_##name *p; \ - for (p = kl->head; p != kl->tail; p = p->next) { \ - kmp_free(name, kl->mp, p); \ - } \ - kmp_free(name, kl->mp, p); \ - kmp_destroy(name, kl->mp); \ - XFREE_CLEAR(kl); \ + struct __kl1_##name { \ + kltype_t data; \ + struct __kl1_##name *next; \ + }; \ + typedef struct __kl1_##name kl1_##name; \ + KMEMPOOL_INIT(name, kl1_##name, kmpfree_t) \ + typedef struct { \ + kl1_##name *head, *tail; \ + kmp_##name##_t *mp; \ + size_t size; \ + } kl_##name##_t; \ + static inline kl_##name##_t *kl_init_##name(void) { \ + kl_##name##_t *kl = xcalloc(1, sizeof(kl_##name##_t)); \ + kl->mp = kmp_init(name); \ + kl->head = kl->tail = kmp_alloc(name, kl->mp); \ + kl->head->next = 0; \ + return kl; \ + } \ + static inline void kl_destroy_##name(kl_##name##_t *kl) \ + REAL_FATTR_UNUSED; \ + static inline void kl_destroy_##name(kl_##name##_t *kl) { \ + kl1_##name *p; \ + for (p = kl->head; p != kl->tail; p = p->next) { \ + kmp_free(name, kl->mp, p); \ } \ - static inline void kl_push_##name(kl_##name##_t *kl, kltype_t d) { \ - kl1_##name *q, *p = kmp_alloc(name, kl->mp); \ - q = kl->tail; p->next = 0; kl->tail->next = p; kl->tail = p; \ - kl->size++; \ - q->data = d; \ + kmp_free(name, kl->mp, p); \ + kmp_destroy(name, kl->mp); \ + XFREE_CLEAR(kl); \ + } \ + static inline void kl_push_##name(kl_##name##_t *kl, kltype_t d) { \ + kl1_##name *q, *p = kmp_alloc(name, kl->mp); \ + q = kl->tail; p->next = 0; kl->tail->next = p; kl->tail = p; \ + kl->size++; \ + q->data = d; \ + } \ + static inline kltype_t kl_shift_at_##name(kl_##name##_t *kl, \ + kl1_##name **n) { \ + assert((*n)->next); \ + kl1_##name *p; \ + kl->size--; \ + p = *n; \ + *n = (*n)->next; \ + if (p == kl->head) { \ + kl->head = *n; \ } \ - static inline kltype_t kl_shift_at_##name(kl_##name##_t *kl, \ - kl1_##name **n) { \ - assert((*n)->next); \ - kl1_##name *p; \ - kl->size--; \ - p = *n; \ - *n = (*n)->next; \ - if (p == kl->head) { \ - kl->head = *n; \ - } \ - kltype_t d = p->data; \ - kmp_free(name, kl->mp, p); \ - return d; \ - } + kltype_t d = p->data; \ + kmp_free(name, kl->mp, p); \ + return d; \ + } #define kliter_t(name) kl1_##name #define klist_t(name) kl_##name##_t diff --git a/src/nvim/lib/kvec.h b/src/nvim/lib/kvec.h index 5bd09930a3..eb2d9bbb77 100644 --- a/src/nvim/lib/kvec.h +++ b/src/nvim/lib/kvec.h @@ -44,25 +44,25 @@ #include "nvim/os/os_defs.h" #define kv_roundup32(x) \ - ((--(x)), \ - ((x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16), \ - (++(x))) + ((--(x)), \ + ((x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16), \ + (++(x))) #define KV_INITIAL_VALUE { .size = 0, .capacity = 0, .items = NULL } #define kvec_t(type) \ - struct { \ - size_t size; \ - size_t capacity; \ - type *items; \ - } + struct { \ + size_t size; \ + size_t capacity; \ + type *items; \ + } #define kv_init(v) ((v).size = (v).capacity = 0, (v).items = 0) #define kv_destroy(v) \ - do { \ - xfree((v).items); \ - kv_init(v); \ - } while (0) + do { \ + xfree((v).items); \ + kv_init(v); \ + } while (0) #define kv_A(v, i) ((v).items[(i)]) #define kv_pop(v) ((v).items[--(v).size]) #define kv_size(v) ((v).size) @@ -79,34 +79,34 @@ #define kv_drop(v, n) ((v).size -= (n)) #define kv_resize(v, s) \ - ((v).capacity = (s), \ - (v).items = xrealloc((v).items, sizeof((v).items[0]) * (v).capacity)) + ((v).capacity = (s), \ + (v).items = xrealloc((v).items, sizeof((v).items[0]) * (v).capacity)) #define kv_resize_full(v) \ - kv_resize(v, (v).capacity ? (v).capacity << 1 : 8) + kv_resize(v, (v).capacity ? (v).capacity << 1 : 8) #define kv_copy(v1, v0) \ - do { \ - if ((v1).capacity < (v0).size) { \ - kv_resize(v1, (v0).size); \ - } \ - (v1).size = (v0).size; \ - memcpy((v1).items, (v0).items, sizeof((v1).items[0]) * (v0).size); \ - } while (0) + do { \ + if ((v1).capacity < (v0).size) { \ + kv_resize(v1, (v0).size); \ + } \ + (v1).size = (v0).size; \ + memcpy((v1).items, (v0).items, sizeof((v1).items[0]) * (v0).size); \ + } while (0) #define kv_pushp(v) \ - ((((v).size == (v).capacity) ? (kv_resize_full(v), 0) : 0), \ - ((v).items + ((v).size++))) + ((((v).size == (v).capacity) ? (kv_resize_full(v), 0) : 0), \ + ((v).items + ((v).size++))) #define kv_push(v, x) \ - (*kv_pushp(v) = (x)) + (*kv_pushp(v) = (x)) #define kv_a(v, i) \ - (*(((v).capacity <= (size_t) (i) \ + (*(((v).capacity <= (size_t)(i) \ ? ((v).capacity = (v).size = (i) + 1, \ kv_roundup32((v).capacity), \ kv_resize((v), (v).capacity), 0UL) \ - : ((v).size <= (size_t) (i) \ + : ((v).size <= (size_t)(i) \ ? (v).size = (i) + 1 \ : 0UL)), \ &(v).items[(i)])) @@ -120,24 +120,23 @@ /// @param[in] type Type of vector elements. /// @param[in] init_size Number of the elements in the initial array. #define kvec_withinit_t(type, INIT_SIZE) \ - struct { \ - size_t size; \ - size_t capacity; \ - type *items; \ - type init_array[INIT_SIZE]; \ - } + struct { \ + size_t size; \ + size_t capacity; \ + type *items; \ + type init_array[INIT_SIZE]; \ + } /// Initialize vector with preallocated array /// /// @param[out] v Vector to initialize. #define kvi_init(v) \ - ((v).capacity = ARRAY_SIZE((v).init_array), \ - (v).size = 0, \ - (v).items = (v).init_array) + ((v).capacity = ARRAY_SIZE((v).init_array), \ + (v).size = 0, \ + (v).items = (v).init_array) /// Move data to a new destination and free source -static inline void *_memcpy_free(void *const restrict dest, - void *const restrict src, +static inline void *_memcpy_free(void *const restrict dest, void *const restrict src, const size_t size) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_ALWAYS_INLINE { @@ -156,15 +155,15 @@ static inline void *_memcpy_free(void *const restrict dest, /// @param[out] v Vector to resize. /// @param[in] s New size. #define kvi_resize(v, s) \ - ((v).capacity = ((s) > ARRAY_SIZE((v).init_array) \ + ((v).capacity = ((s) > ARRAY_SIZE((v).init_array) \ ? (s) \ : ARRAY_SIZE((v).init_array)), \ - (v).items = ((v).capacity == ARRAY_SIZE((v).init_array) \ + (v).items = ((v).capacity == ARRAY_SIZE((v).init_array) \ ? ((v).items == (v).init_array \ ? (v).items \ : _memcpy_free((v).init_array, (v).items, \ (v).size * sizeof((v).items[0]))) \ - : ((v).items == (v).init_array \ + : ((v).items == (v).init_array \ ? memcpy(xmalloc((v).capacity * sizeof((v).items[0])), \ (v).items, \ (v).size * sizeof((v).items[0])) \ @@ -175,13 +174,13 @@ static inline void *_memcpy_free(void *const restrict dest, /// /// @param[out] v Vector to resize. #define kvi_resize_full(v) \ - /* ARRAY_SIZE((v).init_array) is the minimal capacity of this vector. */ \ - /* Thus when vector is full capacity may not be zero and it is safe */ \ - /* not to bother with checking whether (v).capacity is 0. But now */ \ - /* capacity is not guaranteed to have size that is a power of 2, it is */ \ - /* hard to fix this here and is not very necessary if users will use */ \ - /* 2^x initial array size. */ \ - kvi_resize(v, (v).capacity << 1) + /* ARRAY_SIZE((v).init_array) is the minimal capacity of this vector. */ \ + /* Thus when vector is full capacity may not be zero and it is safe */ \ + /* not to bother with checking whether (v).capacity is 0. But now */ \ + /* capacity is not guaranteed to have size that is a power of 2, it is */ \ + /* hard to fix this here and is not very necessary if users will use */ \ + /* 2^x initial array size. */ \ + kvi_resize(v, (v).capacity << 1) /// Get location where to store new element to a vector with preallocated array /// @@ -189,24 +188,24 @@ static inline void *_memcpy_free(void *const restrict dest, /// /// @return Pointer to the place where new value should be stored. #define kvi_pushp(v) \ - ((((v).size == (v).capacity) ? (kvi_resize_full(v), 0) : 0), \ - ((v).items + ((v).size++))) + ((((v).size == (v).capacity) ? (kvi_resize_full(v), 0) : 0), \ + ((v).items + ((v).size++))) /// Push value to a vector with preallocated array /// /// @param[out] v Vector to push to. /// @param[in] x Value to push. #define kvi_push(v, x) \ - (*kvi_pushp(v) = (x)) + (*kvi_pushp(v) = (x)) /// Free array of elements of a vector with preallocated array if needed /// /// @param[out] v Vector to free. #define kvi_destroy(v) \ - do { \ - if ((v).items != (v).init_array) { \ - XFREE_CLEAR((v).items); \ - } \ - } while (0) + do { \ + if ((v).items != (v).init_array) { \ + XFREE_CLEAR((v).items); \ + } \ + } while (0) #endif // NVIM_LIB_KVEC_H diff --git a/src/nvim/lib/queue.h b/src/nvim/lib/queue.h index 452998a5a4..871f49c863 100644 --- a/src/nvim/lib/queue.h +++ b/src/nvim/lib/queue.h @@ -41,7 +41,7 @@ typedef struct _queue { while((q) != (h)) { \ QUEUE *next = q->next; \ code \ - (q) = next; \ + (q) = next; \ } diff --git a/src/nvim/lib/ringbuf.h b/src/nvim/lib/ringbuf.h index cb79eaf742..06f7830bd1 100644 --- a/src/nvim/lib/ringbuf.h +++ b/src/nvim/lib/ringbuf.h @@ -15,24 +15,29 @@ #ifndef NVIM_LIB_RINGBUF_H #define NVIM_LIB_RINGBUF_H -#include <stddef.h> -#include <string.h> #include <assert.h> +#include <stddef.h> #include <stdint.h> +#include <string.h> -#include "nvim/memory.h" #include "nvim/func_attr.h" +#include "nvim/memory.h" #define _RINGBUF_LENGTH(rb) \ - ((rb)->first == NULL ? 0 \ - : ((rb)->next == (rb)->first) ? (size_t) ((rb)->buf_end - (rb)->buf) + 1 \ - : ((rb)->next > (rb)->first) ? (size_t) ((rb)->next - (rb)->first) \ - : (size_t) ((rb)->next - (rb)->buf + (rb)->buf_end - (rb)->first + 1)) + ((rb)->first == NULL ? 0 \ + : ((rb)->next == (rb)->first) ? (size_t)((rb)->buf_end - (rb)->buf) + 1 \ + : ((rb)->next > \ + (rb)->first) ? (size_t)((rb)->next - \ + (rb)->first) \ + : (size_t)((rb)->\ + next - (rb)->buf + \ + (rb)->buf_end - \ + (rb)->first + 1)) #define _RINGBUF_NEXT(rb, var) \ - ((var) == (rb)->buf_end ? (rb)->buf : (var) + 1) + ((var) == (rb)->buf_end ? (rb)->buf : (var) + 1) #define _RINGBUF_PREV(rb, var) \ - ((var) == (rb)->buf ? (rb)->buf_end : (var) - 1) + ((var) == (rb)->buf ? (rb)->buf_end : (var) - 1) /// Iterate over all ringbuf values /// @@ -40,11 +45,11 @@ /// @param RBType Type of the ring buffer element. /// @param varname Variable name. #define RINGBUF_FORALL(rb, RBType, varname) \ - size_t varname##_length_fa_ = _RINGBUF_LENGTH(rb); \ - for (RBType *varname = ((rb)->first == NULL ? (rb)->next : (rb)->first); \ - varname##_length_fa_; \ - (varname = _RINGBUF_NEXT(rb, varname)), \ - varname##_length_fa_--) + size_t varname##_length_fa_ = _RINGBUF_LENGTH(rb); \ + for (RBType *varname = ((rb)->first == NULL ? (rb)->next : (rb)->first); \ + varname##_length_fa_; \ + (varname = _RINGBUF_NEXT(rb, varname)), \ + varname##_length_fa_--) /// Iterate over all ringbuf values, from end to the beginning /// @@ -55,11 +60,11 @@ /// @param RBType Type of the ring buffer element. /// @param varname Variable name. #define RINGBUF_ITER_BACK(rb, RBType, varname) \ - size_t varname##_length_ib_ = _RINGBUF_LENGTH(rb); \ - for (varname = ((rb)->next == (rb)->buf ? (rb)->buf_end : (rb)->next - 1); \ - varname##_length_ib_; \ - (varname = _RINGBUF_PREV(rb, varname)), \ - varname##_length_ib_--) + size_t varname##_length_ib_ = _RINGBUF_LENGTH(rb); \ + for (varname = ((rb)->next == (rb)->buf ? (rb)->buf_end : (rb)->next - 1); \ + varname##_length_ib_; \ + (varname = _RINGBUF_PREV(rb, varname)), \ + varname##_length_ib_--) /// Define a ring buffer structure /// @@ -67,12 +72,12 @@ /// `{TypeName}RingBuffer`. /// @param RBType Type of the single ring buffer element. #define RINGBUF_TYPEDEF(TypeName, RBType) \ -typedef struct { \ - RBType *buf; \ - RBType *next; \ - RBType *first; \ - RBType *buf_end; \ -} TypeName##RingBuffer; + typedef struct { \ + RBType *buf; \ + RBType *next; \ + RBType *first; \ + RBType *buf_end; \ + } TypeName##RingBuffer; /// Dummy item free macros, for use in RINGBUF_INIT /// @@ -92,13 +97,13 @@ typedef struct { \ /// @param varname Variable name. /// @param rbsize Ring buffer size. #define RINGBUF_STATIC(scope, TypeName, RBType, varname, rbsize) \ -static RBType _##varname##_buf[rbsize]; \ -scope TypeName##RingBuffer varname = { \ - .buf = _##varname##_buf, \ - .next = _##varname##_buf, \ - .first = NULL, \ - .buf_end = _##varname##_buf + rbsize - 1, \ -}; + static RBType _##varname##_buf[rbsize]; \ + scope TypeName##RingBuffer varname = { \ + .buf = _##varname##_buf, \ + .next = _##varname##_buf, \ + .first = NULL, \ + .buf_end = _##varname##_buf + rbsize - 1, \ + }; /// Initialize a new ring buffer /// @@ -112,195 +117,191 @@ scope TypeName##RingBuffer varname = { \ /// /// Intended function signature: `void *rbfree(RBType *)`; #define RINGBUF_INIT(TypeName, funcprefix, RBType, rbfree) \ -static inline TypeName##RingBuffer funcprefix##_rb_new(const size_t size) \ + static inline TypeName##RingBuffer funcprefix##_rb_new(const size_t size) \ REAL_FATTR_WARN_UNUSED_RESULT; \ -static inline TypeName##RingBuffer funcprefix##_rb_new(const size_t size) \ -{ \ - assert(size != 0); \ - RBType *buf = xmalloc(size * sizeof(RBType)); \ - return (TypeName##RingBuffer) { \ - .buf = buf, \ - .next = buf, \ - .first = NULL, \ - .buf_end = buf + size - 1, \ - }; \ -} \ + static inline TypeName##RingBuffer funcprefix##_rb_new(const size_t size) \ + { \ + assert(size != 0); \ + RBType *buf = xmalloc(size * sizeof(RBType)); \ + return (TypeName##RingBuffer) { \ + .buf = buf, \ + .next = buf, \ + .first = NULL, \ + .buf_end = buf + size - 1, \ + }; \ + } \ \ -static inline void funcprefix##_rb_free(TypeName##RingBuffer *const rb) \ + static inline void funcprefix##_rb_free(TypeName##RingBuffer *const rb) \ REAL_FATTR_UNUSED; \ -static inline void funcprefix##_rb_free(TypeName##RingBuffer *const rb) \ -{ \ - if (rb == NULL) { \ - return; \ - } \ - RINGBUF_FORALL(rb, RBType, rbitem) { \ - rbfree(rbitem); \ + static inline void funcprefix##_rb_free(TypeName##RingBuffer *const rb) \ + { \ + if (rb == NULL) { \ + return; \ + } \ + RINGBUF_FORALL(rb, RBType, rbitem) { \ + rbfree(rbitem); \ + } \ + XFREE_CLEAR(rb->buf); \ } \ - XFREE_CLEAR(rb->buf); \ -} \ \ -static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \ + static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \ REAL_FATTR_UNUSED; \ -static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \ -{ \ - XFREE_CLEAR(rb->buf); \ -} \ + static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \ + { \ + XFREE_CLEAR(rb->buf); \ + } \ \ -static inline void funcprefix##_rb_push(TypeName##RingBuffer *const rb, \ - RBType item) \ + static inline void funcprefix##_rb_push(TypeName##RingBuffer *const rb, \ + RBType item) \ REAL_FATTR_NONNULL_ARG(1); \ -static inline void funcprefix##_rb_push(TypeName##RingBuffer *const rb, \ - RBType item) \ -{ \ - if (rb->next == rb->first) { \ - rbfree(rb->first); \ - rb->first = _RINGBUF_NEXT(rb, rb->first); \ - } else if (rb->first == NULL) { \ - rb->first = rb->next; \ + static inline void funcprefix##_rb_push(TypeName##RingBuffer *const rb, \ + RBType item) \ + { \ + if (rb->next == rb->first) { \ + rbfree(rb->first); \ + rb->first = _RINGBUF_NEXT(rb, rb->first); \ + } else if (rb->first == NULL) { \ + rb->first = rb->next; \ + } \ + *rb->next = item; \ + rb->next = _RINGBUF_NEXT(rb, rb->next); \ } \ - *rb->next = item; \ - rb->next = _RINGBUF_NEXT(rb, rb->next); \ -} \ \ -static inline ptrdiff_t funcprefix##_rb_find_idx( \ - const TypeName##RingBuffer *const rb, const RBType *const item_p) \ + static inline ptrdiff_t funcprefix##_rb_find_idx(const TypeName##RingBuffer *const rb, \ + const RBType *const item_p) \ REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE REAL_FATTR_UNUSED; \ -static inline ptrdiff_t funcprefix##_rb_find_idx( \ - const TypeName##RingBuffer *const rb, const RBType *const item_p) \ -{ \ - assert(rb->buf <= item_p); \ - assert(rb->buf_end >= item_p); \ - if (rb->first == NULL) { \ - return -1; \ - } else if (item_p >= rb->first) { \ - return item_p - rb->first; \ - } else { \ - return item_p - rb->buf + rb->buf_end - rb->first + 1; \ + static inline ptrdiff_t funcprefix##_rb_find_idx(const TypeName##RingBuffer *const rb, \ + const RBType *const item_p) \ + { \ + assert(rb->buf <= item_p); \ + assert(rb->buf_end >= item_p); \ + if (rb->first == NULL) { \ + return -1; \ + } else if (item_p >= rb->first) { \ + return item_p - rb->first; \ + } else { \ + return item_p - rb->buf + rb->buf_end - rb->first + 1; \ + } \ } \ -} \ \ -static inline size_t funcprefix##_rb_size( \ - const TypeName##RingBuffer *const rb) \ + static inline size_t funcprefix##_rb_size(const TypeName##RingBuffer *const rb) \ REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE; \ -static inline size_t funcprefix##_rb_size( \ - const TypeName##RingBuffer *const rb) \ -{ \ - return (size_t) (rb->buf_end - rb->buf) + 1; \ -} \ + static inline size_t funcprefix##_rb_size(const TypeName##RingBuffer *const rb) \ + { \ + return (size_t)(rb->buf_end - rb->buf) + 1; \ + } \ \ -static inline size_t funcprefix##_rb_length( \ - const TypeName##RingBuffer *const rb) \ + static inline size_t funcprefix##_rb_length(const TypeName##RingBuffer *const rb) \ REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE; \ -static inline size_t funcprefix##_rb_length( \ - const TypeName##RingBuffer *const rb) \ -{ \ - return _RINGBUF_LENGTH(rb); \ -} \ + static inline size_t funcprefix##_rb_length(const TypeName##RingBuffer *const rb) \ + { \ + return _RINGBUF_LENGTH(rb); \ + } \ \ -static inline RBType *funcprefix##_rb_idx_p( \ - const TypeName##RingBuffer *const rb, const size_t idx) \ + static inline RBType *funcprefix##_rb_idx_p(const TypeName##RingBuffer *const rb, \ + const size_t idx) \ REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE; \ -static inline RBType *funcprefix##_rb_idx_p( \ - const TypeName##RingBuffer *const rb, const size_t idx) \ -{ \ - assert(idx <= funcprefix##_rb_size(rb)); \ - assert(idx <= funcprefix##_rb_length(rb)); \ - if (rb->first + idx > rb->buf_end) { \ - return rb->buf + ((rb->first + idx) - (rb->buf_end + 1)); \ - } else { \ - return rb->first + idx; \ + static inline RBType *funcprefix##_rb_idx_p(const TypeName##RingBuffer *const rb, \ + const size_t idx) \ + { \ + assert(idx <= funcprefix##_rb_size(rb)); \ + assert(idx <= funcprefix##_rb_length(rb)); \ + if (rb->first + idx > rb->buf_end) { \ + return rb->buf + ((rb->first + idx) - (rb->buf_end + 1)); \ + } else { \ + return rb->first + idx; \ + } \ } \ -} \ \ -static inline RBType funcprefix##_rb_idx(const TypeName##RingBuffer *const rb, \ - const size_t idx) \ + static inline RBType funcprefix##_rb_idx(const TypeName##RingBuffer *const rb, \ + const size_t idx) \ REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE REAL_FATTR_UNUSED; \ -static inline RBType funcprefix##_rb_idx(const TypeName##RingBuffer *const rb, \ - const size_t idx) \ -{ \ - return *funcprefix##_rb_idx_p(rb, idx); \ -} \ -\ -static inline void funcprefix##_rb_insert(TypeName##RingBuffer *const rb, \ - const size_t idx, \ - RBType item) \ - REAL_FATTR_NONNULL_ARG(1) REAL_FATTR_UNUSED; \ -static inline void funcprefix##_rb_insert(TypeName##RingBuffer *const rb, \ - const size_t idx, \ - RBType item) \ -{ \ - assert(idx <= funcprefix##_rb_size(rb)); \ - assert(idx <= funcprefix##_rb_length(rb)); \ - const size_t length = funcprefix##_rb_length(rb); \ - if (idx == length) { \ - funcprefix##_rb_push(rb, item); \ - return; \ - } \ - RBType *const insertpos = funcprefix##_rb_idx_p(rb, idx); \ - if (insertpos == rb->next) { \ - funcprefix##_rb_push(rb, item); \ - return; \ - } \ - if (length == funcprefix##_rb_size(rb)) { \ - rbfree(rb->first); \ + static inline RBType funcprefix##_rb_idx(const TypeName##RingBuffer *const rb, \ + const size_t idx) \ + { \ + return *funcprefix##_rb_idx_p(rb, idx); \ } \ - if (insertpos < rb->next) { \ - memmove(insertpos + 1, insertpos, \ - (size_t) ((uintptr_t) rb->next - (uintptr_t) insertpos)); \ - } else { \ - assert(insertpos > rb->first); \ - assert(rb->next <= rb->first); \ - memmove(rb->buf + 1, rb->buf, \ - (size_t) ((uintptr_t) rb->next - (uintptr_t) rb->buf)); \ - *rb->buf = *rb->buf_end; \ - memmove(insertpos + 1, insertpos, \ - (size_t) ((uintptr_t) (rb->buf_end + 1) - (uintptr_t) insertpos)); \ - } \ - *insertpos = item; \ - if (length == funcprefix##_rb_size(rb)) { \ - rb->first = _RINGBUF_NEXT(rb, rb->first); \ - } \ - rb->next = _RINGBUF_NEXT(rb, rb->next); \ -} \ \ -static inline void funcprefix##_rb_remove(TypeName##RingBuffer *const rb, \ - const size_t idx) \ + static inline void funcprefix##_rb_insert(TypeName##RingBuffer *const rb, \ + const size_t idx, \ + RBType item) \ REAL_FATTR_NONNULL_ARG(1) REAL_FATTR_UNUSED; \ -static inline void funcprefix##_rb_remove(TypeName##RingBuffer *const rb, \ - const size_t idx) \ -{ \ - assert(idx < funcprefix##_rb_size(rb)); \ - assert(idx < funcprefix##_rb_length(rb)); \ - RBType *const rmpos = funcprefix##_rb_idx_p(rb, idx); \ - rbfree(rmpos); \ - if (rmpos == rb->next - 1) { \ - rb->next--; \ - if (rb->first == rb->next) { \ - rb->first = NULL; \ - rb->next = rb->buf; \ + static inline void funcprefix##_rb_insert(TypeName##RingBuffer *const rb, \ + const size_t idx, \ + RBType item) \ + { \ + assert(idx <= funcprefix##_rb_size(rb)); \ + assert(idx <= funcprefix##_rb_length(rb)); \ + const size_t length = funcprefix##_rb_length(rb); \ + if (idx == length) { \ + funcprefix##_rb_push(rb, item); \ + return; \ + } \ + RBType *const insertpos = funcprefix##_rb_idx_p(rb, idx); \ + if (insertpos == rb->next) { \ + funcprefix##_rb_push(rb, item); \ + return; \ + } \ + if (length == funcprefix##_rb_size(rb)) { \ + rbfree(rb->first); \ } \ - } else if (rmpos == rb->first) { \ - rb->first = _RINGBUF_NEXT(rb, rb->first); \ - if (rb->first == rb->next) { \ - rb->first = NULL; \ - rb->next = rb->buf; \ + if (insertpos < rb->next) { \ + memmove(insertpos + 1, insertpos, \ + (size_t)((uintptr_t)rb->next - (uintptr_t)insertpos)); \ + } else { \ + assert(insertpos > rb->first); \ + assert(rb->next <= rb->first); \ + memmove(rb->buf + 1, rb->buf, \ + (size_t)((uintptr_t)rb->next - (uintptr_t)rb->buf)); \ + *rb->buf = *rb->buf_end; \ + memmove(insertpos + 1, insertpos, \ + (size_t)((uintptr_t)(rb->buf_end + 1) - (uintptr_t)insertpos)); \ } \ - } else if (rb->first < rb->next || rb->next == rb->buf) { \ - assert(rmpos > rb->first); \ - assert(rmpos <= _RINGBUF_PREV(rb, rb->next)); \ - memmove(rb->first + 1, rb->first, \ - (size_t) ((uintptr_t) rmpos - (uintptr_t) rb->first)); \ - rb->first = _RINGBUF_NEXT(rb, rb->first); \ - } else if (rmpos < rb->next) { \ - memmove(rmpos, rmpos + 1, \ - (size_t) ((uintptr_t) rb->next - (uintptr_t) rmpos)); \ - rb->next = _RINGBUF_PREV(rb, rb->next); \ - } else { \ - assert(rb->first < rb->buf_end); \ - memmove(rb->first + 1, rb->first, \ - (size_t) ((uintptr_t) rmpos - (uintptr_t) rb->first)); \ - rb->first = _RINGBUF_NEXT(rb, rb->first); \ + *insertpos = item; \ + if (length == funcprefix##_rb_size(rb)) { \ + rb->first = _RINGBUF_NEXT(rb, rb->first); \ + } \ + rb->next = _RINGBUF_NEXT(rb, rb->next); \ } \ -} +\ + static inline void funcprefix##_rb_remove(TypeName##RingBuffer *const rb, \ + const size_t idx) \ + REAL_FATTR_NONNULL_ARG(1) REAL_FATTR_UNUSED; \ + static inline void funcprefix##_rb_remove(TypeName##RingBuffer *const rb, \ + const size_t idx) \ + { \ + assert(idx < funcprefix##_rb_size(rb)); \ + assert(idx < funcprefix##_rb_length(rb)); \ + RBType *const rmpos = funcprefix##_rb_idx_p(rb, idx); \ + rbfree(rmpos); \ + if (rmpos == rb->next - 1) { \ + rb->next--; \ + if (rb->first == rb->next) { \ + rb->first = NULL; \ + rb->next = rb->buf; \ + } \ + } else if (rmpos == rb->first) { \ + rb->first = _RINGBUF_NEXT(rb, rb->first); \ + if (rb->first == rb->next) { \ + rb->first = NULL; \ + rb->next = rb->buf; \ + } \ + } else if (rb->first < rb->next || rb->next == rb->buf) { \ + assert(rmpos > rb->first); \ + assert(rmpos <= _RINGBUF_PREV(rb, rb->next)); \ + memmove(rb->first + 1, rb->first, \ + (size_t)((uintptr_t)rmpos - (uintptr_t)rb->first)); \ + rb->first = _RINGBUF_NEXT(rb, rb->first); \ + } else if (rmpos < rb->next) { \ + memmove(rmpos, rmpos + 1, \ + (size_t)((uintptr_t)rb->next - (uintptr_t)rmpos)); \ + rb->next = _RINGBUF_PREV(rb, rb->next); \ + } else { \ + assert(rb->first < rb->buf_end); \ + memmove(rb->first + 1, rb->first, \ + (size_t)((uintptr_t)rmpos - (uintptr_t)rb->first)); \ + rb->first = _RINGBUF_NEXT(rb, rb->first); \ + } \ + } #endif // NVIM_LIB_RINGBUF_H diff --git a/src/nvim/log.c b/src/nvim/log.c index 324382a0f7..5539e3d6c5 100644 --- a/src/nvim/log.c +++ b/src/nvim/log.c @@ -17,9 +17,9 @@ #include "auto/config.h" #include "nvim/log.h" -#include "nvim/types.h" #include "nvim/os/os.h" #include "nvim/os/time.h" +#include "nvim/types.h" #define LOG_FILE_ENV "NVIM_LOG_FILE" @@ -124,8 +124,8 @@ void log_unlock(void) /// @param line_num Source line number, or -1 /// @param eol Append linefeed "\n" /// @param fmt printf-style format string -bool logmsg(int log_level, const char *context, const char *func_name, - int line_num, bool eol, const char *fmt, ...) +bool logmsg(int log_level, const char *context, const char *func_name, int line_num, bool eol, + const char *fmt, ...) FUNC_ATTR_UNUSED FUNC_ATTR_PRINTF(6, 7) { if (log_level < MIN_LOG_LEVEL) { @@ -215,8 +215,7 @@ FILE *open_log_file(void) } #ifdef HAVE_EXECINFO_BACKTRACE -void log_callstack_to_file(FILE *log_file, const char *const func_name, - const int line_num) +void log_callstack_to_file(FILE *log_file, const char *const func_name, const int line_num) { void *trace[100]; int trace_size = backtrace(trace, ARRAY_SIZE(trace)); @@ -268,8 +267,7 @@ end: #endif static bool do_log_to_file(FILE *log_file, int log_level, const char *context, - const char *func_name, int line_num, bool eol, - const char *fmt, ...) + const char *func_name, int line_num, bool eol, const char *fmt, ...) FUNC_ATTR_PRINTF(7, 8) { va_list args; @@ -281,9 +279,8 @@ static bool do_log_to_file(FILE *log_file, int log_level, const char *context, return ret; } -static bool v_do_log_to_file(FILE *log_file, int log_level, - const char *context, const char *func_name, - int line_num, bool eol, const char *fmt, +static bool v_do_log_to_file(FILE *log_file, int log_level, const char *context, + const char *func_name, int line_num, bool eol, const char *fmt, va_list args) { static const char *log_levels[] = { @@ -317,10 +314,10 @@ static bool v_do_log_to_file(FILE *log_file, int log_level, ? fprintf(log_file, "%s %s.%03d %-5" PRId64 " %s", log_levels[log_level], date_time, millis, pid, (context == NULL ? "?:" : context)) - : fprintf(log_file, "%s %s.%03d %-5" PRId64 " %s%s:%d: ", - log_levels[log_level], date_time, millis, pid, - (context == NULL ? "" : context), - func_name, line_num); + : fprintf(log_file, "%s %s.%03d %-5" PRId64 " %s%s:%d: ", + log_levels[log_level], date_time, millis, pid, + (context == NULL ? "" : context), + func_name, line_num); if (rv < 0) { return false; } diff --git a/src/nvim/log.h b/src/nvim/log.h index 654b682de8..81e39d1cdd 100644 --- a/src/nvim/log.h +++ b/src/nvim/log.h @@ -1,8 +1,8 @@ #ifndef NVIM_LOG_H #define NVIM_LOG_H -#include <stdio.h> #include <stdbool.h> +#include <stdio.h> #include "auto/config.h" #include "nvim/macros.h" @@ -10,10 +10,10 @@ // USDT probes. Example invocation: // NVIM_PROBE(nvim_foo_bar, 1, string.data); #if defined(HAVE_SYS_SDT_H) -#include <sys/sdt.h> // NOLINT -#define NVIM_PROBE(name, n, ...) STAP_PROBE##n(neovim, name, __VA_ARGS__) +# include <sys/sdt.h> // NOLINT +# define NVIM_PROBE(name, n, ...) STAP_PROBE##n(neovim, name, __VA_ARGS__) #else -#define NVIM_PROBE(name, n, ...) +# define NVIM_PROBE(name, n, ...) #endif @@ -33,7 +33,7 @@ #define ELOGN(...) #ifndef MIN_LOG_LEVEL -# define MIN_LOG_LEVEL INFO_LOG_LEVEL +# define MIN_LOG_LEVEL INFO_LOG_LEVEL #endif #define LOG(level, ...) logmsg((level), NULL, __func__, __LINE__, true, \ diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c index 07c53299fa..ca3c4f604a 100644 --- a/src/nvim/lua/converter.c +++ b/src/nvim/lua/converter.c @@ -755,7 +755,7 @@ void nlua_push_Array(lua_State *lstate, const Array array, bool special) FUNC_ATTR_NONNULL_ALL \ { \ lua_pushnumber(lstate, (lua_Number)(item)); \ -} + } GENERATE_INDEX_FUNCTION(Buffer) GENERATE_INDEX_FUNCTION(Window) @@ -1126,9 +1126,9 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err) size_t len; const char *s = lua_tolstring(lstate, -1, &len); *cur.obj = STRING_OBJ(((String) { - .data = xmemdupz(s, len), - .size = len, - })); + .data = xmemdupz(s, len), + .size = len, + })); break; } case LUA_TNUMBER: { @@ -1147,10 +1147,10 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err) switch (table_props.type) { case kObjectTypeArray: *cur.obj = ARRAY_OBJ(((Array) { - .items = NULL, - .size = 0, - .capacity = 0, - })); + .items = NULL, + .size = 0, + .capacity = 0, + })); if (table_props.maxidx != 0) { cur.obj->data.array.items = xcalloc(table_props.maxidx, @@ -1162,10 +1162,10 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err) break; case kObjectTypeDictionary: *cur.obj = DICTIONARY_OBJ(((Dictionary) { - .items = NULL, - .size = 0, - .capacity = 0, - })); + .items = NULL, + .size = 0, + .capacity = 0, + })); if (table_props.string_keys_num != 0) { cur.obj->data.dictionary.items = xcalloc(table_props.string_keys_num, @@ -1299,3 +1299,31 @@ void nlua_init_types(lua_State *const lstate) lua_rawset(lstate, -3); } + + +void nlua_pop_keydict(lua_State *L, void *retval, field_hash hashy, Error *err) +{ + if (!lua_istable(L, -1)) { + api_set_error(err, kErrorTypeValidation, "Expected lua table"); + lua_pop(L, -1); + return; + } + + lua_pushnil(L); // [dict, nil] + while (lua_next(L, -2)) { + // [dict, key, value] + size_t len; + const char *s = lua_tolstring(L, -2, &len); + Object *field = hashy(retval, s, len); + if (!field) { + api_set_error(err, kErrorTypeValidation, "invalid key: %.*s", (int)len, s); + lua_pop(L, 3); // [] + return; + } + + *field = nlua_pop_Object(L, true, err); + } + // [dict] + lua_pop(L, 1); + // [] +} diff --git a/src/nvim/lua/converter.h b/src/nvim/lua/converter.h index 43a7e06019..1c9e60e4b2 100644 --- a/src/nvim/lua/converter.h +++ b/src/nvim/lua/converter.h @@ -6,8 +6,8 @@ #include <stdint.h> #include "nvim/api/private/defs.h" -#include "nvim/func_attr.h" #include "nvim/eval.h" +#include "nvim/func_attr.h" typedef struct { LuaRef func_ref; diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 8c7dc90111..59ebafd9c8 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -5,6 +5,7 @@ #include <lua.h> #include <lualib.h> +#include "cjson/lua_cjson.h" #include "luv/luv.h" #include "mpack/lmpack.h" #include "nvim/api/private/defs.h" @@ -531,6 +532,9 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL lua_pushcfunction(lstate, &nlua_xdl_diff); lua_setfield(lstate, -2, "diff"); + lua_cjson_new(lstate); + lua_setfield(lstate, -2, "json"); + lua_setglobal(lstate, "vim"); { @@ -786,7 +790,7 @@ int nlua_call(lua_State *lstate) Error err = ERROR_INIT; size_t name_len; const char_u *name = (const char_u *)luaL_checklstring(lstate, 1, &name_len); - if (!nlua_is_deferred_safe(lstate)) { + if (!nlua_is_deferred_safe()) { return luaL_error(lstate, e_luv_api_disabled, "vimL function"); } @@ -842,7 +846,7 @@ free_vim_args: static int nlua_rpcrequest(lua_State *lstate) { - if (!nlua_is_deferred_safe(lstate)) { + if (!nlua_is_deferred_safe()) { return luaL_error(lstate, e_luv_api_disabled, "rpcrequest"); } return nlua_rpc(lstate, true); @@ -1312,7 +1316,7 @@ Object nlua_call_ref(LuaRef ref, const char *name, Array args, bool retval, Erro /// check if the current execution context is safe for calling deferred API /// methods. Luv callbacks are unsafe as they are called inside the uv loop. -bool nlua_is_deferred_safe(lua_State *lstate) +bool nlua_is_deferred_safe(void) { return in_fast_callback == 0; } diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h index ea774ac2e3..a1f66bd02b 100644 --- a/src/nvim/lua/executor.h +++ b/src/nvim/lua/executor.h @@ -1,13 +1,13 @@ #ifndef NVIM_LUA_EXECUTOR_H #define NVIM_LUA_EXECUTOR_H -#include <lua.h> #include <lauxlib.h> +#include <lua.h> #include "nvim/api/private/defs.h" -#include "nvim/func_attr.h" #include "nvim/eval/typval.h" #include "nvim/ex_cmds_defs.h" +#include "nvim/func_attr.h" #include "nvim/lua/converter.h" // Generated by msgpack-gen.lua @@ -19,12 +19,12 @@ EXTERN LuaRef nlua_empty_dict_ref INIT(= LUA_NOREF); EXTERN int nlua_refcount INIT(= 0); #define set_api_error(s, err) \ - do { \ - Error *err_ = (err); \ - err_->type = kErrorTypeException; \ - err_->set = true; \ - memcpy(&err_->msg[0], s, sizeof(s)); \ - } while (0) + do { \ + Error *err_ = (err); \ + err_->type = kErrorTypeException; \ + err_->set = true; \ + memcpy(&err_->msg[0], s, sizeof(s)); \ + } while (0) #define NLUA_CLEAR_REF(x) \ do { \ diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index e19274ced9..02bd612149 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -30,6 +30,7 @@ typedef struct { TSQueryCursor *cursor; int predicated_match; + int max_match_id; } TSLua_cursor; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -260,7 +261,7 @@ int tslua_push_parser(lua_State *L) return 1; } -static TSParser ** parser_check(lua_State *L, uint16_t index) +static TSParser **parser_check(lua_State *L, uint16_t index) { return luaL_checkudata(L, index, TS_META_PARSER); } @@ -933,7 +934,7 @@ push: ts_tree_cursor_current_node(ud), lua_upvalueindex(2)); // [node] - const char * field = ts_tree_cursor_current_field_name(ud); + const char *field = ts_tree_cursor_current_field_name(ud); if (field != NULL) { lua_pushstring(L, ts_tree_cursor_current_field_name(ud)); @@ -1055,6 +1056,8 @@ static int query_next_match(lua_State *L) static int query_next_capture(lua_State *L) { + // Upvalues are: + // [ cursor, node, query, current_match ] TSLua_cursor *ud = lua_touserdata(L, lua_upvalueindex(1)); TSQueryCursor *cursor = ud->cursor; @@ -1078,9 +1081,13 @@ static int query_next_capture(lua_State *L) lua_pushinteger(L, capture.index+1); // [index] push_node(L, capture.node, lua_upvalueindex(2)); // [index, node] + // Now check if we need to run the predicates uint32_t n_pred; ts_query_predicates_for_pattern(query, match.pattern_index, &n_pred); - if (n_pred > 0 && capture_index == 0) { + + if (n_pred > 0 && (ud->max_match_id < (int)match.id)) { + ud->max_match_id = match.id; + lua_pushvalue(L, lua_upvalueindex(4)); // [index, node, match] set_match(L, &match, lua_upvalueindex(2)); lua_pushinteger(L, match.pattern_index+1); @@ -1127,6 +1134,7 @@ static int node_rawquery(lua_State *L) TSLua_cursor *ud = lua_newuserdata(L, sizeof(*ud)); // [udata] ud->cursor = cursor; ud->predicated_match = -1; + ud->max_match_id = -1; lua_getfield(L, LUA_REGISTRYINDEX, TS_META_QUERYCURSOR); lua_setmetatable(L, -2); // [udata] diff --git a/src/nvim/lua/treesitter.h b/src/nvim/lua/treesitter.h index 812166f67b..b69fb9dfae 100644 --- a/src/nvim/lua/treesitter.h +++ b/src/nvim/lua/treesitter.h @@ -1,9 +1,9 @@ #ifndef NVIM_LUA_TREESITTER_H #define NVIM_LUA_TREESITTER_H +#include <lauxlib.h> #include <lua.h> #include <lualib.h> -#include <lauxlib.h> #include "tree_sitter/api.h" diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index ba124c41ad..30c7034209 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -57,28 +57,29 @@ end function vim._load_package(name) local basename = name:gsub('%.', '/') local paths = {"lua/"..basename..".lua", "lua/"..basename.."/init.lua"} - for _,path in ipairs(paths) do - local found = vim.api.nvim_get_runtime_file(path, false) - if #found > 0 then - local f, err = loadfile(found[1]) - return f or error(err) - end + local found = vim.api.nvim__get_runtime(paths, false, {is_lua=true}) + if #found > 0 then + local f, err = loadfile(found[1]) + return f or error(err) end + local so_paths = {} for _,trail in ipairs(vim._so_trails) do local path = "lua"..trail:gsub('?', basename) -- so_trails contains a leading slash - local found = vim.api.nvim_get_runtime_file(path, false) - if #found > 0 then - -- Making function name in Lua 5.1 (see src/loadlib.c:mkfuncname) is - -- a) strip prefix up to and including the first dash, if any - -- b) replace all dots by underscores - -- c) prepend "luaopen_" - -- So "foo-bar.baz" should result in "luaopen_bar_baz" - local dash = name:find("-", 1, true) - local modname = dash and name:sub(dash + 1) or name - local f, err = package.loadlib(found[1], "luaopen_"..modname:gsub("%.", "_")) - return f or error(err) - end + table.insert(so_paths, path) + end + + found = vim.api.nvim__get_runtime(so_paths, false, {is_lua=true}) + if #found > 0 then + -- Making function name in Lua 5.1 (see src/loadlib.c:mkfuncname) is + -- a) strip prefix up to and including the first dash, if any + -- b) replace all dots by underscores + -- c) prepend "luaopen_" + -- So "foo-bar.baz" should result in "luaopen_bar_baz" + local dash = name:find("-", 1, true) + local modname = dash and name:sub(dash + 1) or name + local f, err = package.loadlib(found[1], "luaopen_"..modname:gsub("%.", "_")) + return f or error(err) end return nil end @@ -108,6 +109,9 @@ setmetatable(vim, { elseif key == 'diagnostic' then t.diagnostic = require('vim.diagnostic') return t.diagnostic + elseif key == 'ui' then + t.ui = require('vim.ui') + return t.ui end end }) @@ -319,22 +323,25 @@ end do local validate = vim.validate - local function make_dict_accessor(scope) + local function make_dict_accessor(scope, handle) validate { scope = {scope, 's'}; } local mt = {} function mt:__newindex(k, v) - return vim._setvar(scope, 0, k, v) + return vim._setvar(scope, handle or 0, k, v) end function mt:__index(k) - return vim._getvar(scope, 0, k) + if handle == nil and type(k) == 'number' then + return make_dict_accessor(scope, k) + end + return vim._getvar(scope, handle or 0, k) end return setmetatable({}, mt) end - vim.g = make_dict_accessor('g') - vim.v = make_dict_accessor('v') + vim.g = make_dict_accessor('g', false) + vim.v = make_dict_accessor('v', false) vim.b = make_dict_accessor('b') vim.w = make_dict_accessor('w') vim.t = make_dict_accessor('t') @@ -430,6 +437,7 @@ function vim.notify(msg, log_level, _opts) end +---@private function vim.register_keystroke_callback() error('vim.register_keystroke_callback is deprecated, instead use: vim.on_key') end diff --git a/src/nvim/lua/xdiff.c b/src/nvim/lua/xdiff.c index dc2675a1fe..7eda9b6270 100644 --- a/src/nvim/lua/xdiff.c +++ b/src/nvim/lua/xdiff.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + #include <errno.h> #include <lauxlib.h> #include <lua.h> @@ -50,8 +53,8 @@ static int write_string(void *priv, mmbuffer_t *mb, int nbuf) static int hunk_locations_cb(long start_a, long count_a, long start_b, long count_b, void *cb_data) { // Mimic extra offsets done by xdiff, see: - // src/nvim/xdiff/xemit.c:284 - // src/nvim/xdiff/xutils.c:(356,368) + // src/xdiff/xemit.c:284 + // src/xdiff/xutils.c:(356,368) if (count_a > 0) { start_a += 1; } @@ -59,7 +62,7 @@ static int hunk_locations_cb(long start_a, long count_a, long start_b, long coun start_b += 1; } - lua_State * lstate = (lua_State *)cb_data; + lua_State *lstate = (lua_State *)cb_data; lua_createtable(lstate, 0, 0); lua_pushinteger(lstate, start_a); @@ -80,8 +83,8 @@ static int hunk_locations_cb(long start_a, long count_a, long start_b, long coun static int call_on_hunk_cb(long start_a, long count_a, long start_b, long count_b, void *cb_data) { // Mimic extra offsets done by xdiff, see: - // src/nvim/xdiff/xemit.c:284 - // src/nvim/xdiff/xutils.c:(356,368) + // src/xdiff/xemit.c:284 + // src/xdiff/xutils.c:(356,368) if (count_a > 0) { start_a += 1; } @@ -90,7 +93,7 @@ static int call_on_hunk_cb(long start_a, long count_a, long start_b, long count_ } hunkpriv_t *priv = (hunkpriv_t *)cb_data; - lua_State * lstate = priv->lstate; + lua_State *lstate = priv->lstate; Error *err = priv->err; const int fidx = lua_gettop(lstate); lua_pushvalue(lstate, fidx); @@ -130,7 +133,7 @@ static mmfile_t get_string_arg(lua_State *lstate, int idx) static bool check_xdiff_opt(ObjectType actType, ObjectType expType, const char *name, Error *err) { if (actType != expType) { - const char * type_str = + const char *type_str = expType == kObjectTypeString ? "string" : expType == kObjectTypeInteger ? "integer" : expType == kObjectTypeBoolean ? "boolean" : @@ -262,8 +265,8 @@ int nlua_xdl_diff(lua_State *lstate) Error err = ERROR_INIT; xdemitconf_t cfg; - xpparam_t params; - xdemitcb_t ecb; + xpparam_t params; + xdemitcb_t ecb; memset(&cfg, 0, sizeof(cfg)); memset(¶ms, 0, sizeof(params)); diff --git a/src/nvim/lua/xdiff.h b/src/nvim/lua/xdiff.h index cae7c98e81..b172d2f922 100644 --- a/src/nvim/lua/xdiff.h +++ b/src/nvim/lua/xdiff.h @@ -1,9 +1,9 @@ #ifndef NVIM_LUA_XDIFF_H #define NVIM_LUA_XDIFF_H +#include <lauxlib.h> #include <lua.h> #include <lualib.h> -#include <lauxlib.h> #ifdef INCLUDE_GENERATED_DECLARATIONS # include "lua/xdiff.h.generated.h" diff --git a/src/nvim/macros.h b/src/nvim/macros.h index e1aa1b7704..50ee91dc36 100644 --- a/src/nvim/macros.h +++ b/src/nvim/macros.h @@ -43,15 +43,15 @@ #define TOLOWER_LOC tolower // toupper() and tolower() for ASCII only and ignore the current locale. -# define TOUPPER_ASC(c) (((c) < 'a' || (c) > 'z') ? (c) : (c) - ('a' - 'A')) -# define TOLOWER_ASC(c) (((c) < 'A' || (c) > 'Z') ? (c) : (c) + ('a' - 'A')) +#define TOUPPER_ASC(c) (((c) < 'a' || (c) > 'z') ? (c) : (c) - ('a' - 'A')) +#define TOLOWER_ASC(c) (((c) < 'A' || (c) > 'Z') ? (c) : (c) + ('a' - 'A')) // Like isalpha() but reject non-ASCII characters. Can't be used with a // special key (negative value). -# define ASCII_ISLOWER(c) ((unsigned)(c) >= 'a' && (unsigned)(c) <= 'z') -# define ASCII_ISUPPER(c) ((unsigned)(c) >= 'A' && (unsigned)(c) <= 'Z') -# define ASCII_ISALPHA(c) (ASCII_ISUPPER(c) || ASCII_ISLOWER(c)) -# define ASCII_ISALNUM(c) (ASCII_ISALPHA(c) || ascii_isdigit(c)) +#define ASCII_ISLOWER(c) ((unsigned)(c) >= 'a' && (unsigned)(c) <= 'z') +#define ASCII_ISUPPER(c) ((unsigned)(c) >= 'A' && (unsigned)(c) <= 'Z') +#define ASCII_ISALPHA(c) (ASCII_ISUPPER(c) || ASCII_ISLOWER(c)) +#define ASCII_ISALNUM(c) (ASCII_ISALPHA(c) || ascii_isdigit(c)) // Returns empty string if it is NULL. #define EMPTY_IF_NULL(x) ((x) ? (x) : (char_u *)"") @@ -62,7 +62,7 @@ // Don't apply 'langmap' if the character comes from the Stuff buffer or from a // mapping and the langnoremap option was set. // The do-while is just to ignore a ';' after the macro. -# define LANGMAP_ADJUST(c, condition) \ +#define LANGMAP_ADJUST(c, condition) \ do { \ if (*p_langmap \ && (condition) \ @@ -71,9 +71,9 @@ && (c) >= 0) \ { \ if ((c) < 256) \ - c = langmap_mapchar[c]; \ + c = langmap_mapchar[c]; \ else \ - c = langmap_adjust_mb(c); \ + c = langmap_adjust_mb(c); \ } \ } while (0) @@ -90,9 +90,9 @@ # define mch_open_rw(n, f) os_open((n), (f), 0) #endif -# define REPLACE_NORMAL(s) (((s) & REPLACE_FLAG) && !((s) & VREPLACE_FLAG)) +#define REPLACE_NORMAL(s) (((s) & REPLACE_FLAG) && !((s) & VREPLACE_FLAG)) -# define UTF_COMPOSINGLIKE(p1, p2) utf_composinglike((p1), (p2)) +#define UTF_COMPOSINGLIKE(p1, p2) utf_composinglike((p1), (p2)) // MB_PTR_ADV(): advance a pointer to the next character, taking care of // multi-byte characters if needed. @@ -102,22 +102,22 @@ // PTR2CHAR(): get character from pointer. // Advance multi-byte pointer, skip over composing chars. -# define MB_PTR_ADV(p) (p += mb_ptr2len((char_u *)p)) +#define MB_PTR_ADV(p) (p += mb_ptr2len((char_u *)p)) // Advance multi-byte pointer, do not skip over composing chars. -# define MB_CPTR_ADV(p) (p += utf_ptr2len(p)) +#define MB_CPTR_ADV(p) (p += utf_ptr2len(p)) // Backup multi-byte pointer. Only use with "p" > "s" ! -# define MB_PTR_BACK(s, p) \ - (p -= utf_head_off((char_u *)s, (char_u *)p - 1) + 1) +#define MB_PTR_BACK(s, p) \ + (p -= utf_head_off((char_u *)s, (char_u *)p - 1) + 1) // get length of multi-byte char, not including composing chars -# define MB_CPTR2LEN(p) utf_ptr2len(p) +#define MB_CPTR2LEN(p) utf_ptr2len(p) -# define MB_COPY_CHAR(f, t) mb_copy_char((const char_u **)(&f), &t); +#define MB_COPY_CHAR(f, t) mb_copy_char((const char_u **)(&f), &t); -# define MB_CHARLEN(p) mb_charlen(p) -# define MB_CHAR2LEN(c) mb_char2len(c) -# define PTR2CHAR(p) utf_ptr2char(p) +#define MB_CHARLEN(p) mb_charlen(p) +#define MB_CHAR2LEN(c) mb_char2len(c) +#define PTR2CHAR(p) utf_ptr2char(p) -# define RESET_BINDING(wp) \ +#define RESET_BINDING(wp) \ do { \ (wp)->w_p_scb = false; \ (wp)->w_p_crb = false; \ @@ -132,8 +132,8 @@ /// /// -V:ARRAY_SIZE:1063 #define ARRAY_SIZE(arr) \ - ((sizeof(arr)/sizeof((arr)[0])) \ - / ((size_t)(!(sizeof(arr) % sizeof((arr)[0]))))) + ((sizeof(arr)/sizeof((arr)[0])) \ + / ((size_t)(!(sizeof(arr) % sizeof((arr)[0]))))) /// Get last array entry /// @@ -156,7 +156,7 @@ #ifndef __has_attribute # define NVIM_HAS_ATTRIBUTE(x) 0 #elif defined(__clang__) && __clang__ == 1 \ - && (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ <= 5)) + && (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ <= 5)) // Starting in Clang 3.6, __has_attribute was fixed to only report true for // GNU-style attributes. Prior to that, it reported true if _any_ backend // supported the attribute. @@ -166,7 +166,7 @@ #endif #if NVIM_HAS_ATTRIBUTE(fallthrough) \ - && (!defined(__apple_build_version__) || __apple_build_version__ >= 7000000) + && (!defined(__apple_build_version__) || __apple_build_version__ >= 7000000) # define FALLTHROUGH {} __attribute__((fallthrough)) #else # define FALLTHROUGH @@ -204,29 +204,29 @@ /// #if defined(__clang__) && __clang__ == 1 # define PRAGMA_DIAG_PUSH_IGNORE_MISSING_PROTOTYPES \ - _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic push")\ _Pragma("clang diagnostic ignored \"-Wmissing-prototypes\"") # ifdef HAVE_WIMPLICIT_FALLTHROUGH_FLAG # define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wimplicit-fallthrough\"") + _Pragma("clang diagnostic push")\ + _Pragma("clang diagnostic ignored \"-Wimplicit-fallthrough\"") # else # define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH \ - _Pragma("clang diagnostic push") + _Pragma("clang diagnostic push") # endif # define PRAGMA_DIAG_POP \ - _Pragma("clang diagnostic pop") + _Pragma("clang diagnostic pop") #elif defined(__GNUC__) # define PRAGMA_DIAG_PUSH_IGNORE_MISSING_PROTOTYPES \ - _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic push")\ _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"") # ifdef HAVE_WIMPLICIT_FALLTHROUGH_FLAG # define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") + _Pragma("GCC diagnostic push")\ + _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") # else # define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH \ - _Pragma("GCC diagnostic push") + _Pragma("GCC diagnostic push") # endif # define PRAGMA_DIAG_POP \ _Pragma("GCC diagnostic pop") diff --git a/src/nvim/main.c b/src/nvim/main.c index 1507dfac00..00a43c9c79 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -3,25 +3,22 @@ #define EXTERN #include <assert.h> +#include <msgpack.h> +#include <stdbool.h> #include <stdint.h> #include <string.h> -#include <stdbool.h> - -#include <msgpack.h> #include "nvim/ascii.h" -#include "nvim/channel.h" -#include "nvim/vim.h" -#include "nvim/main.h" #include "nvim/aucmd.h" #include "nvim/buffer.h" +#include "nvim/channel.h" #include "nvim/charset.h" +#include "nvim/decoration.h" #include "nvim/diff.h" #include "nvim/eval.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_docmd.h" -#include "nvim/decoration.h" #include "nvim/fileio.h" #include "nvim/fold.h" #include "nvim/getchar.h" @@ -30,29 +27,36 @@ #include "nvim/iconv.h" #include "nvim/if_cscope.h" #include "nvim/lua/executor.h" +#include "nvim/main.h" +#include "nvim/vim.h" #ifdef HAVE_LOCALE_H # include <locale.h> #endif +#include "nvim/garray.h" +#include "nvim/log.h" #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" +#include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/garray.h" -#include "nvim/log.h" -#include "nvim/memory.h" -#include "nvim/move.h" #include "nvim/mouse.h" +#include "nvim/move.h" #include "nvim/normal.h" #include "nvim/ops.h" #include "nvim/option.h" -#include "nvim/os_unix.h" +#include "nvim/os/fileio.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" #include "nvim/os/os_defs.h" +#include "nvim/os/time.h" +#include "nvim/os_unix.h" #include "nvim/path.h" -#include "nvim/profile.h" #include "nvim/popupmnu.h" +#include "nvim/profile.h" #include "nvim/quickfix.h" #include "nvim/screen.h" +#include "nvim/shada.h" #include "nvim/sign.h" #include "nvim/state.h" #include "nvim/strings.h" @@ -61,24 +65,19 @@ #include "nvim/ui_compositor.h" #include "nvim/version.h" #include "nvim/window.h" -#include "nvim/shada.h" -#include "nvim/os/input.h" -#include "nvim/os/os.h" -#include "nvim/os/time.h" -#include "nvim/os/fileio.h" #ifdef WIN32 # include "nvim/os/os_win_console.h" #endif +#include "nvim/api/private/defs.h" +#include "nvim/api/private/dispatch.h" +#include "nvim/api/private/helpers.h" +#include "nvim/api/ui.h" #include "nvim/event/loop.h" -#include "nvim/os/signal.h" #include "nvim/event/process.h" +#include "nvim/msgpack_rpc/channel.h" #include "nvim/msgpack_rpc/helpers.h" #include "nvim/msgpack_rpc/server.h" -#include "nvim/msgpack_rpc/channel.h" -#include "nvim/api/ui.h" -#include "nvim/api/private/defs.h" -#include "nvim/api/private/helpers.h" -#include "nvim/api/private/dispatch.h" +#include "nvim/os/signal.h" #ifndef WIN32 # include "nvim/os/pty_process_unix.h" #endif @@ -278,9 +277,9 @@ int main(int argc, char **argv) TIME_MSG("expanding arguments"); - if (params.diff_mode && params.window_count == -1) - params.window_count = 0; /* open up to 3 windows */ - + if (params.diff_mode && params.window_count == -1) { + params.window_count = 0; // open up to 3 windows + } // Don't redraw until much later. RedrawingDisabled++; @@ -346,7 +345,8 @@ int main(int argc, char **argv) // Reset 'loadplugins' for "-u NONE" before "--cmd" arguments. // Allows for setting 'loadplugins' there. if (params.use_vimrc != NULL && strequal(params.use_vimrc, "NONE")) { - p_lpl = false; + // When using --clean we still want to load plugins + p_lpl = params.clean; } // Execute --cmd arguments. @@ -583,18 +583,19 @@ void getout(int exitval) { exiting = true; - /* When running in Ex mode an error causes us to exit with a non-zero exit - * code. POSIX requires this, although it's not 100% clear from the - * standard. */ - if (exmode_active) + // When running in Ex mode an error causes us to exit with a non-zero exit + // code. POSIX requires this, although it's not 100% clear from the + // standard. + if (exmode_active) { exitval += ex_exitval; + } set_vim_var_nr(VV_EXITING, exitval); // Position the cursor on the last screen line, below all the text ui_cursor_goto(Rows - 1, 0); - /* Optionally print hashtable efficiency. */ + // Optionally print hashtable efficiency. hash_debug_results(); if (v_dying <= 1) { @@ -605,7 +606,7 @@ void getout(int exitval) next_tp = tp->tp_next; FOR_ALL_WINDOWS_IN_TAB(wp, tp) { if (wp->w_buffer == NULL) { - /* Autocmd must have close the buffer already, skip. */ + // Autocmd must have close the buffer already, skip. continue; } @@ -626,7 +627,7 @@ void getout(int exitval) } } - /* Trigger BufUnload for buffers that are loaded */ + // Trigger BufUnload for buffers that are loaded FOR_ALL_BUFFERS(buf) { if (buf->b_ml.ml_mfp != NULL) { bufref_T bufref; @@ -674,8 +675,8 @@ void getout(int exitval) profile_dump(); if (did_emsg - ) { - /* give the user a chance to read the (error) message */ + ) { + // give the user a chance to read the (error) message no_wait_return = FALSE; wait_return(FALSE); } @@ -727,7 +728,7 @@ static void init_locale(void) setlocale(LC_ALL, ""); # ifdef LC_NUMERIC - /* Make sure strtod() uses a decimal point, not a comma. */ + // Make sure strtod() uses a decimal point, not a comma. setlocale(LC_NUMERIC, "C"); # endif @@ -749,10 +750,10 @@ static void init_locale(void) static bool edit_stdin(bool explicit, mparm_T *parmp) { bool implicit = !headless_mode - && !embedded_mode - && (!exmode_active || parmp->input_neverscript) - && !parmp->input_isatty - && scriptin[0] == NULL; // `-s -` was not given. + && !embedded_mode + && (!exmode_active || parmp->input_neverscript) + && !parmp->input_isatty + && scriptin[0] == NULL; // `-s -` was not given. return explicit || implicit; } @@ -784,270 +785,242 @@ static void command_line_scan(mparm_T *parmp) parmp->commands[parmp->n_commands++] = &(argv[0][1]); } - // Optional argument. + // Optional argument. } else if (argv[0][0] == '-' && !had_minmin) { want_argument = false; c = argv[0][argv_idx++]; switch (c) { - case NUL: { // "nvim -" read from stdin - if (exmode_active) { - // "nvim -e -" silent mode - silent_mode = true; - parmp->no_swap_file = true; - } else { - if (parmp->edit_type != EDIT_NONE - && parmp->edit_type != EDIT_FILE - && parmp->edit_type != EDIT_STDIN) { - mainerr(err_too_many_args, argv[0]); - } - had_stdin_file = true; - parmp->edit_type = EDIT_STDIN; + case NUL: // "nvim -" read from stdin + if (exmode_active) { + // "nvim -e -" silent mode + silent_mode = true; + parmp->no_swap_file = true; + } else { + if (parmp->edit_type != EDIT_NONE + && parmp->edit_type != EDIT_FILE + && parmp->edit_type != EDIT_STDIN) { + mainerr(err_too_many_args, argv[0]); } - argv_idx = -1; // skip to next argument - break; + had_stdin_file = true; + parmp->edit_type = EDIT_STDIN; } - case '-': { // "--" don't take any more option arguments - // "--help" give help message - // "--version" give version message - // "--noplugin[s]" skip plugins - // "--cmd <cmd>" execute cmd before vimrc - if (STRICMP(argv[0] + argv_idx, "help") == 0) { - usage(); - os_exit(0); - } else if (STRICMP(argv[0] + argv_idx, "version") == 0) { - version(); - os_exit(0); - } else if (STRICMP(argv[0] + argv_idx, "api-info") == 0) { - FileDescriptor fp; - const int fof_ret = file_open_fd(&fp, STDOUT_FILENO, - kFileWriteOnly); - msgpack_packer *p = msgpack_packer_new(&fp, msgpack_file_write); - - if (fof_ret != 0) { - emsgf(_("E5421: Failed to open stdin: %s"), os_strerror(fof_ret)); - } + argv_idx = -1; // skip to next argument + break; + case '-': // "--" don't take any more option arguments + // "--help" give help message + // "--version" give version message + // "--noplugin[s]" skip plugins + // "--cmd <cmd>" execute cmd before vimrc + if (STRICMP(argv[0] + argv_idx, "help") == 0) { + usage(); + os_exit(0); + } else if (STRICMP(argv[0] + argv_idx, "version") == 0) { + version(); + os_exit(0); + } else if (STRICMP(argv[0] + argv_idx, "api-info") == 0) { + FileDescriptor fp; + const int fof_ret = file_open_fd(&fp, STDOUT_FILENO, + kFileWriteOnly); + msgpack_packer *p = msgpack_packer_new(&fp, msgpack_file_write); + + if (fof_ret != 0) { + emsgf(_("E5421: Failed to open stdin: %s"), os_strerror(fof_ret)); + } - if (p == NULL) { - EMSG(_(e_outofmem)); - } + if (p == NULL) { + EMSG(_(e_outofmem)); + } - Object md = DICTIONARY_OBJ(api_metadata()); - msgpack_rpc_from_object(md, p); + Object md = DICTIONARY_OBJ(api_metadata()); + msgpack_rpc_from_object(md, p); - msgpack_packer_free(p); - const int ff_ret = file_flush(&fp); - if (ff_ret < 0) { - msgpack_file_write_error(ff_ret); - } - os_exit(0); - } else if (STRICMP(argv[0] + argv_idx, "headless") == 0) { - headless_mode = true; - } else if (STRICMP(argv[0] + argv_idx, "embed") == 0) { - embedded_mode = true; - } else if (STRNICMP(argv[0] + argv_idx, "listen", 6) == 0) { - want_argument = true; - argv_idx += 6; - } else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) { - // Do nothing: file args are always literal. #7679 - } else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0) { - p_lpl = false; - } else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0) { - want_argument = true; - argv_idx += 3; - } else if (STRNICMP(argv[0] + argv_idx, "startuptime", 11) == 0) { - want_argument = true; - argv_idx += 11; - } else if (STRNICMP(argv[0] + argv_idx, "clean", 5) == 0) { - parmp->use_vimrc = "NONE"; - parmp->clean = true; - set_option_value("shadafile", 0L, "NONE", 0); - } else { - if (argv[0][argv_idx]) - mainerr(err_opt_unknown, argv[0]); - had_minmin = true; + msgpack_packer_free(p); + const int ff_ret = file_flush(&fp); + if (ff_ret < 0) { + msgpack_file_write_error(ff_ret); } - if (!want_argument) { - argv_idx = -1; // skip to next argument + os_exit(0); + } else if (STRICMP(argv[0] + argv_idx, "headless") == 0) { + headless_mode = true; + } else if (STRICMP(argv[0] + argv_idx, "embed") == 0) { + embedded_mode = true; + } else if (STRNICMP(argv[0] + argv_idx, "listen", 6) == 0) { + want_argument = true; + argv_idx += 6; + } else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) { + // Do nothing: file args are always literal. #7679 + } else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0) { + p_lpl = false; + } else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0) { + want_argument = true; + argv_idx += 3; + } else if (STRNICMP(argv[0] + argv_idx, "startuptime", 11) == 0) { + want_argument = true; + argv_idx += 11; + } else if (STRNICMP(argv[0] + argv_idx, "clean", 5) == 0) { + parmp->use_vimrc = "NONE"; + parmp->clean = true; + set_option_value("shadafile", 0L, "NONE", 0); + } else { + if (argv[0][argv_idx]) { + mainerr(err_opt_unknown, argv[0]); } - break; + had_minmin = true; } - case 'A': { // "-A" start in Arabic mode. - set_option_value("arabic", 1L, NULL, 0); - break; - } - case 'b': { // "-b" binary mode. - // Needs to be effective before expanding file names, because - // for Win32 this makes us edit a shortcut file itself, - // instead of the file it links to. - set_options_bin(curbuf->b_p_bin, 1, 0); - curbuf->b_p_bin = 1; // Binary file I/O. - break; + if (!want_argument) { + argv_idx = -1; // skip to next argument } + break; + case 'A': // "-A" start in Arabic mode. + set_option_value("arabic", 1L, NULL, 0); + break; + case 'b': // "-b" binary mode. + // Needs to be effective before expanding file names, because + // for Win32 this makes us edit a shortcut file itself, + // instead of the file it links to. + set_options_bin(curbuf->b_p_bin, 1, 0); + curbuf->b_p_bin = 1; // Binary file I/O. + break; - case 'D': { // "-D" Debugging - parmp->use_debug_break_level = 9999; - break; - } - case 'd': { // "-d" 'diff' - parmp->diff_mode = true; - break; - } - case 'e': { // "-e" Ex mode - exmode_active = true; - break; - } - case 'E': { // "-E" Ex mode - exmode_active = true; - parmp->input_neverscript = true; - break; - } - case 'f': { // "-f" GUI: run in foreground. - break; - } - case '?': // "-?" give help message (for MS-Windows) - case 'h': { // "-h" give help message - usage(); - os_exit(0); - } - case 'H': { // "-H" start in Hebrew mode: rl + hkmap set. - p_hkmap = true; - set_option_value("rl", 1L, NULL, 0); - break; - } - case 'l': { // "-l" lisp mode, 'lisp' and 'showmatch' on. - set_option_value("lisp", 1L, NULL, 0); - p_sm = true; - break; - } - case 'M': { // "-M" no changes or writing of files - reset_modifiable(); - FALLTHROUGH; - } - case 'm': { // "-m" no writing of files - p_write = false; - break; - } + case 'D': // "-D" Debugging + parmp->use_debug_break_level = 9999; + break; + case 'd': // "-d" 'diff' + parmp->diff_mode = true; + break; + case 'e': // "-e" Ex mode + exmode_active = true; + break; + case 'E': // "-E" Ex mode + exmode_active = true; + parmp->input_neverscript = true; + break; + case 'f': // "-f" GUI: run in foreground. + break; + case '?': // "-?" give help message (for MS-Windows) + case 'h': // "-h" give help message + usage(); + os_exit(0); + case 'H': // "-H" start in Hebrew mode: rl + hkmap set. + p_hkmap = true; + set_option_value("rl", 1L, NULL, 0); + break; + case 'l': // "-l" lisp mode, 'lisp' and 'showmatch' on. + set_option_value("lisp", 1L, NULL, 0); + p_sm = true; + break; + case 'M': // "-M" no changes or writing of files + reset_modifiable(); + FALLTHROUGH; + case 'm': // "-m" no writing of files + p_write = false; + break; - case 'N': // "-N" Nocompatible - case 'X': // "-X" Do not connect to X server - // No-op - break; + case 'N': // "-N" Nocompatible + case 'X': // "-X" Do not connect to X server + // No-op + break; - case 'n': { // "-n" no swap file - parmp->no_swap_file = true; - break; - } - case 'p': { // "-p[N]" open N tab pages - // default is 0: open window for each file - parmp->window_count = get_number_arg(argv[0], &argv_idx, 0); - parmp->window_layout = WIN_TABS; - break; - } - case 'o': { // "-o[N]" open N horizontal split windows - // default is 0: open window for each file - parmp->window_count = get_number_arg(argv[0], &argv_idx, 0); - parmp->window_layout = WIN_HOR; - break; - } - case 'O': { // "-O[N]" open N vertical split windows - // default is 0: open window for each file - parmp->window_count = get_number_arg(argv[0], &argv_idx, 0); - parmp->window_layout = WIN_VER; - break; - } - case 'q': { // "-q" QuickFix mode - if (parmp->edit_type != EDIT_NONE) { - mainerr(err_too_many_args, argv[0]); - } - parmp->edit_type = EDIT_QF; - if (argv[0][argv_idx]) { // "-q{errorfile}" - parmp->use_ef = (char_u *)argv[0] + argv_idx; - argv_idx = -1; - } else if (argc > 1) { // "-q {errorfile}" - want_argument = true; - } - break; - } - case 'R': { // "-R" readonly mode - readonlymode = true; - curbuf->b_p_ro = true; - p_uc = 10000; // don't update very often - break; + case 'n': // "-n" no swap file + parmp->no_swap_file = true; + break; + case 'p': // "-p[N]" open N tab pages + // default is 0: open window for each file + parmp->window_count = get_number_arg(argv[0], &argv_idx, 0); + parmp->window_layout = WIN_TABS; + break; + case 'o': // "-o[N]" open N horizontal split windows + // default is 0: open window for each file + parmp->window_count = get_number_arg(argv[0], &argv_idx, 0); + parmp->window_layout = WIN_HOR; + break; + case 'O': // "-O[N]" open N vertical split windows + // default is 0: open window for each file + parmp->window_count = get_number_arg(argv[0], &argv_idx, 0); + parmp->window_layout = WIN_VER; + break; + case 'q': // "-q" QuickFix mode + if (parmp->edit_type != EDIT_NONE) { + mainerr(err_too_many_args, argv[0]); } - case 'r': // "-r" recovery mode - case 'L': { // "-L" recovery mode - recoverymode = 1; - break; + parmp->edit_type = EDIT_QF; + if (argv[0][argv_idx]) { // "-q{errorfile}" + parmp->use_ef = (char_u *)argv[0] + argv_idx; + argv_idx = -1; + } else if (argc > 1) { // "-q {errorfile}" + want_argument = true; } - case 's': { - if (exmode_active) { // "-es" silent (batch) Ex-mode - silent_mode = true; - parmp->no_swap_file = true; - } else { // "-s {scriptin}" read from script file - want_argument = true; - } - break; + break; + case 'R': // "-R" readonly mode + readonlymode = true; + curbuf->b_p_ro = true; + p_uc = 10000; // don't update very often + break; + case 'r': // "-r" recovery mode + case 'L': // "-L" recovery mode + recoverymode = 1; + break; + case 's': + if (exmode_active) { // "-es" silent (batch) Ex-mode + silent_mode = true; + parmp->no_swap_file = true; + } else { // "-s {scriptin}" read from script file + want_argument = true; } - case 't': { // "-t {tag}" or "-t{tag}" jump to tag - if (parmp->edit_type != EDIT_NONE) { - mainerr(err_too_many_args, argv[0]); - } - parmp->edit_type = EDIT_TAG; - if (argv[0][argv_idx]) { // "-t{tag}" - parmp->tagname = (char_u *)argv[0] + argv_idx; - argv_idx = -1; - } else { // "-t {tag}" - want_argument = true; - } - break; + break; + case 't': // "-t {tag}" or "-t{tag}" jump to tag + if (parmp->edit_type != EDIT_NONE) { + mainerr(err_too_many_args, argv[0]); } - case 'v': { - version(); - os_exit(0); + parmp->edit_type = EDIT_TAG; + if (argv[0][argv_idx]) { // "-t{tag}" + parmp->tagname = (char_u *)argv[0] + argv_idx; + argv_idx = -1; + } else { // "-t {tag}" + want_argument = true; } - case 'V': { // "-V{N}" Verbose level - // default is 10: a little bit verbose - p_verbose = get_number_arg(argv[0], &argv_idx, 10); - if (argv[0][argv_idx] != NUL) { - set_option_value("verbosefile", 0L, argv[0] + argv_idx, 0); - argv_idx = (int)STRLEN(argv[0]); - } - break; + break; + case 'v': + version(); + os_exit(0); + case 'V': // "-V{N}" Verbose level + // default is 10: a little bit verbose + p_verbose = get_number_arg(argv[0], &argv_idx, 10); + if (argv[0][argv_idx] != NUL) { + set_option_value("verbosefile", 0L, argv[0] + argv_idx, 0); + argv_idx = (int)STRLEN(argv[0]); } - case 'w': { // "-w{number}" set window height - // "-w {scriptout}" write to script - if (ascii_isdigit(((char_u *)argv[0])[argv_idx])) { - n = get_number_arg(argv[0], &argv_idx, 10); - set_option_value("window", n, NULL, 0); - break; - } - want_argument = true; + break; + case 'w': // "-w{number}" set window height + // "-w {scriptout}" write to script + if (ascii_isdigit(((char_u *)argv[0])[argv_idx])) { + n = get_number_arg(argv[0], &argv_idx, 10); + set_option_value("window", n, NULL, 0); break; } + want_argument = true; + break; - case 'c': { // "-c{command}" or "-c {command}" exec command - if (argv[0][argv_idx] != NUL) { - if (parmp->n_commands >= MAX_ARG_CMDS) { - mainerr(err_extra_cmd, NULL); - } - parmp->commands[parmp->n_commands++] = argv[0] + argv_idx; - argv_idx = -1; - break; + case 'c': // "-c{command}" or "-c {command}" exec command + if (argv[0][argv_idx] != NUL) { + if (parmp->n_commands >= MAX_ARG_CMDS) { + mainerr(err_extra_cmd, NULL); } - FALLTHROUGH; - } - case 'S': // "-S {file}" execute Vim script - case 'i': // "-i {shada}" use for ShaDa file - case 'u': // "-u {vimrc}" vim inits file - case 'U': // "-U {gvimrc}" gvim inits file - case 'W': { // "-W {scriptout}" overwrite - want_argument = true; + parmp->commands[parmp->n_commands++] = argv[0] + argv_idx; + argv_idx = -1; break; } + FALLTHROUGH; + case 'S': // "-S {file}" execute Vim script + case 'i': // "-i {shada}" use for ShaDa file + case 'u': // "-u {vimrc}" vim inits file + case 'U': // "-U {gvimrc}" gvim inits file + case 'W': // "-W {scriptout}" overwrite + want_argument = true; + break; - default: { - mainerr(err_opt_unknown, argv[0]); - } + default: + mainerr(err_opt_unknown, argv[0]); } // Handle option arguments with argument. @@ -1065,130 +1038,122 @@ static void command_line_scan(mparm_T *parmp) argv_idx = -1; switch (c) { - case 'c': // "-c {command}" execute command - case 'S': { // "-S {file}" execute Vim script - if (parmp->n_commands >= MAX_ARG_CMDS) { - mainerr(err_extra_cmd, NULL); - } - if (c == 'S') { - char *a; - - if (argc < 1) { - // "-S" without argument: use default session file name. - a = SESSION_FILE; - } else if (argv[0][0] == '-') { - // "-S" followed by another option: use default session file. - a = SESSION_FILE; - ++argc; - --argv; - } else { - a = argv[0]; - } - - size_t s_size = STRLEN(a) + 9; - char *s = xmalloc(s_size); - snprintf(s, s_size, "so %s", a); - parmp->cmds_tofree[parmp->n_commands] = true; - parmp->commands[parmp->n_commands++] = s; + case 'c': // "-c {command}" execute command + case 'S': // "-S {file}" execute Vim script + if (parmp->n_commands >= MAX_ARG_CMDS) { + mainerr(err_extra_cmd, NULL); + } + if (c == 'S') { + char *a; + + if (argc < 1) { + // "-S" without argument: use default session file name. + a = SESSION_FILE; + } else if (argv[0][0] == '-') { + // "-S" followed by another option: use default session file. + a = SESSION_FILE; + ++argc; + --argv; } else { - parmp->commands[parmp->n_commands++] = argv[0]; + a = argv[0]; } - break; + + size_t s_size = STRLEN(a) + 9; + char *s = xmalloc(s_size); + snprintf(s, s_size, "so %s", a); + parmp->cmds_tofree[parmp->n_commands] = true; + parmp->commands[parmp->n_commands++] = s; + } else { + parmp->commands[parmp->n_commands++] = argv[0]; } + break; - case '-': { - if (strequal(argv[-1], "--cmd")) { - // "--cmd {command}" execute command - if (parmp->n_pre_commands >= MAX_ARG_CMDS) { - mainerr(err_extra_cmd, NULL); - } - parmp->pre_commands[parmp->n_pre_commands++] = argv[0]; - } else if (strequal(argv[-1], "--listen")) { - // "--listen {address}" - parmp->listen_addr = argv[0]; + case '-': + if (strequal(argv[-1], "--cmd")) { + // "--cmd {command}" execute command + if (parmp->n_pre_commands >= MAX_ARG_CMDS) { + mainerr(err_extra_cmd, NULL); } - // "--startuptime <file>" already handled - break; + parmp->pre_commands[parmp->n_pre_commands++] = argv[0]; + } else if (strequal(argv[-1], "--listen")) { + // "--listen {address}" + parmp->listen_addr = argv[0]; } + // "--startuptime <file>" already handled + break; - case 'q': { // "-q {errorfile}" QuickFix mode - parmp->use_ef = (char_u *)argv[0]; - break; - } + case 'q': // "-q {errorfile}" QuickFix mode + parmp->use_ef = (char_u *)argv[0]; + break; - case 'i': { // "-i {shada}" use for shada - set_option_value("shadafile", 0L, argv[0], 0); - break; - } + case 'i': // "-i {shada}" use for shada + set_option_value("shadafile", 0L, argv[0], 0); + break; - case 's': { // "-s {scriptin}" read from script file - if (scriptin[0] != NULL) { + case 's': { // "-s {scriptin}" read from script file + if (scriptin[0] != NULL) { scripterror: - vim_snprintf((char *)IObuff, IOSIZE, - _("Attempt to open script file again: \"%s %s\"\n"), - argv[-1], argv[0]); - mch_errmsg((const char *)IObuff); - os_exit(2); - } - int error; - if (strequal(argv[0], "-")) { - const int stdin_dup_fd = os_dup(STDIN_FILENO); + vim_snprintf((char *)IObuff, IOSIZE, + _("Attempt to open script file again: \"%s %s\"\n"), + argv[-1], argv[0]); + mch_errmsg((const char *)IObuff); + os_exit(2); + } + int error; + if (strequal(argv[0], "-")) { + const int stdin_dup_fd = os_dup(STDIN_FILENO); #ifdef WIN32 - // Replace the original stdin with the console input handle. - os_replace_stdin_to_conin(); + // Replace the original stdin with the console input handle. + os_replace_stdin_to_conin(); #endif - FileDescriptor *const stdin_dup = file_open_fd_new( - &error, stdin_dup_fd, kFileReadOnly|kFileNonBlocking); - assert(stdin_dup != NULL); - scriptin[0] = stdin_dup; - } else if ((scriptin[0] = file_open_new( - &error, argv[0], kFileReadOnly|kFileNonBlocking, 0)) == NULL) { - vim_snprintf((char *)IObuff, IOSIZE, - _("Cannot open for reading: \"%s\": %s\n"), - argv[0], os_strerror(error)); - mch_errmsg((const char *)IObuff); - os_exit(2); - } - save_typebuf(); - break; + FileDescriptor *const stdin_dup = file_open_fd_new(&error, stdin_dup_fd, + kFileReadOnly|kFileNonBlocking); + assert(stdin_dup != NULL); + scriptin[0] = stdin_dup; + } else if ((scriptin[0] = + file_open_new(&error, argv[0], kFileReadOnly|kFileNonBlocking, + 0)) == NULL) { + vim_snprintf((char *)IObuff, IOSIZE, + _("Cannot open for reading: \"%s\": %s\n"), + argv[0], os_strerror(error)); + mch_errmsg((const char *)IObuff); + os_exit(2); } + save_typebuf(); + break; + } - case 't': { // "-t {tag}" - parmp->tagname = (char_u *)argv[0]; - break; - } - case 'u': { // "-u {vimrc}" vim inits file - parmp->use_vimrc = argv[0]; - break; - } - case 'U': { // "-U {gvimrc}" gvim inits file + case 't': // "-t {tag}" + parmp->tagname = (char_u *)argv[0]; + break; + case 'u': // "-u {vimrc}" vim inits file + parmp->use_vimrc = argv[0]; + break; + case 'U': // "-U {gvimrc}" gvim inits file + break; + + case 'w': // "-w {nr}" 'window' value + // "-w {scriptout}" append to script file + if (ascii_isdigit(*((char_u *)argv[0]))) { + argv_idx = 0; + n = get_number_arg(argv[0], &argv_idx, 10); + set_option_value("window", n, NULL, 0); + argv_idx = -1; break; } - - case 'w': { // "-w {nr}" 'window' value - // "-w {scriptout}" append to script file - if (ascii_isdigit(*((char_u *)argv[0]))) { - argv_idx = 0; - n = get_number_arg(argv[0], &argv_idx, 10); - set_option_value("window", n, NULL, 0); - argv_idx = -1; - break; - } - FALLTHROUGH; + FALLTHROUGH; + case 'W': // "-W {scriptout}" overwrite script file + if (scriptout != NULL) { + goto scripterror; } - case 'W': { // "-W {scriptout}" overwrite script file - if (scriptout != NULL) { - goto scripterror; - } - if ((scriptout = os_fopen(argv[0], c == 'w' ? APPENDBIN : WRITEBIN)) - == NULL) { - mch_errmsg(_("Cannot open for script output: \"")); - mch_errmsg(argv[0]); - mch_errmsg("\"\n"); - os_exit(2); - } - break; + if ((scriptout = os_fopen(argv[0], c == 'w' ? APPENDBIN : WRITEBIN)) + == NULL) { + mch_errmsg(_("Cannot open for script output: \"")); + mch_errmsg(argv[0]); + mch_errmsg("\"\n"); + os_exit(2); } + break; } } } else { // File name argument. @@ -1209,7 +1174,7 @@ scripterror: if (parmp->diff_mode && os_isdir(p) && GARGCOUNT > 0 && !os_isdir(alist_name(&GARGLIST[0]))) { char_u *r = (char_u *)concat_fnames((char *)p, - (char *)path_tail(alist_name(&GARGLIST[0])), true); + (char *)path_tail(alist_name(&GARGLIST[0])), true); xfree(p); p = r; } @@ -1334,43 +1299,15 @@ static char_u *get_fname(mparm_T *parmp, char_u *cwd) static void set_window_layout(mparm_T *paramp) { if (paramp->diff_mode && paramp->window_layout == 0) { - if (diffopt_horizontal()) - paramp->window_layout = WIN_HOR; /* use horizontal split */ - else - paramp->window_layout = WIN_VER; /* use vertical split */ - } -} - -/* - * Read all the plugin files. - * Only when compiled with +eval, since most plugins need it. - */ -static void load_plugins(void) -{ - if (p_lpl) { - char_u *rtp_copy = NULL; - char_u *const plugin_pattern_vim = (char_u *)"plugin/**/*.vim"; // NOLINT - char_u *const plugin_pattern_lua = (char_u *)"plugin/**/*.lua"; // NOLINT - - // don't use source_runtime() yet so we can check for :packloadall below - source_in_path(p_rtp, plugin_pattern_vim, DIP_ALL | DIP_NOAFTER); - source_in_path(p_rtp, plugin_pattern_lua, DIP_ALL | DIP_NOAFTER); - TIME_MSG("loading rtp plugins"); - xfree(rtp_copy); - - // Only source "start" packages if not done already with a :packloadall - // command. - if (!did_source_packages) { - load_start_packages(); + if (diffopt_horizontal()) { + paramp->window_layout = WIN_HOR; // use horizontal split + } else { + paramp->window_layout = WIN_VER; // use vertical split } - TIME_MSG("loading packages"); - - source_runtime(plugin_pattern_vim, DIP_ALL | DIP_AFTER); - source_runtime(plugin_pattern_lua, DIP_ALL | DIP_AFTER); - TIME_MSG("loading after plugins"); } } + /* * "-q errorfile": Load the error file now. * If the error file can't be read, exit before doing anything else. @@ -1403,9 +1340,10 @@ static void handle_tag(char_u *tagname) do_cmdline_cmd((char *)IObuff); TIME_MSG("jumping to tag"); - /* If the user doesn't want to edit the file then we quit here. */ - if (swap_exists_did_quit) + // If the user doesn't want to edit the file then we quit here. + if (swap_exists_did_quit) { getout(1); + } } } @@ -1443,26 +1381,31 @@ static void create_windows(mparm_T *parmp) /* * Create the number of windows that was requested. */ - if (parmp->window_count == -1) /* was not set */ + if (parmp->window_count == -1) { // was not set parmp->window_count = 1; - if (parmp->window_count == 0) + } + if (parmp->window_count == 0) { parmp->window_count = GARGCOUNT; + } if (parmp->window_count > 1) { // Don't change the windows if there was a command in vimrc that // already split some windows - if (parmp->window_layout == 0) + if (parmp->window_layout == 0) { parmp->window_layout = WIN_HOR; + } if (parmp->window_layout == WIN_TABS) { parmp->window_count = make_tabpages(parmp->window_count); TIME_MSG("making tab pages"); } else if (firstwin->w_next == NULL) { parmp->window_count = make_windows(parmp->window_count, - parmp->window_layout == WIN_VER); + parmp->window_layout == WIN_VER); TIME_MSG("making windows"); - } else + } else { parmp->window_count = win_count(); - } else + } + } else { parmp->window_count = 1; + } if (recoverymode) { // do recover msg_scroll = true; // scroll message up @@ -1482,17 +1425,20 @@ static void create_windows(mparm_T *parmp) dorewind = TRUE; while (done++ < 1000) { if (dorewind) { - if (parmp->window_layout == WIN_TABS) + if (parmp->window_layout == WIN_TABS) { goto_tabpage(1); - else + } else { curwin = firstwin; + } } else if (parmp->window_layout == WIN_TABS) { - if (curtab->tp_next == NULL) + if (curtab->tp_next == NULL) { break; + } goto_tabpage(0); } else { - if (curwin->w_next == NULL) + if (curwin->w_next == NULL) { break; + } curwin = curwin->w_next; } dorewind = FALSE; @@ -1506,13 +1452,13 @@ static void create_windows(mparm_T *parmp) swap_exists_action = SEA_DIALOG; set_buflisted(TRUE); - /* create memfile, read file */ + // create memfile, read file (void)open_buffer(FALSE, NULL, 0); if (swap_exists_action == SEA_QUIT) { if (got_int || only_one_window()) { - /* abort selected or quit and only one window */ - did_emsg = FALSE; /* avoid hit-enter prompt */ + // abort selected or quit and only one window + did_emsg = FALSE; // avoid hit-enter prompt getout(1); } /* We can't close the window, it would disturb what @@ -1521,20 +1467,22 @@ static void create_windows(mparm_T *parmp) setfname(curbuf, NULL, NULL, false); curwin->w_arg_idx = -1; swap_exists_action = SEA_NONE; - } else + } else { handle_swap_exists(NULL); - dorewind = TRUE; /* start again */ + } + dorewind = TRUE; // start again } os_breakcheck(); if (got_int) { - (void)vgetc(); /* only break the file loading, not the rest */ + (void)vgetc(); // only break the file loading, not the rest break; } } - if (parmp->window_layout == WIN_TABS) + if (parmp->window_layout == WIN_TABS) { goto_tabpage(1); - else + } else { curwin = firstwin; + } curbuf = curwin->w_buffer; --autocmd_no_enter; --autocmd_no_leave; @@ -1545,10 +1493,10 @@ static void create_windows(mparm_T *parmp) /// windows. make_windows() has already opened the windows. static void edit_buffers(mparm_T *parmp, char_u *cwd) { - int arg_idx; /* index in argument list */ + int arg_idx; // index in argument list int i; bool advance = true; - win_T *win; + win_T *win; char *p_shm_save = NULL; /* @@ -1557,7 +1505,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) ++autocmd_no_enter; ++autocmd_no_leave; - /* When w_arg_idx is -1 remove the window (see create_windows()). */ + // When w_arg_idx is -1 remove the window (see create_windows()). if (curwin->w_arg_idx == -1) { win_close(curwin, true); advance = false; @@ -1578,8 +1526,9 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) if (advance) { if (parmp->window_layout == WIN_TABS) { - if (curtab->tp_next == NULL) /* just checking */ + if (curtab->tp_next == NULL) { // just checking break; + } goto_tabpage(0); // Temporarily reset 'shm' option to not print fileinfo when // loading the other buffers. This would overwrite the already @@ -1592,8 +1541,9 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) set_option_value("shm", 0L, buf, 0); } } else { - if (curwin->w_next == NULL) /* just checking */ + if (curwin->w_next == NULL) { // just checking break; + } win_enter(curwin->w_next, false); } } @@ -1608,12 +1558,12 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) swap_exists_did_quit = false; (void)do_ecmd(0, arg_idx < GARGCOUNT ? alist_name(&GARGLIST[arg_idx]) : NULL, - NULL, NULL, ECMD_LASTL, ECMD_HIDE, curwin); + NULL, NULL, ECMD_LASTL, ECMD_HIDE, curwin); if (swap_exists_did_quit) { - /* abort or quit selected */ + // abort or quit selected if (got_int || only_one_window()) { - /* abort selected and only one window */ - did_emsg = FALSE; /* avoid hit-enter prompt */ + // abort selected and only one window + did_emsg = FALSE; // avoid hit-enter prompt getout(1); } win_close(curwin, true); @@ -1626,7 +1576,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) } os_breakcheck(); if (got_int) { - (void)vgetc(); /* only break the file loading, not the rest */ + (void)vgetc(); // only break the file loading, not the rest break; } } @@ -1636,13 +1586,14 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) xfree(p_shm_save); } - if (parmp->window_layout == WIN_TABS) + if (parmp->window_layout == WIN_TABS) { goto_tabpage(1); + } --autocmd_no_enter; - /* make the first window the current window */ + // make the first window the current window win = firstwin; - /* Avoid making a preview window the current window. */ + // Avoid making a preview window the current window. while (win->w_p_pvw) { win = win->w_next; if (win == NULL) { @@ -1654,8 +1605,9 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) --autocmd_no_leave; TIME_MSG("editing files in windows"); - if (parmp->window_count > 1 && parmp->window_layout != WIN_TABS) - win_equal(curwin, false, 'b'); /* adjust heights */ + if (parmp->window_count > 1 && parmp->window_layout != WIN_TABS) { + win_equal(curwin, false, 'b'); // adjust heights + } } /* @@ -1668,7 +1620,7 @@ static void exe_pre_commands(mparm_T *parmp) int i; if (cnt > 0) { - curwin->w_cursor.lnum = 0; /* just in case.. */ + curwin->w_cursor.lnum = 0; // just in case.. sourcing_name = (char_u *)_("pre-vimrc command line"); current_sctx.sc_sid = SID_CMDARG; for (i = 0; i < cnt; i++) { @@ -1693,15 +1645,17 @@ static void exe_commands(mparm_T *parmp) * with g`" was used. */ msg_scroll = TRUE; - if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1) + if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1) { curwin->w_cursor.lnum = 0; + } sourcing_name = (char_u *)"command line"; current_sctx.sc_sid = SID_CARG; current_sctx.sc_seq = 0; for (i = 0; i < parmp->n_commands; i++) { do_cmdline_cmd(parmp->commands[i]); - if (parmp->cmds_tofree[i]) + if (parmp->cmds_tofree[i]) { xfree(parmp->commands[i]); + } } sourcing_name = NULL; current_sctx.sc_sid = 0; @@ -1709,12 +1663,14 @@ static void exe_commands(mparm_T *parmp) curwin->w_cursor.lnum = 1; } - if (!exmode_active) + if (!exmode_active) { msg_scroll = FALSE; + } - /* When started with "-q errorfile" jump to first error again. */ - if (parmp->edit_type == EDIT_QF) + // When started with "-q errorfile" jump to first error again. + if (parmp->edit_type == EDIT_QF) { qf_jump(NULL, 0, 0, FALSE); + } TIME_MSG("executing command arguments"); } @@ -1744,7 +1700,7 @@ static void do_system_initialization(void) memcpy(vimrc, dir, dir_len); vimrc[dir_len] = PATHSEP; memcpy(vimrc + dir_len + 1, path_tail, sizeof(path_tail)); - if (do_source((char_u *)vimrc, false, DOSO_NONE) != FAIL) { + if (do_source(vimrc, false, DOSO_NONE) != FAIL) { xfree(vimrc); xfree(config_dirs); return; @@ -1756,7 +1712,7 @@ static void do_system_initialization(void) #ifdef SYS_VIMRC_FILE // Get system wide defaults, if the file name is defined. - (void)do_source((char_u *)SYS_VIMRC_FILE, false, DOSO_NONE); + (void)do_source(SYS_VIMRC_FILE, false, DOSO_NONE); #endif } @@ -1781,24 +1737,24 @@ static bool do_user_initialization(void) } char_u *init_lua_path = (char_u *)stdpaths_user_conf_subpath("init.lua"); - if (os_path_exists(init_lua_path) - && do_source(init_lua_path, true, DOSO_VIMRC)) { - os_setenv("MYVIMRC", (const char *)init_lua_path, 1); - char_u *vimrc_path = (char_u *)stdpaths_user_conf_subpath("init.vim"); + char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim"); - if (os_path_exists(vimrc_path)) { + // init.lua + if (os_path_exists(init_lua_path) + && do_source((char *)init_lua_path, true, DOSO_VIMRC)) { + if (os_path_exists(user_vimrc)) { EMSG3(_("E5422: Conflicting configs: \"%s\" \"%s\""), init_lua_path, - vimrc_path); + user_vimrc); } - xfree(vimrc_path); + xfree(user_vimrc); xfree(init_lua_path); return false; } xfree(init_lua_path); - char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim"); - if (do_source(user_vimrc, true, DOSO_VIMRC) != FAIL) { + // init.vim + if (do_source((char *)user_vimrc, true, DOSO_VIMRC) != FAIL) { do_exrc = p_exrc; if (do_exrc) { do_exrc = (path_full_compare((char_u *)VIMRC_FILE, user_vimrc, @@ -1809,6 +1765,7 @@ static bool do_user_initialization(void) return do_exrc; } xfree(user_vimrc); + char *const config_dirs = stdpaths_get_xdg_var(kXDGConfigDirs); if (config_dirs != NULL) { const void *iter = NULL; @@ -1825,7 +1782,7 @@ static bool do_user_initialization(void) memmove(vimrc, dir, dir_len); vimrc[dir_len] = PATHSEP; memmove(vimrc + dir_len + 1, path_tail, sizeof(path_tail)); - if (do_source((char_u *) vimrc, true, DOSO_VIMRC) != FAIL) { + if (do_source(vimrc, true, DOSO_VIMRC) != FAIL) { do_exrc = p_exrc; if (do_exrc) { do_exrc = (path_full_compare((char_u *)VIMRC_FILE, (char_u *)vimrc, @@ -1839,6 +1796,7 @@ static bool do_user_initialization(void) } while (iter != NULL); xfree(config_dirs); } + if (execute_env("EXINIT") == OK) { do_exrc = p_exrc; return do_exrc; @@ -1856,7 +1814,7 @@ static void source_startup_scripts(const mparm_T *const parmp) || strequal(parmp->use_vimrc, "NORC")) { // Do nothing. } else { - if (do_source((char_u *)parmp->use_vimrc, false, DOSO_NONE) != OK) { + if (do_source(parmp->use_vimrc, false, DOSO_NONE) != OK) { EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc); } } @@ -1875,9 +1833,9 @@ static void source_startup_scripts(const mparm_T *const parmp) // If vimrc file is not owned by user, set 'secure' mode. if (!file_owned(VIMRC_FILE)) #endif - secure = p_secure; + secure = p_secure; - if (do_source((char_u *)VIMRC_FILE, true, DOSO_VIMRC) == FAIL) { + if (do_source(VIMRC_FILE, true, DOSO_VIMRC) == FAIL) { #if defined(UNIX) // if ".exrc" is not owned by user set 'secure' mode if (!file_owned(EXRC_FILE)) { @@ -1886,7 +1844,7 @@ static void source_startup_scripts(const mparm_T *const parmp) secure = 0; } #endif - (void)do_source((char_u *)EXRC_FILE, false, DOSO_NONE); + (void)do_source(EXRC_FILE, false, DOSO_NONE); } } if (secure == 2) { @@ -2031,7 +1989,8 @@ static void usage(void) */ static void check_swap_exists_action(void) { - if (swap_exists_action == SEA_QUIT) + if (swap_exists_action == SEA_QUIT) { getout(1); + } handle_swap_exists(NULL); } diff --git a/src/nvim/main.h b/src/nvim/main.h index d387e6d668..f73af5c288 100644 --- a/src/nvim/main.h +++ b/src/nvim/main.h @@ -1,8 +1,8 @@ #ifndef NVIM_MAIN_H #define NVIM_MAIN_H -#include "nvim/normal.h" #include "nvim/event/loop.h" +#include "nvim/normal.h" // Maximum number of commands from + or -c arguments. #define MAX_ARG_CMDS 10 diff --git a/src/nvim/map.c b/src/nvim/map.c index ccd332192e..20d5570e8c 100644 --- a/src/nvim/map.c +++ b/src/nvim/map.c @@ -8,20 +8,18 @@ // khash.h does not make its own copy of the key or value. // -#include <stdlib.h> +#include <lauxlib.h> +#include <lua.h> #include <stdbool.h> +#include <stdlib.h> #include <string.h> -#include <lua.h> -#include <lauxlib.h> - +#include "nvim/api/private/dispatch.h" +#include "nvim/lib/khash.h" #include "nvim/map.h" #include "nvim/map_defs.h" -#include "nvim/vim.h" #include "nvim/memory.h" -#include "nvim/api/private/dispatch.h" - -#include "nvim/lib/khash.h" +#include "nvim/vim.h" #define cstr_t_hash kh_str_hash_func #define cstr_t_eq kh_str_hash_equal @@ -38,11 +36,11 @@ #if defined(ARCH_64) -#define ptr_t_hash(key) uint64_t_hash((uint64_t)key) -#define ptr_t_eq(a, b) uint64_t_eq((uint64_t)a, (uint64_t)b) +# define ptr_t_hash(key) uint64_t_hash((uint64_t)key) +# define ptr_t_eq(a, b) uint64_t_eq((uint64_t)a, (uint64_t)b) #elif defined(ARCH_32) -#define ptr_t_hash(key) uint32_t_hash((uint32_t)key) -#define ptr_t_eq(a, b) uint32_t_eq((uint32_t)a, (uint32_t)b) +# define ptr_t_hash(key) uint32_t_hash((uint32_t)key) +# define ptr_t_eq(a, b) uint32_t_eq((uint32_t)a, (uint32_t)b) #endif #define INITIALIZER(T, U) T##_##U##_initializer @@ -52,7 +50,7 @@ #define MAP_IMPL(T, U, ...) \ INITIALIZER_DECLARE(T, U, __VA_ARGS__); \ - __KHASH_IMPL(T##_##U##_map,, T, U, 1, T##_hash, T##_eq) \ + __KHASH_IMPL(T##_##U##_map, , T, U, 1, T##_hash, T##_eq) \ \ void map_##T##_##U##_destroy(Map(T, U) *map) \ { \ diff --git a/src/nvim/map.h b/src/nvim/map.h index d6515878a2..6ed341ac76 100644 --- a/src/nvim/map.h +++ b/src/nvim/map.h @@ -3,11 +3,11 @@ #include <stdbool.h> -#include "nvim/map_defs.h" -#include "nvim/extmark_defs.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/dispatch.h" +#include "nvim/extmark_defs.h" #include "nvim/highlight_defs.h" +#include "nvim/map_defs.h" #if defined(__NetBSD__) # undef uint64_t @@ -60,7 +60,7 @@ MAP_DECLS(String, handle_T) MAP_DECLS(ColorKey, ColorItem) #define MAP_INIT { { 0, 0, 0, 0, NULL, NULL, NULL } } -#define map_init(k, v, map) do { *(map) = (Map(k, v))MAP_INIT; } while (false) +#define map_init(k, v, map) do { *(map) = (Map(k, v)) MAP_INIT; } while (false) #define map_destroy(T, U) map_##T##_##U##_destroy #define map_get(T, U) map_##T##_##U##_get diff --git a/src/nvim/map_defs.h b/src/nvim/map_defs.h index d5a302362f..7b4596ce2e 100644 --- a/src/nvim/map_defs.h +++ b/src/nvim/map_defs.h @@ -3,8 +3,8 @@ #include "nvim/lib/khash.h" -typedef const char * cstr_t; -typedef void * ptr_t; +typedef const char *cstr_t; +typedef void *ptr_t; #define Map(T, U) Map_##T##_##U #define PMap(T) Map(T, ptr_t) diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 0b14089550..ea9acdf31a 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -7,35 +7,35 @@ #include <assert.h> #include <inttypes.h> -#include <string.h> #include <limits.h> +#include <string.h> -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/mark.h" #include "nvim/buffer.h" #include "nvim/charset.h" #include "nvim/diff.h" #include "nvim/eval.h" #include "nvim/ex_cmds.h" +#include "nvim/extmark.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/extmark.h" +#include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/normal.h" #include "nvim/option.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" +#include "nvim/os/time.h" #include "nvim/path.h" #include "nvim/quickfix.h" #include "nvim/search.h" #include "nvim/sign.h" #include "nvim/strings.h" #include "nvim/ui.h" -#include "nvim/os/os.h" -#include "nvim/os/time.h" -#include "nvim/os/input.h" +#include "nvim/vim.h" /* * This file contains routines to maintain and manipulate marks. @@ -94,17 +94,19 @@ int setmark_pos(int c, pos_T *pos, int fnum) { int i; - /* Check for a special key (may cause islower() to crash). */ - if (c < 0) + // Check for a special key (may cause islower() to crash). + if (c < 0) { return FAIL; + } if (c == '\'' || c == '`') { if (pos == &curwin->w_cursor) { setpcmark(); - /* keep it even when the cursor doesn't move */ + // keep it even when the cursor doesn't move curwin->w_prev_pcmark = curwin->w_pcmark; - } else + } else { curwin->w_pcmark = *pos; + } return OK; } @@ -119,8 +121,8 @@ int setmark_pos(int c, pos_T *pos, int fnum) return OK; } - /* Allow setting '[ and '] for an autocommand that simulates reading a - * file. */ + // Allow setting '[ and '] for an autocommand that simulates reading a + // file. if (c == '[') { buf->b_op_start = *pos; return OK; @@ -166,11 +168,12 @@ int setmark_pos(int c, pos_T *pos, int fnum) */ void setpcmark(void) { - xfmark_T *fm; + xfmark_T *fm; - /* for :global the mark is set only once */ - if (global_busy || listcmd_busy || cmdmod.keepjumps) + // for :global the mark is set only once + if (global_busy || listcmd_busy || cmdmod.keepjumps) { return; + } curwin->w_prev_pcmark = curwin->w_pcmark; curwin->w_pcmark = curwin->w_cursor; @@ -189,7 +192,7 @@ void setpcmark(void) } } - /* If jumplist is full: remove oldest entry */ + // If jumplist is full: remove oldest entry if (++curwin->w_jumplistlen > JUMPLISTSIZE) { curwin->w_jumplistlen = JUMPLISTSIZE; free_xfmark(curwin->w_jumplist[0]); @@ -214,7 +217,7 @@ void checkpcmark(void) && (equalpos(curwin->w_pcmark, curwin->w_cursor) || curwin->w_pcmark.lnum == 0)) { curwin->w_pcmark = curwin->w_prev_pcmark; - curwin->w_prev_pcmark.lnum = 0; /* Show it has been checked */ + curwin->w_prev_pcmark.lnum = 0; // Show it has been checked } } @@ -223,18 +226,20 @@ void checkpcmark(void) */ pos_T *movemark(int count) { - pos_T *pos; - xfmark_T *jmp; + pos_T *pos; + xfmark_T *jmp; cleanup_jumplist(curwin, true); - if (curwin->w_jumplistlen == 0) /* nothing to jump to */ + if (curwin->w_jumplistlen == 0) { // nothing to jump to return (pos_T *)NULL; + } for (;; ) { if (curwin->w_jumplistidx + count < 0 - || curwin->w_jumplistidx + count >= curwin->w_jumplistlen) + || curwin->w_jumplistidx + count >= curwin->w_jumplistlen) { return (pos_T *)NULL; + } /* * if first CTRL-O or CTRL-I command after a jump, add cursor position @@ -243,30 +248,34 @@ pos_T *movemark(int count) */ if (curwin->w_jumplistidx == curwin->w_jumplistlen) { setpcmark(); - --curwin->w_jumplistidx; /* skip the new entry */ - if (curwin->w_jumplistidx + count < 0) + --curwin->w_jumplistidx; // skip the new entry + if (curwin->w_jumplistidx + count < 0) { return (pos_T *)NULL; + } } curwin->w_jumplistidx += count; jmp = curwin->w_jumplist + curwin->w_jumplistidx; - if (jmp->fmark.fnum == 0) + if (jmp->fmark.fnum == 0) { fname2fnum(jmp); + } if (jmp->fmark.fnum != curbuf->b_fnum) { - /* jump to other file */ - if (buflist_findnr(jmp->fmark.fnum) == NULL) { /* Skip this one .. */ + // jump to other file + if (buflist_findnr(jmp->fmark.fnum) == NULL) { // Skip this one .. count += count < 0 ? -1 : 1; continue; } if (buflist_getfile(jmp->fmark.fnum, jmp->fmark.mark.lnum, - 0, FALSE) == FAIL) + 0, FALSE) == FAIL) { return (pos_T *)NULL; - /* Set lnum again, autocommands my have changed it */ + } + // Set lnum again, autocommands my have changed it curwin->w_cursor = jmp->fmark.mark; pos = (pos_T *)-1; - } else + } else { pos = &(jmp->fmark.mark); + } return pos; } } @@ -278,20 +287,24 @@ pos_T *movechangelist(int count) { int n; - if (curbuf->b_changelistlen == 0) /* nothing to jump to */ + if (curbuf->b_changelistlen == 0) { // nothing to jump to return (pos_T *)NULL; + } n = curwin->w_changelistidx; if (n + count < 0) { - if (n == 0) + if (n == 0) { return (pos_T *)NULL; + } n = 0; } else if (n + count >= curbuf->b_changelistlen) { - if (n == curbuf->b_changelistlen - 1) + if (n == curbuf->b_changelistlen - 1) { return (pos_T *)NULL; + } n = curbuf->b_changelistlen - 1; - } else + } else { n += count; + } curwin->w_changelistidx = n; return &(curbuf->b_changelist[n].mark); } @@ -319,16 +332,17 @@ pos_T *getmark(int c, bool changefile) pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum) { - pos_T *posp; - pos_T *startp, *endp; + pos_T *posp; + pos_T *startp, *endp; static pos_T pos_copy; posp = NULL; - /* Check for special key, can't be a mark name and might cause islower() - * to crash. */ - if (c < 0) + // Check for special key, can't be a mark name and might cause islower() + // to crash. + if (c < 0) { return posp; + } if (c > '~') { // check for islower()/isupper() } else if (c == '\'' || c == '`') { // previous context mark pos_copy = curwin->w_pcmark; // need to make a copy because @@ -351,13 +365,13 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum) pos = curwin->w_cursor; listcmd_busy = true; // avoid that '' is changed if (findpar(&oa.inclusive, - c == '}' ? FORWARD : BACKWARD, 1L, NUL, FALSE)) { + c == '}' ? FORWARD : BACKWARD, 1L, NUL, FALSE)) { pos_copy = curwin->w_cursor; posp = &pos_copy; } curwin->w_cursor = pos; listcmd_busy = slcb; - } else if (c == '(' || c == ')') { /* to previous/next sentence */ + } else if (c == '(' || c == ')') { // to previous/next sentence pos_T pos; bool slcb = listcmd_busy; @@ -369,7 +383,7 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum) } curwin->w_cursor = pos; listcmd_busy = slcb; - } else if (c == '<' || c == '>') { /* start/end of visual area */ + } else if (c == '<' || c == '>') { // start/end of visual area startp = &buf->b_visual.vi_start; endp = &buf->b_visual.vi_end; if (((c == '<') == lt(*startp, *endp) || endp->lnum == 0) @@ -383,86 +397,87 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum) if (buf->b_visual.vi_mode == 'V') { pos_copy = *posp; posp = &pos_copy; - if (c == '<') + if (c == '<') { pos_copy.col = 0; - else + } else { pos_copy.col = MAXCOL; + } pos_copy.coladd = 0; } - } else if (ASCII_ISLOWER(c)) { /* normal named mark */ + } else if (ASCII_ISLOWER(c)) { // normal named mark posp = &(buf->b_namedm[c - 'a'].mark); - } else if (ASCII_ISUPPER(c) || ascii_isdigit(c)) { /* named file mark */ - if (ascii_isdigit(c)) + } else if (ASCII_ISUPPER(c) || ascii_isdigit(c)) { // named file mark + if (ascii_isdigit(c)) { c = c - '0' + NMARKS; - else + } else { c -= 'A'; + } posp = &(namedfm[c].fmark.mark); if (namedfm[c].fmark.fnum == 0) { fname2fnum(&namedfm[c]); } - if (fnum != NULL) + if (fnum != NULL) { *fnum = namedfm[c].fmark.fnum; - else if (namedfm[c].fmark.fnum != buf->b_fnum) { - /* mark is in another file */ + } else if (namedfm[c].fmark.fnum != buf->b_fnum) { + // mark is in another file posp = &pos_copy; if (namedfm[c].fmark.mark.lnum != 0 && changefile && namedfm[c].fmark.fnum) { if (buflist_getfile(namedfm[c].fmark.fnum, - (linenr_T)1, GETF_SETMARK, FALSE) == OK) { - /* Set the lnum now, autocommands could have changed it */ + (linenr_T)1, GETF_SETMARK, FALSE) == OK) { + // Set the lnum now, autocommands could have changed it curwin->w_cursor = namedfm[c].fmark.mark; return (pos_T *)-1; } - pos_copy.lnum = -1; /* can't get file */ - } else - pos_copy.lnum = 0; /* mark exists, but is not valid in - current buffer */ + pos_copy.lnum = -1; // can't get file + } else { + pos_copy.lnum = 0; // mark exists, but is not valid in current buffer + } } } return posp; } -/* - * Search for the next named mark in the current file. - * - * Returns pointer to pos_T of the next mark or NULL if no mark is found. - */ -pos_T * -getnextmark ( - pos_T *startpos, /* where to start */ - int dir, /* direction for search */ - int begin_line -) +/// Search for the next named mark in the current file. +/// +/// @param startpos where to start +/// @param dir direction for search +/// +/// @return pointer to pos_T of the next mark or NULL if no mark is found. +pos_T *getnextmark(pos_T *startpos, int dir, int begin_line) { int i; - pos_T *result = NULL; + pos_T *result = NULL; pos_T pos; pos = *startpos; - /* When searching backward and leaving the cursor on the first non-blank, - * position must be in a previous line. - * When searching forward and leaving the cursor on the first non-blank, - * position must be in a next line. */ - if (dir == BACKWARD && begin_line) + // When searching backward and leaving the cursor on the first non-blank, + // position must be in a previous line. + // When searching forward and leaving the cursor on the first non-blank, + // position must be in a next line. + if (dir == BACKWARD && begin_line) { pos.col = 0; - else if (dir == FORWARD && begin_line) + } else if (dir == FORWARD && begin_line) { pos.col = MAXCOL; + } for (i = 0; i < NMARKS; i++) { if (curbuf->b_namedm[i].mark.lnum > 0) { if (dir == FORWARD) { if ((result == NULL || lt(curbuf->b_namedm[i].mark, *result)) - && lt(pos, curbuf->b_namedm[i].mark)) + && lt(pos, curbuf->b_namedm[i].mark)) { result = &curbuf->b_namedm[i].mark; + } } else { if ((result == NULL || lt(*result, curbuf->b_namedm[i].mark)) - && lt(curbuf->b_namedm[i].mark, pos)) + && lt(curbuf->b_namedm[i].mark, pos)) { result = &curbuf->b_namedm[i].mark; + } } } } @@ -494,10 +509,11 @@ static void fname2fnum(xfmark_T *fm) expand_env((char_u *)"~/", NameBuff, MAXPATHL); len = (int)STRLEN(NameBuff); STRLCPY(NameBuff + len, fm->fname + 2, MAXPATHL - len); - } else + } else { STRLCPY(NameBuff, fm->fname, MAXPATHL); + } - /* Try to shorten the file name. */ + // Try to shorten the file name. os_dirname(IObuff, IOSIZE); p = path_shorten_fname(NameBuff, IObuff); @@ -513,14 +529,16 @@ static void fname2fnum(xfmark_T *fm) */ void fmarks_check_names(buf_T *buf) { - char_u *name = buf->b_ffname; + char_u *name = buf->b_ffname; int i; - if (buf->b_ffname == NULL) + if (buf->b_ffname == NULL) { return; + } - for (i = 0; i < NGLOBALMARKS; ++i) + for (i = 0; i < NGLOBALMARKS; ++i) { fmarks_check_one(&namedfm[i], name, buf); + } FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { for (i = 0; i < wp->w_jumplistlen; ++i) { @@ -550,10 +568,11 @@ int check_mark(pos_T *pos) return FAIL; } if (pos->lnum <= 0) { - /* lnum is negative if mark is in another file can can't get that - * file, error message already give then. */ - if (pos->lnum == 0) + // lnum is negative if mark is in another file can can't get that + // file, error message already give then. + if (pos->lnum == 0) { EMSG(_(e_marknotset)); + } return FAIL; } if (pos->lnum > curbuf->b_ml.ml_line_count) { @@ -593,8 +612,9 @@ void clrallmarks(buf_T *const buf) */ char_u *fm_getname(fmark_T *fmark, int lead_len) { - if (fmark->fnum == curbuf->b_fnum) /* current buffer */ + if (fmark->fnum == curbuf->b_fnum) { // current buffer return mark_line(&(fmark->mark), lead_len); + } return buflist_nr2name(fmark->fnum, FALSE, TRUE); } @@ -604,11 +624,12 @@ char_u *fm_getname(fmark_T *fmark, int lead_len) */ static char_u *mark_line(pos_T *mp, int lead_len) { - char_u *s, *p; + char_u *s, *p; int len; - if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count) + if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count) { return vim_strsave((char_u *)"-invalid-"); + } assert(Columns >= 0 && (size_t)Columns <= SIZE_MAX); // Allow for up to 5 bytes per character. s = vim_strnsave(skipwhite(ml_get(mp->lnum)), (size_t)Columns * 5); @@ -617,8 +638,9 @@ static char_u *mark_line(pos_T *mp, int lead_len) len = 0; for (p = s; *p != NUL; MB_PTR_ADV(p)) { len += ptr2cells(p); - if (len >= Columns - lead_len) + if (len >= Columns - lead_len) { break; + } } *p = NUL; return s; @@ -629,28 +651,32 @@ static char_u *mark_line(pos_T *mp, int lead_len) */ void ex_marks(exarg_T *eap) { - char_u *arg = eap->arg; + char_u *arg = eap->arg; int i; - char_u *name; - pos_T *posp, *startp, *endp; + char_u *name; + pos_T *posp, *startp, *endp; - if (arg != NULL && *arg == NUL) + if (arg != NULL && *arg == NUL) { arg = NULL; + } show_one_mark('\'', arg, &curwin->w_pcmark, NULL, true); - for (i = 0; i < NMARKS; ++i) + for (i = 0; i < NMARKS; ++i) { show_one_mark(i + 'a', arg, &curbuf->b_namedm[i].mark, NULL, true); + } for (i = 0; i < NGLOBALMARKS; ++i) { - if (namedfm[i].fmark.fnum != 0) + if (namedfm[i].fmark.fnum != 0) { name = fm_getname(&namedfm[i].fmark, 15); - else + } else { name = namedfm[i].fname; + } if (name != NULL) { show_one_mark(i >= NMARKS ? i - NMARKS + '0' : i + 'A', - arg, &namedfm[i].fmark.mark, name, - namedfm[i].fmark.fnum == curbuf->b_fnum); - if (namedfm[i].fmark.fnum != 0) + arg, &namedfm[i].fmark.mark, name, + namedfm[i].fmark.fnum == curbuf->b_fnum); + if (namedfm[i].fmark.fnum != 0) { xfree(name); + } } } show_one_mark('"', arg, &curbuf->b_last_cursor.mark, NULL, true); @@ -673,14 +699,8 @@ void ex_marks(exarg_T *eap) show_one_mark(-1, arg, NULL, NULL, false); } -static void -show_one_mark( - int c, - char_u *arg, - pos_T *p, - char_u *name_arg, - int current // in current file -) +/// @param current in current file +static void show_one_mark(int c, char_u *arg, pos_T *p, char_u *name_arg, int current) { static bool did_title = false; bool mustfree = false; @@ -731,41 +751,42 @@ show_one_mark( */ void ex_delmarks(exarg_T *eap) { - char_u *p; + char_u *p; int from, to; int i; int lower; int digit; int n; - if (*eap->arg == NUL && eap->forceit) - /* clear all marks */ + if (*eap->arg == NUL && eap->forceit) { + // clear all marks clrallmarks(curbuf); - else if (eap->forceit) + } else if (eap->forceit) { EMSG(_(e_invarg)); - else if (*eap->arg == NUL) + } else if (*eap->arg == NUL) { EMSG(_(e_argreq)); - else { - /* clear specified marks only */ + } else { + // clear specified marks only for (p = eap->arg; *p != NUL; ++p) { lower = ASCII_ISLOWER(*p); digit = ascii_isdigit(*p); if (lower || digit || ASCII_ISUPPER(*p)) { if (p[1] == '-') { - /* clear range of marks */ + // clear range of marks from = *p; to = p[2]; if (!(lower ? ASCII_ISLOWER(p[2]) - : (digit ? ascii_isdigit(p[2]) - : ASCII_ISUPPER(p[2]))) + : (digit ? ascii_isdigit(p[2]) + : ASCII_ISUPPER(p[2]))) || to < from) { EMSG2(_(e_invarg2), p); return; } p += 2; - } else - /* clear one lower case mark */ + } else { + // clear one lower case mark from = to = *p; + } for (i = from; i <= to; ++i) { if (lower) { @@ -781,19 +802,29 @@ void ex_delmarks(exarg_T *eap) XFREE_CLEAR(namedfm[n].fname); } } - } else + } else { switch (*p) { - case '"': CLEAR_FMARK(&curbuf->b_last_cursor); break; - case '^': CLEAR_FMARK(&curbuf->b_last_insert); break; - case '.': CLEAR_FMARK(&curbuf->b_last_change); break; - case '[': curbuf->b_op_start.lnum = 0; break; - case ']': curbuf->b_op_end.lnum = 0; break; - case '<': curbuf->b_visual.vi_start.lnum = 0; break; - case '>': curbuf->b_visual.vi_end.lnum = 0; break; - case ' ': break; - default: EMSG2(_(e_invarg2), p); + case '"': + CLEAR_FMARK(&curbuf->b_last_cursor); break; + case '^': + CLEAR_FMARK(&curbuf->b_last_insert); break; + case '.': + CLEAR_FMARK(&curbuf->b_last_change); break; + case '[': + curbuf->b_op_start.lnum = 0; break; + case ']': + curbuf->b_op_end.lnum = 0; break; + case '<': + curbuf->b_visual.vi_start.lnum = 0; break; + case '>': + curbuf->b_visual.vi_end.lnum = 0; break; + case ' ': + break; + default: + EMSG2(_(e_invarg2), p); return; } + } } } } @@ -804,7 +835,7 @@ void ex_delmarks(exarg_T *eap) void ex_jumps(exarg_T *eap) { int i; - char_u *name; + char_u *name; cleanup_jumplist(curwin, true); // Highlight title @@ -825,11 +856,11 @@ void ex_jumps(exarg_T *eap) break; } sprintf((char *)IObuff, "%c %2d %5ld %4d ", - i == curwin->w_jumplistidx ? '>' : ' ', - i > curwin->w_jumplistidx ? i - curwin->w_jumplistidx - : curwin->w_jumplistidx - i, - curwin->w_jumplist[i].fmark.mark.lnum, - curwin->w_jumplist[i].fmark.mark.col); + i == curwin->w_jumplistidx ? '>' : ' ', + i > curwin->w_jumplistidx ? i - curwin->w_jumplistidx + : curwin->w_jumplistidx - i, + curwin->w_jumplist[i].fmark.mark.lnum, + curwin->w_jumplist[i].fmark.mark.col); msg_outtrans(IObuff); msg_outtrans_attr(name, curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum @@ -839,8 +870,9 @@ void ex_jumps(exarg_T *eap) } ui_flush(); } - if (curwin->w_jumplistidx == curwin->w_jumplistlen) + if (curwin->w_jumplistidx == curwin->w_jumplistlen) { MSG_PUTS("\n>"); + } } void ex_clearjumps(exarg_T *eap) @@ -856,7 +888,7 @@ void ex_clearjumps(exarg_T *eap) void ex_changes(exarg_T *eap) { int i; - char_u *name; + char_u *name; // Highlight title MSG_PUTS_TITLE(_("\nchange line col text")); @@ -864,14 +896,15 @@ void ex_changes(exarg_T *eap) for (i = 0; i < curbuf->b_changelistlen && !got_int; ++i) { if (curbuf->b_changelist[i].mark.lnum != 0) { msg_putchar('\n'); - if (got_int) + if (got_int) { break; + } sprintf((char *)IObuff, "%c %3d %5ld %4d ", - i == curwin->w_changelistidx ? '>' : ' ', - i > curwin->w_changelistidx ? i - curwin->w_changelistidx - : curwin->w_changelistidx - i, - (long)curbuf->b_changelist[i].mark.lnum, - curbuf->b_changelist[i].mark.col); + i == curwin->w_changelistidx ? '>' : ' ', + i > curwin->w_changelistidx ? i - curwin->w_changelistidx + : curwin->w_changelistidx - i, + (long)curbuf->b_changelist[i].mark.lnum, + curbuf->b_changelist[i].mark.col); msg_outtrans(IObuff); name = mark_line(&curbuf->b_changelist[i].mark, 17); msg_outtrans_attr(name, HL_ATTR(HLF_D)); @@ -880,8 +913,9 @@ void ex_changes(exarg_T *eap) } ui_flush(); } - if (curwin->w_changelistidx == curbuf->b_changelistlen) + if (curwin->w_changelistidx == curbuf->b_changelistlen) { MSG_PUTS("\n>"); + } } #define one_adjust(add) \ @@ -890,27 +924,27 @@ void ex_changes(exarg_T *eap) if (*lp >= line1 && *lp <= line2) \ { \ if (amount == MAXLNUM) \ - *lp = 0; \ + *lp = 0; \ else \ - *lp += amount; \ + *lp += amount; \ } \ else if (amount_after && *lp > line2) \ - *lp += amount_after; \ + *lp += amount_after; \ } -/* don't delete the line, just put at first deleted line */ +// don't delete the line, just put at first deleted line #define one_adjust_nodel(add) \ { \ lp = add; \ if (*lp >= line1 && *lp <= line2) \ { \ if (amount == MAXLNUM) \ - *lp = line1; \ + *lp = line1; \ else \ - *lp += amount; \ + *lp += amount; \ } \ else if (amount_after && *lp > line2) \ - *lp += amount_after; \ + *lp += amount_after; \ } /* @@ -922,13 +956,9 @@ void ex_changes(exarg_T *eap) * If 'amount_after' is non-zero adjust marks after line2. * Example: Delete lines 34 and 35: mark_adjust(34, 35, MAXLNUM, -2); * Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0); - * or: mark_adjust(56, 55, MAXLNUM, 2); + * or: mark_adjust(56, 55, MAXLNUM, 2); */ -void mark_adjust(linenr_T line1, - linenr_T line2, - long amount, - long amount_after, - ExtmarkOp op) +void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after, ExtmarkOp op) { mark_adjust_internal(line1, line2, amount, amount_after, true, op); } @@ -938,54 +968,56 @@ void mark_adjust(linenr_T line1, // This is only useful when folds need to be moved in a way different to // calling foldMarkAdjust() with arguments line1, line2, amount, amount_after, // for an example of why this may be necessary, see do_move(). -void mark_adjust_nofold(linenr_T line1, linenr_T line2, long amount, - long amount_after, +void mark_adjust_nofold(linenr_T line1, linenr_T line2, long amount, long amount_after, ExtmarkOp op) { mark_adjust_internal(line1, line2, amount, amount_after, false, op); } -static void mark_adjust_internal(linenr_T line1, linenr_T line2, - long amount, long amount_after, - bool adjust_folds, - ExtmarkOp op) +static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, long amount_after, + bool adjust_folds, ExtmarkOp op) { int i; int fnum = curbuf->b_fnum; - linenr_T *lp; + linenr_T *lp; static pos_T initpos = { 1, 0, 0 }; - if (line2 < line1 && amount_after == 0L) /* nothing to do */ + if (line2 < line1 && amount_after == 0L) { // nothing to do return; + } if (!cmdmod.lockmarks) { - /* named marks, lower case and upper case */ + // named marks, lower case and upper case for (i = 0; i < NMARKS; i++) { one_adjust(&(curbuf->b_namedm[i].mark.lnum)); - if (namedfm[i].fmark.fnum == fnum) + if (namedfm[i].fmark.fnum == fnum) { one_adjust_nodel(&(namedfm[i].fmark.mark.lnum)); + } } for (i = NMARKS; i < NGLOBALMARKS; i++) { - if (namedfm[i].fmark.fnum == fnum) + if (namedfm[i].fmark.fnum == fnum) { one_adjust_nodel(&(namedfm[i].fmark.mark.lnum)); + } } - /* last Insert position */ + // last Insert position one_adjust(&(curbuf->b_last_insert.mark.lnum)); - /* last change position */ + // last change position one_adjust(&(curbuf->b_last_change.mark.lnum)); - /* last cursor position, if it was set */ - if (!equalpos(curbuf->b_last_cursor.mark, initpos)) + // last cursor position, if it was set + if (!equalpos(curbuf->b_last_cursor.mark, initpos)) { one_adjust(&(curbuf->b_last_cursor.mark.lnum)); + } - /* list of change positions */ - for (i = 0; i < curbuf->b_changelistlen; ++i) + // list of change positions + for (i = 0; i < curbuf->b_changelistlen; ++i) { one_adjust_nodel(&(curbuf->b_changelist[i].mark.lnum)); + } - /* Visual area */ + // Visual area one_adjust_nodel(&(curbuf->b_visual.vi_start.lnum)); one_adjust_nodel(&(curbuf->b_visual.vi_end.lnum)); @@ -1003,29 +1035,31 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, } sign_mark_adjust(line1, line2, amount, amount_after); - if (op != kExtmarkNOOP) { - extmark_adjust(curbuf, line1, line2, amount, amount_after, op); - } } - /* previous context mark */ + if (op != kExtmarkNOOP) { + extmark_adjust(curbuf, line1, line2, amount, amount_after, op); + } + + // previous context mark one_adjust(&(curwin->w_pcmark.lnum)); - /* previous pcmark */ + // previous pcmark one_adjust(&(curwin->w_prev_pcmark.lnum)); - /* saved cursor for formatting */ - if (saved_cursor.lnum != 0) + // saved cursor for formatting + if (saved_cursor.lnum != 0) { one_adjust_nodel(&(saved_cursor.lnum)); + } /* * Adjust items in all windows related to the current buffer. */ FOR_ALL_TAB_WINDOWS(tab, win) { if (!cmdmod.lockmarks) { - /* Marks in the jumplist. When deleting lines, this may create - * duplicate marks in the jumplist, they will be removed later. */ - for (i = 0; i < win->w_jumplistlen; ++i) { + // Marks in the jumplist. When deleting lines, this may create + // duplicate marks in the jumplist, they will be removed later. + for (i = 0; i < win->w_jumplistlen; i++) { if (win->w_jumplist[i].fmark.fnum == fnum) { one_adjust_nodel(&(win->w_jumplist[i].fmark.mark.lnum)); } @@ -1034,7 +1068,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, if (win->w_buffer == curbuf) { if (!cmdmod.lockmarks) { - /* marks in the tag stack */ + // marks in the tag stack for (i = 0; i < win->w_tagstacklen; i++) { if (win->w_tagstack[i].fmark.fnum == fnum) { one_adjust_nodel(&(win->w_tagstack[i].fmark.mark.lnum)); @@ -1042,23 +1076,23 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, } } - /* the displayed Visual area */ + // the displayed Visual area if (win->w_old_cursor_lnum != 0) { one_adjust_nodel(&(win->w_old_cursor_lnum)); one_adjust_nodel(&(win->w_old_visual_lnum)); } - /* topline and cursor position for windows with the same buffer - * other than the current window */ + // topline and cursor position for windows with the same buffer + // other than the current window if (win != curwin) { if (win->w_topline >= line1 && win->w_topline <= line2) { - if (amount == MAXLNUM) { /* topline is deleted */ + if (amount == MAXLNUM) { // topline is deleted if (line1 <= 1) { win->w_topline = 1; } else { win->w_topline = line1 - 1; } - } else { /* keep topline on the same line */ + } else { // keep topline on the same line win->w_topline += amount; } win->w_topfill = 0; @@ -1067,14 +1101,14 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, win->w_topfill = 0; } if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2) { - if (amount == MAXLNUM) { /* line with cursor is deleted */ + if (amount == MAXLNUM) { // line with cursor is deleted if (line1 <= 1) { win->w_cursor.lnum = 1; } else { win->w_cursor.lnum = line1 - 1; } win->w_cursor.col = 0; - } else { /* keep cursor on the same line */ + } else { // keep cursor on the same line win->w_cursor.lnum += amount; } } else if (amount_after && win->w_cursor.lnum > line2) { @@ -1088,11 +1122,11 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, } } - /* adjust diffs */ + // adjust diffs diff_mark_adjust(line1, line2, amount, amount_after); } -/* This code is used often, needs to be fast. */ +// This code is used often, needs to be fast. #define col_adjust(pp) \ { \ posp = pp; \ @@ -1115,56 +1149,58 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, // position. // "spaces_removed" is the number of spaces that were removed, matters when the // cursor is inside them. -void mark_col_adjust( - linenr_T lnum, colnr_T mincol, long lnum_amount, long col_amount, - int spaces_removed) +void mark_col_adjust(linenr_T lnum, colnr_T mincol, long lnum_amount, long col_amount, + int spaces_removed) { int i; int fnum = curbuf->b_fnum; - pos_T *posp; - - if ((col_amount == 0L && lnum_amount == 0L) || cmdmod.lockmarks) - return; /* nothing to do */ + pos_T *posp; - /* named marks, lower case and upper case */ + if ((col_amount == 0L && lnum_amount == 0L) || cmdmod.lockmarks) { + return; // nothing to do + } + // named marks, lower case and upper case for (i = 0; i < NMARKS; i++) { col_adjust(&(curbuf->b_namedm[i].mark)); - if (namedfm[i].fmark.fnum == fnum) + if (namedfm[i].fmark.fnum == fnum) { col_adjust(&(namedfm[i].fmark.mark)); + } } for (i = NMARKS; i < NGLOBALMARKS; i++) { - if (namedfm[i].fmark.fnum == fnum) + if (namedfm[i].fmark.fnum == fnum) { col_adjust(&(namedfm[i].fmark.mark)); + } } - /* last Insert position */ + // last Insert position col_adjust(&(curbuf->b_last_insert.mark)); - /* last change position */ + // last change position col_adjust(&(curbuf->b_last_change.mark)); - /* list of change positions */ - for (i = 0; i < curbuf->b_changelistlen; ++i) + // list of change positions + for (i = 0; i < curbuf->b_changelistlen; ++i) { col_adjust(&(curbuf->b_changelist[i].mark)); + } - /* Visual area */ + // Visual area col_adjust(&(curbuf->b_visual.vi_start)); col_adjust(&(curbuf->b_visual.vi_end)); - /* previous context mark */ + // previous context mark col_adjust(&(curwin->w_pcmark)); - /* previous pcmark */ + // previous pcmark col_adjust(&(curwin->w_prev_pcmark)); - /* saved cursor for formatting */ + // saved cursor for formatting col_adjust(&saved_cursor); /* * Adjust items in all windows related to the current buffer. */ FOR_ALL_WINDOWS_IN_TAB(win, curtab) { - /* marks in the jumplist */ + // marks in the jumplist for (i = 0; i < win->w_jumplistlen; ++i) { if (win->w_jumplist[i].fmark.fnum == fnum) { col_adjust(&(win->w_jumplist[i].fmark.mark)); @@ -1172,14 +1208,14 @@ void mark_col_adjust( } if (win->w_buffer == curbuf) { - /* marks in the tag stack */ + // marks in the tag stack for (i = 0; i < win->w_tagstacklen; i++) { if (win->w_tagstack[i].fmark.fnum == fnum) { col_adjust(&(win->w_tagstack[i].fmark.mark)); } } - /* cursor position for other windows with the same buffer */ + // cursor position for other windows with the same buffer if (win != curwin) { col_adjust(&win->w_cursor); } @@ -1269,8 +1305,9 @@ void copy_jumplist(win_T *from, win_T *to) for (i = 0; i < from->w_jumplistlen; ++i) { to->w_jumplist[i] = from->w_jumplist[i]; - if (from->w_jumplist[i].fname != NULL) + if (from->w_jumplist[i].fname != NULL) { to->w_jumplist[i].fname = vim_strsave(from->w_jumplist[i].fname); + } } to->w_jumplistlen = from->w_jumplistlen; to->w_jumplistidx = from->w_jumplistidx; @@ -1287,18 +1324,17 @@ void copy_jumplist(win_T *from, win_T *to) /// /// @return Pointer that needs to be passed to next `mark_jumplist_iter` call or /// NULL if iteration is over. -const void *mark_jumplist_iter(const void *const iter, const win_T *const win, - xfmark_T *const fm) +const void *mark_jumplist_iter(const void *const iter, const win_T *const win, xfmark_T *const fm) FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT { if (iter == NULL && win->w_jumplistlen == 0) { - *fm = (xfmark_T) {{{0, 0, 0}, 0, 0, NULL}, NULL}; + *fm = (xfmark_T) { { { 0, 0, 0 }, 0, 0, NULL }, NULL }; return NULL; } const xfmark_T *const iter_mark = - (iter == NULL + (iter == NULL ? &(win->w_jumplist[0]) - : (const xfmark_T *const) iter); + : (const xfmark_T *const)iter); *fm = *iter_mark; if (iter_mark == &(win->w_jumplist[win->w_jumplistlen - 1])) { return NULL; @@ -1318,30 +1354,29 @@ const void *mark_jumplist_iter(const void *const iter, const win_T *const win, /// /// @return Pointer that needs to be passed to next `mark_global_iter` call or /// NULL if iteration is over. -const void *mark_global_iter(const void *const iter, char *const name, - xfmark_T *const fm) +const void *mark_global_iter(const void *const iter, char *const name, xfmark_T *const fm) FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT { *name = NUL; const xfmark_T *iter_mark = (iter == NULL ? &(namedfm[0]) - : (const xfmark_T *const) iter); - while ((size_t) (iter_mark - &(namedfm[0])) < ARRAY_SIZE(namedfm) + : (const xfmark_T *const)iter); + while ((size_t)(iter_mark - &(namedfm[0])) < ARRAY_SIZE(namedfm) && !iter_mark->fmark.mark.lnum) { iter_mark++; } - if ((size_t) (iter_mark - &(namedfm[0])) == ARRAY_SIZE(namedfm) + if ((size_t)(iter_mark - &(namedfm[0])) == ARRAY_SIZE(namedfm) || !iter_mark->fmark.mark.lnum) { return NULL; } - size_t iter_off = (size_t) (iter_mark - &(namedfm[0])); - *name = (char) (iter_off < NMARKS - ? 'A' + (char) iter_off - : '0' + (char) (iter_off - NMARKS)); + size_t iter_off = (size_t)(iter_mark - &(namedfm[0])); + *name = (char)(iter_off < NMARKS + ? 'A' + (char)iter_off + : '0' + (char)(iter_off - NMARKS)); *fm = *iter_mark; - while ((size_t) (++iter_mark - &(namedfm[0])) < ARRAY_SIZE(namedfm)) { + while ((size_t)(++iter_mark - &(namedfm[0])) < ARRAY_SIZE(namedfm)) { if (iter_mark->fmark.mark.lnum) { - return (const void *) iter_mark; + return (const void *)iter_mark; } } return NULL; @@ -1358,34 +1393,27 @@ const void *mark_global_iter(const void *const iter, char *const name, /// behaviour is undefined. /// /// @return Pointer to the next mark or NULL. -static inline const fmark_T *next_buffer_mark(const buf_T *const buf, - char *const mark_name) +static inline const fmark_T *next_buffer_mark(const buf_T *const buf, char *const mark_name) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { switch (*mark_name) { - case NUL: { - *mark_name = '"'; - return &(buf->b_last_cursor); - } - case '"': { - *mark_name = '^'; - return &(buf->b_last_insert); - } - case '^': { - *mark_name = '.'; - return &(buf->b_last_change); - } - case '.': { - *mark_name = 'a'; - return &(buf->b_namedm[0]); - } - case 'z': { - return NULL; - } - default: { - (*mark_name)++; - return &(buf->b_namedm[*mark_name - 'a']); - } + case NUL: + *mark_name = '"'; + return &(buf->b_last_cursor); + case '"': + *mark_name = '^'; + return &(buf->b_last_insert); + case '^': + *mark_name = '.'; + return &(buf->b_last_change); + case '.': + *mark_name = 'a'; + return &(buf->b_namedm[0]); + case 'z': + return NULL; + default: + (*mark_name)++; + return &(buf->b_namedm[*mark_name - 'a']); } } @@ -1401,12 +1429,12 @@ static inline const fmark_T *next_buffer_mark(const buf_T *const buf, /// /// @return Pointer that needs to be passed to next `mark_buffer_iter` call or /// NULL if iteration is over. -const void *mark_buffer_iter(const void *const iter, const buf_T *const buf, - char *const name, fmark_T *const fm) +const void *mark_buffer_iter(const void *const iter, const buf_T *const buf, char *const name, + fmark_T *const fm) FUNC_ATTR_NONNULL_ARG(2, 3, 4) FUNC_ATTR_WARN_UNUSED_RESULT { *name = NUL; - char mark_name = (char) (iter == NULL + char mark_name = (char)(iter == NULL ? NUL : (iter == &(buf->b_last_cursor) ? '"' @@ -1414,8 +1442,8 @@ const void *mark_buffer_iter(const void *const iter, const buf_T *const buf, ? '^' : (iter == &(buf->b_last_change) ? '.' - : 'a' + (char) ((const fmark_T *)iter - - &(buf->b_namedm[0])))))); + : 'a' + (char)((const fmark_T *)iter + - &(buf->b_namedm[0])))))); const fmark_T *iter_mark = next_buffer_mark(buf, &mark_name); while (iter_mark != NULL && iter_mark->mark.lnum == 0) { iter_mark = next_buffer_mark(buf, &mark_name); @@ -1423,14 +1451,14 @@ const void *mark_buffer_iter(const void *const iter, const buf_T *const buf, if (iter_mark == NULL) { return NULL; } - size_t iter_off = (size_t) (iter_mark - &(buf->b_namedm[0])); + size_t iter_off = (size_t)(iter_mark - &(buf->b_namedm[0])); if (mark_name) { *name = mark_name; } else { - *name = (char) ('a' + (char) iter_off); + *name = (char)('a' + (char)iter_off); } *fm = *iter_mark; - return (const void *) iter_mark; + return (const void *)iter_mark; } /// Set global mark @@ -1467,8 +1495,7 @@ bool mark_set_global(const char name, const xfmark_T fm, const bool update) /// later then existing one. /// /// @return true on success, false on failure. -bool mark_set_local(const char name, buf_T *const buf, - const fmark_T fm, const bool update) +bool mark_set_local(const char name, buf_T *const buf, const fmark_T fm, const bool update) FUNC_ATTR_NONNULL_ALL { fmark_T *fm_tgt = NULL; @@ -1556,8 +1583,7 @@ void mark_mb_adjustpos(buf_T *buf, pos_T *lp) // Add information about mark 'mname' to list 'l' -static int add_mark(list_T *l, const char *mname, const pos_T *pos, int bufnr, - const char *fname) +static int add_mark(list_T *l, const char *mname, const pos_T *pos, int bufnr, const char *fname) FUNC_ATTR_NONNULL_ARG(1, 2, 3) { if (pos->lnum <= 0) { @@ -1611,6 +1637,15 @@ void get_buf_local_marks(const buf_T *buf, list_T *l) add_mark(l, "'>", &buf->b_visual.vi_end, buf->b_fnum, NULL); } +/// Get a global mark +/// +/// @param[in] Name of named mark +/// @param[out] Global/file mark +xfmark_T get_global_mark(char name) +{ + return namedfm[mark_global_index(name)]; +} + /// Get information about global marks ('A' to 'Z' and '0' to '9') /// /// @param[out] l List to store global marks diff --git a/src/nvim/mark.h b/src/nvim/mark.h index b3d9b5d95a..a55f733d9a 100644 --- a/src/nvim/mark.h +++ b/src/nvim/mark.h @@ -1,55 +1,55 @@ #ifndef NVIM_MARK_H #define NVIM_MARK_H -#include "nvim/macros.h" #include "nvim/ascii.h" #include "nvim/buffer_defs.h" +#include "nvim/ex_cmds_defs.h" // for exarg_T +#include "nvim/extmark_defs.h" #include "nvim/func_attr.h" +#include "nvim/macros.h" #include "nvim/mark_defs.h" -#include "nvim/extmark_defs.h" #include "nvim/memory.h" -#include "nvim/pos.h" #include "nvim/os/time.h" -#include "nvim/ex_cmds_defs.h" // for exarg_T +#include "nvim/pos.h" /// Set fmark using given value #define SET_FMARK(fmarkp_, mark_, fnum_) \ - do { \ - fmark_T *const fmarkp__ = fmarkp_; \ - fmarkp__->mark = mark_; \ - fmarkp__->fnum = fnum_; \ - fmarkp__->timestamp = os_time(); \ - fmarkp__->additional_data = NULL; \ - } while (0) + do { \ + fmark_T *const fmarkp__ = fmarkp_; \ + fmarkp__->mark = mark_; \ + fmarkp__->fnum = fnum_; \ + fmarkp__->timestamp = os_time(); \ + fmarkp__->additional_data = NULL; \ + } while (0) /// Free and set fmark using given value #define RESET_FMARK(fmarkp_, mark_, fnum_) \ - do { \ - fmark_T *const fmarkp___ = fmarkp_; \ - free_fmark(*fmarkp___); \ - SET_FMARK(fmarkp___, mark_, fnum_); \ - } while (0) + do { \ + fmark_T *const fmarkp___ = fmarkp_; \ + free_fmark(*fmarkp___); \ + SET_FMARK(fmarkp___, mark_, fnum_); \ + } while (0) /// Clear given fmark #define CLEAR_FMARK(fmarkp_) \ - RESET_FMARK(fmarkp_, ((pos_T) { 0, 0, 0 }), 0) + RESET_FMARK(fmarkp_, ((pos_T) { 0, 0, 0 }), 0) /// Set given extended mark (regular mark + file name) #define SET_XFMARK(xfmarkp_, mark_, fnum_, fname_) \ - do { \ - xfmark_T *const xfmarkp__ = xfmarkp_; \ - xfmarkp__->fname = fname_; \ - SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_); \ - } while (0) + do { \ + xfmark_T *const xfmarkp__ = xfmarkp_; \ + xfmarkp__->fname = fname_; \ + SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_); \ + } while (0) /// Free and set given extended mark (regular mark + file name) #define RESET_XFMARK(xfmarkp_, mark_, fnum_, fname_) \ - do { \ - xfmark_T *const xfmarkp__ = xfmarkp_; \ - free_xfmark(*xfmarkp__); \ - xfmarkp__->fname = fname_; \ - SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_); \ - } while (0) + do { \ + xfmark_T *const xfmarkp__ = xfmarkp_; \ + free_xfmark(*xfmarkp__); \ + xfmarkp__->fname = fname_; \ + SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_); \ + } while (0) /// Convert mark name to the offset static inline int mark_global_index(const char name) diff --git a/src/nvim/mark_defs.h b/src/nvim/mark_defs.h index 2cb489501e..51199a09e0 100644 --- a/src/nvim/mark_defs.h +++ b/src/nvim/mark_defs.h @@ -1,9 +1,9 @@ #ifndef NVIM_MARK_DEFS_H #define NVIM_MARK_DEFS_H -#include "nvim/pos.h" -#include "nvim/os/time.h" #include "nvim/eval/typval.h" +#include "nvim/os/time.h" +#include "nvim/pos.h" /* * marks: positions in a file @@ -42,7 +42,7 @@ typedef struct filemark { /// Structure defining extended mark (mark with file name attached) typedef struct xfilemark { fmark_T fmark; ///< Actual mark. - char_u *fname; ///< File name, used when fnum == 0. + char_u *fname; ///< File name, used when fnum == 0. } xfmark_T; #endif // NVIM_MARK_DEFS_H diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c index a04f250fc3..39c1e36147 100644 --- a/src/nvim/marktree.c +++ b/src/nvim/marktree.c @@ -49,9 +49,9 @@ #include <assert.h> -#include "nvim/marktree.h" -#include "nvim/lib/kvec.h" #include "nvim/garray.h" +#include "nvim/lib/kvec.h" +#include "nvim/marktree.h" #define T MT_BRANCH_FACTOR #define ILEN (sizeof(mtnode_t)+(2 * T) * sizeof(void *)) @@ -137,7 +137,9 @@ static inline int marktree_getp_aux(const mtnode_t *x, mtkey_t k, int *r) end = mid; } } - if (begin == x->n) { *rr = 1; return x->n - 1; } + if (begin == x->n) { + *rr = 1; return x->n - 1; + } if ((*rr = key_cmp(k, x->key[begin])) < 0) { begin--; } @@ -232,9 +234,8 @@ uint64_t marktree_put(MarkTree *b, int row, int col, bool right_gravity) return id; } -uint64_t marktree_put_pair(MarkTree *b, - int start_row, int start_col, bool start_right, - int end_row, int end_col, bool end_right) +uint64_t marktree_put_pair(MarkTree *b, int start_row, int start_col, bool start_right, int end_row, + int end_col, bool end_right) { uint64_t id = (b->next_id+=ID_INCR)|PAIRED; uint64_t start_id = id|(start_right?RIGHT_GRAVITY:0); @@ -466,7 +467,7 @@ static mtnode_t *merge_node(MarkTree *b, mtnode_t *p, int i) unrelative(x->key[x->n].pos, &x->key[x->n+1+k].pos); } if (x->level) { - memmove(&x->ptr[x->n+1], y->ptr, (size_t)(y->n + 1) * sizeof(mtnode_t *)); + memmove(&x->ptr[x->n+1], y->ptr, ((size_t)y->n + 1) * sizeof(mtnode_t *)); for (int k = 0; k < y->n+1; k++) { x->ptr[x->n+k+1]->parent = x; } @@ -488,7 +489,7 @@ static void pivot_right(MarkTree *b, mtnode_t *p, int i) mtnode_t *x = p->ptr[i], *y = p->ptr[i+1]; memmove(&y->key[1], y->key, (size_t)y->n * sizeof(mtkey_t)); if (y->level) { - memmove(&y->ptr[1], y->ptr, (size_t)(y->n + 1) * sizeof(mtnode_t *)); + memmove(&y->ptr[1], y->ptr, ((size_t)y->n + 1) * sizeof(mtnode_t *)); } y->key[0] = p->key[i]; refkey(b, y, 0); @@ -594,8 +595,8 @@ bool marktree_itr_get(MarkTree *b, int row, int col, MarkTreeIter *itr) itr, false, false, NULL); } -bool marktree_itr_get_ext(MarkTree *b, mtpos_t p, MarkTreeIter *itr, - bool last, bool gravity, mtpos_t *oldbase) +bool marktree_itr_get_ext(MarkTree *b, mtpos_t p, MarkTreeIter *itr, bool last, bool gravity, + mtpos_t *oldbase) { mtkey_t k = { .pos = p, .id = gravity ? RIGHT_GRAVITY : 0 }; if (last && !gravity) { @@ -695,8 +696,7 @@ bool marktree_itr_next(MarkTree *b, MarkTreeIter *itr) return marktree_itr_next_skip(b, itr, false, NULL); } -static bool marktree_itr_next_skip(MarkTree *b, MarkTreeIter *itr, bool skip, - mtpos_t oldbase[]) +static bool marktree_itr_next_skip(MarkTree *b, MarkTreeIter *itr, bool skip, mtpos_t oldbase[]) { if (!itr->node) { return false; @@ -819,8 +819,8 @@ mtmark_t marktree_itr_current(MarkTreeIter *itr) mtpos_t pos = marktree_itr_pos(itr); mtmark_t mark = { .row = pos.row, .col = pos.col, - .id = ANTIGRAVITY(keyid), - .right_gravity = keyid & RIGHT_GRAVITY }; + .id = ANTIGRAVITY(keyid), + .right_gravity = keyid & RIGHT_GRAVITY }; return mark; } return (mtmark_t){ -1, -1, 0, false }; @@ -833,14 +833,12 @@ static void swap_id(uint64_t *id1, uint64_t *id2) *id2 = temp; } -bool marktree_splice(MarkTree *b, - int start_line, int start_col, - int old_extent_line, int old_extent_col, - int new_extent_line, int new_extent_col) +bool marktree_splice(MarkTree *b, int start_line, int start_col, int old_extent_line, + int old_extent_col, int new_extent_line, int new_extent_col) { mtpos_t start = { start_line, start_col }; - mtpos_t old_extent = { (int)old_extent_line, old_extent_col }; - mtpos_t new_extent = { (int)new_extent_line, new_extent_col }; + mtpos_t old_extent = { old_extent_line, old_extent_col }; + mtpos_t new_extent = { new_extent_line, new_extent_col }; bool may_delete = (old_extent.row != 0 || old_extent.col != 0); bool same_line = old_extent.row == 0 && new_extent.row == 0; @@ -903,7 +901,7 @@ continue_same_node: refkey(b, itr->node, itr->i); refkey(b, enditr->node, enditr->i); } else { - past_right = true; // NOLINT + past_right = true; // NOLINT (void)past_right; break; } @@ -994,10 +992,8 @@ past_continue_same_node: return moved; } -void marktree_move_region(MarkTree *b, - int start_row, colnr_T start_col, - int extent_row, colnr_T extent_col, - int new_row, colnr_T new_col) +void marktree_move_region(MarkTree *b, int start_row, colnr_T start_col, int extent_row, + colnr_T extent_col, int new_row, colnr_T new_col) { mtpos_t start = { start_row, start_col }, size = { extent_row, extent_col }; mtpos_t end = size; @@ -1114,8 +1110,7 @@ void marktree_check(MarkTree *b) } #ifndef NDEBUG -static size_t check_node(MarkTree *b, mtnode_t *x, - mtpos_t *last, bool *last_right) +static size_t check_node(MarkTree *b, mtnode_t *x, mtpos_t *last, bool *last_right) { assert(x->n <= 2 * T - 1); // TODO(bfredl): too strict if checking "in repair" post-delete tree. @@ -1173,8 +1168,7 @@ char *mt_inspect_rec(MarkTree *b) void mt_inspect_node(MarkTree *b, garray_T *ga, mtnode_t *n, mtpos_t off) { static char buf[1024]; -#define GA_PUT(x) ga_concat(ga, (char_u *)(x)) - GA_PUT("["); + ga_concat(ga, "["); if (n->level) { mt_inspect_node(b, ga, n->ptr[0], off); } @@ -1182,14 +1176,13 @@ void mt_inspect_node(MarkTree *b, garray_T *ga, mtnode_t *n, mtpos_t off) mtpos_t p = n->key[i].pos; unrelative(off, &p); snprintf((char *)buf, sizeof(buf), "%d/%d", p.row, p.col); - GA_PUT(buf); + ga_concat(ga, buf); if (n->level) { mt_inspect_node(b, ga, n->ptr[i+1], p); } else { - GA_PUT(","); + ga_concat(ga, ","); } } - GA_PUT("]"); -#undef GA_PUT + ga_concat(ga, "]"); } diff --git a/src/nvim/marktree.h b/src/nvim/marktree.h index 7af23765c3..02f73b8052 100644 --- a/src/nvim/marktree.h +++ b/src/nvim/marktree.h @@ -2,9 +2,10 @@ #define NVIM_MARKTREE_H #include <stdint.h> -#include "nvim/pos.h" -#include "nvim/map.h" + #include "nvim/garray.h" +#include "nvim/map.h" +#include "nvim/pos.h" #define MT_MAX_DEPTH 20 #define MT_BRANCH_FACTOR 10 diff --git a/src/nvim/math.c b/src/nvim/math.c index 63309b6f7a..63a29509bd 100644 --- a/src/nvim/math.c +++ b/src/nvim/math.c @@ -21,9 +21,12 @@ int xfpclassify(double d) m = 0xfffffffffffffULL & m; switch (e) { - default: return FP_NORMAL; - case 0x000: return m ? FP_SUBNORMAL : FP_ZERO; - case 0x7ff: return m ? FP_NAN : FP_INFINITE; + default: + return FP_NORMAL; + case 0x000: + return m ? FP_SUBNORMAL : FP_ZERO; + case 0x7ff: + return m ? FP_NAN : FP_INFINITE; } } int xisinf(double d) diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index fea1ab77a2..62cc3b56ed 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -190,9 +190,9 @@ enc_canon_table[] = #define IDX_BIG5 29 { "big5", ENC_DBCS, DBCS_CHT }, - /* MS-DOS and MS-Windows codepages are included here, so that they can be - * used on Unix too. Most of them are similar to ISO-8859 encodings, but - * not exactly the same. */ + // MS-DOS and MS-Windows codepages are included here, so that they can be + // used on Unix too. Most of them are similar to ISO-8859 encodings, but + // not exactly the same. #define IDX_CP437 30 { "cp437", ENC_8BIT, 437 }, // like iso-8859-1 #define IDX_CP737 31 @@ -1066,8 +1066,8 @@ bool utf_printable(int c) */ return iswprint(c); #else - /* Sorted list of non-overlapping intervals. - * 0xd800-0xdfff is reserved for UTF-16, actually illegal. */ + // Sorted list of non-overlapping intervals. + // 0xd800-0xdfff is reserved for UTF-16, actually illegal. static struct interval nonprint[] = { { 0x070f, 0x070f }, { 0x180b, 0x180e }, { 0x200b, 0x200f }, { 0x202a, 0x202e }, @@ -1354,12 +1354,12 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1, size_t n2 return c1 == 0 ? -1 : 1; } - /* Continue with bytewise comparison to produce some result that - * would make comparison operations involving this function transitive. - * - * If only one string had an error, comparison should be made with - * folded version of the other string. In this case it is enough - * to fold just one character to determine the result of comparison. */ + // Continue with bytewise comparison to produce some result that + // would make comparison operations involving this function transitive. + // + // If only one string had an error, comparison should be made with + // folded version of the other string. In this case it is enough + // to fold just one character to determine the result of comparison. if (c1 != -1 && c2 == -1) { n1 = utf_char2bytes(utf_fold(c1), buffer); @@ -1395,9 +1395,9 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1, size_t n2 } #ifdef WIN32 -#ifndef CP_UTF8 -# define CP_UTF8 65001 // magic number from winnls.h -#endif +# ifndef CP_UTF8 +# define CP_UTF8 65001 // magic number from winnls.h +# endif /// Converts string from UTF-8 to UTF-16. /// @@ -1637,8 +1637,8 @@ int utf_head_off(const char_u *base, const char_u *p) while (q > base && (*q & 0xc0) == 0x80) { --q; } - /* Check for illegal sequence. Do allow an illegal byte after where we - * started. */ + // Check for illegal sequence. Do allow an illegal byte after where we + // started. len = utf8len_tab[*q]; if (len != (int)(s - q + 1) && len != (int)(p - q + 1)) { return 0; @@ -1999,7 +1999,7 @@ void mb_check_adjust_col(void *win_) /// @param line start of the string /// /// @return a pointer to the character before "*p", if there is one. -char_u * mb_prevptr(char_u *line, char_u *p) +char_u *mb_prevptr(char_u *line, char_u *p) { if (p > line) { MB_PTR_BACK(line, p); @@ -2099,7 +2099,7 @@ const char *mb_unescape(const char **const pp) /* * Skip the Vim specific head of a 'encoding' name. */ -char_u * enc_skip(char_u *p) +char_u *enc_skip(char_u *p) { if (STRNCMP(p, "2byte-", 6) == 0) { return p + 6; @@ -2202,19 +2202,19 @@ static int enc_alias_search(char_u *name) * Get the canonicalized encoding of the current locale. * Returns an allocated string when successful, NULL when not. */ -char_u * enc_locale(void) +char_u *enc_locale(void) { int i; char buf[50]; const char *s; -# ifdef HAVE_NL_LANGINFO_CODESET +#ifdef HAVE_NL_LANGINFO_CODESET if (!(s = nl_langinfo(CODESET)) || *s == NUL) -# endif +#endif { -# if defined(HAVE_LOCALE_H) +#if defined(HAVE_LOCALE_H) if (!(s = setlocale(LC_CTYPE, NULL)) || *s == NUL) -# endif +#endif { if ((s = os_getenv("LC_ALL"))) { if ((s = os_getenv("LC_CTYPE"))) { @@ -2265,7 +2265,7 @@ enc_locale_copy_enc: return enc_canonize((char_u *)buf); } -# if defined(HAVE_ICONV) +#if defined(HAVE_ICONV) /* @@ -2274,10 +2274,10 @@ enc_locale_copy_enc: * Returns (void *)-1 if failed. * (should return iconv_t, but that causes problems with prototypes). */ -void * my_iconv_open(char_u *to, char_u *from) +void *my_iconv_open(char_u *to, char_u *from) { iconv_t fd; -#define ICONV_TESTLEN 400 +# define ICONV_TESTLEN 400 char_u tobuf[ICONV_TESTLEN]; char *p; size_t tolen; @@ -2335,8 +2335,8 @@ static char_u *iconv_string(const vimconv_T *const vcp, char_u *str, size_t slen fromlen = slen; for (;; ) { if (len == 0 || ICONV_ERRNO == ICONV_E2BIG) { - /* Allocate enough room for most conversions. When re-allocating - * increase the buffer size. */ + // Allocate enough room for most conversions. When re-allocating + // increase the buffer size. len = len + fromlen * 2 + 40; p = xmalloc(len); if (done > 0) { @@ -2395,7 +2395,7 @@ static char_u *iconv_string(const vimconv_T *const vcp, char_u *str, size_t slen return result; } -# endif // HAVE_ICONV +#endif // HAVE_ICONV @@ -2425,11 +2425,11 @@ int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8, c int to_is_utf8; // Reset to no conversion. -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV if (vcp->vc_type == CONV_ICONV && vcp->vc_fd != (iconv_t)-1) { iconv_close(vcp->vc_fd); } -# endif +#endif *vcp = (vimconv_T)MBYTE_NONE_CONV; // No conversion when one of the names is empty or they are equal. @@ -2466,7 +2466,7 @@ int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8, c // Internal utf-8 -> latin9 conversion. vcp->vc_type = CONV_TO_LATIN9; } -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV else { // NOLINT(readability/braces) // Use iconv() for conversion. vcp->vc_fd = (iconv_t)my_iconv_open(to_is_utf8 ? (char_u *)"utf-8" : to, @@ -2476,7 +2476,7 @@ int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8, c vcp->vc_factor = 4; // could be longer too... } } -# endif +#endif if (vcp->vc_type == CONV_NONE) { return FAIL; } @@ -2501,8 +2501,8 @@ char_u *string_convert(const vimconv_T *const vcp, char_u *ptr, size_t *lenp) * an incomplete sequence at the end it is not converted and "*unconvlenp" is * set to the number of remaining bytes. */ -char_u * string_convert_ext(const vimconv_T *const vcp, char_u *ptr, size_t *lenp, - size_t *unconvlenp) +char_u *string_convert_ext(const vimconv_T *const vcp, char_u *ptr, size_t *lenp, + size_t *unconvlenp) { char_u *retval = NULL; char_u *d; @@ -2644,11 +2644,11 @@ char_u * string_convert_ext(const vimconv_T *const vcp, char_u *ptr, size_t *len } break; -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV case CONV_ICONV: // conversion with vcp->vc_fd retval = iconv_string(vcp, ptr, len, unconvlenp, lenp); break; -# endif +#endif } return retval; diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h index 536d58be1f..9926f27411 100644 --- a/src/nvim/mbyte.h +++ b/src/nvim/mbyte.h @@ -1,12 +1,12 @@ #ifndef NVIM_MBYTE_H #define NVIM_MBYTE_H -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include <string.h> -#include "nvim/iconv.h" #include "nvim/func_attr.h" +#include "nvim/iconv.h" #include "nvim/os/os_defs.h" // For indirect #include "nvim/types.h" // for char_u @@ -22,21 +22,21 @@ // max length of an unicode char #define MB_MAXCHAR 6 -/* properties used in enc_canon_table[] (first three mutually exclusive) */ +// properties used in enc_canon_table[] (first three mutually exclusive) #define ENC_8BIT 0x01 #define ENC_DBCS 0x02 #define ENC_UNICODE 0x04 -#define ENC_ENDIAN_B 0x10 /* Unicode: Big endian */ -#define ENC_ENDIAN_L 0x20 /* Unicode: Little endian */ +#define ENC_ENDIAN_B 0x10 // Unicode: Big endian +#define ENC_ENDIAN_L 0x20 // Unicode: Little endian -#define ENC_2BYTE 0x40 /* Unicode: UCS-2 */ -#define ENC_4BYTE 0x80 /* Unicode: UCS-4 */ -#define ENC_2WORD 0x100 /* Unicode: UTF-16 */ +#define ENC_2BYTE 0x40 // Unicode: UCS-2 +#define ENC_4BYTE 0x80 // Unicode: UCS-4 +#define ENC_2WORD 0x100 // Unicode: UTF-16 -#define ENC_LATIN1 0x200 /* Latin1 */ -#define ENC_LATIN9 0x400 /* Latin9 */ -#define ENC_MACROMAN 0x800 /* Mac Roman (not Macro Man! :-) */ +#define ENC_LATIN1 0x200 // Latin1 +#define ENC_LATIN9 0x400 // Latin9 +#define ENC_MACROMAN 0x800 // Mac Roman (not Macro Man! :-) // TODO(bfredl): eventually we should keep only one of the namings #define mb_ptr2len utfc_ptr2len @@ -63,9 +63,9 @@ typedef enum { typedef struct { int vc_type; ///< Zero or more ConvFlags. int vc_factor; ///< Maximal expansion factor. -# ifdef HAVE_ICONV +#ifdef HAVE_ICONV iconv_t vc_fd; ///< Value for CONV_ICONV. -# endif +#endif bool vc_fail; ///< What to do with invalid characters: if true, fail, ///< otherwise use '?'. } vimconv_T; diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c index 7bed644da3..438340e0c4 100644 --- a/src/nvim/memfile.c +++ b/src/nvim/memfile.c @@ -39,24 +39,24 @@ /// mf_fullname() make file name full path (use before first :cd) #include <assert.h> +#include <fcntl.h> #include <inttypes.h> #include <limits.h> -#include <string.h> #include <stdbool.h> -#include <fcntl.h> +#include <string.h> -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/memfile.h" +#include "nvim/assert.h" #include "nvim/fileio.h" +#include "nvim/memfile.h" #include "nvim/memline.h" -#include "nvim/message.h" #include "nvim/memory.h" +#include "nvim/message.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" #include "nvim/os_unix.h" #include "nvim/path.h" -#include "nvim/assert.h" -#include "nvim/os/os.h" -#include "nvim/os/input.h" +#include "nvim/vim.h" #define MEMFILE_PAGE_SIZE 4096 /// default page size @@ -168,7 +168,7 @@ void mf_close(memfile_T *mfp, bool del_file) return; } if (mfp->mf_fd >= 0 && close(mfp->mf_fd) < 0) { - EMSG(_(e_swapclose)); + EMSG(_(e_swapclose)); } if (del_file && mfp->mf_fname != NULL) { os_remove((char *)mfp->mf_fname); @@ -282,14 +282,16 @@ bhdr_T *mf_new(memfile_T *mfp, bool negative, unsigned page_count) bhdr_T *mf_get(memfile_T *mfp, blocknr_T nr, unsigned page_count) { // check block number exists - if (nr >= mfp->mf_blocknr_max || nr <= mfp->mf_blocknr_min) + if (nr >= mfp->mf_blocknr_max || nr <= mfp->mf_blocknr_min) { return NULL; + } // see if it is in the cache bhdr_T *hp = mf_find_hash(mfp, nr); if (hp == NULL) { // not in the hash list - if (nr < 0 || nr >= mfp->mf_infile_count) // can't be in the file + if (nr < 0 || nr >= mfp->mf_infile_count) { // can't be in the file return NULL; + } // could check here if the block is in the free list @@ -331,8 +333,9 @@ void mf_put(memfile_T *mfp, bhdr_T *hp, bool dirty, bool infile) mfp->mf_dirty = true; } hp->bh_flags = flags; - if (infile) + if (infile) { mf_trans_add(mfp, hp); // may translate negative in positive nr + } } /// Signal block as no longer used (may put it in the free list). @@ -381,32 +384,38 @@ int mf_sync(memfile_T *mfp, int flags) // fails then we give up. int status = OK; bhdr_T *hp; - for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev) + for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev) { if (((flags & MFS_ALL) || hp->bh_bnum >= 0) && (hp->bh_flags & BH_DIRTY) && (status == OK || (hp->bh_bnum >= 0 && hp->bh_bnum < mfp->mf_infile_count))) { - if ((flags & MFS_ZERO) && hp->bh_bnum != 0) + if ((flags & MFS_ZERO) && hp->bh_bnum != 0) { continue; + } if (mf_write(mfp, hp) == FAIL) { - if (status == FAIL) // double error: quit syncing + if (status == FAIL) { // double error: quit syncing break; + } status = FAIL; } if (flags & MFS_STOP) { // Stop when char available now. - if (os_char_avail()) + if (os_char_avail()) { break; + } } else { os_breakcheck(); } - if (got_int) + if (got_int) { break; + } } + } // If the whole list is flushed, the memfile is not dirty anymore. // In case of an error, dirty flag is also set, to avoid trying all the time. - if (hp == NULL || status == FAIL) + if (hp == NULL || status == FAIL) { mfp->mf_dirty = false; + } if (flags & MFS_FLUSH) { if (os_fsync(mfp->mf_fd)) { @@ -465,15 +474,17 @@ static void mf_ins_used(memfile_T *mfp, bhdr_T *hp) /// Remove block from memfile's used list. static void mf_rem_used(memfile_T *mfp, bhdr_T *hp) { - if (hp->bh_next == NULL) // last block in used list + if (hp->bh_next == NULL) { // last block in used list mfp->mf_used_last = hp->bh_prev; - else + } else { hp->bh_next->bh_prev = hp->bh_prev; + } - if (hp->bh_prev == NULL) // first block in used list + if (hp->bh_prev == NULL) { // first block in used list mfp->mf_used_first = hp->bh_next; - else + } else { hp->bh_prev->bh_next = hp->bh_next; + } } /// Release as many blocks as possible. @@ -554,8 +565,9 @@ static bhdr_T *mf_rem_free(memfile_T *mfp) /// - Error reading file. static int mf_read(memfile_T *mfp, bhdr_T *hp) { - if (mfp->mf_fd < 0) // there is no file, can't read + if (mfp->mf_fd < 0) { // there is no file, can't read return FAIL; + } unsigned page_size = mfp->mf_page_size; // TODO(elmart): Check (page_size * hp->bh_bnum) within off_T bounds. @@ -592,12 +604,15 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp) unsigned page_count; // number of pages written unsigned size; // number of bytes written - if (mfp->mf_fd < 0) // there is no file, can't write + if (mfp->mf_fd < 0) { // there is no file, can't write return FAIL; + } - if (hp->bh_bnum < 0) // must assign file block number - if (mf_trans_add(mfp, hp) == FAIL) + if (hp->bh_bnum < 0) { // must assign file block number + if (mf_trans_add(mfp, hp) == FAIL) { return FAIL; + } + } page_size = mfp->mf_page_size; @@ -620,10 +635,11 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp) PERROR(_("E296: Seek error in swap file write")); return FAIL; } - if (hp2 == NULL) // freed block, fill with dummy data + if (hp2 == NULL) { // freed block, fill with dummy data page_count = 1; - else + } else { page_count = hp2->bh_page_count; + } size = page_size * page_count; void *data = (hp2 == NULL) ? hp->bh_data : hp2->bh_data; if ((unsigned)write_eintr(mfp->mf_fd, data, size) != size) { @@ -631,18 +647,22 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp) /// disk is full. We give the message again only after a successful /// write or when hitting a key. We keep on trying, in case some /// space becomes available. - if (!did_swapwrite_msg) + if (!did_swapwrite_msg) { EMSG(_("E297: Write error in swap file")); + } did_swapwrite_msg = true; return FAIL; } did_swapwrite_msg = false; - if (hp2 != NULL) // written a non-dummy block + if (hp2 != NULL) { // written a non-dummy block hp2->bh_flags &= ~BH_DIRTY; - if (nr + (blocknr_T)page_count > mfp->mf_infile_count) // appended to file + } + if (nr + (blocknr_T)page_count > mfp->mf_infile_count) { // appended to file mfp->mf_infile_count = nr + page_count; - if (nr == hp->bh_bnum) // written the desired block + } + if (nr == hp->bh_bnum) { // written the desired block break; + } } return OK; } @@ -653,8 +673,9 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp) /// FAIL On failure. static int mf_trans_add(memfile_T *mfp, bhdr_T *hp) { - if (hp->bh_bnum >= 0) // it's already positive + if (hp->bh_bnum >= 0) { // it's already positive return OK; + } mf_blocknr_trans_item_T *np = xmalloc(sizeof(mf_blocknr_trans_item_T)); @@ -702,8 +723,9 @@ blocknr_T mf_trans_del(memfile_T *mfp, blocknr_T old_nr) mf_blocknr_trans_item_T *np = (mf_blocknr_trans_item_T *)mf_hash_find(&mfp->mf_trans, old_nr); - if (np == NULL) // not found + if (np == NULL) { // not found return old_nr; + } mfp->mf_neg_count--; blocknr_T new_bnum = np->nt_new_bnum; @@ -834,8 +856,9 @@ static void mf_hash_free_all(mf_hashtab_T *mht) static mf_hashitem_T *mf_hash_find(mf_hashtab_T *mht, blocknr_T key) { mf_hashitem_T *mhi = mht->mht_buckets[(size_t)key & mht->mht_mask]; - while (mhi != NULL && mhi->mhi_key != key) + while (mhi != NULL && mhi->mhi_key != key) { mhi = mhi->mhi_next; + } return mhi; } @@ -845,8 +868,9 @@ static void mf_hash_add_item(mf_hashtab_T *mht, mf_hashitem_T *mhi) size_t idx = (size_t)mhi->mhi_key & mht->mht_mask; mhi->mhi_next = mht->mht_buckets[idx]; mhi->mhi_prev = NULL; - if (mhi->mhi_next != NULL) + if (mhi->mhi_next != NULL) { mhi->mhi_next->mhi_prev = mhi; + } mht->mht_buckets[idx] = mhi; mht->mht_count++; @@ -861,14 +885,16 @@ static void mf_hash_add_item(mf_hashtab_T *mht, mf_hashitem_T *mhi) /// Remove item from hashtable. Item must be non NULL and within hashtable. static void mf_hash_rem_item(mf_hashtab_T *mht, mf_hashitem_T *mhi) { - if (mhi->mhi_prev == NULL) + if (mhi->mhi_prev == NULL) { mht->mht_buckets[(size_t)mhi->mhi_key & mht->mht_mask] = mhi->mhi_next; - else + } else { mhi->mhi_prev->mhi_next = mhi->mhi_next; + } - if (mhi->mhi_next != NULL) + if (mhi->mhi_next != NULL) { mhi->mhi_next->mhi_prev = mhi->mhi_prev; + } mht->mht_count--; @@ -884,8 +910,9 @@ static void mf_hash_grow(mf_hashtab_T *mht) mf_hashitem_T **buckets = xcalloc(1, size); int shift = 0; - while ((mht->mht_mask >> shift) != 0) + while ((mht->mht_mask >> shift) != 0) { shift++; + } for (size_t i = 0; i <= mht->mht_mask; i++) { /// Traverse the items in the i-th original bucket and move them into @@ -914,13 +941,16 @@ static void mf_hash_grow(mf_hashtab_T *mht) } } - for (size_t j = 0; j < MHT_GROWTH_FACTOR; j++) - if (tails[j] != NULL) + for (size_t j = 0; j < MHT_GROWTH_FACTOR; j++) { + if (tails[j] != NULL) { tails[j]->mhi_next = NULL; + } + } } - if (mht->mht_buckets != mht->mht_small_buckets) + if (mht->mht_buckets != mht->mht_small_buckets) { xfree(mht->mht_buckets); + } mht->mht_buckets = buckets; mht->mht_mask = (mht->mht_mask + 1) * MHT_GROWTH_FACTOR - 1; diff --git a/src/nvim/memfile_defs.h b/src/nvim/memfile_defs.h index 3eaa7d83e0..537d3e5f65 100644 --- a/src/nvim/memfile_defs.h +++ b/src/nvim/memfile_defs.h @@ -1,12 +1,12 @@ #ifndef NVIM_MEMFILE_DEFS_H #define NVIM_MEMFILE_DEFS_H -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include <stdlib.h> -#include "nvim/types.h" #include "nvim/pos.h" +#include "nvim/types.h" /// A block number. /// diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 4ccbb31e2c..29e4a03d51 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -38,29 +38,31 @@ #include <assert.h> #include <errno.h> +#include <fcntl.h> #include <inttypes.h> -#include <string.h> #include <stdbool.h> -#include <fcntl.h> +#include <string.h> #include "nvim/ascii.h" -#include "nvim/vim.h" -#include "nvim/memline.h" #include "nvim/buffer.h" #include "nvim/change.h" #include "nvim/cursor.h" #include "nvim/eval.h" -#include "nvim/getchar.h" #include "nvim/fileio.h" #include "nvim/func_attr.h" +#include "nvim/getchar.h" #include "nvim/main.h" #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memfile.h" +#include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" #include "nvim/option.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" +#include "nvim/os/process.h" #include "nvim/os_unix.h" #include "nvim/path.h" #include "nvim/screen.h" @@ -68,44 +70,42 @@ #include "nvim/spell.h" #include "nvim/strings.h" #include "nvim/ui.h" -#include "nvim/version.h" #include "nvim/undo.h" +#include "nvim/version.h" +#include "nvim/vim.h" #include "nvim/window.h" -#include "nvim/os/os.h" -#include "nvim/os/process.h" -#include "nvim/os/input.h" -#ifndef UNIX /* it's in os/unix_defs.h for Unix */ +#ifndef UNIX // it's in os/unix_defs.h for Unix # include <time.h> #endif -typedef struct block0 ZERO_BL; /* contents of the first block */ -typedef struct pointer_block PTR_BL; /* contents of a pointer block */ -typedef struct data_block DATA_BL; /* contents of a data block */ -typedef struct pointer_entry PTR_EN; /* block/line-count pair */ +typedef struct block0 ZERO_BL; // contents of the first block +typedef struct pointer_block PTR_BL; // contents of a pointer block +typedef struct data_block DATA_BL; // contents of a data block +typedef struct pointer_entry PTR_EN; // block/line-count pair -#define DATA_ID (('d' << 8) + 'a') /* data block id */ -#define PTR_ID (('p' << 8) + 't') /* pointer block id */ -#define BLOCK0_ID0 'b' /* block 0 id 0 */ -#define BLOCK0_ID1 '0' /* block 0 id 1 */ +#define DATA_ID (('d' << 8) + 'a') // data block id +#define PTR_ID (('p' << 8) + 't') // pointer block id +#define BLOCK0_ID0 'b' // block 0 id 0 +#define BLOCK0_ID1 '0' // block 0 id 1 /* * pointer to a block, used in a pointer block */ struct pointer_entry { - blocknr_T pe_bnum; /* block number */ - linenr_T pe_line_count; /* number of lines in this branch */ - linenr_T pe_old_lnum; /* lnum for this block (for recovery) */ - int pe_page_count; /* number of pages in block pe_bnum */ + blocknr_T pe_bnum; // block number + linenr_T pe_line_count; // number of lines in this branch + linenr_T pe_old_lnum; // lnum for this block (for recovery) + int pe_page_count; // number of pages in block pe_bnum }; /* * A pointer block contains a list of branches in the tree. */ struct pointer_block { - uint16_t pb_id; /* ID for pointer block: PTR_ID */ - uint16_t pb_count; /* number of pointers in this block */ - uint16_t pb_count_max; /* maximum value for pb_count */ + uint16_t pb_id; // ID for pointer block: PTR_ID + uint16_t pb_count; // number of pointers in this block + uint16_t pb_count_max; // maximum value for pb_count PTR_EN pb_pointer[1]; /* list of pointers to blocks (actually longer) * followed by empty space until end of page */ }; @@ -140,12 +140,12 @@ struct data_block { #define DB_MARKED ((unsigned)1 << ((sizeof(unsigned) * 8) - 1)) #define DB_INDEX_MASK (~DB_MARKED) -#define INDEX_SIZE (sizeof(unsigned)) /* size of one db_index entry */ -#define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE) /* size of data block header */ +#define INDEX_SIZE (sizeof(unsigned)) // size of one db_index entry +#define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE) // size of data block header -#define B0_FNAME_SIZE_ORG 900 /* what it was in older versions */ -#define B0_FNAME_SIZE_NOCRYPT 898 /* 2 bytes used for other things */ -#define B0_FNAME_SIZE_CRYPT 890 /* 10 bytes used for other things */ +#define B0_FNAME_SIZE_ORG 900 // what it was in older versions +#define B0_FNAME_SIZE_NOCRYPT 898 // 2 bytes used for other things +#define B0_FNAME_SIZE_CRYPT 890 // 10 bytes used for other things #define B0_UNAME_SIZE 40 #define B0_HNAME_SIZE 40 /* @@ -172,18 +172,18 @@ struct data_block { */ struct block0 { char_u b0_id[2]; ///< ID for block 0: BLOCK0_ID0 and BLOCK0_ID1. - char_u b0_version[10]; /* Vim version string */ - char_u b0_page_size[4]; /* number of bytes per page */ - char_u b0_mtime[4]; /* last modification time of file */ - char_u b0_ino[4]; /* inode of b0_fname */ - char_u b0_pid[4]; /* process id of creator (or 0) */ - char_u b0_uname[B0_UNAME_SIZE]; /* name of user (uid if no name) */ - char_u b0_hname[B0_HNAME_SIZE]; /* host name (if it has a name) */ - char_u b0_fname[B0_FNAME_SIZE_ORG]; /* name of file being edited */ - long b0_magic_long; /* check for byte order of long */ - int b0_magic_int; /* check for byte order of int */ - short b0_magic_short; /* check for byte order of short */ - char_u b0_magic_char; /* check for last char */ + char_u b0_version[10]; // Vim version string + char_u b0_page_size[4]; // number of bytes per page + char_u b0_mtime[4]; // last modification time of file + char_u b0_ino[4]; // inode of b0_fname + char_u b0_pid[4]; // process id of creator (or 0) + char_u b0_uname[B0_UNAME_SIZE]; // name of user (uid if no name) + char_u b0_hname[B0_HNAME_SIZE]; // host name (if it has a name) + char_u b0_fname[B0_FNAME_SIZE_ORG]; // name of file being edited + long b0_magic_long; // check for byte order of long + int b0_magic_int; // check for byte order of int + short b0_magic_short; // check for byte order of short + char_u b0_magic_char; // check for last char }; /* @@ -200,20 +200,20 @@ struct block0 { */ #define b0_flags b0_fname[B0_FNAME_SIZE_ORG - 2] -/* The lowest two bits contain the fileformat. Zero means it's not set - * (compatible with Vim 6.x), otherwise it's EOL_UNIX + 1, EOL_DOS + 1 or - * EOL_MAC + 1. */ +// The lowest two bits contain the fileformat. Zero means it's not set +// (compatible with Vim 6.x), otherwise it's EOL_UNIX + 1, EOL_DOS + 1 or +// EOL_MAC + 1. #define B0_FF_MASK 3 -/* Swap file is in directory of edited file. Used to find the file from - * different mount points. */ +// Swap file is in directory of edited file. Used to find the file from +// different mount points. #define B0_SAME_DIR 4 -/* The 'fileencoding' is at the end of b0_fname[], with a NUL in front of it. - * When empty there is only the NUL. */ +// The 'fileencoding' is at the end of b0_fname[], with a NUL in front of it. +// When empty there is only the NUL. #define B0_HAS_FENC 8 -#define STACK_INCR 5 /* nr of entries added to ml_stack at a time */ +#define STACK_INCR 5 // nr of entries added to ml_stack at a time /* * The line number where the first mark may be is remembered. @@ -226,16 +226,16 @@ static linenr_T lowest_marked = 0; /* * arguments for ml_find_line() */ -#define ML_DELETE 0x11 /* delete line */ -#define ML_INSERT 0x12 /* insert line */ -#define ML_FIND 0x13 /* just find the line */ -#define ML_FLUSH 0x02 /* flush locked block */ -#define ML_SIMPLE(x) (x & 0x10) /* DEL, INS or FIND */ +#define ML_DELETE 0x11 // delete line +#define ML_INSERT 0x12 // insert line +#define ML_FIND 0x13 // just find the line +#define ML_FLUSH 0x02 // flush locked block +#define ML_SIMPLE(x) (x & 0x10) // DEL, INS or FIND -/* argument for ml_upd_block0() */ +// argument for ml_upd_block0() typedef enum { - UB_FNAME = 0 /* update timestamp and filename */ - , UB_SAME_DIR /* update the B0_SAME_DIR flag */ + UB_FNAME = 0, // update timestamp and filename + UB_SAME_DIR // update the B0_SAME_DIR flag } upd_block0_T; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -249,10 +249,10 @@ typedef enum { */ int ml_open(buf_T *buf) { - bhdr_T *hp = NULL; - ZERO_BL *b0p; - PTR_BL *pp; - DATA_BL *dp; + bhdr_T *hp = NULL; + ZERO_BL *b0p; + PTR_BL *pp; + DATA_BL *dp; /* * init fields in memline struct @@ -307,7 +307,7 @@ int ml_open(buf_T *buf) b0p->b0_magic_int = (int)B0_MAGIC_INT; b0p->b0_magic_short = (short)B0_MAGIC_SHORT; b0p->b0_magic_char = B0_MAGIC_CHAR; - xstrlcpy(xstpcpy((char *) b0p->b0_version, "VIM "), Version, 6); + xstrlcpy(xstpcpy((char *)b0p->b0_version, "VIM "), Version, 6); long_to_char((long)mfp->mf_page_size, b0p->b0_page_size); if (!buf->b_spell) { @@ -329,14 +329,16 @@ int ml_open(buf_T *buf) * is created. */ mf_put(mfp, hp, true, false); - if (!buf->b_help && !B_SPELL(buf)) + if (!buf->b_help && !B_SPELL(buf)) { (void)mf_sync(mfp, 0); + } /* * Fill in root pointer block and write page 1. */ - if ((hp = ml_new_ptr(mfp)) == NULL) + if ((hp = ml_new_ptr(mfp)) == NULL) { goto error; + } if (hp->bh_bnum != 1) { IEMSG(_("E298: Didn't get block nr 1?")); goto error; @@ -346,7 +348,7 @@ int ml_open(buf_T *buf) pp->pb_pointer[0].pe_bnum = 2; pp->pb_pointer[0].pe_page_count = 1; pp->pb_pointer[0].pe_old_lnum = 1; - pp->pb_pointer[0].pe_line_count = 1; /* line count after insertion */ + pp->pb_pointer[0].pe_line_count = 1; // line count after insertion mf_put(mfp, hp, true, false); /* @@ -359,10 +361,10 @@ int ml_open(buf_T *buf) } dp = hp->bh_data; - dp->db_index[0] = --dp->db_txt_start; /* at end of block */ + dp->db_index[0] = --dp->db_txt_start; // at end of block dp->db_free -= 1 + INDEX_SIZE; dp->db_line_count = 1; - *((char_u *)dp + dp->db_txt_start) = NUL; /* empty line */ + *((char_u *)dp + dp->db_txt_start) = NUL; // empty line return OK; @@ -384,18 +386,18 @@ error: void ml_setname(buf_T *buf) { bool success = false; - memfile_T *mfp; - char_u *fname; - char_u *dirp; + memfile_T *mfp; + char_u *fname; + char_u *dirp; mfp = buf->b_ml.ml_mfp; - if (mfp->mf_fd < 0) { /* there is no swap file yet */ + if (mfp->mf_fd < 0) { // there is no swap file yet /* * When 'updatecount' is 0 and 'noswapfile' there is no swap file. * For help files we will make a swap file now. */ if (p_uc != 0 && !cmdmod.noswapfile) { - ml_open_file(buf); /* create a swap file */ + ml_open_file(buf); // create a swap file } return; } @@ -406,29 +408,32 @@ void ml_setname(buf_T *buf) dirp = p_dir; bool found_existing_dir = false; for (;; ) { - if (*dirp == NUL) /* tried all directories, fail */ + if (*dirp == NUL) { // tried all directories, fail break; + } fname = (char_u *)findswapname(buf, (char **)&dirp, (char *)mfp->mf_fname, &found_existing_dir); - /* alloc's fname */ - if (dirp == NULL) /* out of memory */ + // alloc's fname + if (dirp == NULL) { // out of memory break; - if (fname == NULL) /* no file name found for this dir */ + } + if (fname == NULL) { // no file name found for this dir continue; + } - /* if the file name is the same we don't have to do anything */ + // if the file name is the same we don't have to do anything if (fnamecmp(fname, mfp->mf_fname) == 0) { xfree(fname); success = true; break; } - /* need to close the swap file before renaming */ + // need to close the swap file before renaming if (mfp->mf_fd >= 0) { close(mfp->mf_fd); mfp->mf_fd = -1; } - /* try to rename the swap file */ + // try to rename the swap file if (vim_rename(mfp->mf_fname, fname) == 0) { success = true; mf_free_fnames(mfp); @@ -436,20 +441,21 @@ void ml_setname(buf_T *buf) ml_upd_block0(buf, UB_SAME_DIR); break; } - xfree(fname); /* this fname didn't work, try another */ + xfree(fname); // this fname didn't work, try another } - if (mfp->mf_fd == -1) { /* need to (re)open the swap file */ + if (mfp->mf_fd == -1) { // need to (re)open the swap file mfp->mf_fd = os_open((char *)mfp->mf_fname, O_RDWR, 0); if (mfp->mf_fd < 0) { - /* could not (re)open the swap file, what can we do???? */ + // could not (re)open the swap file, what can we do???? EMSG(_("E301: Oops, lost the swap file!!!")); return; } (void)os_set_cloexec(mfp->mf_fd); } - if (!success) + if (!success) { EMSG(_("E302: Could not rename swap file")); + } } /* @@ -473,21 +479,22 @@ void ml_open_files(void) */ void ml_open_file(buf_T *buf) { - memfile_T *mfp; - char_u *fname; - char_u *dirp; + memfile_T *mfp; + char_u *fname; + char_u *dirp; mfp = buf->b_ml.ml_mfp; if (mfp == NULL || mfp->mf_fd >= 0 || !buf->b_p_swf || cmdmod.noswapfile || buf->terminal) { - return; /* nothing to do */ + return; // nothing to do } - /* For a spell buffer use a temp file name. */ + // For a spell buffer use a temp file name. if (buf->b_spell) { fname = vim_tempname(); - if (fname != NULL) - (void)mf_open_file(mfp, fname); /* consumes fname! */ + if (fname != NULL) { + (void)mf_open_file(mfp, fname); // consumes fname! + } buf->b_may_swap = false; return; } @@ -498,29 +505,32 @@ void ml_open_file(buf_T *buf) dirp = p_dir; bool found_existing_dir = false; for (;; ) { - if (*dirp == NUL) + if (*dirp == NUL) { break; + } // There is a small chance that between choosing the swap file name // and creating it, another Vim creates the file. In that case the // creation will fail and we will use another directory. fname = (char_u *)findswapname(buf, (char **)&dirp, NULL, &found_existing_dir); - if (dirp == NULL) - break; /* out of memory */ - if (fname == NULL) + if (dirp == NULL) { + break; // out of memory + } + if (fname == NULL) { continue; - if (mf_open_file(mfp, fname) == OK) { /* consumes fname! */ + } + if (mf_open_file(mfp, fname) == OK) { // consumes fname! ml_upd_block0(buf, UB_SAME_DIR); - /* Flush block zero, so others can read it */ + // Flush block zero, so others can read it if (mf_sync(mfp, MFS_ZERO) == OK) { - /* Mark all blocks that should be in the swapfile as dirty. - * Needed for when the 'swapfile' option was reset, so that - * the swap file was deleted, and then on again. */ + // Mark all blocks that should be in the swapfile as dirty. + // Needed for when the 'swapfile' option was reset, so that + // the swap file was deleted, and then on again. mf_set_dirty(mfp); break; } - /* Writing block 0 failed: close the file and try another dir */ + // Writing block 0 failed: close the file and try another dir mf_close_file(buf, false); } } @@ -528,13 +538,12 @@ void ml_open_file(buf_T *buf) if (*p_dir != NUL && mfp->mf_fname == NULL) { need_wait_return = true; // call wait_return later no_wait_return++; - (void)EMSG2(_( - "E303: Unable to open swap file for \"%s\", recovery impossible"), - buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname); + (void)EMSG2(_("E303: Unable to open swap file for \"%s\", recovery impossible"), + buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname); --no_wait_return; } - /* don't try to open a swap file again */ + // don't try to open a swap file again buf->b_may_swap = false; } @@ -560,17 +569,19 @@ void check_need_swap(bool newfile) */ void ml_close(buf_T *buf, int del_file) { - if (buf->b_ml.ml_mfp == NULL) /* not open */ + if (buf->b_ml.ml_mfp == NULL) { // not open return; - mf_close(buf->b_ml.ml_mfp, del_file); /* close the .swp file */ - if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY)) + } + mf_close(buf->b_ml.ml_mfp, del_file); // close the .swp file + if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY)) { xfree(buf->b_ml.ml_line_ptr); + } xfree(buf->b_ml.ml_stack); XFREE_CLEAR(buf->b_ml.ml_chunksize); buf->b_ml.ml_mfp = NULL; - /* Reset the "recovered" flag, give the ATTENTION prompt the next time - * this buffer is loaded. */ + // Reset the "recovered" flag, give the ATTENTION prompt the next time + // this buffer is loaded. buf->b_flags &= ~BF_RECOVERED; } @@ -585,8 +596,8 @@ void ml_close_all(int del_file) FOR_ALL_BUFFERS(buf) { ml_close(buf, del_file && ((buf->b_flags & BF_PRESERVED) == 0)); } - spell_delete_wordlist(); /* delete the internal wordlist */ - vim_deltempdir(); /* delete created temp directory */ + spell_delete_wordlist(); // delete the internal wordlist + vim_deltempdir(); // delete created temp directory } /* @@ -597,7 +608,7 @@ void ml_close_notmod(void) { FOR_ALL_BUFFERS(buf) { if (!bufIsChanged(buf)) { - ml_close(buf, TRUE); /* close all not-modified buffers */ + ml_close(buf, TRUE); // close all not-modified buffers } } } @@ -633,13 +644,14 @@ static bool ml_check_b0_strings(ZERO_BL *b0p) */ static void ml_upd_block0(buf_T *buf, upd_block0_T what) { - memfile_T *mfp; - bhdr_T *hp; - ZERO_BL *b0p; + memfile_T *mfp; + bhdr_T *hp; + ZERO_BL *b0p; mfp = buf->b_ml.ml_mfp; - if (mfp == NULL || (hp = mf_get(mfp, 0, 1)) == NULL) + if (mfp == NULL || (hp = mf_get(mfp, 0, 1)) == NULL) { return; + } b0p = hp->bh_data; if (ml_check_b0_id(b0p) == FAIL) { IEMSG(_("E304: ml_upd_block0(): Didn't get block 0??")); @@ -660,9 +672,9 @@ static void ml_upd_block0(buf_T *buf, upd_block0_T what) */ static void set_b0_fname(ZERO_BL *b0p, buf_T *buf) { - if (buf->b_ffname == NULL) + if (buf->b_ffname == NULL) { b0p->b0_fname[0] = NUL; - else { + } else { char uname[B0_UNAME_SIZE]; /* @@ -673,9 +685,9 @@ static void set_b0_fname(ZERO_BL *b0p, buf_T *buf) * Then insert the user name to get "~user/". */ home_replace(NULL, buf->b_ffname, b0p->b0_fname, - B0_FNAME_SIZE_CRYPT, TRUE); + B0_FNAME_SIZE_CRYPT, TRUE); if (b0p->b0_fname[0] == '~') { - /* If there is no user name or it is too long, don't use "~/" */ + // If there is no user name or it is too long, don't use "~/" int retval = os_get_user_name(uname, B0_UNAME_SIZE); size_t ulen = STRLEN(uname); size_t flen = STRLEN(b0p->b0_fname); @@ -702,7 +714,7 @@ static void set_b0_fname(ZERO_BL *b0p, buf_T *buf) } } - /* Also add the 'fileencoding' if there is room. */ + // Also add the 'fileencoding' if there is room. add_b0_fenc(b0p, curbuf); } @@ -714,10 +726,11 @@ static void set_b0_fname(ZERO_BL *b0p, buf_T *buf) */ static void set_b0_dir_flag(ZERO_BL *b0p, buf_T *buf) { - if (same_directory(buf->b_ml.ml_mfp->mf_fname, buf->b_ffname)) + if (same_directory(buf->b_ml.ml_mfp->mf_fname, buf->b_ffname)) { b0p->b0_flags |= B0_SAME_DIR; - else + } else { b0p->b0_flags &= ~B0_SAME_DIR; + } } /* @@ -729,11 +742,11 @@ static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf) int size = B0_FNAME_SIZE_NOCRYPT; n = (int)STRLEN(buf->b_p_fenc); - if ((int)STRLEN(b0p->b0_fname) + n + 1 > size) + if ((int)STRLEN(b0p->b0_fname) + n + 1 > size) { b0p->b0_flags &= ~B0_HAS_FENC; - else { + } else { memmove((char *)b0p->b0_fname + size - n, - (char *)buf->b_p_fenc, (size_t)n); + (char *)buf->b_p_fenc, (size_t)n); *(b0p->b0_fname + size - n - 1) = NUL; b0p->b0_flags |= B0_HAS_FENC; } @@ -745,23 +758,23 @@ static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf) /// swap file. void ml_recover(bool checkext) { - buf_T *buf = NULL; - memfile_T *mfp = NULL; - char_u *fname; - char_u *fname_used = NULL; - bhdr_T *hp = NULL; - ZERO_BL *b0p; + buf_T *buf = NULL; + memfile_T *mfp = NULL; + char_u *fname; + char_u *fname_used = NULL; + bhdr_T *hp = NULL; + ZERO_BL *b0p; int b0_ff; - char_u *b0_fenc = NULL; - PTR_BL *pp; - DATA_BL *dp; - infoptr_T *ip; + char_u *b0_fenc = NULL; + PTR_BL *pp; + DATA_BL *dp; + infoptr_T *ip; blocknr_T bnum; int page_count; int len; bool directly; linenr_T lnum; - char_u *p; + char_u *p; int i; long error; bool cannot_open; @@ -784,8 +797,9 @@ void ml_recover(bool checkext) // If the file name ends in ".s[a-w][a-z]" we assume this is the swap file. // Otherwise a search is done to find the swap file(s). fname = curbuf->b_fname; - if (fname == NULL) /* When there is no file name */ + if (fname == NULL) { // When there is no file name fname = (char_u *)""; + } len = (int)STRLEN(fname); if (checkext && len >= 4 && STRNICMP(fname + len - 4, ".s", 2) == 0 @@ -797,32 +811,34 @@ void ml_recover(bool checkext) } else { directly = false; - /* count the number of matching swap files */ + // count the number of matching swap files len = recover_names(fname, FALSE, 0, NULL); - if (len == 0) { /* no swap files found */ + if (len == 0) { // no swap files found EMSG2(_("E305: No swap file found for %s"), fname); goto theend; } - if (len == 1) /* one swap file found, use it */ + if (len == 1) { // one swap file found, use it i = 1; - else { /* several swap files found, choose */ - /* list the names of the swap files */ + } else { // several swap files found, choose + // list the names of the swap files (void)recover_names(fname, TRUE, 0, NULL); msg_putchar('\n'); MSG_PUTS(_("Enter number of swap file to use (0 to quit): ")); i = get_number(FALSE, NULL); - if (i < 1 || i > len) + if (i < 1 || i > len) { goto theend; + } } - /* get the swap file name that will be used */ + // get the swap file name that will be used (void)recover_names(fname, FALSE, i, &fname_used); } - if (fname_used == NULL) + if (fname_used == NULL) { goto theend; // user chose invalid number. - - /* When called from main() still need to initialize storage structure */ - if (called_from_main && ml_open(curbuf) == FAIL) + } + // When called from main() still need to initialize storage structure + if (called_from_main && ml_open(curbuf) == FAIL) { getout(1); + } /* * Allocate a buffer structure for the swap file that is used for recovery. @@ -844,8 +860,8 @@ void ml_recover(bool checkext) /* * open the memfile from the old swap file */ - p = vim_strsave(fname_used); /* save "fname_used" for the message: - mf_open() will consume "fname_used"! */ + p = vim_strsave(fname_used); // save "fname_used" for the message: + // mf_open() will consume "fname_used"! mfp = mf_open(fname_used, O_RDONLY); fname_used = p; if (mfp == NULL || mfp->mf_fd < 0) { @@ -869,9 +885,8 @@ void ml_recover(bool checkext) msg_start(); MSG_PUTS_ATTR(_("Unable to read block 0 from "), attr | MSG_HIST); msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST); - MSG_PUTS_ATTR(_( - "\nMaybe no changes were made or Vim did not update the swap file."), - attr | MSG_HIST); + MSG_PUTS_ATTR(_("\nMaybe no changes were made or Vim did not update the swap file."), + attr | MSG_HIST); msg_end(); goto theend; } @@ -880,7 +895,7 @@ void ml_recover(bool checkext) msg_start(); msg_outtrans_attr(mfp->mf_fname, MSG_HIST); MSG_PUTS_ATTR(_(" cannot be used with this version of Vim.\n"), - MSG_HIST); + MSG_HIST); MSG_PUTS_ATTR(_("Use Vim version 3.0.\n"), MSG_HIST); msg_end(); goto theend; @@ -893,9 +908,9 @@ void ml_recover(bool checkext) msg_start(); msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST); MSG_PUTS_ATTR(_(" cannot be used on this computer.\n"), - attr | MSG_HIST); + attr | MSG_HIST); MSG_PUTS_ATTR(_("The file was created on "), attr | MSG_HIST); - /* avoid going past the end of a corrupted hostname */ + // avoid going past the end of a corrupted hostname b0p->b0_fname[0] = NUL; MSG_PUTS_ATTR(b0p->b0_hname, attr | MSG_HIST); MSG_PUTS_ATTR(_(",\nor the file has been damaged."), attr | MSG_HIST); @@ -914,9 +929,8 @@ void ml_recover(bool checkext) if (mfp->mf_page_size < previous_page_size) { msg_start(); msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST); - MSG_PUTS_ATTR(_( - " has been damaged (page size is smaller than minimum value).\n"), - attr | MSG_HIST); + MSG_PUTS_ATTR(_(" has been damaged (page size is smaller than minimum value).\n"), + attr | MSG_HIST); msg_end(); goto theend; } @@ -927,7 +941,7 @@ void ml_recover(bool checkext) } mfp->mf_infile_count = mfp->mf_blocknr_max; - /* need to reallocate the memory used to store the data */ + // need to reallocate the memory used to store the data p = xmalloc(mfp->mf_page_size); memmove(p, hp->bh_data, previous_page_size); xfree(hp->bh_data); @@ -948,10 +962,11 @@ void ml_recover(bool checkext) home_replace(NULL, mfp->mf_fname, NameBuff, MAXPATHL, TRUE); smsg(_("Using swap file \"%s\""), NameBuff); - if (buf_spname(curbuf) != NULL) + if (buf_spname(curbuf) != NULL) { STRLCPY(NameBuff, buf_spname(curbuf), MAXPATHL); - else + } else { home_replace(NULL, curbuf->b_ffname, NameBuff, MAXPATHL, TRUE); + } smsg(_("Original file \"%s\""), NameBuff); msg_putchar('\n'); @@ -965,13 +980,13 @@ void ml_recover(bool checkext) && os_fileinfo((char *)curbuf->b_ffname, &org_file_info) && ((os_fileinfo((char *)mfp->mf_fname, &swp_file_info) && org_file_info.stat.st_mtim.tv_sec - > swp_file_info.stat.st_mtim.tv_sec) + > swp_file_info.stat.st_mtim.tv_sec) || org_file_info.stat.st_mtim.tv_sec != mtime)) { EMSG(_("E308: Warning: Original file may have been changed")); } ui_flush(); - /* Get the 'fileformat' and 'fileencoding' from block zero. */ + // Get the 'fileformat' and 'fileencoding' from block zero. b0_ff = (b0p->b0_flags & B0_FF_MASK); if (b0p->b0_flags & B0_HAS_FENC) { int fnsize = B0_FNAME_SIZE_NOCRYPT; @@ -981,7 +996,7 @@ void ml_recover(bool checkext) b0_fenc = vim_strnsave(p, b0p->b0_fname + fnsize - p); } - mf_put(mfp, hp, false, false); /* release block 0 */ + mf_put(mfp, hp, false, false); // release block 0 hp = NULL; /* @@ -996,28 +1011,30 @@ void ml_recover(bool checkext) * Try reading the original file to obtain the values of 'fileformat', * 'fileencoding', etc. Ignore errors. The text itself is not used. */ - if (curbuf->b_ffname != NULL) + if (curbuf->b_ffname != NULL) { orig_file_status = readfile(curbuf->b_ffname, NULL, (linenr_T)0, - (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW); + (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW); + } - /* Use the 'fileformat' and 'fileencoding' as stored in the swap file. */ - if (b0_ff != 0) + // Use the 'fileformat' and 'fileencoding' as stored in the swap file. + if (b0_ff != 0) { set_fileformat(b0_ff - 1, OPT_LOCAL); + } if (b0_fenc != NULL) { set_option_value("fenc", 0L, (char *)b0_fenc, OPT_LOCAL); xfree(b0_fenc); } unchanged(curbuf, true, true); - bnum = 1; /* start with block 1 */ - page_count = 1; /* which is 1 page */ - lnum = 0; /* append after line 0 in curbuf */ + bnum = 1; // start with block 1 + page_count = 1; // which is 1 page + lnum = 0; // append after line 0 in curbuf line_count = 0; - idx = 0; /* start with first index in block 1 */ + idx = 0; // start with first index in block 1 error = 0; buf->b_ml.ml_stack_top = 0; buf->b_ml.ml_stack = NULL; - buf->b_ml.ml_stack_size = 0; /* no stack yet */ + buf->b_ml.ml_stack_size = 0; // no stack yet if (curbuf->b_ffname == NULL) { cannot_open = true; @@ -1027,9 +1044,9 @@ void ml_recover(bool checkext) serious_error = false; for (; !got_int; line_breakcheck()) { - if (hp != NULL) - mf_put(mfp, hp, false, false); /* release previous block */ - + if (hp != NULL) { + mf_put(mfp, hp, false, false); // release previous block + } /* * get block */ @@ -1043,11 +1060,12 @@ void ml_recover(bool checkext) (colnr_T)0, true); } else { // there is a block pp = hp->bh_data; - if (pp->pb_id == PTR_ID) { /* it is a pointer block */ - /* check line count when using pointer block first time */ + if (pp->pb_id == PTR_ID) { // it is a pointer block + // check line count when using pointer block first time if (idx == 0 && line_count != 0) { - for (i = 0; i < (int)pp->pb_count; ++i) + for (i = 0; i < (int)pp->pb_count; ++i) { line_count -= pp->pb_pointer[i].pe_line_count; + } if (line_count != 0) { ++error; ml_append(lnum++, (char_u *)_("???LINE COUNT WRONG"), @@ -1081,7 +1099,7 @@ void ml_recover(bool checkext) ml_append(lnum++, (char_u *)_("???LINES MISSING"), (colnr_T)0, true); } - ++idx; /* get same block again for next index */ + ++idx; // get same block again for next index continue; } @@ -1099,12 +1117,12 @@ void ml_recover(bool checkext) idx = 0; continue; } - } else { /* not a pointer block */ + } else { // not a pointer block dp = hp->bh_data; - if (dp->db_id != DATA_ID) { /* block id wrong */ + if (dp->db_id != DATA_ID) { // block id wrong if (bnum == 1) { EMSG2(_("E310: Block 1 ID wrong (%s not a .swp file?)"), - mfp->mf_fname); + mfp->mf_fname); goto theend; } ++error; @@ -1117,17 +1135,16 @@ void ml_recover(bool checkext) // check length of block // if wrong, use length in pointer block if (page_count * mfp->mf_page_size != dp->db_txt_end) { - ml_append( - lnum++, - (char_u *)_("??? from here until ???END lines" - " may be messed up"), - (colnr_T)0, true); + ml_append(lnum++, + (char_u *)_("??? from here until ???END lines" + " may be messed up"), + (colnr_T)0, true); error++; has_error = true; dp->db_txt_end = page_count * mfp->mf_page_size; } - /* make sure there is a NUL at the end of the block */ + // make sure there is a NUL at the end of the block *((char_u *)dp + dp->db_txt_end - 1) = NUL; /* @@ -1135,11 +1152,10 @@ void ml_recover(bool checkext) * if wrong, use count in data block */ if (line_count != dp->db_line_count) { - ml_append( - lnum++, - (char_u *)_("??? from here until ???END lines" - " may have been inserted/deleted"), - (colnr_T)0, true); + ml_append(lnum++, + (char_u *)_("??? from here until ???END lines" + " may have been inserted/deleted"), + (colnr_T)0, true); error++; has_error = true; } @@ -1150,8 +1166,9 @@ void ml_recover(bool checkext) || txt_start >= (int)dp->db_txt_end) { p = (char_u *)"???"; ++error; - } else + } else { p = (char_u *)dp + txt_start; + } ml_append(lnum++, p, (colnr_T)0, true); } if (has_error) { @@ -1161,15 +1178,16 @@ void ml_recover(bool checkext) } } - if (buf->b_ml.ml_stack_top == 0) /* finished */ + if (buf->b_ml.ml_stack_top == 0) { // finished break; + } /* * go one block up in the tree */ ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]); bnum = ip->ip_bnum; - idx = ip->ip_index + 1; /* go to next index */ + idx = ip->ip_index + 1; // go to next index page_count = 1; } @@ -1181,15 +1199,15 @@ void ml_recover(bool checkext) * Line ml_line_count + 1 in the dummy empty line. */ if (orig_file_status != OK || curbuf->b_ml.ml_line_count != lnum * 2 + 1) { - /* Recovering an empty file results in two lines and the first line is - * empty. Don't set the modified flag then. */ + // Recovering an empty file results in two lines and the first line is + // empty. Don't set the modified flag then. if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL)) { changed_internal(); buf_inc_changedtick(curbuf); } } else { for (idx = 1; idx <= lnum; ++idx) { - /* Need to copy one line, fetching the other one may flush it. */ + // Need to copy one line, fetching the other one may flush it. p = vim_strsave(ml_get(idx)); i = STRCMP(p, ml_get(idx + lnum)); xfree(p); @@ -1206,30 +1224,30 @@ void ml_recover(bool checkext) * empty buffer. These will now be after the last line in the buffer. */ while (curbuf->b_ml.ml_line_count > lnum - && !(curbuf->b_ml.ml_flags & ML_EMPTY)) + && !(curbuf->b_ml.ml_flags & ML_EMPTY)) { ml_delete(curbuf->b_ml.ml_line_count, false); + } curbuf->b_flags |= BF_RECOVERED; check_cursor(); recoverymode = FALSE; - if (got_int) + if (got_int) { EMSG(_("E311: Recovery Interrupted")); - else if (error) { + } else if (error) { ++no_wait_return; MSG(">>>>>>>>>>>>>"); - EMSG(_( - "E312: Errors detected while recovering; look for lines starting with ???")); + EMSG(_( "E312: Errors detected while recovering; look for lines starting with ???")); --no_wait_return; MSG(_("See \":help E312\" for more information.")); MSG(">>>>>>>>>>>>>"); } else { if (curbuf->b_changed) { MSG(_("Recovery completed. You should check if everything is OK.")); - MSG_PUTS(_( - "\n(You might want to write out this file under another name\n")); + MSG_PUTS(_("\n(You might want to write out this file under another name\n")); MSG_PUTS(_("and run diff with the original file to check for changes)")); - } else + } else { MSG(_("Recovery completed. Buffer contents equals file contents.")); + } MSG_PUTS(_("\nYou may want to delete the .swp file now.\n\n")); cmdline_row = msg_row; } @@ -1239,68 +1257,65 @@ theend: xfree(fname_used); recoverymode = FALSE; if (mfp != NULL) { - if (hp != NULL) + if (hp != NULL) { mf_put(mfp, hp, false, false); - mf_close(mfp, false); /* will also xfree(mfp->mf_fname) */ + } + mf_close(mfp, false); // will also xfree(mfp->mf_fname) } if (buf != NULL) { //may be NULL if swap file not found. xfree(buf->b_ml.ml_stack); xfree(buf); } - if (serious_error && called_from_main) + if (serious_error && called_from_main) { ml_close(curbuf, TRUE); - else { + } else { apply_autocmds(EVENT_BUFREADPOST, NULL, curbuf->b_fname, FALSE, curbuf); apply_autocmds(EVENT_BUFWINENTER, NULL, curbuf->b_fname, FALSE, curbuf); } - return; } -/* - * Find the names of swap files in current directory and the directory given - * with the 'directory' option. - * - * Used to: - * - list the swap files for "vim -r" - * - count the number of swap files when recovering - * - list the swap files when recovering - * - find the name of the n'th swap file when recovering - */ -int -recover_names ( - char_u *fname, /* base for swap file name */ - int list, /* when TRUE, list the swap file names */ - int nr, /* when non-zero, return nr'th swap file name */ - char_u **fname_out /* result when "nr" > 0 */ -) +/// Find the names of swap files in current directory and the directory given +/// with the 'directory' option. +/// +/// Used to: +/// - list the swap files for "vim -r" +/// - count the number of swap files when recovering +/// - list the swap files when recovering +/// - find the name of the n'th swap file when recovering +/// +/// @param fname base for swap file name +/// @param list when TRUE, list the swap file names +/// @param nr when non-zero, return nr'th swap file name +/// @param fname_out result when "nr" > 0 +int recover_names(char_u *fname, int list, int nr, char_u **fname_out) { int num_names; - char_u *(names[6]); - char_u *tail; - char_u *p; + char_u *(names[6]); + char_u *tail; + char_u *p; int num_files; int file_count = 0; - char_u **files; - char_u *dirp; - char_u *dir_name; - char_u *fname_res = NULL; + char_u **files; + char_u *dirp; + char_u *dir_name; + char_u *fname_res = NULL; #ifdef HAVE_READLINK char_u fname_buf[MAXPATHL]; #endif if (fname != NULL) { #ifdef HAVE_READLINK - /* Expand symlink in the file name, because the swap file is created - * with the actual file instead of with the symlink. */ - if (resolve_symlink(fname, fname_buf) == OK) + // Expand symlink in the file name, because the swap file is created + // with the actual file instead of with the symlink. + if (resolve_symlink(fname, fname_buf) == OK) { fname_res = fname_buf; - else + } else #endif fname_res = fname; } if (list) { - /* use msg() to start the scrolling properly */ + // use msg() to start the scrolling properly msg((char_u *)_("Swap files found:")); msg_putchar('\n'); } @@ -1315,7 +1330,7 @@ recover_names ( // Advance dirp to next directory name. (void)copy_option_part(&dirp, dir_name, 31000, ","); - if (dir_name[0] == '.' && dir_name[1] == NUL) { /* check current dir */ + if (dir_name[0] == '.' && dir_name[1] == NUL) { // check current dir if (fname == NULL) { names[0] = vim_strsave((char_u *)"*.sw?"); /* For Unix names starting with a dot are special. MS-Windows @@ -1323,9 +1338,10 @@ recover_names ( names[1] = vim_strsave((char_u *)".*.sw?"); names[2] = vim_strsave((char_u *)".sw?"); num_names = 3; - } else + } else { num_names = recov_file_names(names, fname_res, TRUE); - } else { /* check directory dir_name */ + } + } else { // check directory dir_name if (fname == NULL) { names[0] = (char_u *)concat_fnames((char *)dir_name, "*.sw?", TRUE); /* For Unix names starting with a dot are special. MS-Windows @@ -1351,11 +1367,12 @@ recover_names ( } } - if (num_names == 0) + if (num_names == 0) { num_files = 0; - else if (expand_wildcards(num_names, names, &num_files, &files, - EW_KEEPALL|EW_FILE|EW_SILENT) == FAIL) + } else if (expand_wildcards(num_names, names, &num_files, &files, + EW_KEEPALL|EW_FILE|EW_SILENT) == FAIL) { num_files = 0; + } /* * When no swap file found, wildcard expansion might have failed (e.g. @@ -1388,27 +1405,29 @@ recover_names ( // down. When the array becomes empty free it here, since // FreeWild() won't be called below. xfree(files[i]); - if (--num_files == 0) + if (--num_files == 0) { xfree(files); - else - for (; i < num_files; ++i) + } else { + for (; i < num_files; ++i) { files[i] = files[i + 1]; + } + } } } } if (nr > 0) { file_count += num_files; if (nr <= file_count) { - *fname_out = vim_strsave( - files[nr - 1 + num_files - file_count]); - dirp = (char_u *)""; /* stop searching */ + *fname_out = vim_strsave(files[nr - 1 + num_files - file_count]); + dirp = (char_u *)""; // stop searching } } else if (list) { if (dir_name[0] == '.' && dir_name[1] == NUL) { - if (fname == NULL) + if (fname == NULL) { MSG_PUTS(_(" In current directory:\n")); - else + } else { MSG_PUTS(_(" Using specified name:\n")); + } } else { MSG_PUTS(_(" In directory ")); msg_home_replace(dir_name); @@ -1417,23 +1436,27 @@ recover_names ( if (num_files) { for (int i = 0; i < num_files; ++i) { - /* print the swap file name */ + // print the swap file name msg_outnum((long)++file_count); msg_puts(". "); msg_puts((const char *)path_tail(files[i])); msg_putchar('\n'); (void)swapfile_info(files[i]); } - } else + } else { MSG_PUTS(_(" -- none --\n")); + } ui_flush(); - } else + } else { file_count += num_files; + } - for (int i = 0; i < num_names; ++i) + for (int i = 0; i < num_names; ++i) { xfree(names[i]); - if (num_files > 0) + } + if (num_files > 0) { FreeWild(num_files, files); + } } xfree(dir_name); return file_count; @@ -1544,10 +1567,11 @@ static time_t swapfile_info(char_u *fname) MSG_PUTS(_(" [garbled strings (not nul terminated)]")); } else { MSG_PUTS(_(" file name: ")); - if (b0.b0_fname[0] == NUL) + if (b0.b0_fname[0] == NUL) { MSG_PUTS(_("[No Name]")); - else + } else { msg_outtrans(b0.b0_fname); + } MSG_PUTS(_("\n modified: ")); MSG_PUTS(b0.b0_dirty ? _("YES") : _("no")); @@ -1558,10 +1582,11 @@ static time_t swapfile_info(char_u *fname) } if (*(b0.b0_hname) != NUL) { - if (*(b0.b0_uname) != NUL) + if (*(b0.b0_uname) != NUL) { MSG_PUTS(_(" host name: ")); - else + } else { MSG_PUTS(_("\n host name: ")); + } msg_outtrans(b0.b0_hname); } @@ -1578,11 +1603,13 @@ static time_t swapfile_info(char_u *fname) MSG_PUTS(_("\n [not usable on this computer]")); } } - } else + } else { MSG_PUTS(_(" [cannot be read]")); + } close(fd); - } else + } else { MSG_PUTS(_(" [cannot be opened]")); + } msg_putchar('\n'); return x; @@ -1650,18 +1677,20 @@ static int recov_file_names(char_u **names, char_u *path, int prepend_dot) // Form the normal swap file name pattern by appending ".sw?". names[num_names] = (char_u *)concat_fnames((char *)path, ".sw?", FALSE); - if (num_names >= 1) { /* check if we have the same name twice */ + if (num_names >= 1) { // check if we have the same name twice char_u *p = names[num_names - 1]; int i = (int)STRLEN(names[num_names - 1]) - (int)STRLEN(names[num_names]); - if (i > 0) - p += i; /* file name has been expanded to full path */ - - if (STRCMP(p, names[num_names]) != 0) + if (i > 0) { + p += i; // file name has been expanded to full path + } + if (STRCMP(p, names[num_names]) != 0) { ++num_names; - else + } else { xfree(names[num_names]); - } else + } + } else { ++num_names; + } return num_names; } @@ -1676,11 +1705,11 @@ static int recov_file_names(char_u **names, char_u *path, int prepend_dot) void ml_sync_all(int check_file, int check_char, bool do_fsync) { FOR_ALL_BUFFERS(buf) { - if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL) - continue; /* no file */ - - ml_flush_line(buf); /* flush buffered line */ - /* flush locked block */ + if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL) { + continue; // no file + } + ml_flush_line(buf); // flush buffered line + // flush locked block (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); if (bufIsChanged(buf) && check_file && mf_need_trans(buf->b_ml.ml_mfp) && buf->b_ffname != NULL) { @@ -1719,27 +1748,28 @@ void ml_sync_all(int check_file, int check_char, bool do_fsync) */ void ml_preserve(buf_T *buf, int message, bool do_fsync) { - bhdr_T *hp; + bhdr_T *hp; linenr_T lnum; - memfile_T *mfp = buf->b_ml.ml_mfp; + memfile_T *mfp = buf->b_ml.ml_mfp; int status; int got_int_save = got_int; if (mfp == NULL || mfp->mf_fname == NULL) { - if (message) + if (message) { EMSG(_("E313: Cannot preserve, there is no swap file")); + } return; } - /* We only want to stop when interrupted here, not when interrupted - * before. */ - got_int = FALSE; + // We only want to stop when interrupted here, not when interrupted + // before. + got_int = false; ml_flush_line(buf); // flush buffered line (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); // flush locked block status = mf_sync(mfp, MFS_ALL | (do_fsync ? MFS_FLUSH : 0)); - /* stack is invalid after mf_sync(.., MFS_ALL) */ + // stack is invalid after mf_sync(.., MFS_ALL) buf->b_ml.ml_stack_top = 0; /* @@ -1776,10 +1806,11 @@ theend: got_int |= got_int_save; if (message) { - if (status == OK) + if (status == OK) { MSG(_("File preserved")); - else + } else { EMSG(_("E314: Preserve failed")); + } } } @@ -1787,7 +1818,7 @@ theend: * NOTE: The pointer returned by the ml_get_*() functions only remains valid * until the next call! * line1 = ml_get(1); - * line2 = ml_get(2); // line1 is now invalid! + * line2 = ml_get(2); // line1 is now invalid! * Make a copy of the line if necessary. */ /* @@ -1810,26 +1841,18 @@ char_u *ml_get_pos(const pos_T *pos) return ml_get_buf(curbuf, pos->lnum, false) + pos->col; } -/* - * Return a pointer to a line in a specific buffer - * - * "will_change": if TRUE mark the buffer dirty (chars in the line will be - * changed) - */ -char_u * -ml_get_buf ( - buf_T *buf, - linenr_T lnum, - bool will_change // line will be changed -) +/// Return a pointer to a line in a specific buffer +/// +/// @param will_change true mark the buffer dirty (chars in the line will be changed) +char_u *ml_get_buf(buf_T *buf, linenr_T lnum, bool will_change) FUNC_ATTR_NONNULL_ALL { - bhdr_T *hp; - DATA_BL *dp; - char_u *ptr; + bhdr_T *hp; + DATA_BL *dp; + char_u *ptr; static int recursive = 0; - if (lnum > buf->b_ml.ml_line_count) { /* invalid line number */ + if (lnum > buf->b_ml.ml_line_count) { // invalid line number if (recursive == 0) { // Avoid giving this message for a recursive call, may happen when // the GUI redraws part of the text. @@ -1841,11 +1864,13 @@ errorret: STRCPY(IObuff, "???"); return IObuff; } - if (lnum <= 0) /* pretend line 0 is line 1 */ + if (lnum <= 0) { // pretend line 0 is line 1 lnum = 1; + } - if (buf->b_ml.ml_mfp == NULL) /* there are no lines */ + if (buf->b_ml.ml_mfp == NULL) { // there are no lines return (char_u *)""; + } /* * See if it is the same line as requested last time. @@ -1900,88 +1925,89 @@ int ml_line_alloced(void) return curbuf->b_ml.ml_flags & ML_LINE_DIRTY; } -/* - * Append a line after lnum (may be 0 to insert a line in front of the file). - * "line" does not need to be allocated, but can't be another line in a - * buffer, unlocking may make it invalid. - * - * newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum - * will be set for recovery - * Check: The caller of this function should probably also call - * appended_lines(). - * - * return FAIL for failure, OK otherwise - */ -int ml_append( - linenr_T lnum, // append after this line (can be 0) - char_u *line, // text of the new line - colnr_T len, // length of new line, including NUL, or 0 - bool newfile // flag, see above -) +/// Append a line after lnum (may be 0 to insert a line in front of the file). +/// "line" does not need to be allocated, but can't be another line in a +/// buffer, unlocking may make it invalid. +/// +/// newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum +/// will be set for recovery +/// Check: The caller of this function should probably also call +/// appended_lines(). +/// +/// @param lnum append after this line (can be 0) +/// @param line text of the new line +/// @param len length of new line, including NUL, or 0 +/// @param newfile flag, see above +/// +/// @return FAIL for failure, OK otherwise +int ml_append(linenr_T lnum, char_u *line, colnr_T len, bool newfile) { - /* When starting up, we might still need to create the memfile */ - if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL) + // When starting up, we might still need to create the memfile + if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL) { return FAIL; + } - if (curbuf->b_ml.ml_line_lnum != 0) + if (curbuf->b_ml.ml_line_lnum != 0) { ml_flush_line(curbuf); + } return ml_append_int(curbuf, lnum, line, len, newfile, FALSE); } -/* - * Like ml_append() but for an arbitrary buffer. The buffer must already have - * a memline. - */ -int ml_append_buf( - buf_T *buf, - linenr_T lnum, // append after this line (can be 0) - char_u *line, // text of the new line - colnr_T len, // length of new line, including NUL, or 0 - bool newfile // flag, see above -) +/// Like ml_append() but for an arbitrary buffer. The buffer must already have +/// a memline. +/// +/// @param lnum append after this line (can be 0) +/// @param line text of the new line +/// @param len length of new line, including NUL, or 0 +/// @param newfile flag, see above +int ml_append_buf(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, bool newfile) FUNC_ATTR_NONNULL_ARG(1) { - if (buf->b_ml.ml_mfp == NULL) + if (buf->b_ml.ml_mfp == NULL) { return FAIL; + } - if (buf->b_ml.ml_line_lnum != 0) + if (buf->b_ml.ml_line_lnum != 0) { ml_flush_line(buf); + } return ml_append_int(buf, lnum, line, len, newfile, FALSE); } -static int ml_append_int( - buf_T *buf, - linenr_T lnum, // append after this line (can be 0) - char_u *line, // text of the new line - colnr_T len, // length of line, including NUL, or 0 - bool newfile, // flag, see above - int mark // mark the new line -) +/// @param lnum append after this line (can be 0) +/// @param line text of the new line +/// @param len length of line, including NUL, or 0 +/// @param newfile flag, see above +/// @param mark mark the new line +static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, bool newfile, + int mark) { int i; - int line_count; /* number of indexes in current block */ + int line_count; // number of indexes in current block int offset; int from, to; - int space_needed; /* space needed for new line */ + int space_needed; // space needed for new line int page_size; int page_count; - int db_idx; /* index for lnum in data block */ - bhdr_T *hp; - memfile_T *mfp; - DATA_BL *dp; - PTR_BL *pp; - infoptr_T *ip; - - /* lnum out of range */ - if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL) + int db_idx; // index for lnum in data block + bhdr_T *hp; + memfile_T *mfp; + DATA_BL *dp; + PTR_BL *pp; + infoptr_T *ip; + + // lnum out of range + if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL) { return FAIL; + } - if (lowest_marked && lowest_marked > lnum) + if (lowest_marked && lowest_marked > lnum) { lowest_marked = lnum + 1; + } - if (len == 0) - len = (colnr_T)STRLEN(line) + 1; /* space needed for the text */ - space_needed = len + INDEX_SIZE; /* space needed for text + index */ + if (len == 0) { + len = (colnr_T)STRLEN(line) + 1; // space needed for the text + } + space_needed = len + INDEX_SIZE; // space needed for text + index mfp = buf->b_ml.ml_mfp; page_size = mfp->mf_page_size; @@ -1992,16 +2018,18 @@ static int ml_append_int( * This also releases any locked block. */ if ((hp = ml_find_line(buf, lnum == 0 ? (linenr_T)1 : lnum, - ML_INSERT)) == NULL) + ML_INSERT)) == NULL) { return FAIL; + } buf->b_ml.ml_flags &= ~ML_EMPTY; - if (lnum == 0) /* got line one instead, correct db_idx */ - db_idx = -1; /* careful, it is negative! */ - else + if (lnum == 0) { // got line one instead, correct db_idx + db_idx = -1; // careful, it is negative! + } else { db_idx = lnum - buf->b_ml.ml_locked_low; - /* get line count before the insertion */ + } + // get line count before the insertion line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low; dp = hp->bh_data; @@ -2022,11 +2050,12 @@ static int ml_append_int( */ --(buf->b_ml.ml_locked_lineadd); --(buf->b_ml.ml_locked_high); - if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL) + if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL) { return FAIL; + } - db_idx = -1; /* careful, it is negative! */ - /* get line count before the insertion */ + db_idx = -1; // careful, it is negative! + // get line count before the insertion line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low; CHECK(buf->b_ml.ml_locked_low != lnum + 1, "locked_low != lnum + 1"); @@ -2035,7 +2064,7 @@ static int ml_append_int( ++buf->b_ml.ml_line_count; - if ((int)dp->db_free >= space_needed) { /* enough room in data block */ + if ((int)dp->db_free >= space_needed) { // enough room in data block /* * Insert new line in existing data block, or in data block allocated above. */ @@ -2047,38 +2076,43 @@ static int ml_append_int( * move the text of the lines that follow to the front * adjust the indexes of the lines that follow */ - if (line_count > db_idx + 1) { /* if there are following lines */ + if (line_count > db_idx + 1) { // if there are following lines /* * Offset is the start of the previous line. * This will become the character just after the new line. */ - if (db_idx < 0) + if (db_idx < 0) { offset = dp->db_txt_end; - else + } else { offset = ((dp->db_index[db_idx]) & DB_INDEX_MASK); + } memmove((char *)dp + dp->db_txt_start, - (char *)dp + dp->db_txt_start + len, - (size_t)(offset - (dp->db_txt_start + len))); - for (i = line_count - 1; i > db_idx; --i) + (char *)dp + dp->db_txt_start + len, + (size_t)(offset - (dp->db_txt_start + len))); + for (i = line_count - 1; i > db_idx; --i) { dp->db_index[i + 1] = dp->db_index[i] - len; + } dp->db_index[db_idx + 1] = offset - len; - } else /* add line at the end */ + } else { // add line at the end dp->db_index[db_idx + 1] = dp->db_txt_start; + } /* * copy the text into the block */ memmove((char *)dp + dp->db_index[db_idx + 1], line, (size_t)len); - if (mark) + if (mark) { dp->db_index[db_idx + 1] |= DB_MARKED; + } /* * Mark the block dirty. */ buf->b_ml.ml_flags |= ML_LOCKED_DIRTY; - if (!newfile) + if (!newfile) { buf->b_ml.ml_flags |= ML_LOCKED_POS; - } else { /* not enough space in data block */ + } + } else { // not enough space in data block /* * If there is not enough room we have to create a new data block and copy some * lines into it. @@ -2090,20 +2124,20 @@ static int ml_append_int( */ long line_count_left, line_count_right; int page_count_left, page_count_right; - bhdr_T *hp_left; - bhdr_T *hp_right; - bhdr_T *hp_new; + bhdr_T *hp_left; + bhdr_T *hp_right; + bhdr_T *hp_new; int lines_moved; - int data_moved = 0; /* init to shut up gcc */ - int total_moved = 0; /* init to shut up gcc */ - DATA_BL *dp_right, *dp_left; + int data_moved = 0; // init to shut up gcc + int total_moved = 0; // init to shut up gcc + DATA_BL *dp_right, *dp_left; int stack_idx; bool in_left; int lineadd; blocknr_T bnum_left, bnum_right; linenr_T lnum_left, lnum_right; int pb_idx; - PTR_BL *pp_new; + PTR_BL *pp_new; /* * We are going to allocate a new data block. Depending on the @@ -2113,7 +2147,7 @@ static int ml_append_int( * also put in the right block. This method is more efficient when * inserting a lot of lines at one place. */ - if (db_idx < 0) { /* left block is new, right block is existing */ + if (db_idx < 0) { // left block is new, right block is existing lines_moved = 0; in_left = true; // space_needed does not change @@ -2138,12 +2172,12 @@ static int ml_append_int( page_count = ((space_needed + HEADER_SIZE) + page_size - 1) / page_size; hp_new = ml_new_data(mfp, newfile, page_count); - if (db_idx < 0) { /* left block is new */ + if (db_idx < 0) { // left block is new hp_left = hp_new; hp_right = hp; line_count_left = 0; line_count_right = line_count; - } else { /* right block is new */ + } else { // right block is new hp_left = hp; hp_right = hp_new; line_count_left = line_count; @@ -2163,11 +2197,12 @@ static int ml_append_int( dp_right->db_txt_start -= len; dp_right->db_free -= len + INDEX_SIZE; dp_right->db_index[0] = dp_right->db_txt_start; - if (mark) + if (mark) { dp_right->db_index[0] |= DB_MARKED; + } memmove((char *)dp_right + dp_right->db_txt_start, - line, (size_t)len); + line, (size_t)len); ++line_count_right; } /* @@ -2179,8 +2214,8 @@ static int ml_append_int( dp_right->db_txt_start -= data_moved; dp_right->db_free -= total_moved; memmove((char *)dp_right + dp_right->db_txt_start, - (char *)dp_left + dp_left->db_txt_start, - (size_t)data_moved); + (char *)dp_left + dp_left->db_txt_start, + (size_t)data_moved); offset = dp_right->db_txt_start - dp_left->db_txt_start; dp_left->db_txt_start += data_moved; dp_left->db_free += total_moved; @@ -2189,8 +2224,9 @@ static int ml_append_int( * update indexes in the new block */ for (to = line_count_right, from = db_idx + 1; - from < line_count_left; ++from, ++to) + from < line_count_left; ++from, ++to) { dp_right->db_index[to] = dp->db_index[from] + offset; + } line_count_right += lines_moved; line_count_left -= lines_moved; } @@ -2202,22 +2238,24 @@ static int ml_append_int( dp_left->db_txt_start -= len; dp_left->db_free -= len + INDEX_SIZE; dp_left->db_index[line_count_left] = dp_left->db_txt_start; - if (mark) + if (mark) { dp_left->db_index[line_count_left] |= DB_MARKED; + } memmove((char *)dp_left + dp_left->db_txt_start, - line, (size_t)len); + line, (size_t)len); ++line_count_left; } - if (db_idx < 0) { /* left block is new */ + if (db_idx < 0) { // left block is new lnum_left = lnum + 1; lnum_right = 0; - } else { /* right block is new */ + } else { // right block is new lnum_left = 0; - if (in_left) + if (in_left) { lnum_right = lnum + 2; - else + } else { lnum_right = lnum + 1; + } } dp_left->db_line_count = line_count_left; dp_right->db_line_count = line_count_right; @@ -2228,10 +2266,12 @@ static int ml_append_int( * The old one (hp, in ml_locked) gets a positive blocknumber if * we changed it and we are not editing a new file. */ - if (lines_moved || in_left) + if (lines_moved || in_left) { buf->b_ml.ml_flags |= ML_LOCKED_DIRTY; - if (!newfile && db_idx >= 0 && in_left) + } + if (!newfile && db_idx >= 0 && in_left) { buf->b_ml.ml_flags |= ML_LOCKED_POS; + } mf_put(mfp, hp_new, true, false); /* @@ -2250,9 +2290,10 @@ static int ml_append_int( --stack_idx) { ip = &(buf->b_ml.ml_stack[stack_idx]); pb_idx = ip->ip_index; - if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) + if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) { return FAIL; - pp = hp->bh_data; /* must be pointer block */ + } + pp = hp->bh_data; // must be pointer block if (pp->pb_id != PTR_ID) { IEMSG(_("E317: pointer block id wrong 3")); mf_put(mfp, hp, false, false); @@ -2262,12 +2303,13 @@ static int ml_append_int( * TODO: If the pointer block is full and we are adding at the end * try to insert in front of the next block */ - /* block not full, add one entry */ + // block not full, add one entry if (pp->pb_count < pp->pb_count_max) { - if (pb_idx + 1 < (int)pp->pb_count) + if (pb_idx + 1 < (int)pp->pb_count) { memmove(&pp->pb_pointer[pb_idx + 2], - &pp->pb_pointer[pb_idx + 1], - (size_t)(pp->pb_count - pb_idx - 1) * sizeof(PTR_EN)); + &pp->pb_pointer[pb_idx + 1], + (size_t)(pp->pb_count - pb_idx - 1) * sizeof(PTR_EN)); + } ++pp->pb_count; pp->pb_pointer[pb_idx].pe_line_count = line_count_left; pp->pb_pointer[pb_idx].pe_bnum = bnum_left; @@ -2276,19 +2318,21 @@ static int ml_append_int( pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right; pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right; - if (lnum_left != 0) + if (lnum_left != 0) { pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left; - if (lnum_right != 0) + } + if (lnum_right != 0) { pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right; + } mf_put(mfp, hp, true, false); - buf->b_ml.ml_stack_top = stack_idx + 1; /* truncate stack */ + buf->b_ml.ml_stack_top = stack_idx + 1; // truncate stack if (lineadd) { --(buf->b_ml.ml_stack_top); - /* fix line count for rest of blocks in the stack */ + // fix line count for rest of blocks in the stack ml_lineadd(buf, lineadd); - /* fix stack itself */ + // fix stack itself buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high += lineadd; ++(buf->b_ml.ml_stack_top); @@ -2298,21 +2342,23 @@ static int ml_append_int( * We are finished, break the loop here. */ break; - } else { /* pointer block full */ + } else { // pointer block full /* * split the pointer block * allocate a new pointer block * move some of the pointer into the new block * prepare for updating the parent block */ - for (;; ) { /* do this twice when splitting block 1 */ + for (;; ) { // do this twice when splitting block 1 hp_new = ml_new_ptr(mfp); - if (hp_new == NULL) /* TODO: try to fix tree */ + if (hp_new == NULL) { // TODO: try to fix tree return FAIL; + } pp_new = hp_new->bh_data; - if (hp->bh_bnum != 1) + if (hp->bh_bnum != 1) { break; + } /* * if block 1 becomes full the tree is given an extra level @@ -2326,12 +2372,12 @@ static int ml_append_int( pp->pb_pointer[0].pe_line_count = buf->b_ml.ml_line_count; pp->pb_pointer[0].pe_old_lnum = 1; pp->pb_pointer[0].pe_page_count = 1; - mf_put(mfp, hp, true, false); /* release block 1 */ - hp = hp_new; /* new block is to be split */ + mf_put(mfp, hp, true, false); // release block 1 + hp = hp_new; // new block is to be split pp = pp_new; CHECK(stack_idx != 0, _("stack_idx should be 0")); ip->ip_index = 0; - ++stack_idx; /* do block 1 again later */ + ++stack_idx; // do block 1 again later } /* * move the pointers after the current one to the new block @@ -2340,15 +2386,16 @@ static int ml_append_int( total_moved = pp->pb_count - pb_idx - 1; if (total_moved) { memmove(&pp_new->pb_pointer[0], - &pp->pb_pointer[pb_idx + 1], - (size_t)(total_moved) * sizeof(PTR_EN)); + &pp->pb_pointer[pb_idx + 1], + (size_t)(total_moved) * sizeof(PTR_EN)); pp_new->pb_count = total_moved; pp->pb_count -= total_moved - 1; pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right; pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right; pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right; - if (lnum_right) + if (lnum_right) { pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right; + } } else { pp_new->pb_count = 1; pp_new->pb_pointer[0].pe_bnum = bnum_right; @@ -2359,8 +2406,9 @@ static int ml_append_int( pp->pb_pointer[pb_idx].pe_bnum = bnum_left; pp->pb_pointer[pb_idx].pe_line_count = line_count_left; pp->pb_pointer[pb_idx].pe_page_count = page_count_left; - if (lnum_left) + if (lnum_left) { pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left; + } lnum_left = 0; lnum_right = 0; @@ -2368,11 +2416,13 @@ static int ml_append_int( * recompute line counts */ line_count_right = 0; - for (i = 0; i < (int)pp_new->pb_count; ++i) + for (i = 0; i < (int)pp_new->pb_count; ++i) { line_count_right += pp_new->pb_pointer[i].pe_line_count; + } line_count_left = 0; - for (i = 0; i < (int)pp->pb_count; ++i) + for (i = 0; i < (int)pp->pb_count; ++i) { line_count_left += pp->pb_pointer[i].pe_line_count; + } bnum_left = hp->bh_bnum; bnum_right = hp_new->bh_bnum; @@ -2392,7 +2442,7 @@ static int ml_append_int( } } - /* The line was inserted below 'lnum' */ + // The line was inserted below 'lnum' ml_updatechunk(buf, lnum + 1, (long)len, ML_CHNK_ADDLINE); return OK; } @@ -2439,8 +2489,9 @@ int ml_replace(linenr_T lnum, char_u *line, bool copy) // return FAIL for failure, OK otherwise int ml_replace_buf(buf_T *buf, linenr_T lnum, char_u *line, bool copy) { - if (line == NULL) /* just checking... */ + if (line == NULL) { // just checking... return FAIL; + } // When starting up, we might still need to create the memfile if (buf->b_ml.ml_mfp == NULL && open_buffer(false, NULL, 0) == FAIL) { @@ -2487,12 +2538,12 @@ int ml_delete(linenr_T lnum, bool message) static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message) { - bhdr_T *hp; - memfile_T *mfp; - DATA_BL *dp; - PTR_BL *pp; - infoptr_T *ip; - int count; /* number of entries in block */ + bhdr_T *hp; + memfile_T *mfp; + DATA_BL *dp; + PTR_BL *pp; + infoptr_T *ip; + int count; // number of entries in block int idx; int stack_idx; int text_start; @@ -2500,19 +2551,22 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message) long line_size; int i; - if (lnum < 1 || lnum > buf->b_ml.ml_line_count) + if (lnum < 1 || lnum > buf->b_ml.ml_line_count) { return FAIL; + } - if (lowest_marked && lowest_marked > lnum) + if (lowest_marked && lowest_marked > lnum) { lowest_marked--; + } /* * If the file becomes empty the last line is replaced by an empty line. */ - if (buf->b_ml.ml_line_count == 1) { /* file becomes empty */ + if (buf->b_ml.ml_line_count == 1) { // file becomes empty if (message - ) + ) { set_keep_msg((char_u *)_(no_lines_msg), 0); + } i = ml_replace((linenr_T)1, (char_u *)"", true); buf->b_ml.ml_flags |= ML_EMPTY; @@ -2526,14 +2580,16 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message) * This also releases any locked block. */ mfp = buf->b_ml.ml_mfp; - if (mfp == NULL) + if (mfp == NULL) { return FAIL; + } - if ((hp = ml_find_line(buf, lnum, ML_DELETE)) == NULL) + if ((hp = ml_find_line(buf, lnum, ML_DELETE)) == NULL) { return FAIL; + } dp = hp->bh_data; - /* compute line count before the delete */ + // compute line count before the delete count = (long)(buf->b_ml.ml_locked_high) - (long)(buf->b_ml.ml_locked_low) + 2; idx = lnum - buf->b_ml.ml_locked_low; @@ -2541,10 +2597,11 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message) --buf->b_ml.ml_line_count; line_start = ((dp->db_index[idx]) & DB_INDEX_MASK); - if (idx == 0) /* first line in block, text at the end */ + if (idx == 0) { // first line in block, text at the end line_size = dp->db_txt_end - line_start; - else + } else { line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start; + } // Line should always have an NL char internally (represented as NUL), // even if 'noeol' is set. @@ -2560,33 +2617,35 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message) * ml_find_line(). */ if (count == 1) { - mf_free(mfp, hp); /* free the data block */ + mf_free(mfp, hp); // free the data block buf->b_ml.ml_locked = NULL; for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0; --stack_idx) { - buf->b_ml.ml_stack_top = 0; /* stack is invalid when failing */ + buf->b_ml.ml_stack_top = 0; // stack is invalid when failing ip = &(buf->b_ml.ml_stack[stack_idx]); idx = ip->ip_index; - if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) + if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) { return FAIL; - pp = hp->bh_data; /* must be pointer block */ + } + pp = hp->bh_data; // must be pointer block if (pp->pb_id != PTR_ID) { IEMSG(_("E317: pointer block id wrong 4")); mf_put(mfp, hp, false, false); return FAIL; } count = --(pp->pb_count); - if (count == 0) /* the pointer block becomes empty! */ + if (count == 0) { // the pointer block becomes empty! mf_free(mfp, hp); - else { - if (count != idx) /* move entries after the deleted one */ + } else { + if (count != idx) { // move entries after the deleted one memmove(&pp->pb_pointer[idx], &pp->pb_pointer[idx + 1], - (size_t)(count - idx) * sizeof(PTR_EN)); + (size_t)(count - idx) * sizeof(PTR_EN)); + } mf_put(mfp, hp, true, false); - buf->b_ml.ml_stack_top = stack_idx; /* truncate stack */ - /* fix line count for rest of blocks in the stack */ + buf->b_ml.ml_stack_top = stack_idx; // truncate stack + // fix line count for rest of blocks in the stack if (buf->b_ml.ml_locked_lineadd != 0) { ml_lineadd(buf, buf->b_ml.ml_locked_lineadd); buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high += @@ -2604,14 +2663,15 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message) */ text_start = dp->db_txt_start; memmove((char *)dp + text_start + line_size, - (char *)dp + text_start, (size_t)(line_start - text_start)); + (char *)dp + text_start, (size_t)(line_start - text_start)); /* * delete the index by moving the next indexes backwards * Adjust the indexes for the text movement. */ - for (i = idx; i < count - 1; ++i) + for (i = idx; i < count - 1; ++i) { dp->db_index[i] = dp->db_index[i + 1] + line_size; + } dp->db_free += line_size + INDEX_SIZE; dp->db_txt_start += line_size; @@ -2632,24 +2692,25 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message) */ void ml_setmarked(linenr_T lnum) { - bhdr_T *hp; + bhdr_T *hp; DATA_BL *dp; - /* invalid line number */ + // invalid line number if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count - || curbuf->b_ml.ml_mfp == NULL) - return; /* give error message? */ - - if (lowest_marked == 0 || lowest_marked > lnum) + || curbuf->b_ml.ml_mfp == NULL) { + return; // give error message? + } + if (lowest_marked == 0 || lowest_marked > lnum) { lowest_marked = lnum; + } /* * find the data block containing the line * This also fills the stack with the blocks from the root to the data block * This also releases any locked block. */ - if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL) - return; /* give error message? */ - + if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL) { + return; // give error message? + } dp = hp->bh_data; dp->db_index[lnum - curbuf->b_ml.ml_locked_low] |= DB_MARKED; curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY; @@ -2660,13 +2721,14 @@ void ml_setmarked(linenr_T lnum) */ linenr_T ml_firstmarked(void) { - bhdr_T *hp; - DATA_BL *dp; + bhdr_T *hp; + DATA_BL *dp; linenr_T lnum; int i; - if (curbuf->b_ml.ml_mfp == NULL) - return (linenr_T) 0; + if (curbuf->b_ml.ml_mfp == NULL) { + return (linenr_T)0; + } /* * The search starts with lowest_marked line. This is the last line where @@ -2678,22 +2740,23 @@ linenr_T ml_firstmarked(void) * This also fills the stack with the blocks from the root to the data * block This also releases any locked block. */ - if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL) - return (linenr_T)0; /* give error message? */ - + if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL) { + return (linenr_T)0; // give error message? + } dp = hp->bh_data; for (i = lnum - curbuf->b_ml.ml_locked_low; - lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum) + lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum) { if ((dp->db_index[i]) & DB_MARKED) { (dp->db_index[i]) &= DB_INDEX_MASK; curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY; lowest_marked = lnum + 1; return lnum; } + } } - return (linenr_T) 0; + return (linenr_T)0; } /* @@ -2701,13 +2764,14 @@ linenr_T ml_firstmarked(void) */ void ml_clearmarked(void) { - bhdr_T *hp; - DATA_BL *dp; + bhdr_T *hp; + DATA_BL *dp; linenr_T lnum; int i; - if (curbuf->b_ml.ml_mfp == NULL) /* nothing to do */ + if (curbuf->b_ml.ml_mfp == NULL) { // nothing to do return; + } /* * The search starts with line lowest_marked. @@ -2718,21 +2782,21 @@ void ml_clearmarked(void) * This also fills the stack with the blocks from the root to the data * block and releases any locked block. */ - if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL) - return; /* give error message? */ - + if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL) { + return; // give error message? + } dp = hp->bh_data; for (i = lnum - curbuf->b_ml.ml_locked_low; - lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum) + lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum) { if ((dp->db_index[i]) & DB_MARKED) { (dp->db_index[i]) &= DB_INDEX_MASK; curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY; } + } } lowest_marked = 0; - return; } size_t ml_flush_deleted_bytes(buf_T *buf, size_t *codepoints, size_t *codeunits) @@ -2751,11 +2815,11 @@ size_t ml_flush_deleted_bytes(buf_T *buf, size_t *codepoints, size_t *codeunits) */ static void ml_flush_line(buf_T *buf) { - bhdr_T *hp; - DATA_BL *dp; + bhdr_T *hp; + DATA_BL *dp; linenr_T lnum; - char_u *new_line; - char_u *old_line; + char_u *new_line; + char_u *old_line; colnr_T new_len; int old_len; int extra; @@ -2765,13 +2829,14 @@ static void ml_flush_line(buf_T *buf) int i; static bool entered = false; - if (buf->b_ml.ml_line_lnum == 0 || buf->b_ml.ml_mfp == NULL) - return; /* nothing to do */ - + if (buf->b_ml.ml_line_lnum == 0 || buf->b_ml.ml_mfp == NULL) { + return; // nothing to do + } if (buf->b_ml.ml_flags & ML_LINE_DIRTY) { - /* This code doesn't work recursively. */ - if (entered) + // This code doesn't work recursively. + if (entered) { return; + } entered = true; buf->flush_count++; @@ -2787,39 +2852,41 @@ static void ml_flush_line(buf_T *buf) idx = lnum - buf->b_ml.ml_locked_low; start = ((dp->db_index[idx]) & DB_INDEX_MASK); old_line = (char_u *)dp + start; - if (idx == 0) /* line is last in block */ + if (idx == 0) { // line is last in block old_len = dp->db_txt_end - start; - else /* text of previous line follows */ + } else { // text of previous line follows old_len = (dp->db_index[idx - 1] & DB_INDEX_MASK) - start; + } new_len = (colnr_T)STRLEN(new_line) + 1; - extra = new_len - old_len; /* negative if lines gets smaller */ + extra = new_len - old_len; // negative if lines gets smaller /* * if new line fits in data block, replace directly */ if ((int)dp->db_free >= extra) { - /* if the length changes and there are following lines */ + // if the length changes and there are following lines count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1; if (extra != 0 && idx < count - 1) { - /* move text of following lines */ + // move text of following lines memmove((char *)dp + dp->db_txt_start - extra, - (char *)dp + dp->db_txt_start, - (size_t)(start - dp->db_txt_start)); + (char *)dp + dp->db_txt_start, + (size_t)(start - dp->db_txt_start)); - /* adjust pointers of this and following lines */ - for (i = idx + 1; i < count; ++i) + // adjust pointers of this and following lines + for (i = idx + 1; i < count; ++i) { dp->db_index[i] -= extra; + } } dp->db_index[idx] -= extra; - /* adjust free space */ + // adjust free space dp->db_free -= extra; dp->db_txt_start -= extra; - /* copy new line into the data block */ + // copy new line into the data block memmove(old_line - extra, new_line, (size_t)new_len); buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS); - /* The else case is already covered by the insert and delete */ + // The else case is already covered by the insert and delete ml_updatechunk(buf, lnum, (long)extra, ML_CHNK_UPDLINE); } else { // Cannot do it in one data block: Delete and append. @@ -2876,8 +2943,8 @@ static bhdr_T *ml_new_ptr(memfile_T *mfp) * lookup line 'lnum' in a memline * * action: if ML_DELETE or ML_INSERT the line count is updated while searching - * if ML_FLUSH only flush a locked block - * if ML_FIND just find the line + * if ML_FLUSH only flush a locked block + * if ML_FIND just find the line * * If the block was found it is locked and put in ml_locked. * The stack is updated to lead to the locked block. The ip_high field in @@ -2889,11 +2956,11 @@ static bhdr_T *ml_new_ptr(memfile_T *mfp) */ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action) { - DATA_BL *dp; - PTR_BL *pp; - infoptr_T *ip; - bhdr_T *hp; - memfile_T *mfp; + DATA_BL *dp; + PTR_BL *pp; + infoptr_T *ip; + bhdr_T *hp; + memfile_T *mfp; linenr_T t; blocknr_T bnum, bnum2; int dirty; @@ -2927,58 +2994,63 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action) } mf_put(mfp, buf->b_ml.ml_locked, buf->b_ml.ml_flags & ML_LOCKED_DIRTY, - buf->b_ml.ml_flags & ML_LOCKED_POS); + buf->b_ml.ml_flags & ML_LOCKED_POS); buf->b_ml.ml_locked = NULL; /* * If lines have been added or deleted in the locked block, need to * update the line count in pointer blocks. */ - if (buf->b_ml.ml_locked_lineadd != 0) + if (buf->b_ml.ml_locked_lineadd != 0) { ml_lineadd(buf, buf->b_ml.ml_locked_lineadd); + } } - if (action == ML_FLUSH) /* nothing else to do */ + if (action == ML_FLUSH) { // nothing else to do return NULL; + } - bnum = 1; /* start at the root of the tree */ + bnum = 1; // start at the root of the tree page_count = 1; low = 1; high = buf->b_ml.ml_line_count; - if (action == ML_FIND) { /* first try stack entries */ + if (action == ML_FIND) { // first try stack entries for (top = buf->b_ml.ml_stack_top - 1; top >= 0; --top) { ip = &(buf->b_ml.ml_stack[top]); if (ip->ip_low <= lnum && ip->ip_high >= lnum) { bnum = ip->ip_bnum; low = ip->ip_low; high = ip->ip_high; - buf->b_ml.ml_stack_top = top; /* truncate stack at prev entry */ + buf->b_ml.ml_stack_top = top; // truncate stack at prev entry break; } } - if (top < 0) - buf->b_ml.ml_stack_top = 0; /* not found, start at the root */ - } else /* ML_DELETE or ML_INSERT */ - buf->b_ml.ml_stack_top = 0; /* start at the root */ - + if (top < 0) { + buf->b_ml.ml_stack_top = 0; // not found, start at the root + } + } else { // ML_DELETE or ML_INSERT + buf->b_ml.ml_stack_top = 0; // start at the root + } /* * search downwards in the tree until a data block is found */ for (;; ) { - if ((hp = mf_get(mfp, bnum, page_count)) == NULL) + if ((hp = mf_get(mfp, bnum, page_count)) == NULL) { goto error_noblock; + } /* * update high for insert/delete */ - if (action == ML_INSERT) + if (action == ML_INSERT) { ++high; - else if (action == ML_DELETE) + } else if (action == ML_DELETE) { --high; + } dp = hp->bh_data; - if (dp->db_id == DATA_ID) { /* data block */ + if (dp->db_id == DATA_ID) { // data block buf->b_ml.ml_locked = hp; buf->b_ml.ml_locked_low = low; buf->b_ml.ml_locked_high = high; @@ -2987,7 +3059,7 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action) return hp; } - pp = (PTR_BL *)(dp); /* must be pointer block */ + pp = (PTR_BL *)(dp); // must be pointer block if (pp->pb_id != PTR_ID) { IEMSG(_("E317: pointer block id wrong")); goto error_block; @@ -2998,7 +3070,7 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action) ip->ip_bnum = bnum; ip->ip_low = low; ip->ip_high = high; - ip->ip_index = -1; /* index not known yet */ + ip->ip_index = -1; // index not known yet dirty = FALSE; for (idx = 0; idx < (int)pp->pb_count; ++idx) { @@ -3030,7 +3102,6 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action) if (lnum > buf->b_ml.ml_line_count) { IEMSGN(_("E322: line number out of range: %" PRId64 " past the end"), lnum - buf->b_ml.ml_line_count); - } else { IEMSGN(_("E323: line count wrong in block %" PRId64), bnum); } @@ -3054,10 +3125,11 @@ error_noblock: * the incremented/decremented line counts, because there won't be a line * inserted/deleted after all. */ - if (action == ML_DELETE) + if (action == ML_DELETE) { ml_lineadd(buf, 1); - else if (action == ML_INSERT) + } else if (action == ML_INSERT) { ml_lineadd(buf, -1); + } buf->b_ml.ml_stack_top = 0; return NULL; } @@ -3071,9 +3143,9 @@ static int ml_add_stack(buf_T *buf) { int top = buf->b_ml.ml_stack_top; - /* may have to increase the stack size */ + // may have to increase the stack size if (top == buf->b_ml.ml_stack_size) { - CHECK(top > 0, _("Stack size increases")); /* more than 5 levels??? */ + CHECK(top > 0, _("Stack size increases")); // more than 5 levels??? buf->b_ml.ml_stack_size += STACK_INCR; size_t new_size = sizeof(infoptr_T) * buf->b_ml.ml_stack_size; @@ -3097,16 +3169,17 @@ static int ml_add_stack(buf_T *buf) static void ml_lineadd(buf_T *buf, int count) { int idx; - infoptr_T *ip; - PTR_BL *pp; - memfile_T *mfp = buf->b_ml.ml_mfp; - bhdr_T *hp; + infoptr_T *ip; + PTR_BL *pp; + memfile_T *mfp = buf->b_ml.ml_mfp; + bhdr_T *hp; for (idx = buf->b_ml.ml_stack_top - 1; idx >= 0; --idx) { ip = &(buf->b_ml.ml_stack[idx]); - if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) + if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) { break; - pp = hp->bh_data; /* must be pointer block */ + } + pp = hp->bh_data; // must be pointer block if (pp->pb_id != PTR_ID) { mf_put(mfp, hp, false, false); IEMSG(_("E317: pointer block id wrong 2")); @@ -3132,14 +3205,15 @@ int resolve_symlink(const char_u *fname, char_u *buf) int ret; int depth = 0; - if (fname == NULL) + if (fname == NULL) { return FAIL; + } - /* Put the result so far in tmp[], starting with the original name. */ + // Put the result so far in tmp[], starting with the original name. STRLCPY(tmp, fname, MAXPATHL); for (;; ) { - /* Limit symlink depth to 100, catch recursive loops. */ + // Limit symlink depth to 100, catch recursive loops. if (++depth == 100) { EMSG2(_("E773: Symlink loop for \"%s\""), fname); return FAIL; @@ -3148,17 +3222,18 @@ int resolve_symlink(const char_u *fname, char_u *buf) ret = readlink((char *)tmp, (char *)buf, MAXPATHL - 1); if (ret <= 0) { if (errno == EINVAL || errno == ENOENT) { - /* Found non-symlink or not existing file, stop here. - * When at the first level use the unmodified name, skip the - * call to vim_FullName(). */ - if (depth == 1) + // Found non-symlink or not existing file, stop here. + // When at the first level use the unmodified name, skip the + // call to vim_FullName(). + if (depth == 1) { return FAIL; + } - /* Use the resolved name in tmp[]. */ + // Use the resolved name in tmp[]. break; } - /* There must be some error reading links, use original name. */ + // There must be some error reading links, use original name. return FAIL; } buf[ret] = NUL; @@ -3193,8 +3268,8 @@ int resolve_symlink(const char_u *fname, char_u *buf) */ char_u *makeswapname(char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name) { - char_u *r, *s; - char_u *fname_res = fname; + char_u *r, *s; + char_u *fname_res = fname; #ifdef HAVE_READLINK char_u fname_buf[MAXPATHL]; @@ -3221,46 +3296,43 @@ char_u *makeswapname(char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name // Prepend a '.' to the swap file name for the current directory. r = (char_u *)modname((char *)fname_res, ".swp", - dir_name[0] == '.' && dir_name[1] == NUL); - if (r == NULL) /* out of memory */ + dir_name[0] == '.' && dir_name[1] == NUL); + if (r == NULL) { // out of memory return NULL; + } s = get_file_in_dir(r, dir_name); xfree(r); return s; } -/* - * Get file name to use for swap file or backup file. - * Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir' - * option "dname". - * - If "dname" is ".", return "fname" (swap file in dir of file). - * - If "dname" starts with "./", insert "dname" in "fname" (swap file - * relative to dir of file). - * - Otherwise, prepend "dname" to the tail of "fname" (swap file in specific - * dir). - * - * The return value is an allocated string and can be NULL. - */ -char_u * -get_file_in_dir ( - char_u *fname, - char_u *dname /* don't use "dirname", it is a global for Alpha */ -) +/// Get file name to use for swap file or backup file. +/// Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir' +/// option "dname". +/// - If "dname" is ".", return "fname" (swap file in dir of file). +/// - If "dname" starts with "./", insert "dname" in "fname" (swap file +/// relative to dir of file). +/// - Otherwise, prepend "dname" to the tail of "fname" (swap file in specific +/// dir). +/// +/// The return value is an allocated string and can be NULL. +/// +/// @param dname don't use "dirname", it is a global for Alpha +char_u *get_file_in_dir(char_u *fname, char_u *dname) { - char_u *t; - char_u *tail; - char_u *retval; + char_u *t; + char_u *tail; + char_u *retval; int save_char; tail = path_tail(fname); - if (dname[0] == '.' && dname[1] == NUL) + if (dname[0] == '.' && dname[1] == NUL) { retval = vim_strsave(fname); - else if (dname[0] == '.' && vim_ispathsep(dname[1])) { - if (tail == fname) /* no path before file name */ + } else if (dname[0] == '.' && vim_ispathsep(dname[1])) { + if (tail == fname) { // no path before file name retval = (char_u *)concat_fnames((char *)dname + 2, (char *)tail, TRUE); - else { + } else { save_char = *tail; *tail = NUL; t = (char_u *)concat_fnames((char *)fname, (char *)dname + 2, TRUE); @@ -3276,14 +3348,11 @@ get_file_in_dir ( } -/* - * Print the ATTENTION message: info about an existing swap file. - */ -static void -attention_message ( - buf_T *buf, /* buffer being edited */ - char_u *fname /* swap file name */ -) +/// Print the ATTENTION message: info about an existing swap file. +/// +/// @param buf buffer being edited +/// @param fname swap file name +static void attention_message(buf_T *buf, char_u *fname) { assert(buf->b_fname != NULL); @@ -3339,7 +3408,7 @@ attention_message ( */ static int do_swapexists(buf_T *buf, char_u *fname) { - set_vim_var_string(VV_SWAPNAME, (char *) fname, -1); + set_vim_var_string(VV_SWAPNAME, (char *)fname, -1); set_vim_var_string(VV_SWAPCHOICE, NULL, -1); // Trigger SwapExists autocommands with <afile> set to the file being @@ -3351,12 +3420,18 @@ static int do_swapexists(buf_T *buf, char_u *fname) set_vim_var_string(VV_SWAPNAME, NULL, -1); switch (*get_vim_var_str(VV_SWAPCHOICE)) { - case 'o': return 1; - case 'e': return 2; - case 'r': return 3; - case 'd': return 4; - case 'q': return 5; - case 'a': return 6; + case 'o': + return 1; + case 'e': + return 2; + case 'r': + return 3; + case 'd': + return 4; + case 'q': + return 5; + case 'a': + return 6; } return 0; @@ -3385,14 +3460,13 @@ static int do_swapexists(buf_T *buf, char_u *fname) /// never set to false. /// /// @return [allocated] Name of the swap file. -static char *findswapname(buf_T *buf, char **dirp, char *old_fname, - bool *found_existing_dir) +static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_existing_dir) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1, 2, 4) { char *fname; size_t n; char *dir_name; - char *buf_fname = (char *) buf->b_fname; + char *buf_fname = (char *)buf->b_fname; /* * Isolate a directory name from *dirp and put it in dir_name. @@ -3400,7 +3474,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, */ const size_t dir_len = strlen(*dirp) + 1; dir_name = xmalloc(dir_len); - (void)copy_option_part((char_u **) dirp, (char_u *) dir_name, dir_len, ","); + (void)copy_option_part((char_u **)dirp, (char_u *)dir_name, dir_len, ","); /* * we try different names until we find one that does not exist yet @@ -3459,7 +3533,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, // inode too. expand_env(b0.b0_fname, NameBuff, MAXPATHL); if (fnamecmp_ino(buf->b_ffname, NameBuff, - char_to_long(b0.b0_ino))) { + char_to_long(b0.b0_ino))) { differ = TRUE; } } @@ -3468,7 +3542,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, // "~user/path/file". Expand it first. expand_env(b0.b0_fname, NameBuff, MAXPATHL); if (fnamecmp_ino(buf->b_ffname, NameBuff, - char_to_long(b0.b0_ino))) { + char_to_long(b0.b0_ino))) { differ = TRUE; } } @@ -3532,12 +3606,10 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, choice = do_dialog(VIM_WARNING, (char_u *)_("VIM - ATTENTION"), (char_u *)name, process_still_running - ? (char_u *)_( - "&Open Read-Only\n&Edit anyway\n&Recover" - "\n&Quit\n&Abort") : - (char_u *)_( - "&Open Read-Only\n&Edit anyway\n&Recover" - "\n&Delete it\n&Quit\n&Abort"), + ? (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover" + "\n&Quit\n&Abort") : + (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover" + "\n&Delete it\n&Quit\n&Abort"), 1, NULL, false); if (process_still_running && choice >= 4) { @@ -3582,7 +3654,6 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, need_wait_return = true; } } - } } } @@ -3593,19 +3664,19 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, * If that still isn't enough decrement the last but one char: ".svz" * Can happen when editing many "No Name" buffers. */ - if (fname[n - 1] == 'a') { /* ".s?a" */ - if (fname[n - 2] == 'a') { /* ".saa": tried enough, give up */ + if (fname[n - 1] == 'a') { // ".s?a" + if (fname[n - 2] == 'a') { // ".saa": tried enough, give up EMSG(_("E326: Too many swap files found")); XFREE_CLEAR(fname); break; } - --fname[n - 2]; /* ".svz", ".suz", etc. */ + --fname[n - 2]; // ".svz", ".suz", etc. fname[n - 1] = 'z' + 1; } - --fname[n - 1]; /* ".swo", ".swn", etc. */ + --fname[n - 1]; // ".swo", ".swn", etc. } - if (os_isdir((char_u *) dir_name)) { + if (os_isdir((char_u *)dir_name)) { *found_existing_dir = true; } else if (!*found_existing_dir && **dirp == NUL) { int ret; @@ -3630,66 +3701,62 @@ static int b0_magic_wrong(ZERO_BL *b0p) || b0p->b0_magic_char != B0_MAGIC_CHAR; } -/* - * Compare current file name with file name from swap file. - * Try to use inode numbers when possible. - * Return non-zero when files are different. - * - * When comparing file names a few things have to be taken into consideration: - * - When working over a network the full path of a file depends on the host. - * We check the inode number if possible. It is not 100% reliable though, - * because the device number cannot be used over a network. - * - When a file does not exist yet (editing a new file) there is no inode - * number. - * - The file name in a swap file may not be valid on the current host. The - * "~user" form is used whenever possible to avoid this. - * - * This is getting complicated, let's make a table: - * - * ino_c ino_s fname_c fname_s differ = - * - * both files exist -> compare inode numbers: - * != 0 != 0 X X ino_c != ino_s - * - * inode number(s) unknown, file names available -> compare file names - * == 0 X OK OK fname_c != fname_s - * X == 0 OK OK fname_c != fname_s - * - * current file doesn't exist, file for swap file exist, file name(s) not - * available -> probably different - * == 0 != 0 FAIL X TRUE - * == 0 != 0 X FAIL TRUE - * - * current file exists, inode for swap unknown, file name(s) not - * available -> probably different - * != 0 == 0 FAIL X TRUE - * != 0 == 0 X FAIL TRUE - * - * current file doesn't exist, inode for swap unknown, one file name not - * available -> probably different - * == 0 == 0 FAIL OK TRUE - * == 0 == 0 OK FAIL TRUE - * - * current file doesn't exist, inode for swap unknown, both file names not - * available -> compare file names - * == 0 == 0 FAIL FAIL fname_c != fname_s - * - * Only the last 32 bits of the inode will be used. This can't be changed - * without making the block 0 incompatible with 32 bit versions. - */ - -static bool fnamecmp_ino( - char_u *fname_c, // current file name - char_u *fname_s, // file name from swap file - long ino_block0 -) +/// Compare current file name with file name from swap file. +/// Try to use inode numbers when possible. +/// Return non-zero when files are different. +/// +/// When comparing file names a few things have to be taken into consideration: +/// - When working over a network the full path of a file depends on the host. +/// We check the inode number if possible. It is not 100% reliable though, +/// because the device number cannot be used over a network. +/// - When a file does not exist yet (editing a new file) there is no inode +/// number. +/// - The file name in a swap file may not be valid on the current host. The +/// "~user" form is used whenever possible to avoid this. +/// +/// This is getting complicated, let's make a table: +/// +/// ino_c ino_s fname_c fname_s differ = +/// +/// both files exist -> compare inode numbers: +/// != 0 != 0 X X ino_c != ino_s +/// +/// inode number(s) unknown, file names available -> compare file names +/// == 0 X OK OK fname_c != fname_s +/// X == 0 OK OK fname_c != fname_s +/// +/// current file doesn't exist, file for swap file exist, file name(s) not +/// available -> probably different +/// == 0 != 0 FAIL X TRUE +/// == 0 != 0 X FAIL TRUE +/// +/// current file exists, inode for swap unknown, file name(s) not +/// available -> probably different +/// != 0 == 0 FAIL X TRUE +/// != 0 == 0 X FAIL TRUE +/// +/// current file doesn't exist, inode for swap unknown, one file name not +/// available -> probably different +/// == 0 == 0 FAIL OK TRUE +/// == 0 == 0 OK FAIL TRUE +/// +/// current file doesn't exist, inode for swap unknown, both file names not +/// available -> compare file names +/// == 0 == 0 FAIL FAIL fname_c != fname_s +/// +/// Only the last 32 bits of the inode will be used. This can't be changed +/// without making the block 0 incompatible with 32 bit versions. +/// +/// @param fname_c current file name +/// @param fname_s file name from swap file +static bool fnamecmp_ino(char_u *fname_c, char_u *fname_s, long ino_block0) { - uint64_t ino_c = 0; /* ino of current file */ - uint64_t ino_s; /* ino of file from swap file */ - char_u buf_c[MAXPATHL]; /* full path of fname_c */ - char_u buf_s[MAXPATHL]; /* full path of fname_s */ - int retval_c; /* flag: buf_c valid */ - int retval_s; /* flag: buf_s valid */ + uint64_t ino_c = 0; // ino of current file + uint64_t ino_s; // ino of file from swap file + char_u buf_c[MAXPATHL]; // full path of fname_c + char_u buf_s[MAXPATHL]; // full path of fname_s + int retval_c; // flag: buf_c valid + int retval_s; // flag: buf_s valid FileInfo file_info; if (os_fileinfo((char *)fname_c, &file_info)) { @@ -3707,8 +3774,9 @@ static bool fnamecmp_ino( ino_s = (uint64_t)ino_block0; } - if (ino_c && ino_s) + if (ino_c && ino_s) { return ino_c != ino_s; + } /* * One of the inode numbers is unknown, try a forced vim_FullName() and @@ -3716,8 +3784,9 @@ static bool fnamecmp_ino( */ retval_c = vim_FullName((char *)fname_c, (char *)buf_c, MAXPATHL, TRUE); retval_s = vim_FullName((char *)fname_s, (char *)buf_s, MAXPATHL, TRUE); - if (retval_c == OK && retval_s == OK) + if (retval_c == OK && retval_s == OK) { return STRCMP(buf_c, buf_s) != 0; + } /* * Can't compare inodes or file names, guess that the files are different, @@ -3768,11 +3837,12 @@ static long char_to_long(char_u *s) */ void ml_setflags(buf_T *buf) { - bhdr_T *hp; - ZERO_BL *b0p; + bhdr_T *hp; + ZERO_BL *b0p; - if (!buf->b_ml.ml_mfp) + if (!buf->b_ml.ml_mfp) { return; + } for (hp = buf->b_ml.ml_mfp->mf_used_last; hp != NULL; hp = hp->bh_prev) { if (hp->bh_bnum == 0) { b0p = hp->bh_data; @@ -3787,19 +3857,19 @@ void ml_setflags(buf_T *buf) } } -#define MLCS_MAXL 800 /* max no of lines in chunk */ -#define MLCS_MINL 400 /* should be half of MLCS_MAXL */ +#define MLCS_MAXL 800 // max no of lines in chunk +#define MLCS_MINL 400 // should be half of MLCS_MAXL /* * Keep information for finding byte offset of a line, updtype may be one of: * ML_CHNK_ADDLINE: Add len to parent chunk, possibly splitting it - * Careful: ML_CHNK_ADDLINE may cause ml_find_line() to be called. + * Careful: ML_CHNK_ADDLINE may cause ml_find_line() to be called. * ML_CHNK_DELLINE: Subtract len from parent chunk, possibly deleting it * ML_CHNK_UPDLINE: Add len to parent chunk, as a signed entity. */ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) { - static buf_T *ml_upd_lastbuf = NULL; + static buf_T *ml_upd_lastbuf = NULL; static linenr_T ml_upd_lastline; static linenr_T ml_upd_lastcurline; static int ml_upd_lastcurix; @@ -3807,13 +3877,14 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) linenr_T curline = ml_upd_lastcurline; int curix = ml_upd_lastcurix; long size; - chunksize_T *curchnk; + chunksize_T *curchnk; int rest; - bhdr_T *hp; - DATA_BL *dp; + bhdr_T *hp; + DATA_BL *dp; - if (buf->b_ml.ml_usedchunks == -1 || len == 0) + if (buf->b_ml.ml_usedchunks == -1 || len == 0) { return; + } if (buf->b_ml.ml_chunksize == NULL) { buf->b_ml.ml_chunksize = xmalloc(sizeof(chunksize_T) * 100); buf->b_ml.ml_numchunks = 100; @@ -3841,8 +3912,8 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) || updtype != ML_CHNK_ADDLINE) { for (curline = 1, curix = 0; curix < buf->b_ml.ml_usedchunks - 1 - && line >= curline + - buf->b_ml.ml_chunksize[curix].mlcs_numlines; + && line >= curline + + buf->b_ml.ml_chunksize[curix].mlcs_numlines; curix++) { curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines; } @@ -3854,31 +3925,31 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) } curchnk = buf->b_ml.ml_chunksize + curix; - if (updtype == ML_CHNK_DELLINE) + if (updtype == ML_CHNK_DELLINE) { len = -len; + } curchnk->mlcs_totalsize += len; if (updtype == ML_CHNK_ADDLINE) { curchnk->mlcs_numlines++; - /* May resize here so we don't have to do it in both cases below */ + // May resize here so we don't have to do it in both cases below if (buf->b_ml.ml_usedchunks + 1 >= buf->b_ml.ml_numchunks) { buf->b_ml.ml_numchunks = buf->b_ml.ml_numchunks * 3 / 2; - buf->b_ml.ml_chunksize = xrealloc( - buf->b_ml.ml_chunksize, - sizeof(chunksize_T) * buf->b_ml.ml_numchunks); + buf->b_ml.ml_chunksize = xrealloc(buf->b_ml.ml_chunksize, + sizeof(chunksize_T) * buf->b_ml.ml_numchunks); } if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL) { - int count; /* number of entries in block */ + int count; // number of entries in block int idx; int text_end; int linecnt; memmove(buf->b_ml.ml_chunksize + curix + 1, - buf->b_ml.ml_chunksize + curix, - (buf->b_ml.ml_usedchunks - curix) * - sizeof(chunksize_T)); - /* Compute length of first half of lines in the split chunk */ + buf->b_ml.ml_chunksize + curix, + (buf->b_ml.ml_usedchunks - curix) * + sizeof(chunksize_T)); + // Compute length of first half of lines in the split chunk size = 0; linecnt = 0; while (curline < buf->b_ml.ml_line_count @@ -3892,11 +3963,12 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) (long)(buf->b_ml.ml_locked_low) + 1; idx = curline - buf->b_ml.ml_locked_low; curline = buf->b_ml.ml_locked_high + 1; - if (idx == 0) /* first line in block, text at the end */ + if (idx == 0) { // first line in block, text at the end text_end = dp->db_txt_end; - else + } else { text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK); - /* Compute index of last line to use in this MEMLINE */ + } + // Compute index of last line to use in this MEMLINE rest = count - idx; if (linecnt + rest > MLCS_MINL) { idx += MLCS_MINL - linecnt - 1; @@ -3912,7 +3984,7 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) buf->b_ml.ml_chunksize[curix].mlcs_totalsize = size; buf->b_ml.ml_chunksize[curix + 1].mlcs_totalsize -= size; buf->b_ml.ml_usedchunks++; - ml_upd_lastbuf = NULL; /* Force recalc of curix & curline */ + ml_upd_lastbuf = NULL; // Force recalc of curix & curline return; } else if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MINL && curix == buf->b_ml.ml_usedchunks - 1 @@ -3937,12 +4009,13 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) return; } dp = hp->bh_data; - if (dp->db_line_count == 1) + if (dp->db_line_count == 1) { rest = dp->db_txt_end - dp->db_txt_start; - else + } else { rest = ((dp->db_index[dp->db_line_count - 2]) & DB_INDEX_MASK) - dp->db_txt_start; + } curchnk->mlcs_totalsize = rest; curchnk->mlcs_numlines = 1; curchnk[-1].mlcs_totalsize -= rest; @@ -3951,7 +4024,7 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) } } else if (updtype == ML_CHNK_DELLINE) { curchnk->mlcs_numlines--; - ml_upd_lastbuf = NULL; /* Force recalc of curix & curline */ + ml_upd_lastbuf = NULL; // Force recalc of curix & curline if (curix < (buf->b_ml.ml_usedchunks - 1) && (curchnk->mlcs_numlines + curchnk[1].mlcs_numlines) <= MLCS_MINL) { @@ -3960,7 +4033,7 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) } else if (curix == 0 && curchnk->mlcs_numlines <= 0) { buf->b_ml.ml_usedchunks--; memmove(buf->b_ml.ml_chunksize, buf->b_ml.ml_chunksize + 1, - buf->b_ml.ml_usedchunks * sizeof(chunksize_T)); + buf->b_ml.ml_usedchunks * sizeof(chunksize_T)); return; } else if (curix == 0 || (curchnk->mlcs_numlines > 10 && (curchnk->mlcs_numlines + @@ -3969,15 +4042,15 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) return; } - /* Collapse chunks */ + // Collapse chunks curchnk[-1].mlcs_numlines += curchnk->mlcs_numlines; curchnk[-1].mlcs_totalsize += curchnk->mlcs_totalsize; buf->b_ml.ml_usedchunks--; if (curix < buf->b_ml.ml_usedchunks) { memmove(buf->b_ml.ml_chunksize + curix, - buf->b_ml.ml_chunksize + curix + 1, - (buf->b_ml.ml_usedchunks - curix) * - sizeof(chunksize_T)); + buf->b_ml.ml_chunksize + curix + 1, + (buf->b_ml.ml_usedchunks - curix) * + sizeof(chunksize_T)); } return; } @@ -4002,9 +4075,9 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff) linenr_T curline; int curix; long size; - bhdr_T *hp; - DATA_BL *dp; - int count; /* number of entries in block */ + bhdr_T *hp; + DATA_BL *dp; + int count; // number of entries in block int idx; int start_idx; int text_end; @@ -4032,15 +4105,18 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff) if (buf->b_ml.ml_usedchunks == -1 || buf->b_ml.ml_chunksize == NULL - || lnum < 0) + || lnum < 0) { return -1; + } - if (offp == NULL) + if (offp == NULL) { offset = 0; - else + } else { offset = *offp; - if (lnum == 0 && offset <= 0) - return 1; /* Not a "find offset" and offset 0 _must_ be in line 1 */ + } + if (lnum == 0 && offset <= 0) { + return 1; // Not a "find offset" and offset 0 _must_ be in line 1 + } /* * Find the last chunk before the one containing our line. Last chunk is * special because it will never qualify @@ -4056,36 +4132,41 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff) + ffdos * buf->b_ml.ml_chunksize[curix].mlcs_numlines))) { curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines; size += buf->b_ml.ml_chunksize[curix].mlcs_totalsize; - if (offset && ffdos) + if (offset && ffdos) { size += buf->b_ml.ml_chunksize[curix].mlcs_numlines; + } curix++; } while ((lnum != 0 && curline < lnum) || (offset != 0 && size < offset)) { if (curline > buf->b_ml.ml_line_count - || (hp = ml_find_line(buf, curline, ML_FIND)) == NULL) + || (hp = ml_find_line(buf, curline, ML_FIND)) == NULL) { return -1; + } dp = hp->bh_data; count = (long)(buf->b_ml.ml_locked_high) - (long)(buf->b_ml.ml_locked_low) + 1; start_idx = idx = curline - buf->b_ml.ml_locked_low; - if (idx == 0) /* first line in block, text at the end */ + if (idx == 0) { // first line in block, text at the end text_end = dp->db_txt_end; - else + } else { text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK); - /* Compute index of last line to use in this MEMLINE */ + } + // Compute index of last line to use in this MEMLINE if (lnum != 0) { - if (curline + (count - idx) >= lnum) + if (curline + (count - idx) >= lnum) { idx += lnum - curline - 1; - else + } else { idx = count - 1; + } } else { extra = 0; while (offset >= size + text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK) + ffdos) { - if (ffdos) + if (ffdos) { size++; + } if (idx == count - 1) { extra = 1; break; @@ -4096,28 +4177,31 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff) len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK); size += len; if (offset != 0 && size >= offset) { - if (size + ffdos == offset) + if (size + ffdos == offset) { *offp = 0; - else if (idx == start_idx) + } else if (idx == start_idx) { *offp = offset - size + len; - else + } else { *offp = offset - size + len - (text_end - ((dp->db_index[idx - 1]) & DB_INDEX_MASK)); + } curline += idx - start_idx + extra; - if (curline > buf->b_ml.ml_line_count) - return -1; /* exactly one byte beyond the end */ + if (curline > buf->b_ml.ml_line_count) { + return -1; // exactly one byte beyond the end + } return curline; } curline = buf->b_ml.ml_locked_high + 1; } if (lnum != 0) { - /* Count extra CR characters. */ - if (ffdos) + // Count extra CR characters. + if (ffdos) { size += lnum - 1; + } - /* Don't count the last line break if 'noeol' and ('bin' or - * 'nofixeol'). */ + // Don't count the last line break if 'noeol' and ('bin' or + // 'nofixeol'). if ((!buf->b_p_fixeol || buf->b_p_bin) && !buf->b_p_eol && lnum > buf->b_ml.ml_line_count) { size -= ffdos + 1; diff --git a/src/nvim/memline.h b/src/nvim/memline.h index a239c6a031..441adf3e87 100644 --- a/src/nvim/memline.h +++ b/src/nvim/memline.h @@ -1,9 +1,9 @@ #ifndef NVIM_MEMLINE_H #define NVIM_MEMLINE_H +#include "nvim/buffer_defs.h" // for buf_T +#include "nvim/pos.h" // for pos_T, linenr_T, colnr_T #include "nvim/types.h" -#include "nvim/pos.h" // for pos_T, linenr_T, colnr_T -#include "nvim/buffer_defs.h" // for buf_T #ifdef INCLUDE_GENERATED_DECLARATIONS # include "memline.h.generated.h" diff --git a/src/nvim/memline_defs.h b/src/nvim/memline_defs.h index dc4755f83d..922a2c98d1 100644 --- a/src/nvim/memline_defs.h +++ b/src/nvim/memline_defs.h @@ -43,9 +43,9 @@ typedef struct ml_chunksize { typedef struct memline { linenr_T ml_line_count; // number of lines in the buffer - memfile_T *ml_mfp; // pointer to associated memfile + memfile_T *ml_mfp; // pointer to associated memfile - infoptr_T *ml_stack; // stack of pointer blocks (array of IPTRs) + infoptr_T *ml_stack; // stack of pointer blocks (array of IPTRs) int ml_stack_top; // current top of ml_stack int ml_stack_size; // total number of entries in ml_stack @@ -56,11 +56,11 @@ typedef struct memline { int ml_flags; linenr_T ml_line_lnum; // line number of cached line, 0 if not valid - char_u *ml_line_ptr; // pointer to cached line + char_u *ml_line_ptr; // pointer to cached line size_t ml_line_offset; // cached byte offset of ml_line_lnum int ml_line_offset_ff; // fileformat of cached line - bhdr_T *ml_locked; // block used by last ml_get + bhdr_T *ml_locked; // block used by last ml_get linenr_T ml_locked_low; // first line in ml_locked linenr_T ml_locked_high; // last line in ml_locked int ml_locked_lineadd; // number of lines inserted in ml_locked diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 7a8fc4da75..5e6c6a8189 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -1,26 +1,26 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com - // Various routines dealing with allocation and deallocation of memory. +// Various routines dealing with allocation and deallocation of memory. #include <assert.h> #include <inttypes.h> -#include <string.h> #include <stdbool.h> +#include <string.h> -#include "nvim/vim.h" +#include "nvim/api/vim.h" #include "nvim/context.h" +#include "nvim/decoration.h" #include "nvim/eval.h" #include "nvim/highlight.h" +#include "nvim/lua/executor.h" #include "nvim/memfile.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/ui.h" #include "nvim/sign.h" -#include "nvim/api/vim.h" -#include "nvim/lua/executor.h" -#include "nvim/decoration.h" +#include "nvim/ui.h" +#include "nvim/vim.h" #ifdef UNIT_TESTING # define malloc(size) mem_malloc(size) @@ -47,8 +47,9 @@ void try_to_free_memory(void) { static bool trying_to_free = false; // avoid recursive calls - if (trying_to_free) + if (trying_to_free) { return; + } trying_to_free = true; // free any scrollback text @@ -169,6 +170,8 @@ void *xrealloc(void *ptr, size_t size) /// xmalloc() wrapper that allocates size + 1 bytes and zeroes the last byte /// +/// Commonly used to allocate strings, e.g. `char *s = xmallocz(len)`. +/// /// @see {xmalloc} /// @param size /// @return pointer to allocated space. Never NULL @@ -182,7 +185,7 @@ void *xmallocz(size_t size) } void *ret = xmalloc(total_size); - ((char*)ret)[size] = 0; + ((char *)ret)[size] = 0; return ret; } @@ -339,16 +342,16 @@ char *xstpcpy(char *restrict dst, const char *restrict src) char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen) FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - const char *p = memchr(src, '\0', maxlen); - if (p) { - size_t srclen = (size_t)(p - src); - memcpy(dst, src, srclen); - memset(dst + srclen, 0, maxlen - srclen); - return dst + srclen; - } else { - memcpy(dst, src, maxlen); - return dst + maxlen; - } + const char *p = memchr(src, '\0', maxlen); + if (p) { + size_t srclen = (size_t)(p - src); + memcpy(dst, src, srclen); + memset(dst + srclen, 0, maxlen - srclen); + return dst + srclen; + } else { + memcpy(dst, src, maxlen); + return dst + maxlen; + } } /// xstrlcpy - Copy a NUL-terminated string into a sized buffer @@ -447,7 +450,7 @@ void *xmemrchr(const void *src, uint8_t c, size_t len) { while (len--) { if (((uint8_t *)src)[len] == c) { - return (uint8_t *) src + len; + return (uint8_t *)src + len; } } return NULL; @@ -500,7 +503,7 @@ bool striequal(const char *a, const char *b) void do_outofmem_msg(size_t size) { if (!did_outofmem_msg) { - /* Don't hide this message */ + // Don't hide this message emsg_silent = 0; /* Must come first to avoid coming back here when printing the error @@ -523,35 +526,35 @@ void time_to_bytes(time_t time_, uint8_t buf[8]) #if defined(EXITFREE) -#include "nvim/file_search.h" -#include "nvim/buffer.h" -#include "nvim/charset.h" -#include "nvim/diff.h" -#include "nvim/edit.h" -#include "nvim/ex_cmds.h" -#include "nvim/ex_docmd.h" -#include "nvim/ex_getln.h" -#include "nvim/fileio.h" -#include "nvim/fold.h" -#include "nvim/getchar.h" -#include "nvim/mark.h" -#include "nvim/mbyte.h" -#include "nvim/memline.h" -#include "nvim/move.h" -#include "nvim/option.h" -#include "nvim/ops.h" -#include "nvim/os_unix.h" -#include "nvim/path.h" -#include "nvim/quickfix.h" -#include "nvim/regexp.h" -#include "nvim/screen.h" -#include "nvim/search.h" -#include "nvim/spell.h" -#include "nvim/syntax.h" -#include "nvim/tag.h" -#include "nvim/window.h" -#include "nvim/os/os.h" -#include "nvim/eval/typval.h" +# include "nvim/buffer.h" +# include "nvim/charset.h" +# include "nvim/diff.h" +# include "nvim/edit.h" +# include "nvim/eval/typval.h" +# include "nvim/ex_cmds.h" +# include "nvim/ex_docmd.h" +# include "nvim/ex_getln.h" +# include "nvim/file_search.h" +# include "nvim/fileio.h" +# include "nvim/fold.h" +# include "nvim/getchar.h" +# include "nvim/mark.h" +# include "nvim/mbyte.h" +# include "nvim/memline.h" +# include "nvim/move.h" +# include "nvim/ops.h" +# include "nvim/option.h" +# include "nvim/os/os.h" +# include "nvim/os_unix.h" +# include "nvim/path.h" +# include "nvim/quickfix.h" +# include "nvim/regexp.h" +# include "nvim/screen.h" +# include "nvim/search.h" +# include "nvim/spell.h" +# include "nvim/syntax.h" +# include "nvim/tag.h" +# include "nvim/window.h" /* * Free everything that we allocated. @@ -562,7 +565,7 @@ void time_to_bytes(time_t time_, uint8_t buf[8]) */ void free_all_mem(void) { - buf_T *buf, *nextbuf; + buf_T *buf, *nextbuf; // When we cause a crash here it is caught and Vim tries to exit cleanly. // Don't try freeing everything again. @@ -574,10 +577,11 @@ void free_all_mem(void) // Don't want to trigger autocommands from here on. block_autocmds(); - /* Close all tabs and windows. Reset 'equalalways' to avoid redraws. */ + // Close all tabs and windows. Reset 'equalalways' to avoid redraws. p_ea = false; - if (first_tabpage->tp_next != NULL) + if (first_tabpage->tp_next != NULL) { do_cmdline_cmd("tabonly!"); + } if (!ONE_WINDOW) { // to keep things simple, don't perform this @@ -586,17 +590,17 @@ void free_all_mem(void) do_cmdline_cmd("only!"); } - /* Free all spell info. */ + // Free all spell info. spell_free_all(); - /* Clear user commands (before deleting buffers). */ + // Clear user commands (before deleting buffers). ex_comclear(NULL); - /* Clear menus. */ + // Clear menus. do_cmdline_cmd("aunmenu *"); do_cmdline_cmd("menutranslate clear"); - /* Clear mappings, abbreviations, breakpoints. */ + // Clear mappings, abbreviations, breakpoints. do_cmdline_cmd("lmapclear"); do_cmdline_cmd("xmapclear"); do_cmdline_cmd("mapclear"); @@ -609,7 +613,7 @@ void free_all_mem(void) free_titles(); free_findfile(); - /* Obviously named calls. */ + // Obviously named calls. free_all_autocmds(); free_all_marks(); alist_clear(&global_alist); @@ -627,25 +631,25 @@ void free_all_mem(void) diff_clear(curtab); clear_sb_text(true); // free any scrollback text - /* Free some global vars. */ + // Free some global vars. xfree(last_cmdline); xfree(new_last_cmdline); set_keep_msg(NULL, 0); - /* Clear cmdline history. */ + // Clear cmdline history. p_hi = 0; init_history(); qf_free_all(NULL); - /* Free all location lists */ + // Free all location lists FOR_ALL_TAB_WINDOWS(tab, win) { qf_free_all(win); } - /* Close all script inputs. */ + // Close all script inputs. close_all_scripts(); - /* Destroy all windows. Must come before freeing buffers. */ + // Destroy all windows. Must come before freeing buffers. win_free_all(); // Free all option values. Must come after closing windows. @@ -653,13 +657,13 @@ void free_all_mem(void) free_arshape_buf(); - /* Clear registers. */ + // Clear registers. clear_registers(); ResetRedobuff(); ResetRedobuff(); - /* highlight info */ + // highlight info free_highlight(); reset_last_sourcing(); @@ -667,10 +671,12 @@ void free_all_mem(void) free_tabpage(first_tabpage); first_tabpage = NULL; - /* message history */ - for (;; ) - if (delete_first_msg() == FAIL) + // message history + for (;; ) { + if (delete_first_msg() == FAIL) { break; + } + } eval_clear(); api_vim_free_all_mem(); diff --git a/src/nvim/memory.h b/src/nvim/memory.h index 5b39d002c9..a4be2643d8 100644 --- a/src/nvim/memory.h +++ b/src/nvim/memory.h @@ -2,8 +2,8 @@ #define NVIM_MEMORY_H #include <stdbool.h> // for bool -#include <stdint.h> // for uint8_t #include <stddef.h> // for size_t +#include <stdint.h> // for uint8_t #include <time.h> // for time_t /// `malloc()` function signature diff --git a/src/nvim/menu.c b/src/nvim/menu.c index 5c07f87bd5..2250002f86 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -10,27 +10,27 @@ #include <inttypes.h> #include <string.h> -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/menu.h" #include "nvim/charset.h" #include "nvim/cursor.h" #include "nvim/eval.h" +#include "nvim/eval/typval.h" #include "nvim/ex_docmd.h" +#include "nvim/garray.h" #include "nvim/getchar.h" +#include "nvim/keymap.h" #include "nvim/memory.h" +#include "nvim/menu.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/keymap.h" -#include "nvim/garray.h" +#include "nvim/screen.h" #include "nvim/state.h" #include "nvim/strings.h" #include "nvim/ui.h" -#include "nvim/eval/typval.h" -#include "nvim/screen.h" +#include "nvim/vim.h" #include "nvim/window.h" -#define MENUDEPTH 10 /* maximum depth of menus */ +#define MENUDEPTH 10 // maximum depth of menus #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -43,8 +43,7 @@ /// The character for each menu mode static char_u menu_mode_chars[] = { 'n', 'v', 's', 'o', 'i', 'c', 't' }; -static char_u e_notsubmenu[] = N_( - "E327: Part of menu-item path is not sub-menu"); +static char_u e_notsubmenu[] = N_("E327: Part of menu-item path is not sub-menu"); static char_u e_othermode[] = N_("E328: Menu only exists in another mode"); static char_u e_nomenu[] = N_("E329: No menu \"%s\""); @@ -63,18 +62,17 @@ static vimmenu_T **get_root_menu(const char_u *const name) /// Do the :menu command and relatives. /// @param eap Ex command arguments -void -ex_menu(exarg_T *eap) +void ex_menu(exarg_T *eap) { - char_u *menu_path; + char *menu_path; int modes; - char_u *map_to; // command mapped to the menu entry + char_u *map_to; // command mapped to the menu entry int noremap; bool silent = false; int unmenu; - char_u *map_buf; - char_u *arg; - char_u *p; + char_u *map_buf; + char_u *arg; + char_u *p; int i; long pri_tab[MENUDEPTH + 1]; TriState enable = kNone; // kTrue for "menu enable", @@ -109,8 +107,9 @@ ex_menu(exarg_T *eap) if (STRNCMP(arg, "icon=", 5) == 0) { arg += 5; while (*arg != NUL && *arg != ' ') { - if (*arg == '\\') + if (*arg == '\\') { STRMOVE(arg, arg + 1); + } MB_PTR_ADV(arg); } if (*arg != NUL) { @@ -139,11 +138,13 @@ ex_menu(exarg_T *eap) } else if (eap->addr_count && eap->line2 != 0) { pri_tab[0] = eap->line2; i = 1; - } else + } else { i = 0; - while (i < MENUDEPTH) + } + while (i < MENUDEPTH) { pri_tab[i++] = 500; - pri_tab[MENUDEPTH] = -1; /* mark end of the table */ + } + pri_tab[MENUDEPTH] = -1; // mark end of the table /* * Check for "disable" or "enable" argument. @@ -165,7 +166,7 @@ ex_menu(exarg_T *eap) } - menu_path = arg; + menu_path = (char *)arg; if (*menu_path == '.') { EMSG2(_(e_invarg2), menu_path); goto theend; @@ -177,59 +178,62 @@ ex_menu(exarg_T *eap) * If there is only a menu name, display menus with that name. */ if (*map_to == NUL && !unmenu && enable == kNone) { - show_menus(menu_path, modes); + show_menus((char_u *)menu_path, modes); goto theend; } else if (*map_to != NUL && (unmenu || enable != kNone)) { EMSG(_(e_trailing)); goto theend; } - vimmenu_T **root_menu_ptr = get_root_menu(menu_path); + vimmenu_T **root_menu_ptr = get_root_menu((char_u *)menu_path); if (enable != kNone) { // Change sensitivity of the menu. // For the PopUp menu, remove a menu for each mode separately. // Careful: menu_enable_recurse() changes menu_path. if (STRCMP(menu_path, "*") == 0) { // meaning: do all menus - menu_path = (char_u *)""; + menu_path = ""; } if (menu_is_popup(menu_path)) { - for (i = 0; i < MENU_INDEX_TIP; ++i) + for (i = 0; i < MENU_INDEX_TIP; i++) { if (modes & (1 << i)) { p = popup_mode_name(menu_path, i); menu_enable_recurse(*root_menu_ptr, p, MENU_ALL_MODES, enable); xfree(p); } + } } - menu_enable_recurse(*root_menu_ptr, menu_path, modes, enable); + menu_enable_recurse(*root_menu_ptr, (char_u *)menu_path, modes, enable); } else if (unmenu) { /* * Delete menu(s). */ - if (STRCMP(menu_path, "*") == 0) /* meaning: remove all menus */ - menu_path = (char_u *)""; + if (STRCMP(menu_path, "*") == 0) { // meaning: remove all menus + menu_path = ""; + } /* * For the PopUp menu, remove a menu for each mode separately. */ if (menu_is_popup(menu_path)) { - for (i = 0; i < MENU_INDEX_TIP; ++i) + for (i = 0; i < MENU_INDEX_TIP; i++) { if (modes & (1 << i)) { p = popup_mode_name(menu_path, i); remove_menu(root_menu_ptr, p, MENU_ALL_MODES, true); xfree(p); } + } } // Careful: remove_menu() changes menu_path - remove_menu(root_menu_ptr, menu_path, modes, false); + remove_menu(root_menu_ptr, (char_u *)menu_path, modes, false); } else { /* * Add menu(s). * Replace special key codes. */ - if (STRICMP(map_to, "<nop>") == 0) { /* "<Nop>" means nothing */ + if (STRICMP(map_to, "<nop>") == 0) { // "<Nop>" means nothing map_to = (char_u *)""; map_buf = NULL; } else if (modes & MENU_TIP_MODE) { @@ -241,13 +245,13 @@ ex_menu(exarg_T *eap) menuarg.modes = modes; menuarg.noremap[0] = noremap; menuarg.silent[0] = silent; - add_menu_path(menu_path, &menuarg, pri_tab, map_to); + add_menu_path((char_u *)menu_path, &menuarg, pri_tab, map_to); /* * For the PopUp menu, add a menu for each mode separately. */ if (menu_is_popup(menu_path)) { - for (i = 0; i < MENU_INDEX_TIP; ++i) + for (i = 0; i < MENU_INDEX_TIP; i++) { if (modes & (1 << i)) { p = popup_mode_name(menu_path, i); // Include all modes, to make ":amenu" work @@ -255,6 +259,7 @@ ex_menu(exarg_T *eap) add_menu_path(p, &menuarg, pri_tab, map_to); xfree(p); } + } } xfree(map_buf); @@ -272,33 +277,28 @@ theend: /// @param[out] menuarg menu entry /// @param[] pri_tab priority table /// @param[in] call_data Right hand side command -static int -add_menu_path( - const char_u *const menu_path, - vimmenu_T *menuarg, - const long *const pri_tab, - const char_u *const call_data -) +static int add_menu_path(const char_u *const menu_path, vimmenu_T *menuarg, + const long *const pri_tab, const char_u *const call_data) { - char_u *path_name; + char_u *path_name; int modes = menuarg->modes; - vimmenu_T *menu = NULL; - vimmenu_T *parent; - vimmenu_T **lower_pri; - char_u *p; - char_u *name; - char_u *dname; - char_u *next_name; + vimmenu_T *menu = NULL; + vimmenu_T *parent; + vimmenu_T **lower_pri; + char_u *p; + char_u *name; + char_u *dname; + char_u *next_name; char_u c; char_u d; int i; int pri_idx = 0; int old_modes = 0; int amenu; - char_u *en_name; - char_u *map_to = NULL; + char_u *en_name; + char_u *map_to = NULL; - /* Make a copy so we can stuff around with it, since it could be const */ + // Make a copy so we can stuff around with it, since it could be const path_name = vim_strsave(menu_path); vimmenu_T **root_menu_ptr = get_root_menu(menu_path); vimmenu_T **menup = root_menu_ptr; @@ -317,12 +317,12 @@ add_menu_path( } dname = menu_text(name, NULL, NULL); if (*dname == NUL) { - /* Only a mnemonic or accelerator is not valid. */ + // Only a mnemonic or accelerator is not valid. EMSG(_("E792: Empty menu name")); goto erret; } - /* See if it's already there */ + // See if it's already there lower_pri = menup; menu = *menup; while (menu != NULL) { @@ -343,8 +343,8 @@ add_menu_path( } menup = &menu->next; - /* Count menus, to find where this one needs to be inserted. - * Ignore menus that are not in the menubar (PopUp and Toolbar) */ + // Count menus, to find where this one needs to be inserted. + // Ignore menus that are not in the menubar (PopUp and Toolbar) if (parent != NULL || menu_is_menubar(menu->name)) { if (menu->priority <= pri_tab[pri_idx]) { lower_pri = menup; @@ -364,7 +364,7 @@ add_menu_path( goto erret; } - /* Not already there, so lets add it */ + // Not already there, so lets add it menu = xcalloc(1, sizeof(vimmenu_T)); menu->modes = modes; @@ -387,7 +387,6 @@ add_menu_path( *lower_pri = menu; old_modes = 0; - } else { old_modes = menu->modes; @@ -419,16 +418,17 @@ add_menu_path( */ amenu = ((modes & (MENU_NORMAL_MODE | MENU_INSERT_MODE)) == (MENU_NORMAL_MODE | MENU_INSERT_MODE)); - if (sys_menu) + if (sys_menu) { modes &= ~old_modes; + } if (menu != NULL && modes) { p = (call_data == NULL) ? NULL : vim_strsave(call_data); - /* loop over all modes, may add more than one */ + // loop over all modes, may add more than one for (i = 0; i < MENU_MODES; ++i) { if (modes & (1 << i)) { - /* free any old menu */ + // free any old menu free_menu_string(menu, i); // For "amenu", may insert an extra character. @@ -462,7 +462,7 @@ add_menu_path( if (c == Ctrl_C) { int len = (int)STRLEN(menu->strings[i]); - /* Append CTRL-\ CTRL-G to obey 'insertmode'. */ + // Append CTRL-\ CTRL-G to obey 'insertmode'. menu->strings[i][len] = Ctrl_BSL; menu->strings[i][len + 1] = Ctrl_G; menu->strings[i][len + 2] = NUL; @@ -504,20 +504,17 @@ erret: * Set the (sub)menu with the given name to enabled or disabled. * Called recursively. */ -static int menu_enable_recurse(vimmenu_T *menu, - char_u *name, - int modes, - int enable) +static int menu_enable_recurse(vimmenu_T *menu, char_u *name, int modes, int enable) { - char_u *p; - - if (menu == NULL) - return OK; /* Got to bottom of hierarchy */ + char_u *p; - /* Get name of this element in the menu hierarchy */ + if (menu == NULL) { + return OK; // Got to bottom of hierarchy + } + // Get name of this element in the menu hierarchy p = menu_name_skip(name); - /* Find the menu */ + // Find the menu while (menu != NULL) { if (*name == NUL || *name == '*' || menu_name_equal(name, menu)) { if (*p != NUL) { @@ -539,8 +536,9 @@ static int menu_enable_recurse(vimmenu_T *menu, * modes, so keep looping, otherwise we are just doing the named * menu item (which has been found) so break here. */ - if (*name != NUL && *name != '*') + if (*name != NUL && *name != '*') { break; + } } menu = menu->next; } @@ -553,42 +551,39 @@ static int menu_enable_recurse(vimmenu_T *menu, return OK; } -/* - * Remove the (sub)menu with the given name from the menu hierarchy - * Called recursively. - */ -static int -remove_menu ( - vimmenu_T **menup, - char_u *name, - int modes, - bool silent /* don't give error messages */ -) +/// Remove the (sub)menu with the given name from the menu hierarchy +/// Called recursively. +/// +/// @param silent don't give error messages +static int remove_menu(vimmenu_T **menup, char_u *name, int modes, bool silent) { - vimmenu_T *menu; - vimmenu_T *child; - char_u *p; - - if (*menup == NULL) - return OK; /* Got to bottom of hierarchy */ + vimmenu_T *menu; + vimmenu_T *child; + char_u *p; - /* Get name of this element in the menu hierarchy */ + if (*menup == NULL) { + return OK; // Got to bottom of hierarchy + } + // Get name of this element in the menu hierarchy p = menu_name_skip(name); - /* Find the menu */ + // Find the menu while ((menu = *menup) != NULL) { if (*name == NUL || menu_name_equal(name, menu)) { if (*p != NUL && menu->children == NULL) { - if (!silent) + if (!silent) { EMSG(_(e_notsubmenu)); + } return FAIL; } if ((menu->modes & modes) != 0x0) { - if (remove_menu(&menu->children, p, modes, silent) == FAIL) + if (remove_menu(&menu->children, p, modes, silent) == FAIL) { return FAIL; + } } else if (*name != NUL) { - if (!silent) + if (!silent) { EMSG(_(e_othermode)); + } return FAIL; } @@ -597,39 +592,45 @@ remove_menu ( * modes, so keep looping, otherwise we are just removing the named * menu item (which has been found) so break here. */ - if (*name != NUL) + if (*name != NUL) { break; + } - /* Remove the menu item for the given mode[s]. If the menu item - * is no longer valid in ANY mode, delete it */ + // Remove the menu item for the given mode[s]. If the menu item + // is no longer valid in ANY mode, delete it menu->modes &= ~modes; - if (modes & MENU_TIP_MODE) + if (modes & MENU_TIP_MODE) { free_menu_string(menu, MENU_INDEX_TIP); - if ((menu->modes & MENU_ALL_MODES) == 0) + } + if ((menu->modes & MENU_ALL_MODES) == 0) { free_menu(menup); - else + } else { menup = &menu->next; - } else + } + } else { menup = &menu->next; + } } if (*name != NUL) { if (menu == NULL) { - if (!silent) + if (!silent) { EMSG2(_(e_nomenu), name); + } return FAIL; } - /* Recalculate modes for menu based on the new updated children */ + // Recalculate modes for menu based on the new updated children menu->modes &= ~modes; child = menu->children; - for (; child != NULL; child = child->next) + for (; child != NULL; child = child->next) { menu->modes |= child->modes; + } if (modes & MENU_TIP_MODE) { free_menu_string(menu, MENU_INDEX_TIP); } if ((menu->modes & MENU_ALL_MODES) == 0) { - /* The menu item is no longer valid in ANY mode, so delete it */ + // The menu item is no longer valid in ANY mode, so delete it *menup = menu; free_menu(menup); } @@ -644,7 +645,7 @@ remove_menu ( static void free_menu(vimmenu_T **menup) { int i; - vimmenu_T *menu; + vimmenu_T *menu; menu = *menup; @@ -657,10 +658,10 @@ static void free_menu(vimmenu_T **menup) xfree(menu->en_name); xfree(menu->en_dname); xfree(menu->actext); - for (i = 0; i < MENU_MODES; i++) + for (i = 0; i < MENU_MODES; i++) { free_menu_string(menu, i); + } xfree(menu); - } /* @@ -671,11 +672,14 @@ static void free_menu_string(vimmenu_T *menu, int idx) int count = 0; int i; - for (i = 0; i < MENU_MODES; i++) - if (menu->strings[i] == menu->strings[idx]) + for (i = 0; i < MENU_MODES; i++) { + if (menu->strings[i] == menu->strings[idx]) { count++; - if (count == 1) + } + } + if (count == 1) { xfree(menu->strings[idx]); + } menu->strings[idx] = NULL; } @@ -793,8 +797,8 @@ static vimmenu_T *find_menu(vimmenu_T *menu, char_u *name, int modes) if (menu_name_equal(name, menu)) { // Found menu if (*p != NUL && menu->children == NULL) { - EMSG(_(e_notsubmenu)); - return NULL; + EMSG(_(e_notsubmenu)); + return NULL; } else if ((menu->modes & modes) == 0x0) { EMSG(_(e_othermode)); return NULL; @@ -826,8 +830,8 @@ static int show_menus(char_u *const path_name, int modes) return FAIL; } - /* Now we have found the matching menu, and we list the mappings */ - /* Highlight title */ + // Now we have found the matching menu, and we list the mappings + // Highlight title MSG_PUTS_TITLE(_("\n--- Menus ---")); show_menus_recursive(menu->parent, modes, 0); @@ -840,17 +844,20 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth) int i; int bit; - if (menu != NULL && (menu->modes & modes) == 0x0) + if (menu != NULL && (menu->modes & modes) == 0x0) { return; + } if (menu != NULL) { msg_putchar('\n'); - if (got_int) /* "q" hit for "--more--" */ + if (got_int) { // "q" hit for "--more--" return; - for (i = 0; i < depth; i++) + } + for (i = 0; i < depth; i++) { MSG_PUTS(" "); + } if (menu->priority) { - msg_outnum((long)menu->priority); + msg_outnum(menu->priority); MSG_PUTS(" "); } // Same highlighting as for directories!? @@ -858,28 +865,33 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth) } if (menu != NULL && menu->children == NULL) { - for (bit = 0; bit < MENU_MODES; bit++) + for (bit = 0; bit < MENU_MODES; bit++) { if ((menu->modes & modes & (1 << bit)) != 0) { msg_putchar('\n'); - if (got_int) /* "q" hit for "--more--" */ + if (got_int) { // "q" hit for "--more--" return; - for (i = 0; i < depth + 2; i++) + } + for (i = 0; i < depth + 2; i++) { MSG_PUTS(" "); + } msg_putchar(menu_mode_chars[bit]); - if (menu->noremap[bit] == REMAP_NONE) + if (menu->noremap[bit] == REMAP_NONE) { msg_putchar('*'); - else if (menu->noremap[bit] == REMAP_SCRIPT) + } else if (menu->noremap[bit] == REMAP_SCRIPT) { msg_putchar('&'); - else + } else { msg_putchar(' '); - if (menu->silent[bit]) + } + if (menu->silent[bit]) { msg_putchar('s'); - else + } else { msg_putchar(' '); - if ((menu->modes & menu->enabled & (1 << bit)) == 0) + } + if ((menu->modes & menu->enabled & (1 << bit)) == 0) { msg_putchar('-'); - else + } else { msg_putchar(' '); + } MSG_PUTS(" "); if (*menu->strings[bit] == NUL) { msg_puts_attr("<Nop>", HL_ATTR(HLF_8)); @@ -887,17 +899,21 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth) msg_outtrans_special(menu->strings[bit], false, 0); } } + } } else { if (menu == NULL) { menu = root_menu; depth--; - } else + } else { menu = menu->children; + } - /* recursively show all children. Skip PopUp[nvoci]. */ - for (; menu != NULL && !got_int; menu = menu->next) - if (!menu_is_hidden(menu->dname)) + // recursively show all children. Skip PopUp[nvoci]. + for (; menu != NULL && !got_int; menu = menu->next) { + if (!menu_is_hidden(menu->dname)) { show_menus_recursive(menu, modes, depth + 1); + } + } } } @@ -905,54 +921,58 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth) /* * Used when expanding menu names. */ -static vimmenu_T *expand_menu = NULL; +static vimmenu_T *expand_menu = NULL; static int expand_modes = 0x0; -static int expand_emenu; /* TRUE for ":emenu" command */ +static int expand_emenu; // TRUE for ":emenu" command /* * Work out what to complete when doing command line completion of menu names. */ -char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg, - bool forceit) +char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg, bool forceit) FUNC_ATTR_NONNULL_ALL { - char_u *after_dot; - char_u *p; - char_u *path_name = NULL; - char_u *name; + char_u *after_dot; + char_u *p; + char_u *path_name = NULL; + char_u *name; int unmenu; - vimmenu_T *menu; + vimmenu_T *menu; int expand_menus; xp->xp_context = EXPAND_UNSUCCESSFUL; - /* Check for priority numbers, enable and disable */ - for (p = arg; *p; ++p) - if (!ascii_isdigit(*p) && *p != '.') + // Check for priority numbers, enable and disable + for (p = arg; *p; ++p) { + if (!ascii_isdigit(*p) && *p != '.') { break; + } + } if (!ascii_iswhite(*p)) { if (STRNCMP(arg, "enable", 6) == 0 - && (arg[6] == NUL || ascii_iswhite(arg[6]))) + && (arg[6] == NUL || ascii_iswhite(arg[6]))) { p = arg + 6; - else if (STRNCMP(arg, "disable", 7) == 0 - && (arg[7] == NUL || ascii_iswhite(arg[7]))) + } else if (STRNCMP(arg, "disable", 7) == 0 + && (arg[7] == NUL || ascii_iswhite(arg[7]))) { p = arg + 7; - else + } else { p = arg; + } } - while (*p != NUL && ascii_iswhite(*p)) + while (*p != NUL && ascii_iswhite(*p)) { ++p; + } arg = after_dot = p; for (; *p && !ascii_iswhite(*p); ++p) { - if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL) + if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL) { p++; - else if (*p == '.') + } else if (*p == '.') { after_dot = p + 1; + } } // ":popup" only uses menus, not entries @@ -966,12 +986,13 @@ char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg, // With :menu though you might want to add a menu with the same name as // one in another mode, so match menus from other modes too. expand_modes = get_menu_cmd_modes(cmd, forceit, NULL, &unmenu); - if (!unmenu) + if (!unmenu) { expand_modes = MENU_ALL_MODES; + } menu = root_menu; if (after_dot > arg) { - size_t path_len = (size_t) (after_dot - arg); + size_t path_len = (size_t)(after_dot - arg); path_name = xmalloc(path_len); STRLCPY(path_name, arg, path_len); } @@ -980,7 +1001,7 @@ char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg, p = menu_name_skip(name); while (menu != NULL) { if (menu_name_equal(name, menu)) { - /* Found menu */ + // Found menu if ((*p != NUL && menu->children == NULL) || ((menu->modes & expand_modes) == 0x0)) { /* @@ -995,7 +1016,7 @@ char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg, menu = menu->next; } if (menu == NULL) { - /* No menu found with the name we were looking for */ + // No menu found with the name we were looking for xfree(path_name); return NULL; } @@ -1019,35 +1040,38 @@ char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg, */ char_u *get_menu_name(expand_T *xp, int idx) { - static vimmenu_T *menu = NULL; - char_u *str; + static vimmenu_T *menu = NULL; + char_u *str; static int should_advance = FALSE; - if (idx == 0) { /* first call: start at first item */ + if (idx == 0) { // first call: start at first item menu = expand_menu; should_advance = false; } - /* Skip PopUp[nvoci]. */ + // Skip PopUp[nvoci]. while (menu != NULL && (menu_is_hidden(menu->dname) || menu_is_separator(menu->dname) || menu->children == NULL)) { menu = menu->next; } - if (menu == NULL) /* at end of linked list */ + if (menu == NULL) { // at end of linked list return NULL; + } - if (menu->modes & expand_modes) - if (should_advance) + if (menu->modes & expand_modes) { + if (should_advance) { str = menu->en_dname; - else { + } else { str = menu->dname; - if (menu->en_dname == NULL) + if (menu->en_dname == NULL) { should_advance = TRUE; + } } - else + } else { str = (char_u *)""; + } if (should_advance) { // Advance to next menu entry. @@ -1065,18 +1089,18 @@ char_u *get_menu_name(expand_T *xp, int idx) */ char_u *get_menu_names(expand_T *xp, int idx) { - static vimmenu_T *menu = NULL; + static vimmenu_T *menu = NULL; #define TBUFFER_LEN 256 - static char_u tbuffer[TBUFFER_LEN]; /*hack*/ - char_u *str; + static char_u tbuffer[TBUFFER_LEN]; //hack + char_u *str; static bool should_advance = false; - if (idx == 0) { /* first call: start at first item */ + if (idx == 0) { // first call: start at first item menu = expand_menu; should_advance = false; } - /* Skip Browse-style entries, popup menus and separators. */ + // Skip Browse-style entries, popup menus and separators. while (menu != NULL && (menu_is_hidden(menu->dname) || (expand_emenu && menu_is_separator(menu->dname)) @@ -1084,8 +1108,9 @@ char_u *get_menu_names(expand_T *xp, int idx) menu = menu->next; } - if (menu == NULL) /* at end of linked list */ + if (menu == NULL) { // at end of linked list return NULL; + } if (menu->modes & expand_modes) { if (menu->children != NULL) { @@ -1102,17 +1127,18 @@ char_u *get_menu_names(expand_T *xp, int idx) STRCAT(tbuffer, "\001"); str = tbuffer; } else { - if (should_advance) + if (should_advance) { str = menu->en_dname; - else { + } else { str = menu->dname; if (menu->en_dname == NULL) { should_advance = true; } } } - } else + } else { str = (char_u *)""; + } if (should_advance) { // Advance to next menu entry. @@ -1132,17 +1158,19 @@ char_u *get_menu_names(expand_T *xp, int idx) /// @return start of the next element char_u *menu_name_skip(char_u *const name) { - char_u *p; + char_u *p; for (p = name; *p && *p != '.'; MB_PTR_ADV(p)) { if (*p == '\\' || *p == Ctrl_V) { STRMOVE(p, p + 1); - if (*p == NUL) + if (*p == NUL) { break; + } } } - if (*p) + if (*p) { *p++ = NUL; + } return p; } @@ -1154,8 +1182,9 @@ static bool menu_name_equal(const char_u *const name, vimmenu_T *const menu) { if (menu->en_name != NULL && (menu_namecmp(name, menu->en_name) - || menu_namecmp(name, menu->en_dname))) + || menu_namecmp(name, menu->en_dname))) { return true; + } return menu_namecmp(name, menu->name) || menu_namecmp(name, menu->dname); } @@ -1163,9 +1192,11 @@ static bool menu_namecmp(const char_u *const name, const char_u *const mname) { int i; - for (i = 0; name[i] != NUL && name[i] != TAB; ++i) - if (name[i] != mname[i]) + for (i = 0; name[i] != NUL && name[i] != TAB; ++i) { + if (name[i] != mname[i]) { break; + } + } return (name[i] == NUL || name[i] == TAB) && (mname[i] == NUL || mname[i] == TAB); } @@ -1180,45 +1211,39 @@ static bool menu_namecmp(const char_u *const name, const char_u *const mname) /// to whether the command is a "nore" command. /// @param[out] unmenu If not NULL, the flag it points to is set according /// to whether the command is an "unmenu" command. -int -get_menu_cmd_modes( - const char *cmd, - bool forceit, - int *noremap, - int *unmenu -) +int get_menu_cmd_modes(const char *cmd, bool forceit, int *noremap, int *unmenu) { int modes; switch (*cmd++) { - case 'v': /* vmenu, vunmenu, vnoremenu */ + case 'v': // vmenu, vunmenu, vnoremenu modes = MENU_VISUAL_MODE | MENU_SELECT_MODE; break; - case 'x': /* xmenu, xunmenu, xnoremenu */ + case 'x': // xmenu, xunmenu, xnoremenu modes = MENU_VISUAL_MODE; break; - case 's': /* smenu, sunmenu, snoremenu */ + case 's': // smenu, sunmenu, snoremenu modes = MENU_SELECT_MODE; break; - case 'o': /* omenu */ + case 'o': // omenu modes = MENU_OP_PENDING_MODE; break; - case 'i': /* imenu */ + case 'i': // imenu modes = MENU_INSERT_MODE; break; case 't': - modes = MENU_TIP_MODE; /* tmenu */ + modes = MENU_TIP_MODE; // tmenu break; - case 'c': /* cmenu */ + case 'c': // cmenu modes = MENU_CMDLINE_MODE; break; - case 'a': /* amenu */ + case 'a': // amenu modes = MENU_INSERT_MODE | MENU_CMDLINE_MODE | MENU_NORMAL_MODE | MENU_VISUAL_MODE | MENU_SELECT_MODE | MENU_OP_PENDING_MODE; break; case 'n': - if (*cmd != 'o') { /* nmenu, not noremenu */ + if (*cmd != 'o') { // nmenu, not noremenu modes = MENU_NORMAL_MODE; break; } @@ -1235,10 +1260,12 @@ get_menu_cmd_modes( } } - if (noremap != NULL) + if (noremap != NULL) { *noremap = (*cmd == 'n' ? REMAP_NONE : REMAP_YES); - if (unmenu != NULL) + } + if (unmenu != NULL) { *unmenu = (*cmd == 'u'); + } return modes; } @@ -1246,12 +1273,12 @@ get_menu_cmd_modes( * Modify a menu name starting with "PopUp" to include the mode character. * Returns the name in allocated memory. */ -static char_u *popup_mode_name(char_u *name, int idx) +static char_u *popup_mode_name(char *name, int idx) { size_t len = STRLEN(name); assert(len >= 4); - char_u *p = vim_strnsave(name, len + 1); + char_u *p = vim_strnsave((char_u *)name, len + 1); memmove(p + 6, p + 5, len - 4); p[5] = menu_mode_chars[idx]; @@ -1274,27 +1301,31 @@ static char_u *menu_text(const char_u *str, int *mnemonic, char_u **actext) FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1) { - char_u *p; - char_u *text; + char_u *p; + char_u *text; - /* Locate accelerator text, after the first TAB */ + // Locate accelerator text, after the first TAB p = vim_strchr(str, TAB); if (p != NULL) { - if (actext != NULL) + if (actext != NULL) { *actext = vim_strsave(p + 1); + } assert(p >= str); text = vim_strnsave(str, (size_t)(p - str)); - } else + } else { text = vim_strsave(str); + } - /* Find mnemonic characters "&a" and reduce "&&" to "&". */ + // Find mnemonic characters "&a" and reduce "&&" to "&". for (p = text; p != NULL; ) { p = vim_strchr(p, '&'); if (p != NULL) { - if (p[1] == NUL) /* trailing "&" */ + if (p[1] == NUL) { // trailing "&" break; - if (mnemonic != NULL && p[1] != '&') + } + if (mnemonic != NULL && p[1] != '&') { *mnemonic = p[1]; + } STRMOVE(p, p + 1); p = p + 1; } @@ -1306,14 +1337,14 @@ static char_u *menu_text(const char_u *str, int *mnemonic, char_u **actext) bool menu_is_menubar(const char_u *const name) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - return !menu_is_popup(name) + return !menu_is_popup((char *)name) && !menu_is_toolbar(name) && !menu_is_winbar(name) && *name != MNU_HIDDEN_CHAR; } // Return true if "name" is a popup menu name. -bool menu_is_popup(const char_u *const name) +bool menu_is_popup(const char *const name) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { return STRNCMP(name, "PopUp", 5) == 0; @@ -1343,7 +1374,7 @@ int menu_is_separator(char_u *name) static int menu_is_hidden(char_u *name) { return (name[0] == MNU_HIDDEN_CHAR) - || (menu_is_popup(name) && name[5] != NUL); + || (menu_is_popup((char *)name) && name[5] != NUL); } // Execute "menu". Use by ":emenu" and the window toolbar. @@ -1352,25 +1383,25 @@ static void execute_menu(const exarg_T *eap, vimmenu_T *menu) FUNC_ATTR_NONNULL_ARG(2) { int idx = -1; - char_u *mode; + char *mode; // Use the Insert mode entry when returning to Insert mode. if (((State & INSERT) || restart_edit) && !current_sctx.sc_sid) { - mode = (char_u *)"Insert"; + mode = "Insert"; idx = MENU_INDEX_INSERT; } else if (State & CMDLINE) { - mode = (char_u *)"Command"; - idx = MENU_INDEX_CMDLINE; + mode = "Command"; + idx = MENU_INDEX_CMDLINE; } else if (get_real_state() & VISUAL) { /* Detect real visual mode -- if we are really in visual mode we * don't need to do any guesswork to figure out what the selection * is. Just execute the visual binding for the menu. */ - mode = (char_u *)"Visual"; + mode = "Visual"; idx = MENU_INDEX_VISUAL; } else if (eap != NULL && eap->addr_count) { pos_T tpos; - mode = (char_u *)"Visual"; + mode = "Visual"; idx = MENU_INDEX_VISUAL; /* GEDDES: This is not perfect - but it is a @@ -1379,13 +1410,13 @@ static void execute_menu(const exarg_T *eap, vimmenu_T *menu) * select start and end. */ if ((curbuf->b_visual.vi_start.lnum == eap->line1) && (curbuf->b_visual.vi_end.lnum) == eap->line2) { - /* Set it up for visual mode - equivalent to gv. */ + // Set it up for visual mode - equivalent to gv. VIsual_mode = curbuf->b_visual.vi_mode; tpos = curbuf->b_visual.vi_end; curwin->w_cursor = curbuf->b_visual.vi_start; curwin->w_curswant = curbuf->b_visual.vi_curswant; } else { - /* Set it up for line-wise visual mode */ + // Set it up for line-wise visual mode VIsual_mode = 'V'; curwin->w_cursor.lnum = eap->line1; curwin->w_cursor.col = 1; @@ -1394,7 +1425,7 @@ static void execute_menu(const exarg_T *eap, vimmenu_T *menu) tpos.coladd = 0; } - /* Activate visual mode */ + // Activate visual mode VIsual_active = TRUE; VIsual_reselect = TRUE; check_cursor(); @@ -1411,7 +1442,7 @@ static void execute_menu(const exarg_T *eap, vimmenu_T *menu) } if (idx == -1 || eap == NULL) { - mode = (char_u *)"Normal"; + mode = "Normal"; idx = MENU_INDEX_NORMAL; } @@ -1484,15 +1515,15 @@ void ex_emenu(exarg_T *eap) */ typedef struct { - char_u *from; /* English name */ - char_u *from_noamp; /* same, without '&' */ - char_u *to; /* translated name */ + char_u *from; // English name + char_u *from_noamp; // same, without '&' + char_u *to; // translated name } menutrans_T; static garray_T menutrans_ga = GA_EMPTY_INIT_VALUE; #define FREE_MENUTRANS(mt) \ - menutrans_T* _mt = (mt); \ + menutrans_T *_mt = (mt); \ xfree(_mt->from); \ xfree(_mt->from_noamp); \ xfree(_mt->to) @@ -1504,11 +1535,12 @@ static garray_T menutrans_ga = GA_EMPTY_INIT_VALUE; */ void ex_menutranslate(exarg_T *eap) { - char_u *arg = eap->arg; - char_u *from, *from_noamp, *to; + char_u *arg = eap->arg; + char_u *from, *from_noamp, *to; - if (menutrans_ga.ga_itemsize == 0) + if (menutrans_ga.ga_itemsize == 0) { ga_init(&menutrans_ga, (int)sizeof(menutrans_T), 5); + } /* * ":menutrans clear": clear all translations. @@ -1516,18 +1548,18 @@ void ex_menutranslate(exarg_T *eap) if (STRNCMP(arg, "clear", 5) == 0 && ends_excmd(*skipwhite(arg + 5))) { GA_DEEP_CLEAR(&menutrans_ga, menutrans_T, FREE_MENUTRANS); - /* Delete all "menutrans_" global variables. */ + // Delete all "menutrans_" global variables. del_menutrans_vars(); } else { - /* ":menutrans from to": add translation */ + // ":menutrans from to": add translation from = arg; arg = menu_skip_part(arg); to = skipwhite(arg); *arg = NUL; arg = menu_skip_part(to); - if (arg == to) + if (arg == to) { EMSG(_(e_invarg)); - else { + } else { from = vim_strsave(from); from_noamp = menu_text(from, NULL, NULL); assert(arg >= to); @@ -1536,7 +1568,7 @@ void ex_menutranslate(exarg_T *eap) menu_translate_tab_and_shift(to); menu_unescape_name(from); menu_unescape_name(to); - menutrans_T* tp = GA_APPEND_VIA_PTR(menutrans_T, &menutrans_ga); + menutrans_T *tp = GA_APPEND_VIA_PTR(menutrans_T, &menutrans_ga); tp->from = from; tp->from_noamp = from_noamp; tp->to = to; @@ -1550,8 +1582,9 @@ void ex_menutranslate(exarg_T *eap) static char_u *menu_skip_part(char_u *p) { while (*p != NUL && *p != '.' && !ascii_iswhite(*p)) { - if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL) + if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL) { ++p; + } ++p; } return p; @@ -1563,8 +1596,8 @@ static char_u *menu_skip_part(char_u *p) */ static char_u *menutrans_lookup(char_u *name, int len) { - menutrans_T *tp = (menutrans_T *)menutrans_ga.ga_data; - char_u *dname; + menutrans_T *tp = (menutrans_T *)menutrans_ga.ga_data; + char_u *dname; for (int i = 0; i < menutrans_ga.ga_len; i++) { if (STRNICMP(name, tp[i].from, len) == 0 && tp[i].from[len] == NUL) { @@ -1572,7 +1605,7 @@ static char_u *menutrans_lookup(char_u *name, int len) } } - /* Now try again while ignoring '&' characters. */ + // Now try again while ignoring '&' characters. char_u c = name[len]; name[len] = NUL; dname = menu_text(name, NULL, NULL); @@ -1593,7 +1626,7 @@ static char_u *menutrans_lookup(char_u *name, int len) */ static void menu_unescape_name(char_u *name) { - char_u *p; + char_u *p; for (p = name; *p && *p != '.'; MB_PTR_ADV(p)) { if (*p == '\\') { @@ -1608,19 +1641,20 @@ static void menu_unescape_name(char_u *name) */ static char_u *menu_translate_tab_and_shift(char_u *arg_start) { - char_u *arg = arg_start; + char_u *arg = arg_start; while (*arg && !ascii_iswhite(*arg)) { - if ((*arg == '\\' || *arg == Ctrl_V) && arg[1] != NUL) + if ((*arg == '\\' || *arg == Ctrl_V) && arg[1] != NUL) { arg++; - else if (STRNICMP(arg, "<TAB>", 5) == 0) { + } else if (STRNICMP(arg, "<TAB>", 5) == 0) { *arg = TAB; STRMOVE(arg + 1, arg + 5); } arg++; } - if (*arg != NUL) + if (*arg != NUL) { *arg++ = NUL; + } arg = skipwhite(arg); return arg; diff --git a/src/nvim/menu.h b/src/nvim/menu.h index 642d9aafac..5c65918d79 100644 --- a/src/nvim/menu.h +++ b/src/nvim/menu.h @@ -1,10 +1,10 @@ #ifndef NVIM_MENU_H #define NVIM_MENU_H -#include <stdbool.h> // for bool +#include <stdbool.h> // for bool -#include "nvim/types.h" // for char_u and expand_T -#include "nvim/ex_cmds_defs.h" // for exarg_T +#include "nvim/ex_cmds_defs.h" // for exarg_T +#include "nvim/types.h" // for char_u and expand_T /// @} /// note MENU_INDEX_TIP is not a 'real' mode diff --git a/src/nvim/message.c b/src/nvim/message.c index f9ed9f3004..279f84f3d4 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -7,42 +7,42 @@ #include <assert.h> #include <inttypes.h> -#include <stdbool.h> #include <stdarg.h> +#include <stdbool.h> #include <string.h> -#include "nvim/vim.h" +#include "nvim/api/private/helpers.h" #include "nvim/ascii.h" #include "nvim/assert.h" -#include "nvim/message.h" #include "nvim/charset.h" #include "nvim/eval.h" -#include "nvim/ex_eval.h" #include "nvim/ex_docmd.h" +#include "nvim/ex_eval.h" #include "nvim/fileio.h" #include "nvim/func_attr.h" +#include "nvim/garray.h" #include "nvim/getchar.h" +#include "nvim/highlight.h" +#include "nvim/keymap.h" #include "nvim/main.h" #include "nvim/mbyte.h" #include "nvim/memory.h" +#include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/keymap.h" -#include "nvim/garray.h" +#include "nvim/mouse.h" +#include "nvim/normal.h" #include "nvim/ops.h" #include "nvim/option.h" -#include "nvim/normal.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" +#include "nvim/os/time.h" #include "nvim/regexp.h" #include "nvim/screen.h" #include "nvim/strings.h" #include "nvim/syntax.h" -#include "nvim/highlight.h" #include "nvim/ui.h" #include "nvim/ui_compositor.h" -#include "nvim/mouse.h" -#include "nvim/os/os.h" -#include "nvim/os/input.h" -#include "nvim/os/time.h" -#include "nvim/api/private/helpers.h" +#include "nvim/vim.h" /* * To be able to scroll back at the "more" and "hit-enter" prompts we need to @@ -50,24 +50,24 @@ */ typedef struct msgchunk_S msgchunk_T; struct msgchunk_S { - msgchunk_T *sb_next; - msgchunk_T *sb_prev; - char sb_eol; /* TRUE when line ends after this text */ - int sb_msg_col; /* column in which text starts */ - int sb_attr; /* text attributes */ - char_u sb_text[1]; /* text to be displayed, actually longer */ + msgchunk_T *sb_next; + msgchunk_T *sb_prev; + char sb_eol; // TRUE when line ends after this text + int sb_msg_col; // column in which text starts + int sb_attr; // text attributes + char_u sb_text[1]; // text to be displayed, actually longer }; -/* Magic chars used in confirm dialog strings */ +// Magic chars used in confirm dialog strings #define DLG_BUTTON_SEP '\n' #define DLG_HOTKEY_CHAR '&' -static int confirm_msg_used = FALSE; /* displaying confirm_msg */ +static int confirm_msg_used = FALSE; // displaying confirm_msg #ifdef INCLUDE_GENERATED_DECLARATIONS # include "message.c.generated.h" #endif -static char_u *confirm_msg = NULL; /* ":confirm" message */ -static char_u *confirm_msg_tail; /* tail of confirm_msg */ +static char_u *confirm_msg = NULL; // ":confirm" message +static char_u *confirm_msg_tail; // tail of confirm_msg MessageHistoryEntry *first_msg_hist = NULL; MessageHistoryEntry *last_msg_hist = NULL; @@ -79,37 +79,37 @@ static int verbose_did_open = FALSE; /* * When writing messages to the screen, there are many different situations. * A number of variables is used to remember the current state: - * msg_didany true when messages were written since the last time the - * user reacted to a prompt. - * Reset: After hitting a key for the hit-return prompt, - * hitting <CR> for the command line or input(). - * Set: When any message is written to the screen. - * msg_didout true when something was written to the current line. - * Reset: When advancing to the next line, when the current - * text can be overwritten. - * Set: When any message is written to the screen. - * msg_nowait No extra delay for the last drawn message. - * Used in normal_cmd() before the mode message is drawn. + * msg_didany true when messages were written since the last time the + * user reacted to a prompt. + * Reset: After hitting a key for the hit-return prompt, + * hitting <CR> for the command line or input(). + * Set: When any message is written to the screen. + * msg_didout true when something was written to the current line. + * Reset: When advancing to the next line, when the current + * text can be overwritten. + * Set: When any message is written to the screen. + * msg_nowait No extra delay for the last drawn message. + * Used in normal_cmd() before the mode message is drawn. * emsg_on_display There was an error message recently. Indicates that there - * should be a delay before redrawing. - * msg_scroll The next message should not overwrite the current one. - * msg_scrolled How many lines the screen has been scrolled (because of - * messages). Used in update_screen() to scroll the screen - * back. Incremented each time the screen scrolls a line. + * should be a delay before redrawing. + * msg_scroll The next message should not overwrite the current one. + * msg_scrolled How many lines the screen has been scrolled (because of + * messages). Used in update_screen() to scroll the screen + * back. Incremented each time the screen scrolls a line. * msg_scrolled_ign TRUE when msg_scrolled is non-zero and msg_puts_attr() - * writes something without scrolling should not make - * need_wait_return to be set. This is a hack to make ":ts" - * work without an extra prompt. - * lines_left Number of lines available for messages before the - * more-prompt is to be given. -1 when not set. + * writes something without scrolling should not make + * need_wait_return to be set. This is a hack to make ":ts" + * work without an extra prompt. + * lines_left Number of lines available for messages before the + * more-prompt is to be given. -1 when not set. * need_wait_return true when the hit-return prompt is needed. - * Reset: After giving the hit-return prompt, when the user - * has answered some other prompt. - * Set: When the ruler or typeahead display is overwritten, - * scrolling the screen for some message. - * keep_msg Message to be displayed after redrawing the screen, in - * main_loop(). - * This is an allocated string or NULL when not used. + * Reset: After giving the hit-return prompt, when the user + * has answered some other prompt. + * Set: When the ruler or typeahead display is overwritten, + * scrolling the screen for some message. + * keep_msg Message to be displayed after redrawing the screen, in + * main_loop(). + * This is an allocated string or NULL when not used. */ @@ -231,8 +231,7 @@ int msg_attr(const char *s, const int attr) } /// similar to msg_outtrans_attr, but support newlines and tabs. -void msg_multiline_attr(const char *s, int attr, - bool check_int, bool *need_clear) +void msg_multiline_attr(const char *s, int attr, bool check_int, bool *need_clear) FUNC_ATTR_NONNULL_ALL { const char *next_spec = s; @@ -287,16 +286,17 @@ bool msg_attr_keep(char_u *s, int attr, bool keep, bool multiline) } if (attr == 0) { - set_vim_var_string(VV_STATUSMSG, (char *) s, -1); + set_vim_var_string(VV_STATUSMSG, (char *)s, -1); } /* * It is possible that displaying a messages causes a problem (e.g., - * when redrawing the window), which causes another message, etc.. To + * when redrawing the window), which causes another message, etc.. To * break this loop, limit the recursiveness to 3 levels. */ - if (entered >= 3) + if (entered >= 3) { return TRUE; + } ++entered; /* Add message to history (unless it's a repeated kept message or a @@ -309,11 +309,12 @@ bool msg_attr_keep(char_u *s, int attr, bool keep, bool multiline) add_msg_hist((const char *)s, -1, attr, multiline); } - /* Truncate the message if needed. */ + // Truncate the message if needed. msg_start(); buf = msg_strtrunc(s, FALSE); - if (buf != NULL) + if (buf != NULL) { s = buf; + } bool need_clear = true; if (multiline) { @@ -336,31 +337,28 @@ bool msg_attr_keep(char_u *s, int attr, bool keep, bool multiline) return retval; } -/* - * Truncate a string such that it can be printed without causing a scroll. - * Returns an allocated string or NULL when no truncating is done. - */ -char_u * -msg_strtrunc ( - char_u *s, - int force /* always truncate */ -) +/// Truncate a string such that it can be printed without causing a scroll. +/// Returns an allocated string or NULL when no truncating is done. +/// +/// @param force always truncate +char_u *msg_strtrunc(char_u *s, int force) { - char_u *buf = NULL; + char_u *buf = NULL; int len; int room; - /* May truncate message to avoid a hit-return prompt */ + // May truncate message to avoid a hit-return prompt if ((!msg_scroll && !need_wait_return && shortmess(SHM_TRUNCALL) && !exmode_active && msg_silent == 0 && !ui_has(kUIMessages)) || force) { len = vim_strsize(s); - if (msg_scrolled != 0) - /* Use all the columns. */ + if (msg_scrolled != 0) { + // Use all the columns. room = (int)(Rows - msg_row) * Columns - 1; - else - /* Use up to 'showcmd' column. */ + } else { + // Use up to 'showcmd' column. room = (int)(Rows - msg_row - 1) * Columns + sc_col - 1; + } if (len > room && room > 0) { // may have up to 18 bytes per cell (6 per char, up to two // composing chars) @@ -390,10 +388,10 @@ void trunc_string(char_u *s, char_u *buf, int room_in, int buflen) } half = room / 2; - /* First part: Start of the string. */ + // First part: Start of the string. for (e = 0; len < half && e < buflen; ++e) { if (s[e] == NUL) { - /* text fits without truncating! */ + // text fits without truncating! buf[e] = NUL; return; } @@ -497,7 +495,7 @@ int smsg_attr_keep(int attr, char *s, ...) * isn't printed each time when it didn't change. */ static int last_sourcing_lnum = 0; -static char_u *last_sourcing_name = NULL; +static char_u *last_sourcing_name = NULL; /* * Reset the last used sourcing name/lnum. Makes sure it is displayed again @@ -515,8 +513,9 @@ void reset_last_sourcing(void) static int other_sourcing_name(void) { if (sourcing_name != NULL) { - if (last_sourcing_name != NULL) + if (last_sourcing_name != NULL) { return STRCMP(sourcing_name, last_sourcing_name) != 0; + } return TRUE; } return FALSE; @@ -577,16 +576,17 @@ void msg_source(int attr) if (p != NULL) { msg_attr(p, HL_ATTR(HLF_N)); xfree(p); - last_sourcing_lnum = sourcing_lnum; /* only once for each line */ + last_sourcing_lnum = sourcing_lnum; // only once for each line } - /* remember the last sourcing name printed, also when it's empty */ + // remember the last sourcing name printed, also when it's empty if (sourcing_name == NULL || other_sourcing_name()) { xfree(last_sourcing_name); - if (sourcing_name == NULL) + if (sourcing_name == NULL) { last_sourcing_name = NULL; - else + } else { last_sourcing_name = vim_strsave(sourcing_name); + } } --no_wait_return; } @@ -601,9 +601,9 @@ int emsg_not_now(void) { if ((emsg_off > 0 && vim_strchr(p_debug, 'm') == NULL && vim_strchr(p_debug, 't') == NULL) - || emsg_skip > 0 - ) + || emsg_skip > 0) { return TRUE; + } return FALSE; } @@ -762,7 +762,7 @@ bool emsgf_multiline(const char *const fmt, ...) va_list ap; - static char errbuf[MULTILINE_BUFSIZE]; + static char errbuf[MULTILINE_BUFSIZE]; if (emsg_not_now()) { return true; } @@ -794,9 +794,9 @@ static bool emsgfv(const char *fmt, va_list ap) /// detected when fuzzing vim. void iemsg(const char *s) { - emsg((char_u *)s); + emsg((char_u *)s); #ifdef ABORT_ON_INTERNAL_ERROR - abort(); + abort(); #endif } @@ -805,19 +805,19 @@ void iemsg(const char *s) /// detected when fuzzing vim. void iemsgf(const char *s, ...) { - va_list ap; - va_start(ap, s); - (void)emsgfv(s, ap); - va_end(ap); + va_list ap; + va_start(ap, s); + (void)emsgfv(s, ap); + va_end(ap); #ifdef ABORT_ON_INTERNAL_ERROR - abort(); + abort(); #endif } /// Give an "Internal error" message. void internal_error(char *where) { - IEMSG2(_(e_intern2), where); + IEMSG2(_(e_intern2), where); } static void msg_emsgf_event(void **argv) @@ -858,8 +858,9 @@ char_u *msg_trunc_attr(char_u *s, int force, int attr) n = msg_attr((const char *)s, attr); msg_hist_off = false; - if (n) + if (n) { return s; + } return NULL; } @@ -930,18 +931,21 @@ void add_hl_msg_hist(HlMessage hl_msg) /// @param[in] len Length of s or -1. static void add_msg_hist(const char *s, int len, int attr, bool multiline) { - if (msg_hist_off || msg_silent != 0) + if (msg_hist_off || msg_silent != 0) { return; + } - /* Don't let the message history get too big */ - while (msg_hist_len > MAX_MSG_HIST_LEN) + // Don't let the message history get too big + while (msg_hist_len > MAX_MSG_HIST_LEN) { (void)delete_first_msg(); + } - /* allocate an entry and add the message at the end of the history */ + // allocate an entry and add the message at the end of the history struct msg_hist *p = xmalloc(sizeof(struct msg_hist)); - if (len < 0) + if (len < 0) { len = (int)STRLEN(s); - /* remove leading and trailing newlines */ + } + // remove leading and trailing newlines while (len > 0 && *s == '\n') { ++s; --len; @@ -972,11 +976,12 @@ int delete_first_msg(void) { struct msg_hist *p; - if (msg_hist_len <= 0) + if (msg_hist_len <= 0) { return FAIL; + } p = first_msg_hist; first_msg_hist = p->next; - if (first_msg_hist == NULL) { /* history is becoming empty */ + if (first_msg_hist == NULL) { // history is becoming empty assert(msg_hist_len == 1); last_msg_hist = NULL; } @@ -1078,7 +1083,7 @@ void wait_return(int redraw) int oldState; int tmpState; int had_got_int; - FILE *save_scriptout; + FILE *save_scriptout; if (redraw == true) { redraw_all_later(NOT_VALID); @@ -1086,8 +1091,9 @@ void wait_return(int redraw) /* If using ":silent cmd", don't wait for a return. Also don't set * need_wait_return to do it later. */ - if (msg_silent != 0) + if (msg_silent != 0) { return; + } /* * When inside vgetc(), we can't wait for a typed character at all. @@ -1095,24 +1101,26 @@ void wait_return(int redraw) * the end. Adjust cmdline_row to avoid the next message overwriting the * last one. */ - if (vgetc_busy > 0) + if (vgetc_busy > 0) { return; + } need_wait_return = true; if (no_wait_return) { - if (!exmode_active) + if (!exmode_active) { cmdline_row = msg_row; + } return; } redir_off = true; // don't redirect this message oldState = State; if (quit_more) { - c = CAR; /* just pretend CR was hit */ + c = CAR; // just pretend CR was hit quit_more = FALSE; got_int = FALSE; } else if (exmode_active) { - MSG_PUTS(" "); /* make sure the cursor is on the right line */ - c = CAR; /* no need for a return in ex mode */ + MSG_PUTS(" "); // make sure the cursor is on the right line + c = CAR; // no need for a return in ex mode got_int = FALSE; } else { // Make sure the hit-return prompt is on screen when 'guioptions' was @@ -1176,7 +1184,7 @@ void wait_return(int redraw) 0; } if (quit_more) { - c = CAR; /* just pretend CR was hit */ + c = CAR; // just pretend CR was hit quit_more = FALSE; got_int = FALSE; } else if (c != K_IGNORE) { @@ -1185,8 +1193,9 @@ void wait_return(int redraw) } } else if (msg_scrolled > Rows - 2 && (c == 'j' || c == 'd' || c == 'f' - || c == K_DOWN || c == K_PAGEDOWN)) + || c == K_DOWN || c == K_PAGEDOWN)) { c = K_IGNORE; + } } } while ((had_got_int && c == Ctrl_C) || c == K_IGNORE @@ -1201,9 +1210,9 @@ void wait_return(int redraw) * Avoid that the mouse-up event causes visual mode to start. */ if (c == K_LEFTMOUSE || c == K_MIDDLEMOUSE || c == K_RIGHTMOUSE - || c == K_X1MOUSE || c == K_X2MOUSE) + || c == K_X1MOUSE || c == K_X2MOUSE) { (void)jump_to_mouse(MOUSE_SETPOS, NULL, 0); - else if (vim_strchr((char_u *)"\r\n ", c) == NULL && c != Ctrl_C) { + } else if (vim_strchr((char_u *)"\r\n ", c) == NULL && c != Ctrl_C) { /* Put the character back in the typeahead buffer. Don't use the * stuff buffer, because lmaps wouldn't work. */ ins_char_typebuf(c); @@ -1216,8 +1225,9 @@ void wait_return(int redraw) // If the user hits ':', '?' or '/' we get a command line from the next // line. if (c == ':' || c == '?' || c == '/') { - if (!exmode_active) + if (!exmode_active) { cmdline_row = msg_row; + } skip_redraw = true; // skip redraw once do_redraw = false; msg_ext_keep_after_cmdline = true; @@ -1240,7 +1250,7 @@ void wait_return(int redraw) XFREE_CLEAR(keep_msg); // don't redisplay message, it's too long } - if (tmpState == SETWSIZE) { /* got resize event while in vgetc() */ + if (tmpState == SETWSIZE) { // got resize event while in vgetc() ui_refresh(); } else if (!skip_redraw) { if (redraw == true || (msg_scrolled != 0 && redraw != -1)) { @@ -1259,9 +1269,10 @@ static void hit_return_msg(void) { int save_p_more = p_more; - p_more = FALSE; /* don't want see this message when scrolling back */ - if (msg_didout) /* start on a new line */ + p_more = FALSE; // don't want see this message when scrolling back + if (msg_didout) { // start on a new line msg_putchar('\n'); + } msg_ext_set_kind("return_prompt"); if (got_int) { MSG_PUTS(_("Interrupt: ")); @@ -1280,10 +1291,11 @@ static void hit_return_msg(void) void set_keep_msg(char_u *s, int attr) { xfree(keep_msg); - if (s != NULL && msg_silent == 0) + if (s != NULL && msg_silent == 0) { keep_msg = vim_strsave(s); - else + } else { keep_msg = NULL; + } keep_msg_more = false; keep_msg_attr = attr; } @@ -1327,8 +1339,9 @@ void msg_start(void) did_return = true; cmdline_row = msg_row; } - if (!msg_didany || lines_left < 0) + if (!msg_didany || lines_left < 0) { msg_starthere(); + } if (msg_silent == 0) { msg_didout = false; // no output on current line yet } @@ -1396,7 +1409,7 @@ void msg_home_replace_hl(char_u *fname) static void msg_home_replace_attr(char_u *fname, int attr) { - char_u *name; + char_u *name; name = home_replace_save(NULL, fname); msg_outtrans_attr(name, attr); @@ -1449,7 +1462,7 @@ int msg_outtrans_len_attr(const char_u *msgstr, int len, int attr) int mb_l; int c; - /* if MSG_HIST flag set, add message to history */ + // if MSG_HIST flag set, add message to history if (attr & MSG_HIST) { add_msg_hist(str, len, attr, false); attr &= ~MSG_HIST; @@ -1518,13 +1531,16 @@ void msg_make(char_u *arg) static char_u *str = (char_u *)"eeffoc", *rs = (char_u *)"Plon#dqg#vxjduB"; arg = skipwhite(arg); - for (i = 5; *arg && i >= 0; --i) - if (*arg++ != str[i]) + for (i = 5; *arg && i >= 0; --i) { + if (*arg++ != str[i]) { break; + } + } if (i < 0) { msg_putchar('\n'); - for (i = 0; rs[i]; ++i) + for (i = 0; rs[i]; ++i) { msg_putchar(rs[i] - 3); + } } } @@ -1540,11 +1556,10 @@ void msg_make(char_u *arg) /// Otherwise characters are not highlighted. /// This function is used to show mappings, where we want to see how to type /// the character/string -- webb -int msg_outtrans_special( - const char_u *strstart, - bool from, ///< true for LHS of a mapping - int maxlen ///< screen columns, 0 for unlimeted -) +/// +/// @param from true for LHS of a mapping +/// @param maxlen screen columns, 0 for unlimited +int msg_outtrans_special(const char_u *strstart, bool from, int maxlen) { if (strstart == NULL) { return 0; // Do nothing. @@ -1585,8 +1600,7 @@ int msg_outtrans_special( /// @param[in] replace_lt Convert `<` into `<lt>`. /// /// @return [allocated] Converted string. -char *str2special_save(const char *const str, const bool replace_spaces, - const bool replace_lt) +char *str2special_save(const char *const str, const bool replace_spaces, const bool replace_lt) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_RET { @@ -1595,7 +1609,7 @@ char *str2special_save(const char *const str, const bool replace_spaces, const char *p = str; while (*p != NUL) { - ga_concat(&ga, (const char_u *)str2special(&p, replace_spaces, replace_lt)); + ga_concat(&ga, str2special(&p, replace_spaces, replace_lt)); } ga_append(&ga, NUL); return (char *)ga.ga_data; @@ -1611,8 +1625,7 @@ char *str2special_save(const char *const str, const bool replace_spaces, /// @return Converted key code, in a static buffer. Buffer is always one and the /// same, so save converted string somewhere before running str2special /// for the second time. -const char *str2special(const char **const sp, const bool replace_spaces, - const bool replace_lt) +const char *str2special(const char **const sp, const bool replace_spaces, const bool replace_lt) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET { static char buf[7]; @@ -1834,8 +1847,9 @@ void msg_prt_line(char_u *s, int list) } } - if (c == NUL) + if (c == NUL) { break; + } msg_putchar_attr(c, attr); col++; @@ -2022,8 +2036,7 @@ static void msg_ext_emit_chunk(void) * The display part of msg_puts_attr_len(). * May be called recursively to display scroll-back text. */ -static void msg_puts_display(const char_u *str, int maxlen, int attr, - int recurse) +static void msg_puts_display(const char_u *str, int maxlen, int attr, int recurse) { const char_u *s = str; const char_u *t_s = str; // String from "t_s" to "s" is still todo. @@ -2076,17 +2089,19 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, t_puts(&t_col, t_s, s, attr); } - /* When no more prompt and no more room, truncate here */ - if (msg_no_more && lines_left == 0) + // When no more prompt and no more room, truncate here + if (msg_no_more && lines_left == 0) { break; + } // Scroll the screen up one line. bool has_last_char = (*s >= ' ' && !cmdmsg_rl); msg_scroll_up(!has_last_char); msg_row = Rows - 2; - if (msg_col >= Columns) /* can happen after screen resize */ + if (msg_col >= Columns) { // can happen after screen resize msg_col = Columns - 1; + } // Display char in last column before showing more-prompt. if (has_last_char) { @@ -2127,20 +2142,24 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, * If screen is completely filled and 'more' is set then wait * for a character. */ - if (lines_left > 0) + if (lines_left > 0) { --lines_left; + } if (p_more && lines_left == 0 && State != HITRETURN && !msg_no_more && !exmode_active) { - if (do_more_prompt(NUL)) + if (do_more_prompt(NUL)) { s = confirm_msg_tail; - if (quit_more) + } + if (quit_more) { return; + } } /* When we displayed a char in last column need to check if there * is still more. */ - if (did_last_char) + if (did_last_char) { continue; + } } wrap = *s == '\n' @@ -2171,10 +2190,11 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, } } else if (*s == '\r') { // go to column 0 msg_col = 0; - } else if (*s == '\b') { /* go to previous char */ - if (msg_col) + } else if (*s == '\b') { // go to previous char + if (msg_col) { --msg_col; - } else if (*s == TAB) { /* translate Tab into spaces */ + } + } else if (*s == TAB) { // translate Tab into spaces do { msg_screen_putchar(' ', attr); } while (msg_col & 7); @@ -2198,9 +2218,10 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, msg_screen_putchar(*s, attr); } } else { - /* postpone this character until later */ - if (t_col == 0) + // postpone this character until later + if (t_col == 0) { t_s = s; + } t_col += cw; s += l - 1; } @@ -2342,7 +2363,7 @@ void msg_reset_scroll(void) // non-displayed part of msg_grid is considered invalid. for (int i = 0; i < MIN(msg_scrollsize(), msg_grid.Rows); i++) { grid_clear_line(&msg_grid, msg_grid.line_offset[i], - (int)msg_grid.Columns, false); + msg_grid.Columns, false); } } } else { @@ -2358,7 +2379,7 @@ void msg_reset_scroll(void) static void inc_msg_scrolled(void) { if (*get_vim_var_str(VV_SCROLLSTART) == NUL) { - char *p = (char *) sourcing_name; + char *p = (char *)sourcing_name; char *tofree = NULL; // v:scrollstart is empty, set it to the script/function name and line @@ -2369,7 +2390,7 @@ static void inc_msg_scrolled(void) size_t len = strlen(p) + 40; tofree = xmalloc(len); vim_snprintf(tofree, len, _("%s line %" PRId64), - p, (int64_t) sourcing_lnum); + p, (int64_t)sourcing_lnum); p = tofree; } set_vim_var_string(VV_SCROLLSTART, p, -1); @@ -2394,15 +2415,13 @@ typedef enum { static sb_clear_T do_clear_sb_text = SB_CLEAR_NONE; /// Store part of a printed message for displaying when scrolling back. -static void store_sb_text( - char_u **sb_str, // start of string - char_u *s, // just after string - int attr, - int *sb_col, - int finish // line ends -) +/// +/// @param sb_str start of string +/// @param s just after string +/// @param finish line ends +static void store_sb_text(char_u **sb_str, char_u *s, int attr, int *sb_col, int finish) { - msgchunk_T *mp; + msgchunk_T *mp; if (do_clear_sb_text == SB_CLEAR_ALL || do_clear_sb_text == SB_CLEAR_CMDLINE_DONE) { @@ -2427,8 +2446,9 @@ static void store_sb_text( last_msgchunk = mp; } mp->sb_next = NULL; - } else if (finish && last_msgchunk != NULL) + } else if (finish && last_msgchunk != NULL) { last_msgchunk->sb_eol = TRUE; + } *sb_str = s; *sb_col = 0; @@ -2460,8 +2480,8 @@ void sb_text_end_cmdline(void) /// Called when redrawing the screen. void clear_sb_text(int all) { - msgchunk_T *mp; - msgchunk_T **lastp; + msgchunk_T *mp; + msgchunk_T **lastp; if (all) { lastp = &last_msgchunk; @@ -2484,7 +2504,7 @@ void clear_sb_text(int all) */ void show_sb_text(void) { - msgchunk_T *mp; + msgchunk_T *mp; /* Only show something if there is more than one line, otherwise it looks * weird, typing a command without output results in one line. */ @@ -2504,8 +2524,9 @@ static msgchunk_T *msg_sb_start(msgchunk_T *mps) { msgchunk_T *mp = mps; - while (mp != NULL && mp->sb_prev != NULL && !mp->sb_prev->sb_eol) + while (mp != NULL && mp->sb_prev != NULL && !mp->sb_prev->sb_eol) { mp = mp->sb_prev; + } return mp; } @@ -2514,8 +2535,9 @@ static msgchunk_T *msg_sb_start(msgchunk_T *mps) */ void msg_sb_eol(void) { - if (last_msgchunk != NULL) + if (last_msgchunk != NULL) { last_msgchunk->sb_eol = TRUE; + } } /* @@ -2524,18 +2546,20 @@ void msg_sb_eol(void) */ static msgchunk_T *disp_sb_line(int row, msgchunk_T *smp) { - msgchunk_T *mp = smp; - char_u *p; + msgchunk_T *mp = smp; + char_u *p; for (;; ) { msg_row = row; msg_col = mp->sb_msg_col; p = mp->sb_text; - if (*p == '\n') /* don't display the line break */ + if (*p == '\n') { // don't display the line break ++p; + } msg_puts_display(p, -1, mp->sb_attr, TRUE); - if (mp->sb_eol || mp->sb_next == NULL) + if (mp->sb_eol || mp->sb_next == NULL) { break; + } mp = mp->sb_next; } @@ -2633,8 +2657,8 @@ static int do_more_prompt(int typed_char) int retval = FALSE; int toscroll; bool to_redraw = false; - msgchunk_T *mp_last = NULL; - msgchunk_T *mp; + msgchunk_T *mp_last = NULL; + msgchunk_T *mp; int i; // If headless mode is enabled and no input is required, this variable @@ -2651,23 +2675,25 @@ static int do_more_prompt(int typed_char) entered = true; if (typed_char == 'G') { - /* "g<": Find first line on the last page. */ + // "g<": Find first line on the last page. mp_last = msg_sb_start(last_msgchunk); for (i = 0; i < Rows - 2 && mp_last != NULL - && mp_last->sb_prev != NULL; ++i) + && mp_last->sb_prev != NULL; ++i) { mp_last = msg_sb_start(mp_last->sb_prev); + } } State = ASKMORE; setmouse(); - if (typed_char == NUL) + if (typed_char == NUL) { msg_moremsg(FALSE); + } for (;; ) { /* * Get a typed character directly from the user. */ if (used_typed_char != NUL) { - c = used_typed_char; /* was typed at hit-enter prompt */ + c = used_typed_char; // was typed at hit-enter prompt used_typed_char = NUL; } else { c = get_keystroke(resize_events); @@ -2676,50 +2702,50 @@ static int do_more_prompt(int typed_char) toscroll = 0; switch (c) { - case BS: /* scroll one line back */ + case BS: // scroll one line back case K_BS: case 'k': case K_UP: toscroll = -1; break; - case CAR: /* one extra line */ + case CAR: // one extra line case NL: case 'j': case K_DOWN: toscroll = 1; break; - case 'u': /* Up half a page */ + case 'u': // Up half a page toscroll = -(Rows / 2); break; - case 'd': /* Down half a page */ + case 'd': // Down half a page toscroll = Rows / 2; break; - case 'b': /* one page back */ + case 'b': // one page back case K_PAGEUP: toscroll = -(Rows - 1); break; - case ' ': /* one extra page */ + case ' ': // one extra page case 'f': case K_PAGEDOWN: case K_LEFTMOUSE: toscroll = Rows - 1; break; - case 'g': /* all the way back to the start */ + case 'g': // all the way back to the start toscroll = -999999; break; - case 'G': /* all the way to the end */ + case 'G': // all the way to the end toscroll = 999999; lines_left = 999999; break; - case ':': /* start new command line */ + case ':': // start new command line if (!confirm_msg_used) { /* Since got_int is set all typeahead will be flushed, but we * want to keep this ':', remember that in a special way. */ @@ -2733,7 +2759,7 @@ static int do_more_prompt(int typed_char) case Ctrl_C: case ESC: if (confirm_msg_used) { - /* Jump to the choices of the dialog. */ + // Jump to the choices of the dialog. retval = TRUE; } else { got_int = TRUE; @@ -2752,7 +2778,7 @@ static int do_more_prompt(int typed_char) to_redraw = true; break; - default: /* no valid response */ + default: // no valid response msg_moremsg(TRUE); continue; } @@ -2771,10 +2797,11 @@ static int do_more_prompt(int typed_char) mp = NULL; } - /* go to start of line at top of the screen */ + // go to start of line at top of the screen for (i = 0; i < Rows - 2 && mp != NULL && mp->sb_prev != NULL; - ++i) + ++i) { mp = msg_sb_start(mp->sb_prev); + } if (mp != NULL && (mp->sb_prev != NULL || to_redraw)) { // Find line to be displayed at top @@ -2783,10 +2810,11 @@ static int do_more_prompt(int typed_char) break; } mp = msg_sb_start(mp->sb_prev); - if (mp_last == NULL) + if (mp_last == NULL) { mp_last = msg_sb_start(last_msgchunk); - else + } else { mp_last = msg_sb_start(mp_last->sb_prev); + } } if (toscroll == -1 && !to_redraw) { @@ -2810,7 +2838,7 @@ static int do_more_prompt(int typed_char) toscroll = 0; } } else { - /* First display any text that we scrolled back. */ + // First display any text that we scrolled back. while (toscroll > 0 && mp_last != NULL) { if (msg_do_throttle() && !msg_grid.throttled) { // Tricky: we redraw at one line higher than usual. Therefore @@ -2836,7 +2864,7 @@ static int do_more_prompt(int typed_char) continue; } - /* display more text, return to caller */ + // display more text, return to caller lines_left = toscroll; } @@ -2917,7 +2945,7 @@ static void msg_screen_putchar(int c, int attr) void msg_moremsg(int full) { int attr; - char_u *s = (char_u *)_("-- More --"); + char_u *s = (char_u *)_("-- More --"); attr = hl_combine_attr(HL_ATTR(HLF_MSG), HL_ATTR(HLF_M)); grid_puts(&msg_grid_adj, s, Rows - 1, 0, attr); @@ -2935,13 +2963,13 @@ void msg_moremsg(int full) void repeat_message(void) { if (State == ASKMORE) { - msg_moremsg(TRUE); /* display --more-- message again */ + msg_moremsg(TRUE); // display --more-- message again msg_row = Rows - 1; } else if (State == CONFIRM) { - display_confirm_msg(); /* display ":confirm" message again */ + display_confirm_msg(); // display ":confirm" message again msg_row = Rows - 1; } else if (State == EXTERNCMD) { - ui_cursor_goto(msg_row, msg_col); /* put cursor back */ + ui_cursor_goto(msg_row, msg_col); // put cursor back } else if (State == HITRETURN || State == SETWSIZE) { if (msg_row == Rows - 1) { /* Avoid drawing the "hit-enter" prompt below the previous one, @@ -2962,8 +2990,9 @@ void repeat_message(void) */ void msg_clr_eos(void) { - if (msg_silent == 0) + if (msg_silent == 0) { msg_clr_eos_force(); + } } /* @@ -3129,16 +3158,18 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) return; } - /* Don't do anything for displaying prompts and the like. */ - if (redir_off) + // Don't do anything for displaying prompts and the like. + if (redir_off) { return; + } - /* If 'verbosefile' is set prepare for writing in that file. */ - if (*p_vfile != NUL && verbose_fd == NULL) + // If 'verbosefile' is set prepare for writing in that file. + if (*p_vfile != NUL && verbose_fd == NULL) { verbose_open(); + } if (redirecting()) { - /* If the string doesn't start with CR or NL, go to msg_col */ + // If the string doesn't start with CR or NL, go to msg_col if (*s != '\n' && *s != '\r') { while (cur_col < msg_col) { if (capture_ga) { @@ -3160,7 +3191,7 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen; if (capture_ga) { - ga_concat_len(capture_ga, (const char *)str, len); + ga_concat_len(capture_ga, str, len); } if (redir_reg) { write_reg_contents(redir_reg, s, len, true); @@ -3190,8 +3221,9 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) s++; } - if (msg_silent != 0) /* should update msg_col */ + if (msg_silent != 0) { // should update msg_col msg_col = cur_col; + } } } @@ -3207,8 +3239,9 @@ int redirecting(void) */ void verbose_enter(void) { - if (*p_vfile != NUL) + if (*p_vfile != NUL) { ++msg_silent; + } } /* @@ -3217,9 +3250,11 @@ void verbose_enter(void) */ void verbose_leave(void) { - if (*p_vfile != NUL) - if (--msg_silent < 0) + if (*p_vfile != NUL) { + if (--msg_silent < 0) { msg_silent = 0; + } + } } /* @@ -3227,11 +3262,12 @@ void verbose_leave(void) */ void verbose_enter_scroll(void) { - if (*p_vfile != NUL) + if (*p_vfile != NUL) { ++msg_silent; - else - /* always scroll up, don't overwrite */ + } else { + // always scroll up, don't overwrite msg_scroll = TRUE; + } } /* @@ -3240,10 +3276,12 @@ void verbose_enter_scroll(void) void verbose_leave_scroll(void) { if (*p_vfile != NUL) { - if (--msg_silent < 0) + if (--msg_silent < 0) { msg_silent = 0; - } else + } + } else { cmdline_row = msg_row; + } } /* @@ -3265,7 +3303,7 @@ void verbose_stop(void) int verbose_open(void) { if (verbose_fd == NULL && !verbose_did_open) { - /* Only give the error message once. */ + // Only give the error message once. verbose_did_open = TRUE; verbose_fd = os_fopen((char *)p_vfile, "a"); @@ -3324,8 +3362,8 @@ void give_warning2(char_u *const message, char_u *const a1, bool hl) */ void msg_advance(int col) { - if (msg_silent != 0) { /* nothing to advance to */ - msg_col = col; /* for redirection, may fill it up later */ + if (msg_silent != 0) { // nothing to advance to + msg_col = col; // for redirection, may fill it up later return; } if (ui_has(kUIMessages)) { @@ -3336,49 +3374,44 @@ void msg_advance(int col) } return; } - if (col >= Columns) /* not enough room */ + if (col >= Columns) { // not enough room col = Columns - 1; - if (cmdmsg_rl) - while (msg_col > Columns - col) + } + if (cmdmsg_rl) { + while (msg_col > Columns - col) { msg_putchar(' '); - else - while (msg_col < col) + } + } else { + while (msg_col < col) { msg_putchar(' '); + } + } } -/* - * Used for "confirm()" function, and the :confirm command prefix. - * Versions which haven't got flexible dialogs yet, and console - * versions, get this generic handler which uses the command line. - * - * type = one of: - * VIM_QUESTION, VIM_INFO, VIM_WARNING, VIM_ERROR or VIM_GENERIC - * title = title string (can be NULL for default) - * (neither used in console dialogs at the moment) - * - * Format of the "buttons" string: - * "Button1Name\nButton2Name\nButton3Name" - * The first button should normally be the default/accept - * The second button should be the 'Cancel' button - * Other buttons- use your imagination! - * A '&' in a button name becomes a shortcut, so each '&' should be before a - * different letter. - */ -int -do_dialog ( - int type, - char_u *title, - char_u *message, - char_u *buttons, - int dfltbutton, - char_u *textfield, /* IObuff for inputdialog(), NULL - otherwise */ - int ex_cmd /* when TRUE pressing : accepts default and starts - Ex command */ -) +/// Used for "confirm()" function, and the :confirm command prefix. +/// Versions which haven't got flexible dialogs yet, and console +/// versions, get this generic handler which uses the command line. +/// +/// type = one of: +/// VIM_QUESTION, VIM_INFO, VIM_WARNING, VIM_ERROR or VIM_GENERIC +/// title = title string (can be NULL for default) +/// (neither used in console dialogs at the moment) +/// +/// Format of the "buttons" string: +/// "Button1Name\nButton2Name\nButton3Name" +/// The first button should normally be the default/accept +/// The second button should be the 'Cancel' button +/// Other buttons- use your imagination! +/// A '&' in a button name becomes a shortcut, so each '&' should be before a +/// different letter. +/// +/// @param textfiel IObuff for inputdialog(), NULL otherwise +/// @param ex_cmd when TRUE pressing : accepts default and starts Ex command +int do_dialog(int type, char_u *title, char_u *message, char_u *buttons, int dfltbutton, + char_u *textfield, int ex_cmd) { int retval = 0; - char_u *hotkeys; + char_u *hotkeys; int c; int i; @@ -3407,16 +3440,16 @@ do_dialog ( // Get a typed character directly from the user. c = get_keystroke(NULL); switch (c) { - case CAR: /* User accepts default option */ + case CAR: // User accepts default option case NL: retval = dfltbutton; break; - case Ctrl_C: /* User aborts/cancels */ + case Ctrl_C: // User aborts/cancels case ESC: retval = 0; break; - default: /* Could be a hotkey? */ - if (c < 0) { /* special keys are ignored here */ + default: // Could be a hotkey? + if (c < 0) { // special keys are ignored here continue; } if (c == ':' && ex_cmd) { @@ -3435,9 +3468,10 @@ do_dialog ( i += utfc_ptr2len(hotkeys + i) - 1; retval++; } - if (hotkeys[i]) + if (hotkeys[i]) { break; - /* No hotkey match, so keep waiting */ + } + // No hotkey match, so keep waiting continue; } break; @@ -3455,15 +3489,11 @@ do_dialog ( } -/* - * Copy one character from "*from" to "*to", taking care of multi-byte - * characters. Return the length of the character in bytes. - */ -static int copy_char( - const char_u *from, - char_u *to, - bool lowercase // make character lower case -) +/// Copy one character from "*from" to "*to", taking care of multi-byte +/// characters. Return the length of the character in bytes. +/// +/// @param lowercase make character lower case +static int copy_char(const char_u *from, char_u *to, bool lowercase) FUNC_ATTR_NONNULL_ALL { if (lowercase) { @@ -3490,9 +3520,7 @@ static int copy_char( /// corresponding button has a hotkey /// /// @return Pointer to memory allocated for storing hotkeys -static char_u * console_dialog_alloc(const char_u *message, - char_u *buttons, - bool has_hotkey[]) +static char_u *console_dialog_alloc(const char_u *message, char_u *buttons, bool has_hotkey[]) { int lenhotkey = HOTK_LEN; // count first button has_hotkey[0] = false; @@ -3521,9 +3549,9 @@ static char_u * console_dialog_alloc(const char_u *message, } len += (int)(STRLEN(message) - + 2 // for the NL's - + STRLEN(buttons) - + 3); // for the ": " and NUL + + 2 // for the NL's + + STRLEN(buttons) + + 3); // for the ": " and NUL lenhotkey++; // for the NUL // If no hotkey is specified, first char is used. @@ -3552,7 +3580,7 @@ static char_u * console_dialog_alloc(const char_u *message, static char_u *msg_show_console_dialog(char_u *message, char_u *buttons, int dfltbutton) FUNC_ATTR_NONNULL_RET { - bool has_hotkey[HAS_HOTKEY_LEN] = {false}; + bool has_hotkey[HAS_HOTKEY_LEN] = { false }; char_u *hotk = console_dialog_alloc(message, buttons, has_hotkey); copy_hotkeys_and_msg(message, buttons, dfltbutton, has_hotkey, hotk); @@ -3569,9 +3597,8 @@ static char_u *msg_show_console_dialog(char_u *message, char_u *buttons, int dfl /// @param has_hotkey An element in this array is true if corresponding button /// has a hotkey /// @param[out] hotkeys_ptr Pointer to the memory location where hotkeys will be copied -static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons, - int default_button_idx, const bool has_hotkey[], - char_u *hotkeys_ptr) +static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons, int default_button_idx, + const bool has_hotkey[], char_u *hotkeys_ptr) { *confirm_msg = '\n'; STRCPY(confirm_msg + 1, message); @@ -3611,7 +3638,6 @@ static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons, if (idx < HAS_HOTKEY_LEN - 1 && !has_hotkey[++idx]) { first_hotkey = true; } - } else if (*r == DLG_HOTKEY_CHAR || first_hotkey) { if (*r == DLG_HOTKEY_CHAR) { ++r; @@ -3660,21 +3686,24 @@ void display_confirm_msg(void) int vim_dialog_yesno(int type, char_u *title, char_u *message, int dflt) { if (do_dialog(type, - title == NULL ? (char_u *)_("Question") : title, - message, - (char_u *)_("&Yes\n&No"), dflt, NULL, FALSE) == 1) + title == NULL ? (char_u *)_("Question") : title, + message, + (char_u *)_("&Yes\n&No"), dflt, NULL, FALSE) == 1) { return VIM_YES; + } return VIM_NO; } int vim_dialog_yesnocancel(int type, char_u *title, char_u *message, int dflt) { switch (do_dialog(type, - title == NULL ? (char_u *)_("Question") : title, - message, - (char_u *)_("&Yes\n&No\n&Cancel"), dflt, NULL, FALSE)) { - case 1: return VIM_YES; - case 2: return VIM_NO; + title == NULL ? (char_u *)_("Question") : title, + message, + (char_u *)_("&Yes\n&No\n&Cancel"), dflt, NULL, FALSE)) { + case 1: + return VIM_YES; + case 2: + return VIM_NO; } return VIM_CANCEL; } @@ -3682,14 +3711,18 @@ int vim_dialog_yesnocancel(int type, char_u *title, char_u *message, int dflt) int vim_dialog_yesnoallcancel(int type, char_u *title, char_u *message, int dflt) { switch (do_dialog(type, - title == NULL ? (char_u *)"Question" : title, - message, - (char_u *)_("&Yes\n&No\nSave &All\n&Discard All\n&Cancel"), - dflt, NULL, FALSE)) { - case 1: return VIM_YES; - case 2: return VIM_NO; - case 3: return VIM_ALL; - case 4: return VIM_DISCARDALL; + title == NULL ? (char_u *)"Question" : title, + message, + (char_u *)_("&Yes\n&No\nSave &All\n&Discard All\n&Cancel"), + dflt, NULL, FALSE)) { + case 1: + return VIM_YES; + case 2: + return VIM_NO; + case 3: + return VIM_ALL; + case 4: + return VIM_DISCARDALL; } return VIM_CANCEL; } diff --git a/src/nvim/message.h b/src/nvim/message.h index 377c725fa1..6d4d030500 100644 --- a/src/nvim/message.h +++ b/src/nvim/message.h @@ -1,15 +1,15 @@ #ifndef NVIM_MESSAGE_H #define NVIM_MESSAGE_H -#include <stdbool.h> #include <stdarg.h> +#include <stdbool.h> #include <stddef.h> -#include "nvim/macros.h" -#include "nvim/types.h" -#include "nvim/grid_defs.h" #include "nvim/api/private/defs.h" +#include "nvim/grid_defs.h" #include "nvim/lib/kvec.h" +#include "nvim/macros.h" +#include "nvim/types.h" /* * Types of dialogs passed to do_dialog(). @@ -19,7 +19,7 @@ #define VIM_WARNING 2 #define VIM_INFO 3 #define VIM_QUESTION 4 -#define VIM_LAST_TYPE 4 /* sentinel value */ +#define VIM_LAST_TYPE 4 // sentinel value /* * Return values for functions like vim_dialogyesno() @@ -42,16 +42,16 @@ #define EMSG(s) emsg((char_u *)(s)) /// Like #EMSG, but for messages with one "%s" inside -#define EMSG2(s, p) emsgf((const char *) (s), (p)) +#define EMSG2(s, p) emsgf((const char *)(s), (p)) /// Like #EMSG, but for messages with two "%s" inside -#define EMSG3(s, p, q) emsgf((const char *) (s), (p), (q)) +#define EMSG3(s, p, q) emsgf((const char *)(s), (p), (q)) /// Like #EMSG, but for messages with one "%" PRId64 inside -#define EMSGN(s, n) emsgf((const char *) (s), (int64_t)(n)) +#define EMSGN(s, n) emsgf((const char *)(s), (int64_t)(n)) /// Like #EMSG, but for messages with one "%" PRIu64 inside -#define EMSGU(s, n) emsgf((const char *) (s), (uint64_t)(n)) +#define EMSGU(s, n) emsgf((const char *)(s), (uint64_t)(n)) /// Like #EMSG, but for internal messages #define IEMSG(s) iemsg((const char *)(s)) diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index 6d94632687..40db5b7cf3 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -7,37 +7,43 @@ #include <assert.h> #include <inttypes.h> +#include <limits.h> #include <stdbool.h> #include <string.h> -#include <limits.h> -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/misc1.h" +#include "nvim/buffer.h" +#include "nvim/buffer_updates.h" #include "nvim/charset.h" #include "nvim/cursor.h" #include "nvim/diff.h" #include "nvim/edit.h" #include "nvim/eval.h" +#include "nvim/event/stream.h" #include "nvim/ex_cmds.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/fold.h" +#include "nvim/func_attr.h" +#include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/indent.h" #include "nvim/indent_c.h" -#include "nvim/buffer_updates.h" #include "nvim/main.h" #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/message.h" -#include "nvim/garray.h" -#include "nvim/move.h" +#include "nvim/misc1.h" #include "nvim/mouse.h" +#include "nvim/move.h" #include "nvim/option.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" +#include "nvim/os/shell.h" +#include "nvim/os/signal.h" +#include "nvim/os/time.h" #include "nvim/os_unix.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" @@ -48,14 +54,8 @@ #include "nvim/tag.h" #include "nvim/ui.h" #include "nvim/undo.h" +#include "nvim/vim.h" #include "nvim/window.h" -#include "nvim/os/os.h" -#include "nvim/os/shell.h" -#include "nvim/os/signal.h" -#include "nvim/os/input.h" -#include "nvim/os/time.h" -#include "nvim/event/stream.h" -#include "nvim/buffer.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "misc1.c.generated.h" @@ -73,23 +73,23 @@ static garray_T ga_users = GA_EMPTY_INIT_VALUE; * If "include_space" is set, include trailing whitespace while calculating the * length. */ -int get_leader_len(char_u *line, char_u **flags, - bool backward, bool include_space) +int get_leader_len(char_u *line, char_u **flags, bool backward, bool include_space) { int i, j; int result; int got_com = FALSE; int found_one; - char_u part_buf[COM_MAX_LEN]; /* buffer for one option part */ - char_u *string; /* pointer to comment string */ - char_u *list; + char_u part_buf[COM_MAX_LEN]; // buffer for one option part + char_u *string; // pointer to comment string + char_u *list; int middle_match_len = 0; - char_u *prev_list; - char_u *saved_flags = NULL; + char_u *prev_list; + char_u *saved_flags = NULL; result = i = 0; - while (ascii_iswhite(line[i])) /* leading white space is ignored */ + while (ascii_iswhite(line[i])) { // leading white space is ignored ++i; + } /* * Repeat to match several nested comment strings. @@ -102,51 +102,60 @@ int get_leader_len(char_u *line, char_u **flags, for (list = curbuf->b_p_com; *list; ) { /* Get one option part into part_buf[]. Advance "list" to next * one. Put "string" at start of string. */ - if (!got_com && flags != NULL) - *flags = list; /* remember where flags started */ + if (!got_com && flags != NULL) { + *flags = list; // remember where flags started + } prev_list = list; (void)copy_option_part(&list, part_buf, COM_MAX_LEN, ","); string = vim_strchr(part_buf, ':'); - if (string == NULL) /* missing ':', ignore this part */ + if (string == NULL) { // missing ':', ignore this part continue; - *string++ = NUL; /* isolate flags from string */ + } + *string++ = NUL; // isolate flags from string /* If we found a middle match previously, use that match when this * is not a middle or end. */ if (middle_match_len != 0 && vim_strchr(part_buf, COM_MIDDLE) == NULL - && vim_strchr(part_buf, COM_END) == NULL) + && vim_strchr(part_buf, COM_END) == NULL) { break; + } /* When we already found a nested comment, only accept further * nested comments. */ - if (got_com && vim_strchr(part_buf, COM_NEST) == NULL) + if (got_com && vim_strchr(part_buf, COM_NEST) == NULL) { continue; + } - /* When 'O' flag present and using "O" command skip this one. */ - if (backward && vim_strchr(part_buf, COM_NOBACK) != NULL) + // When 'O' flag present and using "O" command skip this one. + if (backward && vim_strchr(part_buf, COM_NOBACK) != NULL) { continue; + } /* Line contents and string must match. * When string starts with white space, must have some white space * (but the amount does not need to match, there might be a mix of * TABs and spaces). */ if (ascii_iswhite(string[0])) { - if (i == 0 || !ascii_iswhite(line[i - 1])) - continue; /* missing white space */ - while (ascii_iswhite(string[0])) + if (i == 0 || !ascii_iswhite(line[i - 1])) { + continue; // missing white space + } + while (ascii_iswhite(string[0])) { ++string; + } } - for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j) + for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j) { ; - if (string[j] != NUL) - continue; /* string doesn't match */ - + } + if (string[j] != NUL) { + continue; // string doesn't match + } /* When 'b' flag used, there must be white space or an * end-of-line after the string in the line. */ if (vim_strchr(part_buf, COM_BLANK) != NULL - && !ascii_iswhite(line[i + j]) && line[i + j] != NUL) + && !ascii_iswhite(line[i + j]) && line[i + j] != NUL) { continue; + } /* We have found a match, stop searching unless this is a middle * comment. The middle comment can be a substring of the end @@ -160,13 +169,15 @@ int get_leader_len(char_u *line, char_u **flags, } continue; } - if (middle_match_len != 0 && j > middle_match_len) + if (middle_match_len != 0 && j > middle_match_len) { /* Use this match instead of the middle match, since it's a * longer thus better match. */ middle_match_len = 0; + } - if (middle_match_len == 0) + if (middle_match_len == 0) { i += j; + } found_one = TRUE; break; } @@ -174,29 +185,34 @@ int get_leader_len(char_u *line, char_u **flags, if (middle_match_len != 0) { /* Use the previously found middle match after failing to find a * match with an end. */ - if (!got_com && flags != NULL) + if (!got_com && flags != NULL) { *flags = saved_flags; + } i += middle_match_len; found_one = TRUE; } - /* No match found, stop scanning. */ - if (!found_one) + // No match found, stop scanning. + if (!found_one) { break; + } result = i; - /* Include any trailing white space. */ - while (ascii_iswhite(line[i])) + // Include any trailing white space. + while (ascii_iswhite(line[i])) { ++i; + } - if (include_space) + if (include_space) { result = i; + } - /* If this comment doesn't nest, stop here. */ + // If this comment doesn't nest, stop here. got_com = TRUE; - if (vim_strchr(part_buf, COM_NEST) == NULL) + if (vim_strchr(part_buf, COM_NEST) == NULL) { break; + } } return result; } @@ -213,12 +229,12 @@ int get_last_leader_offset(char_u *line, char_u **flags) int result = -1; int i, j; int lower_check_bound = 0; - char_u *string; - char_u *com_leader; - char_u *com_flags; - char_u *list; + char_u *string; + char_u *com_leader; + char_u *com_flags; + char_u *list; int found_one; - char_u part_buf[COM_MAX_LEN]; /* buffer for one option part */ + char_u part_buf[COM_MAX_LEN]; // buffer for one option part /* * Repeat to match several nested comment strings. @@ -242,7 +258,7 @@ int get_last_leader_offset(char_u *line, char_u **flags) * happen. */ continue; } - *string++ = NUL; /* Isolate flags from string. */ + *string++ = NUL; // Isolate flags from string. com_leader = string; /* @@ -252,16 +268,19 @@ int get_last_leader_offset(char_u *line, char_u **flags) * TABs and spaces). */ if (ascii_iswhite(string[0])) { - if (i == 0 || !ascii_iswhite(line[i - 1])) + if (i == 0 || !ascii_iswhite(line[i - 1])) { continue; + } while (ascii_iswhite(*string)) { string++; } } - for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j) + for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j) { /* do nothing */; - if (string[j] != NUL) + } + if (string[j] != NUL) { continue; + } /* * When 'b' flag used, there must be white space or an @@ -290,23 +309,25 @@ int get_last_leader_offset(char_u *line, char_u **flags) */ found_one = TRUE; - if (flags) + if (flags) { *flags = flags_save; + } com_flags = flags_save; break; } if (found_one) { - char_u part_buf2[COM_MAX_LEN]; /* buffer for one option part */ + char_u part_buf2[COM_MAX_LEN]; // buffer for one option part int len1, len2, off; result = i; /* * If this comment nests, continue searching. */ - if (vim_strchr(part_buf, COM_NEST) != NULL) + if (vim_strchr(part_buf, COM_NEST) != NULL) { continue; + } lower_check_bound = i; @@ -316,31 +337,36 @@ int get_last_leader_offset(char_u *line, char_u **flags) * the comment leader correctly. */ - while (ascii_iswhite(*com_leader)) + while (ascii_iswhite(*com_leader)) { ++com_leader; + } len1 = (int)STRLEN(com_leader); for (list = curbuf->b_p_com; *list; ) { char_u *flags_save = list; (void)copy_option_part(&list, part_buf2, COM_MAX_LEN, ","); - if (flags_save == com_flags) + if (flags_save == com_flags) { continue; + } string = vim_strchr(part_buf2, ':'); ++string; - while (ascii_iswhite(*string)) + while (ascii_iswhite(*string)) { ++string; + } len2 = (int)STRLEN(string); - if (len2 == 0) + if (len2 == 0) { continue; + } /* Now we have to verify whether string ends with a substring * beginning the com_leader. */ for (off = (len2 > i ? i : len2); off > 0 && off + len1 > len2; ) { --off; if (!STRNCMP(string + off, com_leader, len2 - off)) { - if (i - off < lower_check_bound) + if (i - off < lower_check_bound) { lower_check_bound = i - off; + } } } } @@ -361,7 +387,7 @@ int gchar_pos(pos_T *pos) /* * check_status: called when the status bars for the buffer 'buf' - * need to be updated + * need to be updated */ void check_status(buf_T *buf) { @@ -459,7 +485,7 @@ int is_mouse_key(int c) */ int get_keystroke(MultiQueue *events) { - char_u *buf = NULL; + char_u *buf = NULL; int buflen = 150; int maxlen; int len = 0; @@ -493,9 +519,9 @@ int get_keystroke(MultiQueue *events) n = fix_input_buffer(buf + len, n); len += n; waited = 0; - } else if (len > 0) - ++waited; /* keep track of the waiting time */ - + } else if (len > 0) { + ++waited; // keep track of the waiting time + } if (n > 0) { // found a termcode: adjust length len = n; } @@ -503,19 +529,20 @@ int get_keystroke(MultiQueue *events) continue; } - /* Handle modifier and/or special key code. */ + // Handle modifier and/or special key code. n = buf[0]; if (n == K_SPECIAL) { n = TO_SPECIAL(buf[1], buf[2]); if (buf[1] == KS_MODIFIER || n == K_IGNORE - || (is_mouse_key(n) && n != K_LEFTMOUSE) - ) { - if (buf[1] == KS_MODIFIER) + || (is_mouse_key(n) && n != K_LEFTMOUSE)) { + if (buf[1] == KS_MODIFIER) { mod_mask = buf[2]; + } len -= 3; - if (len > 0) + if (len > 0) { memmove(buf, buf + 3, (size_t)len); + } continue; } break; @@ -534,27 +561,25 @@ int get_keystroke(MultiQueue *events) return n; } -/* - * Get a number from the user. - * When "mouse_used" is not NULL allow using the mouse. - */ -int -get_number ( - int colon, /* allow colon to abort */ - int *mouse_used -) +/// Get a number from the user. +/// When "mouse_used" is not NULL allow using the mouse. +/// +/// @param colon allow colon to abort +int get_number(int colon, int *mouse_used) { int n = 0; int c; int typed = 0; - if (mouse_used != NULL) + if (mouse_used != NULL) { *mouse_used = FALSE; + } /* When not printing messages, the user won't know what to type, return a * zero (as if CR was hit). */ - if (msg_silent != 0) + if (msg_silent != 0) { return 0; + } no_mapping++; for (;; ) { @@ -576,8 +601,9 @@ get_number ( break; } else if (n == 0 && c == ':' && colon) { stuffcharReadbuff(':'); - if (!exmode_active) + if (!exmode_active) { cmdline_row = msg_row; + } skip_redraw = true; // skip redraw once do_redraw = false; break; @@ -643,40 +669,45 @@ void msgmore(long n) { long pn; - if (global_busy /* no messages now, wait until global is finished */ - || !messaging()) /* 'lazyredraw' set, don't do messages now */ + if (global_busy // no messages now, wait until global is finished + || !messaging()) { // 'lazyredraw' set, don't do messages now return; + } /* We don't want to overwrite another important message, but do overwrite * a previous "more lines" or "fewer lines" message, so that "5dd" and * then "put" reports the last action. */ - if (keep_msg != NULL && !keep_msg_more) + if (keep_msg != NULL && !keep_msg_more) { return; + } - if (n > 0) + if (n > 0) { pn = n; - else + } else { pn = -n; + } if (pn > p_report) { if (pn == 1) { - if (n > 0) + if (n > 0) { STRLCPY(msg_buf, _("1 more line"), MSG_BUF_LEN); - else + } else { STRLCPY(msg_buf, _("1 line less"), MSG_BUF_LEN); + } } else { - if (n > 0) - vim_snprintf((char *)msg_buf, MSG_BUF_LEN, - _("%" PRId64 " more lines"), (int64_t)pn); - else - vim_snprintf((char *)msg_buf, MSG_BUF_LEN, - _("%" PRId64 " fewer lines"), (int64_t)pn); + if (n > 0) { + vim_snprintf(msg_buf, MSG_BUF_LEN, + _("%" PRId64 " more lines"), (int64_t)pn); + } else { + vim_snprintf(msg_buf, MSG_BUF_LEN, + _("%" PRId64 " fewer lines"), (int64_t)pn); + } } if (got_int) { - xstrlcat((char *)msg_buf, _(" (Interrupted)"), MSG_BUF_LEN); + xstrlcat(msg_buf, _(" (Interrupted)"), MSG_BUF_LEN); } - if (msg(msg_buf)) { - set_keep_msg(msg_buf, 0); + if (msg((char_u *)msg_buf)) { + set_keep_msg((char_u *)msg_buf, 0); keep_msg_more = true; } } @@ -752,7 +783,7 @@ static void init_users(void) } lazy_init_done = TRUE; - + os_get_usernames(&ga_users); } @@ -762,8 +793,9 @@ static void init_users(void) char_u *get_users(expand_T *xp, int idx) { init_users(); - if (idx < ga_users.ga_len) + if (idx < ga_users.ga_len) { return ((char_u **)ga_users.ga_data)[idx]; + } return NULL; } @@ -780,10 +812,12 @@ int match_user(char_u *name) init_users(); for (int i = 0; i < ga_users.ga_len; i++) { - if (STRCMP(((char_u **)ga_users.ga_data)[i], name) == 0) - return 2; /* full match */ - if (STRNCMP(((char_u **)ga_users.ga_data)[i], name, n) == 0) - result = 1; /* partial match */ + if (STRCMP(((char_u **)ga_users.ga_data)[i], name) == 0) { + return 2; // full match + } + if (STRNCMP(((char_u **)ga_users.ga_data)[i], name, n) == 0) { + result = 1; // partial match + } } return result; } @@ -840,7 +874,7 @@ void preserve_exit(void) */ #ifndef BREAKCHECK_SKIP -# define BREAKCHECK_SKIP 1000 +# define BREAKCHECK_SKIP 1000 #endif static int breakcheck_count = 0; @@ -921,8 +955,7 @@ int call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg) /// @param ret_len length of the stdout /// /// @return an allocated string, or NULL for error. -char_u *get_cmd_output(char_u *cmd, char_u *infile, ShellOpts flags, - size_t *ret_len) +char_u *get_cmd_output(char_u *cmd, char_u *infile, ShellOpts flags, size_t *ret_len) { char_u *buffer = NULL; @@ -970,12 +1003,14 @@ char_u *get_cmd_output(char_u *cmd, char_u *infile, ShellOpts flags, EMSG2(_(e_notread), tempname); XFREE_CLEAR(buffer); } else if (ret_len == NULL) { - /* Change NUL into SOH, otherwise the string is truncated. */ - for (i = 0; i < len; ++i) - if (buffer[i] == NUL) + // Change NUL into SOH, otherwise the string is truncated. + for (i = 0; i < len; ++i) { + if (buffer[i] == NUL) { buffer[i] = 1; + } + } - buffer[len] = NUL; /* make sure the buffer is terminated */ + buffer[len] = NUL; // make sure the buffer is terminated } else { *ret_len = len; } @@ -991,10 +1026,12 @@ done: */ void FreeWild(int count, char_u **files) { - if (count <= 0 || files == NULL) + if (count <= 0 || files == NULL) { return; - while (count--) + } + while (count--) { xfree(files[count]); + } xfree(files); } diff --git a/src/nvim/misc1.h b/src/nvim/misc1.h index f0f66854d8..4ce142c4c5 100644 --- a/src/nvim/misc1.h +++ b/src/nvim/misc1.h @@ -1,15 +1,15 @@ #ifndef NVIM_MISC1_H #define NVIM_MISC1_H -#include "nvim/vim.h" #include "nvim/os/shell.h" +#include "nvim/vim.h" -/* flags for open_line() */ -#define OPENLINE_DELSPACES 1 /* delete spaces after cursor */ -#define OPENLINE_DO_COM 2 /* format comments */ -#define OPENLINE_KEEPTRAIL 4 /* keep trailing spaces */ -#define OPENLINE_MARKFIX 8 /* fix mark positions */ -#define OPENLINE_COM_LIST 16 /* format comments with list/2nd line indent */ +// flags for open_line() +#define OPENLINE_DELSPACES 1 // delete spaces after cursor +#define OPENLINE_DO_COM 2 // format comments +#define OPENLINE_KEEPTRAIL 4 // keep trailing spaces +#define OPENLINE_MARKFIX 8 // fix mark positions +#define OPENLINE_COM_LIST 16 // format comments with list/2nd line indent #ifdef INCLUDE_GENERATED_DECLARATIONS # include "misc1.h.generated.h" diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index c4fa269851..f02c000e82 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -3,26 +3,26 @@ #include <stdbool.h> -#include "nvim/mouse.h" -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/window.h" +#include "nvim/buffer_defs.h" +#include "nvim/charset.h" +#include "nvim/cursor.h" +#include "nvim/diff.h" +#include "nvim/fold.h" +#include "nvim/memline.h" +#include "nvim/misc1.h" +#include "nvim/mouse.h" +#include "nvim/move.h" +#include "nvim/os_unix.h" +#include "nvim/plines.h" +#include "nvim/screen.h" #include "nvim/state.h" #include "nvim/strings.h" -#include "nvim/screen.h" #include "nvim/syntax.h" #include "nvim/ui.h" #include "nvim/ui_compositor.h" -#include "nvim/os_unix.h" -#include "nvim/fold.h" -#include "nvim/diff.h" -#include "nvim/move.h" -#include "nvim/misc1.h" -#include "nvim/plines.h" -#include "nvim/cursor.h" -#include "nvim/buffer_defs.h" -#include "nvim/memline.h" -#include "nvim/charset.h" +#include "nvim/vim.h" +#include "nvim/window.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "mouse.c.generated.h" @@ -31,33 +31,34 @@ static linenr_T orig_topline = 0; static int orig_topfill = 0; -// Move the cursor to the specified row and column on the screen. -// Change current window if necessary. Returns an integer with the -// CURSOR_MOVED bit set if the cursor has moved or unset otherwise. -// -// The MOUSE_FOLD_CLOSE bit is set when clicked on the '-' in a fold column. -// The MOUSE_FOLD_OPEN bit is set when clicked on the '+' in a fold column. -// -// If flags has MOUSE_FOCUS, then the current window will not be changed, and -// if the mouse is outside the window then the text will scroll, or if the -// mouse was previously on a status line, then the status line may be dragged. -// -// If flags has MOUSE_MAY_VIS, then VIsual mode will be started before the -// cursor is moved unless the cursor was on a status line. -// This function returns one of IN_UNKNOWN, IN_BUFFER, IN_STATUS_LINE or -// IN_SEP_LINE depending on where the cursor was clicked. -// -// If flags has MOUSE_MAY_STOP_VIS, then Visual mode will be stopped, unless -// the mouse is on the status line of the same window. -// -// If flags has MOUSE_DID_MOVE, nothing is done if the mouse didn't move since -// the last call. -// -// If flags has MOUSE_SETPOS, nothing is done, only the current position is -// remembered. -int jump_to_mouse(int flags, - bool *inclusive, // used for inclusive operator, can be NULL - int which_button) // MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE +/// Move the cursor to the specified row and column on the screen. +/// Change current window if necessary. Returns an integer with the +/// CURSOR_MOVED bit set if the cursor has moved or unset otherwise. +/// +/// The MOUSE_FOLD_CLOSE bit is set when clicked on the '-' in a fold column. +/// The MOUSE_FOLD_OPEN bit is set when clicked on the '+' in a fold column. +/// +/// If flags has MOUSE_FOCUS, then the current window will not be changed, and +/// if the mouse is outside the window then the text will scroll, or if the +/// mouse was previously on a status line, then the status line may be dragged. +/// +/// If flags has MOUSE_MAY_VIS, then VIsual mode will be started before the +/// cursor is moved unless the cursor was on a status line. +/// This function returns one of IN_UNKNOWN, IN_BUFFER, IN_STATUS_LINE or +/// IN_SEP_LINE depending on where the cursor was clicked. +/// +/// If flags has MOUSE_MAY_STOP_VIS, then Visual mode will be stopped, unless +/// the mouse is on the status line of the same window. +/// +/// If flags has MOUSE_DID_MOVE, nothing is done if the mouse didn't move since +/// the last call. +/// +/// If flags has MOUSE_SETPOS, nothing is done, only the current position is +/// remembered. +/// +/// @param inclusive used for inclusive operator, can be NULL +/// @param which_button MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE +int jump_to_mouse(int flags, bool *inclusive, int which_button) { static int on_status_line = 0; // #lines below bottom of window static int on_sep_line = 0; // on separator right of window @@ -66,7 +67,7 @@ int jump_to_mouse(int flags, static win_T *dragwin = NULL; // window being dragged static int did_drag = false; // drag was noticed - win_T *wp, *old_curwin; + win_T *wp, *old_curwin; pos_T old_cursor; int count; bool first; @@ -81,8 +82,9 @@ int jump_to_mouse(int flags, if (flags & MOUSE_RELEASED) { // On button release we may change window focus if positioned on a // status line and no dragging happened. - if (dragwin != NULL && !did_drag) + if (dragwin != NULL && !did_drag) { flags &= ~(MOUSE_FOCUS | MOUSE_DID_MOVE); + } dragwin = NULL; did_drag = false; } @@ -109,15 +111,16 @@ retnomove: prev_row = mouse_row; prev_col = mouse_col; - if (flags & MOUSE_SETPOS) + if (flags & MOUSE_SETPOS) { goto retnomove; // ugly goto... - + } old_curwin = curwin; old_cursor = curwin->w_cursor; if (!(flags & MOUSE_FOCUS)) { - if (row < 0 || col < 0) // check if it makes sense + if (row < 0 || col < 0) { // check if it makes sense return IN_UNKNOWN; + } // find the window where the row is in wp = mouse_find_win(&grid, &row, &col); @@ -151,10 +154,11 @@ retnomove: // The rightmost character of the status line might be a vertical // separator character if there is no connecting window to the right. if (on_status_line && on_sep_line) { - if (stl_connected(wp)) + if (stl_connected(wp)) { on_sep_line = 0; - else + } else { on_status_line = 0; + } } // Before jumping to another buffer, or moving the cursor for a left @@ -181,28 +185,32 @@ retnomove: // Only change window focus when not clicking on or dragging the // status line. Do change focus when releasing the mouse button // (MOUSE_FOCUS was set above if we dragged first). - if (dragwin == NULL || (flags & MOUSE_RELEASED)) + if (dragwin == NULL || (flags & MOUSE_RELEASED)) { win_enter(wp, true); // can make wp invalid! + } // set topline, to be able to check for double click ourselves - if (curwin != old_curwin) + if (curwin != old_curwin) { set_mouse_topline(curwin); + } if (on_status_line) { // In (or below) status line // Don't use start_arrow() if we're in the same window - if (curwin == old_curwin) + if (curwin == old_curwin) { return IN_STATUS_LINE; - else + } else { return IN_STATUS_LINE | CURSOR_MOVED; + } } if (on_sep_line) { // In (or below) status line // Don't use start_arrow() if we're in the same window - if (curwin == old_curwin) + if (curwin == old_curwin) { return IN_SEP_LINE; - else + } else { return IN_SEP_LINE | CURSOR_MOVED; + } } curwin->w_cursor.lnum = curwin->w_topline; - } else if (on_status_line && which_button == MOUSE_LEFT) { + } else if (on_status_line && which_button == MOUSE_LEFT) { if (dragwin != NULL) { // Drag the status line count = row - dragwin->w_winrow - dragwin->w_height + 1 @@ -211,7 +219,7 @@ retnomove: did_drag |= count; } return IN_STATUS_LINE; // Cursor didn't move - } else if (on_sep_line && which_button == MOUSE_LEFT) { + } else if (on_sep_line && which_button == MOUSE_LEFT) { if (dragwin != NULL) { // Drag the separator column count = col - dragwin->w_wincol - dragwin->w_width + 1 @@ -228,12 +236,17 @@ retnomove: redraw_curbuf_later(INVERTED); // delete the inversion } + if (grid == 0) { + row -= curwin->w_grid_alloc.comp_row+curwin->w_grid.row_offset; + col -= curwin->w_grid_alloc.comp_col+curwin->w_grid.col_offset; + } + // When clicking beyond the end of the window, scroll the screen. // Scroll by however many rows outside the window we are. if (row < 0) { count = 0; for (first = true; curwin->w_topline > 1; ) { - if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)) { + if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) { count++; } else { count += plines_win(curwin, curwin->w_topline - 1, true); @@ -243,8 +256,8 @@ retnomove: } first = false; (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); - if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)) { - ++curwin->w_topfill; + if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) { + curwin->w_topfill++; } else { --curwin->w_topline; curwin->w_topfill = 0; @@ -255,7 +268,7 @@ retnomove: ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP); redraw_later(curwin, VALID); row = 0; - } else if (row >= curwin->w_height_inner) { + } else if (row >= curwin->w_height_inner) { count = 0; for (first = true; curwin->w_topline < curbuf->b_ml.ml_line_count; ) { if (curwin->w_topfill > 0) { @@ -275,11 +288,10 @@ retnomove: } if (curwin->w_topfill > 0) { - --curwin->w_topfill; + curwin->w_topfill--; } else { - ++curwin->w_topline; - curwin->w_topfill = - diff_check_fill(curwin, curwin->w_topline); + curwin->w_topline++; + curwin->w_topfill = win_get_fill(curwin, curwin->w_topline); } } check_topfill(curwin, false); @@ -287,7 +299,7 @@ retnomove: curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP); row = curwin->w_height_inner - 1; - } else if (row == 0) { + } else if (row == 0) { // When dragging the mouse, while the text has been scrolled up as // far as it goes, moving the mouse in the top line should scroll // the text down (done later when recomputing w_topline). @@ -365,12 +377,12 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump) while (row > 0) { // Don't include filler lines in "count" - if (win->w_p_diff + if (win_may_fill(win) && !hasFoldingWin(win, lnum, NULL, NULL, true, NULL)) { if (lnum == win->w_topline) { row -= win->w_topfill; } else { - row -= diff_check_fill(win, lnum); + row -= win_get_fill(win, lnum); } count = plines_win_nofill(win, lnum, true); } else { @@ -394,8 +406,9 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump) if (!retval) { // Compute the column without wrapping. off = win_col_off(win) - win_col_off2(win); - if (col < off) + if (col < off) { col = off; + } col += row * (win->w_width_inner - off); // add skip column (for long wrapping line) col += win->w_skipcol; @@ -431,23 +444,26 @@ win_T *mouse_find_win(int *gridp, int *rowp, int *colp) } - frame_T *fp; + frame_T *fp; fp = topframe; *rowp -= firstwin->w_winrow; for (;; ) { - if (fp->fr_layout == FR_LEAF) + if (fp->fr_layout == FR_LEAF) { break; + } if (fp->fr_layout == FR_ROW) { for (fp = fp->fr_child; fp->fr_next != NULL; fp = fp->fr_next) { - if (*colp < fp->fr_width) + if (*colp < fp->fr_width) { break; + } *colp -= fp->fr_width; } } else { // fr_layout == FR_COL for (fp = fp->fr_child; fp->fr_next != NULL; fp = fp->fr_next) { - if (*rowp < fp->fr_height) + if (*rowp < fp->fr_height) { break; + } *rowp -= fp->fr_height; } } @@ -465,7 +481,7 @@ win_T *mouse_find_win(int *gridp, int *rowp, int *colp) static win_T *mouse_find_grid_win(int *gridp, int *rowp, int *colp) { if (*gridp == msg_grid.handle) { - // rowp += msg_grid_pos; // PVS: dead store #11612 + *rowp += msg_grid_pos; *gridp = DEFAULT_GRID_HANDLE; } else if (*gridp > 1) { win_T *wp = get_win_by_grid_handle(*gridp); @@ -574,21 +590,21 @@ static linenr_T find_longest_lnum(void) bool mouse_scroll_horiz(int dir) { if (curwin->w_p_wrap) { - return false; + return false; } int step = 6; if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { - step = curwin->w_width_inner; + step = curwin->w_width_inner; } int leftcol = curwin->w_leftcol + (dir == MSCR_RIGHT ? -step : +step); if (leftcol < 0) { - leftcol = 0; + leftcol = 0; } if (curwin->w_leftcol == leftcol) { - return false; + return false; } curwin->w_leftcol = (colnr_T)leftcol; @@ -597,8 +613,8 @@ bool mouse_scroll_horiz(int dir) // longest visible line. if (!virtual_active() && (colnr_T)leftcol > scroll_line_len(curwin->w_cursor.lnum)) { - curwin->w_cursor.lnum = find_longest_lnum(); - curwin->w_cursor.col = 0; + curwin->w_cursor.lnum = find_longest_lnum(); + curwin->w_cursor.col = 0; } return leftcol_changed(); @@ -666,8 +682,8 @@ static int mouse_adjust_click(win_T *wp, int row, int col) vcol = offset; -#define incr() nudge++; ptr_end += utfc_ptr2len(ptr_end) -#define decr() nudge--; ptr_end -= utfc_ptr2len(ptr_end) +#define INCR() nudge++; ptr_end += utfc_ptr2len(ptr_end) +#define DECR() nudge--; ptr_end -= utfc_ptr2len(ptr_end) while (ptr < ptr_end && *ptr != NUL) { cwidth = win_chartabsize(curwin, ptr, vcol); @@ -676,7 +692,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) // A tab will "absorb" any previous adjustments. cwidth = MIN(cwidth, nudge); while (cwidth > 0) { - decr(); + DECR(); cwidth--; } } @@ -684,20 +700,20 @@ static int mouse_adjust_click(win_T *wp, int row, int col) matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line)); if (matchid != 0) { if (wp->w_p_cole == 3) { - incr(); + INCR(); } else { if (!(row > 0 && ptr == ptr_row_offset) && (wp->w_p_cole == 1 || (wp->w_p_cole == 2 && (wp->w_p_lcs_chars.conceal != NUL || syn_get_sub_char() != NUL)))) { // At least one placeholder character will be displayed. - decr(); + DECR(); } prev_matchid = matchid; while (prev_matchid == matchid && *ptr != NUL) { - incr(); + INCR(); ptr += utfc_ptr2len(ptr); matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line)); } diff --git a/src/nvim/mouse.h b/src/nvim/mouse.h index 6c5bc5dc0e..bf4f9c57e5 100644 --- a/src/nvim/mouse.h +++ b/src/nvim/mouse.h @@ -3,8 +3,8 @@ #include <stdbool.h> -#include "nvim/vim.h" #include "nvim/buffer_defs.h" +#include "nvim/vim.h" // jump_to_mouse() returns one of first four these values, possibly with // some of the other three added. diff --git a/src/nvim/move.c b/src/nvim/move.c index 9fc434923f..64ba02064f 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -18,7 +18,6 @@ #include "nvim/ascii.h" #include "nvim/buffer.h" -#include "nvim/move.h" #include "nvim/charset.h" #include "nvim/cursor.h" #include "nvim/diff.h" @@ -27,17 +26,18 @@ #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/misc1.h" -#include "nvim/plines.h" +#include "nvim/move.h" #include "nvim/option.h" +#include "nvim/plines.h" #include "nvim/popupmnu.h" #include "nvim/screen.h" #include "nvim/strings.h" #include "nvim/window.h" typedef struct { - linenr_T lnum; /* line number */ - int fill; /* filler lines */ - int height; /* height of added line */ + linenr_T lnum; // line number + int fill; // filler lines + int height; // height of added line } lineoff_T; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -85,7 +85,7 @@ static void comp_botline(win_T *wp) lnum = last; } - /* wp->w_botline is the line that is just below the window */ + // wp->w_botline is the line that is just below the window wp->w_botline = lnum; wp->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP; wp->w_viewport_invalid = true; @@ -197,7 +197,7 @@ void update_topline(win_T *wp) } } // Check if there are more filler lines than allowed. - if (!check_topline && wp->w_topfill > diff_check_fill(wp, wp->w_topline)) { + if (!check_topline && wp->w_topfill > win_get_fill(wp, wp->w_topline)) { check_topline = true; } @@ -274,8 +274,7 @@ void update_topline(win_T *wp) n += wp->w_filler_rows; loff.height = 0; while (loff.lnum < wp->w_botline - && (loff.lnum + 1 < wp->w_botline || loff.fill == 0) - ) { + && (loff.lnum + 1 < wp->w_botline || loff.fill == 0)) { n += loff.height; if (n >= *so_ptr) { break; @@ -287,7 +286,7 @@ void update_topline(win_T *wp) check_botline = false; } } else { - /* sufficient context, no need to scroll */ + // sufficient context, no need to scroll check_botline = false; } } @@ -325,8 +324,7 @@ void update_topline(win_T *wp) * Need to redraw when topline changed. */ if (wp->w_topline != old_topline - || wp->w_topfill != old_topfill - ) { + || wp->w_topfill != old_topfill) { dollar_vcol = -1; if (wp->w_skipcol != 0) { wp->w_skipcol = 0; @@ -346,7 +344,7 @@ void update_topline(win_T *wp) /* * Update win->w_topline to move the cursor onto the screen. */ -void update_topline_win(win_T* win) +void update_topline_win(win_T *win) { win_T *save_curwin; switch_win(&save_curwin, NULL, win, NULL, true); @@ -374,8 +372,7 @@ static bool check_top_offset(void) { long so = get_scrolloff_value(curwin); if (curwin->w_cursor.lnum < curwin->w_topline + so - || hasAnyFolding(curwin) - ) { + || hasAnyFolding(curwin)) { lineoff_T loff; loff.lnum = curwin->w_cursor.lnum; loff.fill = 0; @@ -385,8 +382,8 @@ static bool check_top_offset(void) topline_back(curwin, &loff); // Stop when included a line above the window. if (loff.lnum < curwin->w_topline - || (loff.lnum == curwin->w_topline && loff.fill > 0) - ) { + || (loff.lnum == curwin->w_topline && + loff.fill > 0)) { break; } n += loff.height; @@ -420,8 +417,8 @@ void check_cursor_moved(win_T *wp) wp->w_viewport_invalid = true; } else if (wp->w_cursor.col != wp->w_valid_cursor.col || wp->w_leftcol != wp->w_valid_leftcol - || wp->w_cursor.coladd != wp->w_valid_cursor.coladd - ) { + || wp->w_cursor.coladd != + wp->w_valid_cursor.coladd) { wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL); wp->w_valid_cursor.col = wp->w_cursor.col; wp->w_valid_leftcol = wp->w_leftcol; @@ -560,7 +557,7 @@ void validate_cursor(void) */ static void curs_rows(win_T *wp) { - /* Check if wp->w_lines[].wl_size is invalid */ + // Check if wp->w_lines[].wl_size is invalid int all_invalid = (!redrawing() || wp->w_lines_valid == 0 || wp->w_lines[0].wl_lnum > wp->w_topline); @@ -569,27 +566,28 @@ static void curs_rows(win_T *wp) for (linenr_T lnum = wp->w_topline; lnum < wp->w_cursor.lnum; ++i) { bool valid = false; if (!all_invalid && i < wp->w_lines_valid) { - if (wp->w_lines[i].wl_lnum < lnum || !wp->w_lines[i].wl_valid) - continue; /* skip changed or deleted lines */ + if (wp->w_lines[i].wl_lnum < lnum || !wp->w_lines[i].wl_valid) { + continue; // skip changed or deleted lines + } if (wp->w_lines[i].wl_lnum == lnum) { /* Check for newly inserted lines below this row, in which * case we need to check for folded lines. */ if (!wp->w_buffer->b_mod_set || wp->w_lines[i].wl_lastlnum < wp->w_cursor.lnum - || wp->w_buffer->b_mod_top - > wp->w_lines[i].wl_lastlnum + 1) + || wp->w_buffer->b_mod_top + > wp->w_lines[i].wl_lastlnum + 1) { valid = true; + } } else if (wp->w_lines[i].wl_lnum > lnum) { - --i; /* hold at inserted lines */ + --i; // hold at inserted lines } } - if (valid - && (lnum != wp->w_topline || !wp->w_p_diff) - ) { + if (valid && (lnum != wp->w_topline || !win_may_fill(wp))) { lnum = wp->w_lines[i].wl_lastlnum + 1; - /* Cursor inside folded lines, don't count this row */ - if (lnum > wp->w_cursor.lnum) + // Cursor inside folded lines, don't count this row + if (lnum > wp->w_cursor.lnum) { break; + } wp->w_cline_row += wp->w_lines[i].wl_size; } else { linenr_T last = lnum; @@ -613,7 +611,7 @@ static void curs_rows(win_T *wp) wp->w_cline_height = plines_win_full(wp, wp->w_cursor.lnum, NULL, &wp->w_cline_folded, true); } else if (i > wp->w_lines_valid) { - /* a line that is too long to fit on the last screen line */ + // a line that is too long to fit on the last screen line wp->w_cline_height = 0; wp->w_cline_folded = hasFoldingWin(wp, wp->w_cursor.lnum, NULL, NULL, true, NULL); @@ -645,9 +643,9 @@ void validate_virtcol_win(win_T *wp) getvvcol(wp, &wp->w_cursor, NULL, &(wp->w_virtcol), NULL); wp->w_valid |= VALID_VIRTCOL; if (wp->w_p_cuc - && !pum_visible() - ) + && !pum_visible()) { redraw_later(wp, SOME_VALID); + } } } @@ -718,8 +716,9 @@ int curwin_col_off(void) */ int win_col_off2(win_T *wp) { - if ((wp->w_p_nu || wp->w_p_rnu) && vim_strchr(p_cpo, CPO_NUMCOL) != NULL) + if ((wp->w_p_nu || wp->w_p_rnu) && vim_strchr(p_cpo, CPO_NUMCOL) != NULL) { return number_width(wp) + 1; + } return 0; } @@ -732,10 +731,7 @@ int curwin_col_off2(void) // Also updates curwin->w_wrow and curwin->w_cline_row. // Also updates curwin->w_leftcol. // @param may_scroll when true, may scroll horizontally -void curs_columns( - win_T *wp, - int may_scroll -) +void curs_columns(win_T *wp, int may_scroll) { int n; int width = 0; @@ -765,9 +761,10 @@ void curs_columns( getvvcol(wp, &wp->w_cursor, &startcol, &(wp->w_virtcol), &endcol); } - /* remove '$' from change command when cursor moves onto it */ - if (startcol > dollar_vcol) + // remove '$' from change command when cursor moves onto it + if (startcol > dollar_vcol) { dollar_vcol = -1; + } int extra = win_col_off(wp); wp->w_wcol = wp->w_virtcol + extra; @@ -782,8 +779,7 @@ void curs_columns( wp->w_wcol = wp->w_width_inner - 1; wp->w_wrow = wp->w_height_inner - 1; } else if (wp->w_p_wrap - && wp->w_width_inner != 0 - ) { + && wp->w_width_inner != 0) { width = textwidth + win_col_off2(wp); // long line wrapping, adjust wp->w_wrow @@ -798,13 +794,12 @@ void curs_columns( // column char_u *const sbr = get_showbreak_value(wp); if (*sbr && *get_cursor_pos_ptr() == NUL - && wp->w_wcol == (int)vim_strsize(sbr)) { + && wp->w_wcol == vim_strsize(sbr)) { wp->w_wcol = 0; } } } else if (may_scroll - && !wp->w_cline_folded - ) { + && !wp->w_cline_folded) { // No line wrapping: compute wp->w_leftcol if scrolling is on and line // is not folded. // If scrolling is off, wp->w_leftcol is assumed to be 0 @@ -816,7 +811,7 @@ void curs_columns( assert(siso <= INT_MAX); int off_left = startcol - wp->w_leftcol - (int)siso; int off_right = - endcol - wp->w_leftcol - wp->w_width_inner + (int)siso + 1; + endcol - wp->w_leftcol - wp->w_width_inner + (int)siso + 1; if (off_left < 0 || off_right > 0) { int diff = (off_left < 0) ? -off_left: off_right; @@ -836,8 +831,9 @@ void curs_columns( new_leftcol = wp->w_leftcol + diff; } } - if (new_leftcol < 0) + if (new_leftcol < 0) { new_leftcol = 0; + } if (new_leftcol != (int)wp->w_leftcol) { wp->w_leftcol = new_leftcol; win_check_anchored_floats(wp); @@ -857,7 +853,7 @@ void curs_columns( if (wp->w_cursor.lnum == wp->w_topline) { wp->w_wrow += wp->w_topfill; } else { - wp->w_wrow += diff_check_fill(wp, wp->w_cursor.lnum); + wp->w_wrow += win_get_fill(wp, wp->w_cursor.lnum); } prev_skipcol = wp->w_skipcol; @@ -867,13 +863,12 @@ void curs_columns( || ((prev_skipcol > 0 || wp->w_wrow + so >= wp->w_height_inner) && (plines = - plines_win_nofill(wp, wp->w_cursor.lnum, false)) - 1 + plines_win_nofill(wp, wp->w_cursor.lnum, false)) - 1 >= wp->w_height_inner)) && wp->w_height_inner != 0 && wp->w_cursor.lnum == wp->w_topline && width > 0 - && wp->w_width_inner != 0 - ) { + && wp->w_width_inner != 0) { /* Cursor past end of screen. Happens with a single line that does * not fit on screen. Find a skipcol to show the text around the * cursor. Avoid scrolling all the time. compute value of "extra": @@ -972,8 +967,8 @@ void curs_columns( /// @param[out] scolp start screen column /// @param[out] ccolp cursor screen column /// @param[out] ecolp end screen column -void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp, - int *ccolp, int *ecolp, bool local) +void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp, int *ccolp, int *ecolp, + bool local) { colnr_T scol = 0, ccol = 0, ecol = 0; int row = 0; @@ -996,7 +991,7 @@ void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp, if ((local && existing_row) || visible_row) { colnr_T off; colnr_T col; - int width; + int width; getvcol(wp, pos, &scol, &ccol, &ecol); @@ -1041,39 +1036,42 @@ bool scrolldown(long line_count, int byfold) { int done = 0; // total # of physical lines done - /* Make sure w_topline is at the first of a sequence of folded lines. */ + // Make sure w_topline is at the first of a sequence of folded lines. (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); - validate_cursor(); /* w_wrow needs to be valid */ + validate_cursor(); // w_wrow needs to be valid while (line_count-- > 0) { - if (curwin->w_topfill < diff_check(curwin, curwin->w_topline) + if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline) && curwin->w_topfill < curwin->w_height_inner - 1) { curwin->w_topfill++; done++; } else { - if (curwin->w_topline == 1) + if (curwin->w_topline == 1) { break; + } --curwin->w_topline; curwin->w_topfill = 0; - /* A sequence of folded lines only counts for one logical line */ + // A sequence of folded lines only counts for one logical line linenr_T first; if (hasFolding(curwin->w_topline, &first, NULL)) { ++done; - if (!byfold) + if (!byfold) { line_count -= curwin->w_topline - first - 1; + } curwin->w_botline -= curwin->w_topline - first; curwin->w_topline = first; } else { done += plines_win_nofill(curwin, curwin->w_topline, true); } } - --curwin->w_botline; /* approximate w_botline */ + --curwin->w_botline; // approximate w_botline invalidate_botline(); } - curwin->w_wrow += done; /* keep w_wrow updated */ - curwin->w_cline_row += done; /* keep w_cline_row updated */ + curwin->w_wrow += done; // keep w_wrow updated + curwin->w_cline_row += done; // keep w_cline_row updated - if (curwin->w_cursor.lnum == curwin->w_topline) + if (curwin->w_cursor.lnum == curwin->w_topline) { curwin->w_cline_row = 0; + } check_topfill(curwin, true); /* @@ -1082,8 +1080,7 @@ bool scrolldown(long line_count, int byfold) */ int wrow = curwin->w_wrow; if (curwin->w_p_wrap - && curwin->w_width_inner != 0 - ) { + && curwin->w_width_inner != 0) { validate_virtcol(); validate_cheight(); wrow += curwin->w_cline_height - 1 - @@ -1094,10 +1091,11 @@ bool scrolldown(long line_count, int byfold) linenr_T first; if (hasFolding(curwin->w_cursor.lnum, &first, NULL)) { --wrow; - if (first == 1) + if (first == 1) { curwin->w_cursor.lnum = 1; - else + } else { curwin->w_cursor.lnum = first - 1; + } } else { wrow -= plines_win(curwin, curwin->w_cursor.lnum--, true); } @@ -1106,7 +1104,7 @@ bool scrolldown(long line_count, int byfold) moved = true; } if (moved) { - /* Move cursor to first line of closed fold. */ + // Move cursor to first line of closed fold. foldAdjustCursor(); coladvance(curwin->w_curswant); } @@ -1123,39 +1121,44 @@ bool scrollup(long line_count, int byfold) linenr_T botline = curwin->w_botline; if ((byfold && hasAnyFolding(curwin)) - || curwin->w_p_diff) { + || win_may_fill(curwin)) { // count each sequence of folded lines as one logical line linenr_T lnum = curwin->w_topline; while (line_count--) { - if (curwin->w_topfill > 0) + if (curwin->w_topfill > 0) { --curwin->w_topfill; - else { - if (byfold) + } else { + if (byfold) { (void)hasFolding(lnum, NULL, &lnum); - if (lnum >= curbuf->b_ml.ml_line_count) + } + if (lnum >= curbuf->b_ml.ml_line_count) { break; - ++lnum; - curwin->w_topfill = diff_check_fill(curwin, lnum); + } + lnum++; + curwin->w_topfill = win_get_fill(curwin, lnum); } } - /* approximate w_botline */ + // approximate w_botline curwin->w_botline += lnum - curwin->w_topline; curwin->w_topline = lnum; } else { curwin->w_topline += line_count; - curwin->w_botline += line_count; /* approximate w_botline */ + curwin->w_botline += line_count; // approximate w_botline } - if (curwin->w_topline > curbuf->b_ml.ml_line_count) + if (curwin->w_topline > curbuf->b_ml.ml_line_count) { curwin->w_topline = curbuf->b_ml.ml_line_count; - if (curwin->w_botline > curbuf->b_ml.ml_line_count + 1) + } + if (curwin->w_botline > curbuf->b_ml.ml_line_count + 1) { curwin->w_botline = curbuf->b_ml.ml_line_count + 1; + } check_topfill(curwin, false); - if (hasAnyFolding(curwin)) - /* Make sure w_topline is at the first of a sequence of folded lines. */ + if (hasAnyFolding(curwin)) { + // Make sure w_topline is at the first of a sequence of folded lines. (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); + } curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE); if (curwin->w_cursor.lnum < curwin->w_topline) { @@ -1166,19 +1169,15 @@ bool scrollup(long line_count, int byfold) } bool moved = topline != curwin->w_topline - || botline != curwin->w_botline; + || botline != curwin->w_botline; return moved; } -/* - * Don't end up with too many filler lines in the window. - */ -void -check_topfill ( - win_T *wp, - bool down /* when true scroll down when not enough space */ -) +/// Don't end up with too many filler lines in the window. +/// +/// @param down when true scroll down when not enough space +void check_topfill(win_T *wp, bool down) { if (wp->w_topfill > 0) { int n = plines_win_nofill(wp, wp->w_topline, true); @@ -1207,7 +1206,7 @@ static void max_topfill(void) if (n >= curwin->w_height_inner) { curwin->w_topfill = 0; } else { - curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline); + curwin->w_topfill = win_get_fill(curwin, curwin->w_topline); if (curwin->w_topfill + n > curwin->w_height_inner) { curwin->w_topfill = curwin->w_height_inner - n; } @@ -1220,15 +1219,14 @@ static void max_topfill(void) */ void scrolldown_clamp(void) { - int can_fill = (curwin->w_topfill - < diff_check_fill(curwin, curwin->w_topline)); + int can_fill = (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)); if (curwin->w_topline <= 1 - && !can_fill - ) + && !can_fill) { return; + } - validate_cursor(); /* w_wrow needs to be valid */ + validate_cursor(); // w_wrow needs to be valid // Compute the row number of the last row of the cursor line // and make sure it doesn't go off the screen. Make sure the cursor @@ -1254,7 +1252,7 @@ void scrolldown_clamp(void) curwin->w_topfill = 0; } (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); - --curwin->w_botline; /* approximate w_botline */ + --curwin->w_botline; // approximate w_botline curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE); } } @@ -1266,11 +1264,11 @@ void scrolldown_clamp(void) void scrollup_clamp(void) { if (curwin->w_topline == curbuf->b_ml.ml_line_count - && curwin->w_topfill == 0 - ) + && curwin->w_topfill == 0) { return; + } - validate_cursor(); /* w_wrow needs to be valid */ + validate_cursor(); // w_wrow needs to be valid // Compute the row number of the first row of the cursor line // and make sure it doesn't go off the screen. Make sure the cursor @@ -1302,7 +1300,7 @@ void scrollup_clamp(void) */ static void topline_back(win_T *wp, lineoff_T *lp) { - if (lp->fill < diff_check_fill(wp, lp->lnum)) { + if (lp->fill < win_get_fill(wp, lp->lnum)) { // Add a filler line lp->fill++; lp->height = 1; @@ -1328,7 +1326,7 @@ static void topline_back(win_T *wp, lineoff_T *lp) */ static void botline_forw(win_T *wp, lineoff_T *lp) { - if (lp->fill < diff_check_fill(wp, lp->lnum + 1)) { + if (lp->fill < win_get_fill(wp, lp->lnum + 1)) { // Add a filler line. lp->fill++; lp->height = 1; @@ -1355,8 +1353,8 @@ static void botline_forw(win_T *wp, lineoff_T *lp) static void botline_topline(lineoff_T *lp) { if (lp->fill > 0) { - ++lp->lnum; - lp->fill = diff_check_fill(curwin, lp->lnum) - lp->fill + 1; + lp->lnum++; + lp->fill = win_get_fill(curwin, lp->lnum) - lp->fill + 1; } } @@ -1368,8 +1366,8 @@ static void botline_topline(lineoff_T *lp) static void topline_botline(lineoff_T *lp) { if (lp->fill > 0) { - lp->fill = diff_check_fill(curwin, lp->lnum) - lp->fill + 1; - --lp->lnum; + lp->fill = win_get_fill(curwin, lp->lnum) - lp->fill + 1; + lp->lnum--; } } @@ -1381,15 +1379,16 @@ static void topline_botline(lineoff_T *lp) void scroll_cursor_top(int min_scroll, int always) { int scrolled = 0; - linenr_T top; /* just above displayed lines */ - linenr_T bot; /* just below displayed lines */ + linenr_T top; // just above displayed lines + linenr_T bot; // just below displayed lines linenr_T old_topline = curwin->w_topline; linenr_T old_topfill = curwin->w_topfill; linenr_T new_topline; int off = (int)get_scrolloff_value(curwin); - if (mouse_dragging > 0) + if (mouse_dragging > 0) { off = mouse_dragging - 1; + } /* * Decrease topline until: @@ -1416,7 +1415,7 @@ void scroll_cursor_top(int min_scroll, int always) // "used" already contains the number of filler lines above, don't add it // again. // Hide filler lines above cursor line by adding them to "extra". - int extra = diff_check_fill(curwin, curwin->w_cursor.lnum); + int extra = win_get_fill(curwin, curwin->w_cursor.lnum); /* * Check if the lines from "top" to "bot" fit in the window. If they do, @@ -1446,8 +1445,9 @@ void scroll_cursor_top(int min_scroll, int always) * If scrolling is needed, scroll at least 'sj' lines. */ if ((new_topline >= curwin->w_topline || scrolled > min_scroll) - && extra >= off) + && extra >= off) { break; + } extra += i; new_topline = top; @@ -1467,22 +1467,25 @@ void scroll_cursor_top(int min_scroll, int always) * If "always" is false, only adjust topline to a lower value, higher * value may happen with wrapping lines */ - if (new_topline < curwin->w_topline || always) + if (new_topline < curwin->w_topline || always) { curwin->w_topline = new_topline; - if (curwin->w_topline > curwin->w_cursor.lnum) + } + if (curwin->w_topline > curwin->w_cursor.lnum) { curwin->w_topline = curwin->w_cursor.lnum; - curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline); + } + curwin->w_topfill = win_get_fill(curwin, curwin->w_topline); if (curwin->w_topfill > 0 && extra > off) { curwin->w_topfill -= extra - off; - if (curwin->w_topfill < 0) + if (curwin->w_topfill < 0) { curwin->w_topfill = 0; + } } check_topfill(curwin, false); if (curwin->w_topline != old_topline - || curwin->w_topfill != old_topfill - ) + || curwin->w_topfill != old_topfill) { curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP); + } curwin->w_valid |= VALID_TOPLINE; curwin->w_viewport_invalid = true; } @@ -1500,10 +1503,10 @@ void set_empty_rows(win_T *wp, int used) } else { wp->w_empty_rows = wp->w_height_inner - used; if (wp->w_botline <= wp->w_buffer->b_ml.ml_line_count) { - wp->w_filler_rows = diff_check_fill(wp, wp->w_botline); - if (wp->w_empty_rows > wp->w_filler_rows) + wp->w_filler_rows = win_get_fill(wp, wp->w_botline); + if (wp->w_empty_rows > wp->w_filler_rows) { wp->w_empty_rows -= wp->w_filler_rows; - else { + } else { wp->w_filler_rows = wp->w_empty_rows; wp->w_empty_rows = 0; } @@ -1526,10 +1529,10 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) lineoff_T boff; int fill_below_window; linenr_T old_topline = curwin->w_topline; - int old_topfill = curwin->w_topfill; + int old_topfill = curwin->w_topfill; linenr_T old_botline = curwin->w_botline; - int old_valid = curwin->w_valid; - int old_empty_rows = curwin->w_empty_rows; + int old_valid = curwin->w_valid; + int old_empty_rows = curwin->w_empty_rows; linenr_T cln = curwin->w_cursor.lnum; // Cursor Line Number long so = get_scrolloff_value(curwin); @@ -1552,9 +1555,9 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) set_empty_rows(curwin, used); curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP; if (curwin->w_topline != old_topline - || curwin->w_topfill != old_topfill - ) + || curwin->w_topfill != old_topfill) { curwin->w_valid &= ~(VALID_WROW|VALID_CROW); + } } else { validate_botline(curwin); } @@ -1567,8 +1570,9 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) // botline. if (cln >= curwin->w_botline) { scrolled = used; - if (cln == curwin->w_botline) + if (cln == curwin->w_botline) { scrolled -= curwin->w_empty_rows; + } } /* @@ -1584,7 +1588,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) } loff.fill = 0; boff.fill = 0; - fill_below_window = diff_check_fill(curwin, curwin->w_botline) + fill_below_window = win_get_fill(curwin, curwin->w_botline) - curwin->w_filler_rows; while (loff.lnum > 1) { @@ -1595,8 +1599,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) || boff.lnum + 1 > curbuf->b_ml.ml_line_count) && loff.lnum <= curwin->w_botline && (loff.lnum < curwin->w_botline - || loff.fill >= fill_below_window) - ) { + || loff.fill >= fill_below_window)) { break; } @@ -1612,9 +1615,8 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) } if (loff.lnum >= curwin->w_botline && (loff.lnum > curwin->w_botline - || loff.fill <= fill_below_window) - ) { - /* Count screen lines that are below the window. */ + || loff.fill <= fill_below_window)) { + // Count screen lines that are below the window. scrolled += loff.height; if (loff.lnum == curwin->w_botline && loff.fill == 0) { @@ -1634,14 +1636,13 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) extra += boff.height; if (boff.lnum >= curwin->w_botline || (boff.lnum + 1 == curwin->w_botline - && boff.fill > curwin->w_filler_rows) - ) { - /* Count screen lines that are below the window. */ + && boff.fill > curwin->w_filler_rows)) { + // Count screen lines that are below the window. scrolled += boff.height; if (boff.lnum == curwin->w_botline - && boff.fill == 0 - ) + && boff.fill == 0) { scrolled -= curwin->w_empty_rows; + } } } } @@ -1651,10 +1652,10 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) // curwin->w_empty_rows is larger, no need to scroll if (scrolled <= 0) { line_count = 0; - // more than a screenfull, don't scroll but redraw + // more than a screenfull, don't scroll but redraw } else if (used > curwin->w_height_inner) { line_count = used; - // scroll minimal number of lines + // scroll minimal number of lines } else { line_count = 0; boff.fill = curwin->w_topfill; @@ -1665,8 +1666,9 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) i += boff.height; ++line_count; } - if (i < scrolled) /* below curwin->w_botline, don't scroll */ + if (i < scrolled) { // below curwin->w_botline, don't scroll line_count = 9999; + } } /* @@ -1713,7 +1715,7 @@ void scroll_cursor_halfway(int atend) boff.fill = 0; linenr_T topline = loff.lnum; while (topline > 1) { - if (below <= above) { /* add a line below the cursor first */ + if (below <= above) { // add a line below the cursor first if (boff.lnum < curbuf->b_ml.ml_line_count) { botline_forw(curwin, &boff); used += boff.height; @@ -1722,9 +1724,10 @@ void scroll_cursor_halfway(int atend) } below += boff.height; } else { - ++below; /* count a "~" line */ - if (atend) + ++below; // count a "~" line + if (atend) { ++used; + } } } @@ -1743,8 +1746,9 @@ void scroll_cursor_halfway(int atend) topfill = loff.fill; } } - if (!hasFolding(topline, &curwin->w_topline, NULL)) + if (!hasFolding(topline, &curwin->w_topline, NULL)) { curwin->w_topline = topline; + } curwin->w_topfill = topfill; if (old_topline > curwin->w_topline + curwin->w_height_inner) { curwin->w_botfill = false; @@ -1793,12 +1797,12 @@ void cursor_correct(void) * If there are sufficient file-lines above and below the cursor, we can * return now. */ - linenr_T cln = curwin->w_cursor.lnum; /* Cursor Line Number */ + linenr_T cln = curwin->w_cursor.lnum; // Cursor Line Number if (cln >= curwin->w_topline + above_wanted && cln < curwin->w_botline - below_wanted - && !hasAnyFolding(curwin) - ) + && !hasAnyFolding(curwin)) { return; + } /* * Narrow down the area where the cursor can be put by taking lines from @@ -1808,9 +1812,9 @@ void cursor_correct(void) */ linenr_T topline = curwin->w_topline; linenr_T botline = curwin->w_botline - 1; - /* count filler lines as context */ - int above = curwin->w_topfill; /* screen lines above topline */ - int below = curwin->w_filler_rows; /* screen lines below botline */ + // count filler lines as context + int above = curwin->w_topfill; // screen lines above topline + int below = curwin->w_filler_rows; // screen lines below botline while ((above < above_wanted || below < below_wanted) && topline < botline) { if (below < below_wanted && (below <= above || above >= above_wanted)) { if (hasFolding(botline, &botline, NULL)) { @@ -1827,17 +1831,18 @@ void cursor_correct(void) above += plines_win_nofill(curwin, topline, true); } - /* Count filler lines below this line as context. */ - if (topline < botline) - above += diff_check_fill(curwin, topline + 1); + // Count filler lines below this line as context. + if (topline < botline) { + above += win_get_fill(curwin, topline + 1); + } ++topline; } } - if (topline == botline || botline == 0) + if (topline == botline || botline == 0) { curwin->w_cursor.lnum = topline; - else if (topline > botline) + } else if (topline > botline) { curwin->w_cursor.lnum = botline; - else { + } else { if (cln < topline && curwin->w_topline > 1) { curwin->w_cursor.lnum = topline; curwin->w_valid &= @@ -1867,7 +1872,7 @@ int onepage(Direction dir, long count) linenr_T old_topline = curwin->w_topline; long so = get_scrolloff_value(curwin); - if (curbuf->b_ml.ml_line_count == 1) { /* nothing to do */ + if (curbuf->b_ml.ml_line_count == 1) { // nothing to do beep_flush(); return FAIL; } @@ -1882,9 +1887,7 @@ int onepage(Direction dir, long count) ? ((curwin->w_topline >= curbuf->b_ml.ml_line_count - so) && curwin->w_botline > curbuf->b_ml.ml_line_count) : (curwin->w_topline == 1 - && curwin->w_topfill == - diff_check_fill(curwin, curwin->w_topline) - )) { + && curwin->w_topfill == win_get_fill(curwin, curwin->w_topline))) { beep_flush(); retval = FAIL; break; @@ -1893,16 +1896,18 @@ int onepage(Direction dir, long count) loff.fill = 0; if (dir == FORWARD) { if (ONE_WINDOW && p_window > 0 && p_window < Rows - 1) { - /* Vi compatible scrolling */ - if (p_window <= 2) + // Vi compatible scrolling + if (p_window <= 2) { ++curwin->w_topline; - else + } else { curwin->w_topline += p_window - 2; - if (curwin->w_topline > curbuf->b_ml.ml_line_count) + } + if (curwin->w_topline > curbuf->b_ml.ml_line_count) { curwin->w_topline = curbuf->b_ml.ml_line_count; + } curwin->w_cursor.lnum = curwin->w_topline; } else if (curwin->w_botline > curbuf->b_ml.ml_line_count) { - /* at end of file */ + // at end of file curwin->w_topline = curbuf->b_ml.ml_line_count; curwin->w_topfill = 0; curwin->w_valid &= ~(VALID_WROW|VALID_CROW); @@ -1910,7 +1915,7 @@ int onepage(Direction dir, long count) /* For the overlap, start with the line just below the window * and go upwards. */ loff.lnum = curwin->w_botline; - loff.fill = diff_check_fill(curwin, loff.lnum) + loff.fill = win_get_fill(curwin, loff.lnum) - curwin->w_filler_rows; get_scroll_overlap(&loff, -1); curwin->w_topline = loff.lnum; @@ -1920,23 +1925,26 @@ int onepage(Direction dir, long count) curwin->w_valid &= ~(VALID_WCOL|VALID_CHEIGHT|VALID_WROW| VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP); } - } else { /* dir == BACKWARDS */ + } else { // dir == BACKWARDS if (curwin->w_topline == 1) { - /* Include max number of filler lines */ + // Include max number of filler lines max_topfill(); continue; } if (ONE_WINDOW && p_window > 0 && p_window < Rows - 1) { - /* Vi compatible scrolling (sort of) */ - if (p_window <= 2) + // Vi compatible scrolling (sort of) + if (p_window <= 2) { --curwin->w_topline; - else + } else { curwin->w_topline -= p_window - 2; - if (curwin->w_topline < 1) + } + if (curwin->w_topline < 1) { curwin->w_topline = 1; + } curwin->w_cursor.lnum = curwin->w_topline + p_window - 1; - if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) + if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) { curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; + } continue; } @@ -1944,8 +1952,7 @@ int onepage(Direction dir, long count) * line at the bottom of the window. Make sure this results in * the same line as before doing CTRL-F. */ loff.lnum = curwin->w_topline - 1; - loff.fill = diff_check_fill(curwin, loff.lnum + 1) - - curwin->w_topfill; + loff.fill = win_get_fill(curwin, loff.lnum + 1) - curwin->w_topfill; get_scroll_overlap(&loff, 1); if (loff.lnum >= curbuf->b_ml.ml_line_count) { @@ -1967,12 +1974,12 @@ int onepage(Direction dir, long count) n += loff.height; } } - if (loff.lnum < 1) { /* at begin of file */ + if (loff.lnum < 1) { // at begin of file curwin->w_topline = 1; max_topfill(); curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE); } else { - /* Go two lines forward again. */ + // Go two lines forward again. topline_botline(&loff); botline_forw(curwin, &loff); botline_forw(curwin, &loff); @@ -1984,14 +1991,13 @@ int onepage(Direction dir, long count) * very long lines. */ if (loff.lnum >= curwin->w_topline && (loff.lnum > curwin->w_topline - || loff.fill >= curwin->w_topfill) - ) { + || loff.fill >= curwin->w_topfill)) { /* First try using the maximum number of filler lines. If * that's not enough, backup one line. */ loff.fill = curwin->w_topfill; - if (curwin->w_topfill < diff_check_fill(curwin, - curwin->w_topline)) + if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) { max_topfill(); + } if (curwin->w_topfill == loff.fill) { --curwin->w_topline; curwin->w_topfill = 0; @@ -2042,12 +2048,12 @@ int onepage(Direction dir, long count) * This is symmetric, so that doing both keeps the same lines displayed. * Three lines are examined: * - * before CTRL-F after CTRL-F / before CTRL-B - * etc. l1 - * l1 last but one line ------------ - * l2 last text line l2 top text line - * ------------- l3 second text line - * l3 etc. + * before CTRL-F after CTRL-F / before CTRL-B + * etc. l1 + * l1 last but one line ------------ + * l2 last text line l2 top text line + * ------------- l3 second text line + * l3 etc. */ static void get_scroll_overlap(lineoff_T *lp, int dir) { @@ -2059,9 +2065,9 @@ static void get_scroll_overlap(lineoff_T *lp, int dir) lp->height = plines_win_nofill(curwin, lp->lnum, true); } int h1 = lp->height; - if (h1 > min_height) - return; /* no overlap */ - + if (h1 > min_height) { + return; // no overlap + } lineoff_T loff0 = *lp; if (dir > 0) { botline_forw(curwin, lp); @@ -2070,7 +2076,7 @@ static void get_scroll_overlap(lineoff_T *lp, int dir) } int h2 = lp->height; if (h2 == MAXCOL || h2 + h1 > min_height) { - *lp = loff0; /* no overlap */ + *lp = loff0; // no overlap return; } @@ -2082,7 +2088,7 @@ static void get_scroll_overlap(lineoff_T *lp, int dir) } int h3 = lp->height; if (h3 == MAXCOL || h3 + h2 > min_height) { - *lp = loff0; /* no overlap */ + *lp = loff0; // no overlap return; } @@ -2093,11 +2099,11 @@ static void get_scroll_overlap(lineoff_T *lp, int dir) topline_back(curwin, lp); } int h4 = lp->height; - if (h4 == MAXCOL || h4 + h3 + h2 > min_height || h3 + h2 + h1 > min_height) - *lp = loff1; /* 1 line overlap */ - else - *lp = loff2; /* 2 lines overlap */ - return; + if (h4 == MAXCOL || h4 + h3 + h2 > min_height || h3 + h2 + h1 > min_height) { + *lp = loff1; // 1 line overlap + } else { + *lp = loff2; // 2 lines overlap + } } // Scroll 'scroll' lines up or down. @@ -2108,11 +2114,11 @@ void halfpage(bool flag, linenr_T Prenum) if (Prenum) { curwin->w_p_scr = (Prenum > curwin->w_height_inner) ? curwin->w_height_inner - : Prenum; + : Prenum; } assert(curwin->w_p_scr <= INT_MAX); int n = curwin->w_p_scr <= curwin->w_height_inner ? (int)curwin->w_p_scr - : curwin->w_height_inner; + : curwin->w_height_inner; update_topline(curwin); validate_botline(curwin); @@ -2129,11 +2135,12 @@ void halfpage(bool flag, linenr_T Prenum) } else { i = plines_win_nofill(curwin, curwin->w_topline, true); n -= i; - if (n < 0 && scrolled > 0) + if (n < 0 && scrolled > 0) { break; + } (void)hasFolding(curwin->w_topline, NULL, &curwin->w_topline); - ++curwin->w_topline; - curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline); + curwin->w_topline++; + curwin->w_topfill = win_get_fill(curwin, curwin->w_topline); if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) { ++curwin->w_cursor.lnum; @@ -2144,13 +2151,11 @@ void halfpage(bool flag, linenr_T Prenum) curwin->w_valid &= ~(VALID_CROW|VALID_WROW); scrolled += i; - /* - * Correct w_botline for changed w_topline. - * Won't work when there are filler lines. - */ - if (curwin->w_p_diff) + // Correct w_botline for changed w_topline. + // Won't work when there are filler lines. + if (win_may_fill(curwin)) { curwin->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP); - else { + } else { room += i; do { i = plines_win(curwin, curwin->w_botline, true); @@ -2170,11 +2175,12 @@ void halfpage(bool flag, linenr_T Prenum) while (--n >= 0 && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) { (void)hasFolding(curwin->w_cursor.lnum, NULL, - &curwin->w_cursor.lnum); + &curwin->w_cursor.lnum); ++curwin->w_cursor.lnum; } - } else + } else { curwin->w_cursor.lnum += n; + } check_cursor_lnum(); } } else { @@ -2182,15 +2188,16 @@ void halfpage(bool flag, linenr_T Prenum) * scroll the text down */ while (n > 0 && curwin->w_topline > 1) { - if (curwin->w_topfill < diff_check_fill(curwin, curwin->w_topline)) { + if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) { i = 1; n--; curwin->w_topfill++; } else { i = plines_win_nofill(curwin, curwin->w_topline - 1, true); n -= i; - if (n < 0 && scrolled > 0) + if (n < 0 && scrolled > 0) { break; + } --curwin->w_topline; (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); curwin->w_topfill = 0; @@ -2206,19 +2213,20 @@ void halfpage(bool flag, linenr_T Prenum) // When hit top of the file: move cursor up. if (n > 0) { - if (curwin->w_cursor.lnum <= (linenr_T)n) + if (curwin->w_cursor.lnum <= (linenr_T)n) { curwin->w_cursor.lnum = 1; - else if (hasAnyFolding(curwin)) { + } else if (hasAnyFolding(curwin)) { while (--n >= 0 && curwin->w_cursor.lnum > 1) { --curwin->w_cursor.lnum; (void)hasFolding(curwin->w_cursor.lnum, - &curwin->w_cursor.lnum, NULL); + &curwin->w_cursor.lnum, NULL); } - } else + } else { curwin->w_cursor.lnum -= n; + } } } - /* Move cursor to first line of closed fold. */ + // Move cursor to first line of closed fold. foldAdjustCursor(); check_topfill(curwin, !flag); cursor_correct(); @@ -2245,7 +2253,7 @@ void do_check_cursorbind(void) FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { curwin = wp; curbuf = curwin->w_buffer; - /* skip original window and windows with 'noscrollbind' */ + // skip original window and windows with 'noscrollbind' if (curwin != old_curwin && curwin->w_p_crb) { if (curwin->w_p_diff) { curwin->w_cursor.lnum = diff --git a/src/nvim/move.h b/src/nvim/move.h index 3670dc9086..dd944e39ee 100644 --- a/src/nvim/move.h +++ b/src/nvim/move.h @@ -2,6 +2,7 @@ #define NVIM_MOVE_H #include <stdbool.h> + #include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 813f21407c..a1a1f0f8c0 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -33,8 +33,8 @@ #include "nvim/vim.h" #if MIN_LOG_LEVEL > DEBUG_LOG_LEVEL -#define log_client_msg(...) -#define log_server_msg(...) +# define log_client_msg(...) +# define log_server_msg(...) #endif static PMap(cstr_t) event_strings = MAP_INIT; @@ -699,14 +699,14 @@ const char *rpc_client_name(Channel *chan) } #if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL -#define REQ "[request] " -#define RES "[response] " -#define NOT "[notify] " -#define ERR "[error] " +# define REQ "[request] " +# define RES "[response] " +# define NOT "[notify] " +# define ERR "[error] " // Cannot define array with negative offsets, so this one is needed to be added // to MSGPACK_UNPACK_\* values. -#define MUR_OFF 2 +# define MUR_OFF 2 static const char *const msgpack_error_messages[] = { [MSGPACK_UNPACK_EXTRA_BYTES + MUR_OFF] = "extra bytes found", diff --git a/src/nvim/msgpack_rpc/channel.h b/src/nvim/msgpack_rpc/channel.h index 90e1c7d48b..eb0de47437 100644 --- a/src/nvim/msgpack_rpc/channel.h +++ b/src/nvim/msgpack_rpc/channel.h @@ -5,10 +5,10 @@ #include <uv.h> #include "nvim/api/private/defs.h" -#include "nvim/event/socket.h" +#include "nvim/channel.h" #include "nvim/event/process.h" +#include "nvim/event/socket.h" #include "nvim/vim.h" -#include "nvim/channel.h" #define METHOD_MAXLEN 512 diff --git a/src/nvim/msgpack_rpc/channel_defs.h b/src/nvim/msgpack_rpc/channel_defs.h index de328af1ce..6647779db9 100644 --- a/src/nvim/msgpack_rpc/channel_defs.h +++ b/src/nvim/msgpack_rpc/channel_defs.h @@ -1,13 +1,13 @@ #ifndef NVIM_MSGPACK_RPC_CHANNEL_DEFS_H #define NVIM_MSGPACK_RPC_CHANNEL_DEFS_H +#include <msgpack.h> #include <stdbool.h> #include <uv.h> -#include <msgpack.h> #include "nvim/api/private/defs.h" -#include "nvim/event/socket.h" #include "nvim/event/process.h" +#include "nvim/event/socket.h" #include "nvim/vim.h" typedef struct Channel Channel; diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 0bc58fffba..f805858904 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -15,50 +15,13 @@ #include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS +# include "keysets.generated.h" # include "msgpack_rpc/helpers.c.generated.h" #endif static msgpack_zone zone; static msgpack_sbuffer sbuffer; -#define HANDLE_TYPE_CONVERSION_IMPL(t, lt) \ - static bool msgpack_rpc_to_##lt(const msgpack_object *const obj, \ - Integer *const arg) \ - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT \ - { \ - if (obj->type != MSGPACK_OBJECT_EXT \ - || obj->via.ext.type + EXT_OBJECT_TYPE_SHIFT != kObjectType##t) { \ - return false; \ - } \ - \ - msgpack_object data; \ - msgpack_unpack_return ret = msgpack_unpack(obj->via.ext.ptr, \ - obj->via.ext.size, \ - NULL, \ - &zone, \ - &data); \ - \ - if (ret != MSGPACK_UNPACK_SUCCESS) { \ - return false; \ - } \ - \ - *arg = (handle_T)data.via.i64; \ - return true; \ - } \ - \ - static void msgpack_rpc_from_##lt(Integer o, msgpack_packer *res) \ -/* uncrustify:indent-off */ \ - FUNC_ATTR_NONNULL_ARG(2) \ -/* uncrustify:indent-on */ \ - { \ - msgpack_packer pac; \ - msgpack_packer_init(&pac, &sbuffer, msgpack_sbuffer_write); \ - msgpack_pack_int64(&pac, (handle_T)o); \ - msgpack_pack_ext(res, sbuffer.size, \ - kObjectType##t - EXT_OBJECT_TYPE_SHIFT); \ - msgpack_pack_ext_body(res, sbuffer.data, sbuffer.size); \ - msgpack_sbuffer_clear(&sbuffer); \ - } void msgpack_rpc_helpers_init(void) { @@ -66,10 +29,6 @@ void msgpack_rpc_helpers_init(void) msgpack_sbuffer_init(&sbuffer); } -HANDLE_TYPE_CONVERSION_IMPL(Buffer, buffer) -HANDLE_TYPE_CONVERSION_IMPL(Window, window) -HANDLE_TYPE_CONVERSION_IMPL(Tabpage, tabpage) - typedef struct { const msgpack_object *mobj; Object *aobj; @@ -90,11 +49,11 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg) kvec_withinit_t(MPToAPIObjectStackItem, 2) stack = KV_INITIAL_VALUE; kvi_init(stack); kvi_push(stack, ((MPToAPIObjectStackItem) { - .mobj = obj, - .aobj = arg, - .container = false, - .idx = 0, - })); + .mobj = obj, + .aobj = arg, + .container = false, + .idx = 0, + })); while (ret && kv_size(stack)) { MPToAPIObjectStackItem cur = kv_last(stack); if (!cur.container) { @@ -154,19 +113,19 @@ case type: { \ cur.idx++; kv_last(stack) = cur; kvi_push(stack, ((MPToAPIObjectStackItem) { - .mobj = &cur.mobj->via.array.ptr[idx], - .aobj = &cur.aobj->data.array.items[idx], - .container = false, - })); + .mobj = &cur.mobj->via.array.ptr[idx], + .aobj = &cur.aobj->data.array.items[idx], + .container = false, + })); } } else { *cur.aobj = ARRAY_OBJ(((Array) { - .size = size, - .capacity = size, - .items = (size > 0 + .size = size, + .capacity = size, + .items = (size > 0 ? xcalloc(size, sizeof(*cur.aobj->data.array.items)) : NULL), - })); + })); cur.container = true; kv_last(stack) = cur; } @@ -207,48 +166,38 @@ case type: { \ } if (ret) { kvi_push(stack, ((MPToAPIObjectStackItem) { - .mobj = &cur.mobj->via.map.ptr[idx].val, - .aobj = &cur.aobj->data.dictionary.items[idx].value, - .container = false, - })); + .mobj = &cur.mobj->via.map.ptr[idx].val, + .aobj = &cur.aobj->data.dictionary.items[idx].value, + .container = false, + })); } } } else { *cur.aobj = DICTIONARY_OBJ(((Dictionary) { - .size = size, - .capacity = size, - .items = (size > 0 + .size = size, + .capacity = size, + .items = (size > 0 ? xcalloc(size, sizeof(*cur.aobj->data.dictionary.items)) : NULL), - })); + })); cur.container = true; kv_last(stack) = cur; } break; } case MSGPACK_OBJECT_EXT: - switch ((ObjectType)(cur.mobj->via.ext.type + EXT_OBJECT_TYPE_SHIFT)) { - case kObjectTypeBuffer: - cur.aobj->type = kObjectTypeBuffer; - ret = msgpack_rpc_to_buffer(cur.mobj, &cur.aobj->data.integer); - break; - case kObjectTypeWindow: - cur.aobj->type = kObjectTypeWindow; - ret = msgpack_rpc_to_window(cur.mobj, &cur.aobj->data.integer); - break; - case kObjectTypeTabpage: - cur.aobj->type = kObjectTypeTabpage; - ret = msgpack_rpc_to_tabpage(cur.mobj, &cur.aobj->data.integer); - break; - case kObjectTypeNil: - case kObjectTypeBoolean: - case kObjectTypeInteger: - case kObjectTypeFloat: - case kObjectTypeString: - case kObjectTypeArray: - case kObjectTypeDictionary: - case kObjectTypeLuaRef: - break; + if (0 <= cur.mobj->via.ext.type && cur.mobj->via.ext.type <= EXT_OBJECT_TYPE_MAX) { + cur.aobj->type = (ObjectType)(cur.mobj->via.ext.type + EXT_OBJECT_TYPE_SHIFT); + msgpack_object data; + msgpack_unpack_return status = msgpack_unpack(cur.mobj->via.ext.ptr, cur.mobj->via.ext.size, + NULL, &zone, &data); + + if (status != MSGPACK_UNPACK_SUCCESS || data.type != MSGPACK_OBJECT_POSITIVE_INTEGER) { + ret = false; + break; + } + cur.aobj->data.integer = (handle_T)data.via.i64; + ret = true; } break; #undef STR_CASE @@ -350,6 +299,17 @@ void msgpack_rpc_from_string(const String result, msgpack_packer *res) } } +static void msgpack_rpc_from_handle(ObjectType type, Integer o, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(3) +{ + msgpack_packer pac; + msgpack_packer_init(&pac, &sbuffer, msgpack_sbuffer_write); + msgpack_pack_int64(&pac, (handle_T)o); + msgpack_pack_ext(res, sbuffer.size, (int8_t)(type - EXT_OBJECT_TYPE_SHIFT)); + msgpack_pack_ext_body(res, sbuffer.data, sbuffer.size); + msgpack_sbuffer_clear(&sbuffer); +} + typedef struct { const Object *aobj; bool container; @@ -394,13 +354,9 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res) msgpack_rpc_from_string(cur.aobj->data.string, res); break; case kObjectTypeBuffer: - msgpack_rpc_from_buffer(cur.aobj->data.integer, res); - break; case kObjectTypeWindow: - msgpack_rpc_from_window(cur.aobj->data.integer, res); - break; case kObjectTypeTabpage: - msgpack_rpc_from_tabpage(cur.aobj->data.integer, res); + msgpack_rpc_from_handle(cur.aobj->type, cur.aobj->data.integer, res); break; case kObjectTypeArray: { const size_t size = cur.aobj->data.array.size; @@ -412,9 +368,9 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res) cur.idx++; kv_last(stack) = cur; kvi_push(stack, ((APIToMPObjectStackItem) { - .aobj = &cur.aobj->data.array.items[idx], - .container = false, - })); + .aobj = &cur.aobj->data.array.items[idx], + .container = false, + })); } } else { msgpack_pack_array(res, size); @@ -435,9 +391,9 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res) msgpack_rpc_from_string(cur.aobj->data.dictionary.items[idx].key, res); kvi_push(stack, ((APIToMPObjectStackItem) { - .aobj = &cur.aobj->data.dictionary.items[idx].value, - .container = false, - })); + .aobj = &cur.aobj->data.dictionary.items[idx].value, + .container = false, + })); } } else { msgpack_pack_map(res, size); diff --git a/src/nvim/msgpack_rpc/helpers.h b/src/nvim/msgpack_rpc/helpers.h index 0e4cd1be6d..e5fd92374d 100644 --- a/src/nvim/msgpack_rpc/helpers.h +++ b/src/nvim/msgpack_rpc/helpers.h @@ -1,13 +1,12 @@ #ifndef NVIM_MSGPACK_RPC_HELPERS_H #define NVIM_MSGPACK_RPC_HELPERS_H -#include <stdint.h> -#include <stdbool.h> - #include <msgpack.h> +#include <stdbool.h> +#include <stdint.h> -#include "nvim/event/wstream.h" #include "nvim/api/private/defs.h" +#include "nvim/event/wstream.h" /// Value by which objects represented as EXT type are shifted /// @@ -15,6 +14,7 @@ /// buffer/window/tabpage block inside ObjectType enum. This block yet cannot be /// split or reordered. #define EXT_OBJECT_TYPE_SHIFT kObjectTypeBuffer +#define EXT_OBJECT_TYPE_MAX (kObjectTypeTabpage - EXT_OBJECT_TYPE_SHIFT) #ifdef INCLUDE_GENERATED_DECLARATIONS # include "msgpack_rpc/helpers.h.generated.h" diff --git a/src/nvim/normal.c b/src/nvim/normal.c index b8a62a8fea..686071e25a 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -349,8 +349,8 @@ static const struct nv_cmd { // Sorted index of commands in nv_cmds[]. static short nv_cmd_idx[NV_CMDS_SIZE]; -/* The highest index for which - * nv_cmds[idx].cmd_char == nv_cmd_idx[nv_cmds[idx].cmd_char] */ +// The highest index for which +// nv_cmds[idx].cmd_char == nv_cmd_idx[nv_cmds[idx].cmd_char] static int nv_max_linear; /* @@ -2167,6 +2167,7 @@ static void op_function(const oparg_T *oap) FUNC_ATTR_NONNULL_ALL { const TriState save_virtual_op = virtual_op; + const bool save_finish_op = finish_op; if (*p_opfunc == NUL) { EMSG(_("E774: 'operatorfunc' is empty")); @@ -2193,9 +2194,13 @@ static void op_function(const oparg_T *oap) // function. virtual_op = kNone; + // Reset finish_op so that mode() returns the right value. + finish_op = false; + (void)call_func_retnr(p_opfunc, 1, argv); virtual_op = save_virtual_op; + finish_op = save_finish_op; } } @@ -3372,7 +3377,7 @@ static void may_clear_cmdline(void) } // Routines for displaying a partly typed command -# define SHOWCMD_BUFLEN SHOWCMD_COLS + 1 + 30 +#define SHOWCMD_BUFLEN SHOWCMD_COLS + 1 + 30 static char_u showcmd_buf[SHOWCMD_BUFLEN]; static char_u old_showcmd_buf[SHOWCMD_BUFLEN]; // For push_showcmd() static bool showcmd_is_clear = true; @@ -3623,8 +3628,8 @@ void do_check_scrollbind(bool check) static colnr_T old_leftcol = 0; if (check && curwin->w_p_scb) { - /* If a ":syncbind" command was just used, don't scroll, only reset - * the values. */ + // If a ":syncbind" command was just used, don't scroll, only reset + // the values. if (did_syncbind) { did_syncbind = false; } else if (curwin == old_curwin) { @@ -4264,8 +4269,8 @@ void scroll_redraw(int up, long count) break; } } - /* Mark w_topline as valid, otherwise the screen jumps back at the - * end of the file. */ + // Mark w_topline as valid, otherwise the screen jumps back at the + // end of the file. check_cursor_moved(curwin); curwin->w_valid |= VALID_TOPLINE; } @@ -4712,9 +4717,9 @@ dozet: if (ptr == NULL) { pos_T pos = curwin->w_cursor; - /* Find bad word under the cursor. When 'spell' is - * off this fails and find_ident_under_cursor() is - * used below. */ + // Find bad word under the cursor. When 'spell' is + // off this fails and find_ident_under_cursor() is + // used below. emsg_off++; len = spell_move_to(curwin, FORWARD, true, true, NULL); emsg_off--; @@ -4833,10 +4838,8 @@ static void nv_colon(cmdarg_T *cap) && (cap->oap->start.lnum > curbuf->b_ml.ml_line_count || cap->oap->start.col > (colnr_T)STRLEN(ml_get(cap->oap->start.lnum)) - || did_emsg - )) { - /* The start of the operator has become invalid by the Ex command. - */ + || did_emsg)) { + // The start of the operator has become invalid by the Ex command. clearopbeep(cap->oap); } } @@ -5261,16 +5264,15 @@ static void nv_scroll(cmdarg_T *cap) } else { if (cap->cmdchar == 'M') { // Don't count filler lines above the window. - used -= diff_check_fill(curwin, curwin->w_topline) + used -= win_get_fill(curwin, curwin->w_topline) - curwin->w_topfill; validate_botline(curwin); // make sure w_empty_rows is valid half = (curwin->w_height_inner - curwin->w_empty_rows + 1) / 2; for (n = 0; curwin->w_topline + n < curbuf->b_ml.ml_line_count; n++) { // Count half he number of filler lines to be "below this // line" and half to be "above the next line". - if (n > 0 && used + diff_check_fill(curwin, curwin->w_topline - + n) / 2 >= half) { - --n; + if (n > 0 && used + win_get_fill(curwin, curwin->w_topline + n) / 2 >= half) { + n--; break; } used += plines_win(curwin, curwin->w_topline + n, true); @@ -5668,8 +5670,8 @@ static int normal_search(cmdarg_T *cap, int dir, char_u *pat, int opt, int *wrap } } - /* "/$" will put the cursor after the end of the line, may need to - * correct that here */ + // "/$" will put the cursor after the end of the line, may need to + // correct that here check_cursor(); return i; } @@ -5849,16 +5851,15 @@ static void nv_brackets(cmdarg_T *cap) } c = gchar_cursor(); if (c == '{' || c == '}') { - /* Must have found end/start of class: use it. - * Or found the place to be at. */ + // Must have found end/start of class: use it. + // Or found the place to be at. if ((c == findc && norm) || (n == 1 && !norm)) { new_pos = curwin->w_cursor; pos = &new_pos; n = 0; - } - /* if no match found at all, we started outside of the - * class and we're inside now. Just go on. */ - else if (new_pos.lnum == 0) { + } else if (new_pos.lnum == 0) { + // if no match found at all, we started outside of the + // class and we're inside now. Just go on. new_pos = curwin->w_cursor; pos = &new_pos; } @@ -6307,8 +6308,8 @@ static void v_swap_corners(int cmdchar) curwin->w_cursor.lnum = old_cursor.lnum; curwin->w_curswant = right; - /* 'selection "exclusive" and cursor at right-bottom corner: move it - * right one column */ + // 'selection "exclusive" and cursor at right-bottom corner: move it + // right one column if (old_cursor.lnum >= VIsual.lnum && *p_sel == 'e') { ++curwin->w_curswant; } @@ -6480,8 +6481,8 @@ static void v_visop(cmdarg_T *cap) { static char_u trans[] = "YyDdCcxdXdAAIIrr"; - /* Uppercase means linewise, except in block mode, then "D" deletes till - * the end of the line, and "C" replaces till EOL */ + // Uppercase means linewise, except in block mode, then "D" deletes till + // the end of the line, and "C" replaces till EOL if (isupper(cap->cmdchar)) { if (VIsual_mode != Ctrl_V) { VIsual_mode_orig = VIsual_mode; @@ -6913,8 +6914,8 @@ static void nv_g_cmd(cmdarg_T *cap) VIsual_active = true; VIsual_reselect = true; - /* Set Visual to the start and w_cursor to the end of the Visual - * area. Make sure they are on an existing character. */ + // Set Visual to the start and w_cursor to the end of the Visual + // area. Make sure they are on an existing character. check_cursor(); VIsual = curwin->w_cursor; curwin->w_cursor = tpos; @@ -6957,10 +6958,9 @@ static void nv_g_cmd(cmdarg_T *cap) nv_visual(cap); break; - /* "gn", "gN" visually select next/previous search match - * "gn" selects next match - * "gN" selects previous match - */ + // "gn", "gN" visually select next/previous search match + // "gn" selects next match + // "gN" selects previous match case 'N': case 'n': if (!current_search(cap->count1, cap->nchar == 'n')) { @@ -7034,9 +7034,9 @@ static void nv_g_cmd(cmdarg_T *cap) } else { i = curwin->w_leftcol; } - /* Go to the middle of the screen line. When 'number' or - * 'relativenumber' is on and lines are wrapping the middle can be more - * to the left. */ + // Go to the middle of the screen line. When 'number' or + // 'relativenumber' is on and lines are wrapping the middle can be more + // to the left. if (cap->nchar == 'm') { i += (curwin->w_width_inner - curwin_col_off() + ((curwin->w_p_wrap && i > 0) @@ -7684,11 +7684,10 @@ static void nv_wordcmd(cmdarg_T *cap) */ static void adjust_cursor(oparg_T *oap) { - /* The cursor cannot remain on the NUL when: - * - the column is > 0 - * - not in Visual mode or 'selection' is "o" - * - 'virtualedit' is not "all" and not "onemore". - */ + // The cursor cannot remain on the NUL when: + // - the column is > 0 + // - not in Visual mode or 'selection' is "o" + // - 'virtualedit' is not "all" and not "onemore". if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL && (!VIsual_active || *p_sel == 'o') && !virtual_active() && @@ -7957,8 +7956,8 @@ static void nv_edit(cmdarg_T *cap) if (curwin->w_cursor.coladd && cap->cmdchar != 'A') { int save_State = State; - /* Pretend Insert mode here to allow the cursor on the - * character past the end of the line */ + // Pretend Insert mode here to allow the cursor on the + // character past the end of the line State = INSERT; coladvance(getviscol()); State = save_State; @@ -7975,9 +7974,9 @@ static void invoke_edit(cmdarg_T *cap, int repl, int cmd, int startln) { int restart_edit_save = 0; - /* Complicated: When the user types "a<C-O>a" we don't want to do Insert - * mode recursively. But when doing "a<C-O>." or "a<C-O>rx" we do allow - * it. */ + // Complicated: When the user types "a<C-O>a" we don't want to do Insert + // mode recursively. But when doing "a<C-O>." or "a<C-O>rx" we do allow + // it. if (repl || !stuff_empty()) { restart_edit_save = restart_edit; } else { @@ -8261,8 +8260,8 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent) && curwin->w_cursor.col < curbuf->b_op_start.col) || (VIsual_mode == 'V' && curwin->w_cursor.lnum < curbuf->b_op_start.lnum)) { - /* cursor is at the end of the line or end of file, put - * forward. */ + // cursor is at the end of the line or end of file, put + // forward. dir = FORWARD; } // May have been reset in do_put(). @@ -8276,8 +8275,8 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent) xfree(savereg); } - /* What to reselect with "gv"? Selecting the just put text seems to - * be the most useful, since the original text was removed. */ + // What to reselect with "gv"? Selecting the just put text seems to + // be the most useful, since the original text was removed. if (was_visual) { curbuf->b_visual.vi_start = curbuf->b_op_start; curbuf->b_visual.vi_end = curbuf->b_op_end; diff --git a/src/nvim/normal.h b/src/nvim/normal.h index 8e15e909d4..fbcc6da75b 100644 --- a/src/nvim/normal.h +++ b/src/nvim/normal.h @@ -2,13 +2,14 @@ #define NVIM_NORMAL_H #include <stdbool.h> -#include "nvim/pos.h" + #include "nvim/buffer_defs.h" // for win_T +#include "nvim/pos.h" -/* Values for find_ident_under_cursor() */ -#define FIND_IDENT 1 /* find identifier (word) */ -#define FIND_STRING 2 /* find any string (WORD) */ -#define FIND_EVAL 4 /* include "->", "[]" and "." */ +// Values for find_ident_under_cursor() +#define FIND_IDENT 1 // find identifier (word) +#define FIND_STRING 2 // find any string (WORD) +#define FIND_EVAL 4 // include "->", "[]" and "." /// Motion types, used for operators and for yank/delete registers. /// @@ -56,24 +57,24 @@ typedef struct oparg_S { * Arguments for Normal mode commands. */ typedef struct cmdarg_S { - oparg_T *oap; /* Operator arguments */ - int prechar; /* prefix character (optional, always 'g') */ - int cmdchar; /* command character */ - int nchar; /* next command character (optional) */ - int ncharC1; /* first composing character (optional) */ - int ncharC2; /* second composing character (optional) */ - int extra_char; /* yet another character (optional) */ - long opcount; /* count before an operator */ - long count0; /* count before command, default 0 */ - long count1; /* count before command, default 1 */ - int arg; /* extra argument from nv_cmds[] */ - int retval; /* return: CA_* values */ - char_u *searchbuf; /* return: pointer to search pattern or NULL */ + oparg_T *oap; // Operator arguments + int prechar; // prefix character (optional, always 'g') + int cmdchar; // command character + int nchar; // next command character (optional) + int ncharC1; // first composing character (optional) + int ncharC2; // second composing character (optional) + int extra_char; // yet another character (optional) + long opcount; // count before an operator + long count0; // count before command, default 0 + long count1; // count before command, default 1 + int arg; // extra argument from nv_cmds[] + int retval; // return: CA_* values + char_u *searchbuf; // return: pointer to search pattern or NULL } cmdarg_T; -/* values for retval: */ -#define CA_COMMAND_BUSY 1 /* skip restarting edit() once */ -#define CA_NO_ADJ_OP_END 2 /* don't adjust operator end */ +// values for retval: +#define CA_COMMAND_BUSY 1 // skip restarting edit() once +#define CA_NO_ADJ_OP_END 2 // don't adjust operator end #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 12fb8439f1..3a8f7c42a5 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -376,7 +376,7 @@ static void shift_block(oparg_T *oap, int amount) */ total += bd.pre_whitesp; // all virtual WS up to & incl a split TAB colnr_T ws_vcol = bd.start_vcol - bd.pre_whitesp; - char_u * old_textstart = bd.textstart; + char_u *old_textstart = bd.textstart; if (bd.startspaces) { if (utfc_ptr2len(bd.textstart) == 1) { bd.textstart++; @@ -435,9 +435,9 @@ static void shift_block(oparg_T *oap, int amount) * non-whitespace character. */ - /* If "bd.startspaces" is set, "bd.textstart" points to the character, - * the part of which is displayed at the block's beginning. Let's start - * searching from the next character. */ + // If "bd.startspaces" is set, "bd.textstart" points to the character, + // the part of which is displayed at the block's beginning. Let's start + // searching from the next character. if (bd.startspaces) { MB_PTR_ADV(non_white); } @@ -614,8 +614,8 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def skipped, offset-startcol, kExtmarkUndo); if (lnum == oap->end.lnum) { - /* Set "']" mark to the end of the block instead of the end of - * the insert in the first line. */ + // Set "']" mark to the end of the block instead of the end of + // the insert in the first line. curbuf->b_op_end.lnum = oap->end.lnum; curbuf->b_op_end.col = offset; } @@ -804,12 +804,6 @@ bool valid_yank_reg(int regname, bool writing) return false; } -typedef enum { - YREG_PASTE, - YREG_YANK, - YREG_PUT, -} yreg_mode_t; - /// Return yankreg_T to use, according to the value of `regname`. /// Cannot handle the '_' (black hole) register. /// Must only be called with a valid register name! @@ -1852,8 +1846,8 @@ int op_replace(oparg_T *oap, int c) numc -= (oap->end_vcol - bd.end_vcol) + 1; } - /* A double-wide character can be replaced only up to half the - * times. */ + // A double-wide character can be replaced only up to half the + // times. if ((*mb_char2cells)(c) > 1) { if ((numc & 1) && !bd.is_short) { ++bd.endspaces; @@ -1944,8 +1938,8 @@ int op_replace(oparg_T *oap, int c) n = gchar_cursor(); if (n != NUL) { if ((*mb_char2len)(c) > 1 || (*mb_char2len)(n) > 1) { - /* This is slow, but it handles replacing a single-byte - * with a multi-byte and the other way around. */ + // This is slow, but it handles replacing a single-byte + // with a multi-byte and the other way around. if (curwin->w_cursor.lnum == oap->end.lnum) { oap->end.col += (*mb_char2len)(c) - (*mb_char2len)(n); } @@ -1955,8 +1949,8 @@ int op_replace(oparg_T *oap, int c) int end_vcol = 0; if (curwin->w_cursor.lnum == oap->end.lnum) { - /* oap->end has to be recalculated when - * the tab breaks */ + // oap->end has to be recalculated when + // the tab breaks end_vcol = getviscol2(oap->end.col, oap->end.coladd); } @@ -1975,9 +1969,9 @@ int op_replace(oparg_T *oap, int c) virtcols -= oap->start.coladd; } - /* oap->end has been trimmed so it's effectively inclusive; - * as a result an extra +1 must be counted so we don't - * trample the NUL byte. */ + // oap->end has been trimmed so it's effectively inclusive; + // as a result an extra +1 must be counted so we don't + // trample the NUL byte. coladvance_force(getviscol2(oap->end.col, oap->end.coladd) + 1); curwin->w_cursor.col -= (virtcols + 1); for (; virtcols >= 0; virtcols--) { @@ -2234,8 +2228,8 @@ void op_insert(oparg_T *oap, long count1) ++curwin->w_cursor.col; } if (bd.is_short && !bd.is_MAX) { - /* First line was too short, make it longer and adjust the - * values in "bd". */ + // First line was too short, make it longer and adjust the + // values in "bd". if (u_save_cursor() == FAIL) { return; } @@ -2392,8 +2386,8 @@ int op_change(oparg_T *oap) } } - /* First delete the text in the region. In an empty buffer only need to - * save for undo */ + // First delete the text in the region. In an empty buffer only need to + // save for undo if (curbuf->b_ml.ml_flags & ML_EMPTY) { if (u_save_cursor() == FAIL) { return FALSE; @@ -2823,17 +2817,17 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) tv_list_append_string(list, (const char *)reg->y_array[i], -1); } tv_list_set_lock(list, VAR_FIXED); - tv_dict_add_list(dict, S_LEN("regcontents"), list); + (void)tv_dict_add_list(dict, S_LEN("regcontents"), list); // Register type. char buf[NUMBUFLEN+2]; format_reg_type(reg->y_type, reg->y_width, buf, ARRAY_SIZE(buf)); - tv_dict_add_str(dict, S_LEN("regtype"), buf); + (void)tv_dict_add_str(dict, S_LEN("regtype"), buf); // Name of requested register, or empty string for unnamed operation. buf[0] = (char)oap->regname; buf[1] = NUL; - tv_dict_add_str(dict, S_LEN("regname"), buf); + (void)tv_dict_add_str(dict, S_LEN("regname"), buf); // Motion type: inclusive or exclusive. tv_dict_add_bool(dict, S_LEN("inclusive"), @@ -2842,11 +2836,11 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) // Kind of operation: yank, delete, change). buf[0] = (char)get_op_char(oap->op_type); buf[1] = NUL; - tv_dict_add_str(dict, S_LEN("operator"), buf); + (void)tv_dict_add_str(dict, S_LEN("operator"), buf); // Selection type: visual or not. - tv_dict_add_bool(dict, S_LEN("visual"), - oap->is_VIsual ? kBoolVarTrue : kBoolVarFalse); + (void)tv_dict_add_bool(dict, S_LEN("visual"), + oap->is_VIsual ? kBoolVarTrue : kBoolVarFalse); tv_dict_set_keys_readonly(dict); textlock++; @@ -3650,6 +3644,12 @@ int get_register_name(int num) } } +/// @return the index of the register "" points to. +int get_unname_register(void) +{ + return y_previous == NULL ? -1 : (int)(y_previous - &y_regs[0]); +} + /* * ":dis" and ":registers": Display the contents of the yank registers. */ @@ -3872,10 +3872,9 @@ char_u *skip_comment(char_u *line, bool process, bool include_space, bool *is_co ++comment_flags; } - /* If we found a colon, it means that we are not processing a line - * starting with a closing part of a three-part comment. That's good, - * because we don't want to remove those as this would be annoying. - */ + // If we found a colon, it means that we are not processing a line + // starting with a closing part of a three-part comment. That's good, + // because we don't want to remove those as this would be annoying. if (*comment_flags == ':' || *comment_flags == NUL) { line += lead_len; } @@ -4054,8 +4053,8 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions curwin->w_buffer->b_op_end.col = sumsize; } - /* Only report the change in the first line here, del_lines() will report - * the deleted line. */ + // Only report the change in the first line here, del_lines() will report + // the deleted line. changed_lines(curwin->w_cursor.lnum, currsize, curwin->w_cursor.lnum + 1, 0L, true); @@ -4172,8 +4171,8 @@ void op_format(oparg_T *oap, int keep_cursor) { long old_line_count = curbuf->b_ml.ml_line_count; - /* Place the cursor where the "gq" or "gw" command was given, so that "u" - * can put it back there. */ + // Place the cursor where the "gq" or "gw" command was given, so that "u" + // can put it back there. curwin->w_cursor = oap->cursor_start; if (u_save((linenr_T)(oap->start.lnum - 1), @@ -4190,8 +4189,8 @@ void op_format(oparg_T *oap, int keep_cursor) // Set '[ mark at the start of the formatted area curbuf->b_op_start = oap->start; - /* For "gw" remember the cursor position and put it back below (adjusted - * for joined and split lines). */ + // For "gw" remember the cursor position and put it back below (adjusted + // for joined and split lines). if (keep_cursor) { saved_cursor = oap->cursor_start; } @@ -4221,8 +4220,8 @@ void op_format(oparg_T *oap, int keep_cursor) if (oap->is_VIsual) { FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { if (wp->w_old_cursor_lnum != 0) { - /* When lines have been inserted or deleted, adjust the end of - * the Visual area to be redrawn. */ + // When lines have been inserted or deleted, adjust the end of + // the Visual area to be redrawn. if (wp->w_old_cursor_lnum > wp->w_old_visual_lnum) { wp->w_old_cursor_lnum += old_line_count; } else { @@ -4244,16 +4243,16 @@ void op_formatexpr(oparg_T *oap) } if (fex_format(oap->start.lnum, oap->line_count, NUL) != 0) { - /* As documented: when 'formatexpr' returns non-zero fall back to - * internal formatting. */ - op_format(oap, FALSE); + // As documented: when 'formatexpr' returns non-zero fall back to + // internal formatting. + op_format(oap, false); } } /// @param c character to be inserted int fex_format(linenr_T lnum, long count, int c) { - int use_sandbox = was_set_insecurely(curwin, (char_u *)"formatexpr", OPT_LOCAL); + int use_sandbox = was_set_insecurely(curwin, "formatexpr", OPT_LOCAL); int r; char_u *fex; @@ -4325,8 +4324,8 @@ void format_lines(linenr_T line_count, int avoid_fex) } else { is_not_par = true; } - next_is_not_par = fmt_check_par(curwin->w_cursor.lnum - , &next_leader_len, &next_leader_flags, do_comments + next_is_not_par = fmt_check_par(curwin->w_cursor.lnum, + &next_leader_len, &next_leader_flags, do_comments ); is_end_par = (is_not_par || next_is_not_par); if (!is_end_par && do_trail_white) { @@ -4354,8 +4353,8 @@ void format_lines(linenr_T line_count, int avoid_fex) next_leader_len = 0; next_leader_flags = NULL; } else { - next_is_not_par = fmt_check_par(curwin->w_cursor.lnum + 1 - , &next_leader_len, &next_leader_flags, do_comments + next_is_not_par = fmt_check_par(curwin->w_cursor.lnum + 1, + &next_leader_len, &next_leader_flags, do_comments ); if (do_number_indent) { next_is_start_par = @@ -4424,8 +4423,8 @@ void format_lines(linenr_T line_count, int avoid_fex) */ if (is_end_par || force_format) { if (need_set_indent) { - /* replace indent in first line with minimal number of - * tabs and spaces, according to current options */ + // replace indent in first line with minimal number of + // tabs and spaces, according to current options (void)set_indent(get_indent(), SIN_CHANGED); } @@ -4451,8 +4450,8 @@ void format_lines(linenr_T line_count, int avoid_fex) // at end of par.: need to set indent of next par. need_set_indent = is_end_par; if (is_end_par) { - /* When called with a negative line count, break at the - * end of the paragraph. */ + // When called with a negative line count, break at the + // end of the paragraph. if (line_count < 0) { break; } @@ -4674,9 +4673,9 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool } else { bdp->startspaces = oap->end_vcol - oap->start_vcol + 1; if (is_del && oap->op_type != OP_LSHIFT) { - /* just putting the sum of those two into - * bdp->startspaces doesn't work for Visual replace, - * so we have to split the tab in two */ + // just putting the sum of those two into + // bdp->startspaces doesn't work for Visual replace, + // so we have to split the tab in two bdp->startspaces = bdp->start_char_vcols - (bdp->start_vcol - oap->start_vcol); bdp->endspaces = bdp->end_vcol - oap->end_vcol - 1; @@ -4817,7 +4816,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) if (change_cnt == 1) { MSG(_("1 line changed")); } else { - smsg((char *)_("%" PRId64 " lines changed"), (int64_t)change_cnt); + smsg(_("%" PRId64 " lines changed"), (int64_t)change_cnt); } } } @@ -5560,6 +5559,11 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char_u *str } } + // Without any lines make the register empty. + if (y_ptr->y_size + newlines == 0) { + XFREE_CLEAR(y_ptr->y_array); + return; + } // Grow the register array to hold the pointers to the new lines. char_u **pp = xrealloc(y_ptr->y_array, @@ -6051,7 +6055,7 @@ bool prepare_yankreg_from_object(yankreg_T *reg, String regtype, size_t lines) void finish_yankreg_from_object(yankreg_T *reg, bool clipboard_adjust) { - if (reg->y_size > 0 && strlen((char *)reg->y_array[reg->y_size-1]) == 0) { + if (reg->y_size > 0 && STRLEN(reg->y_array[reg->y_size-1]) == 0) { // a known-to-be charwise yank might have a final linebreak // but otherwise there is no line after the final newline if (reg->y_type != kMTCharWise) { @@ -6116,7 +6120,7 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet) goto err; } char_u *regtype = TV_LIST_ITEM_TV(tv_list_last(res))->vval.v_string; - if (regtype == NULL || strlen((char *)regtype) > 1) { + if (regtype == NULL || STRLEN(regtype) > 1) { goto err; } switch (regtype[0]) { @@ -6159,7 +6163,7 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet) reg->y_array[tv_idx++] = (char_u *)xstrdupnul((const char *)TV_LIST_ITEM_TV(li)->vval.v_string); }); - if (reg->y_size > 0 && strlen((char *)reg->y_array[reg->y_size-1]) == 0) { + if (reg->y_size > 0 && STRLEN(reg->y_array[reg->y_size-1]) == 0) { // a known-to-be charwise yank might have a final linebreak // but otherwise there is no line after the final newline if (reg->y_type != kMTCharWise) { diff --git a/src/nvim/ops.h b/src/nvim/ops.h index 112ffbeaba..11049b72c0 100644 --- a/src/nvim/ops.h +++ b/src/nvim/ops.h @@ -3,14 +3,14 @@ #include <stdbool.h> -#include "nvim/macros.h" #include "nvim/ascii.h" -#include "nvim/types.h" -#include "nvim/extmark.h" #include "nvim/eval/typval.h" +#include "nvim/ex_cmds_defs.h" // for exarg_T +#include "nvim/extmark.h" +#include "nvim/macros.h" +#include "nvim/normal.h" // for MotionType and oparg_T #include "nvim/os/time.h" -#include "nvim/normal.h" // for MotionType and oparg_T -#include "nvim/ex_cmds_defs.h" // for exarg_T +#include "nvim/types.h" typedef int (*Indenter)(void); @@ -90,6 +90,13 @@ typedef struct yankreg { dict_T *additional_data; ///< Additional data from ShaDa file. } yankreg_T; +/// Modes for get_yank_register() +typedef enum { + YREG_PASTE, + YREG_YANK, + YREG_PUT, +} yreg_mode_t; + /// Convert register name into register index /// /// @param[in] regname Register name. diff --git a/src/nvim/option.c b/src/nvim/option.c index d3056aaa83..fb888ffd0f 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -22,50 +22,50 @@ #define IN_OPTION_C #include <assert.h> #include <inttypes.h> +#include <limits.h> #include <stdbool.h> -#include <string.h> #include <stdlib.h> -#include <limits.h> +#include <string.h> -#include "nvim/vim.h" -#include "nvim/macros.h" #include "nvim/ascii.h" -#include "nvim/edit.h" -#include "nvim/option.h" #include "nvim/buffer.h" #include "nvim/charset.h" #include "nvim/cursor.h" +#include "nvim/cursor_shape.h" #include "nvim/diff.h" #include "nvim/digraph.h" +#include "nvim/edit.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" +#include "nvim/ex_session.h" #include "nvim/fileio.h" #include "nvim/fold.h" +#include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/hardcopy.h" #include "nvim/highlight.h" #include "nvim/indent_c.h" +#include "nvim/keymap.h" +#include "nvim/macros.h" #include "nvim/mbyte.h" #include "nvim/memfile.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/runtime.h" -#include "nvim/keymap.h" -#include "nvim/garray.h" -#include "nvim/cursor_shape.h" -#include "nvim/move.h" #include "nvim/mouse.h" +#include "nvim/move.h" #include "nvim/normal.h" +#include "nvim/option.h" +#include "nvim/os/os.h" #include "nvim/os_unix.h" #include "nvim/path.h" #include "nvim/popupmnu.h" #include "nvim/regexp.h" -#include "nvim/ex_session.h" +#include "nvim/runtime.h" #include "nvim/screen.h" #include "nvim/spell.h" #include "nvim/spellfile.h" @@ -74,13 +74,13 @@ #include "nvim/ui.h" #include "nvim/ui_compositor.h" #include "nvim/undo.h" +#include "nvim/vim.h" #include "nvim/window.h" -#include "nvim/os/os.h" #ifdef WIN32 # include "nvim/os/pty_conpty_win.h" #endif -#include "nvim/lua/executor.h" #include "nvim/api/private/helpers.h" +#include "nvim/lua/executor.h" #include "nvim/os/input.h" #include "nvim/os/lang.h" #include "nvim/quickfix.h" @@ -124,64 +124,64 @@ static char *p_ttytype = NULL; static int p_ai; static int p_bin; static int p_bomb; -static char_u *p_bh; -static char_u *p_bt; +static char_u *p_bh; +static char_u *p_bt; static int p_bl; static long p_channel; static int p_ci; static int p_cin; -static char_u *p_cink; -static char_u *p_cino; -static char_u *p_cinw; -static char_u *p_com; -static char_u *p_cms; -static char_u *p_cpt; -static char_u *p_cfu; -static char_u *p_ofu; -static char_u *p_tfu; +static char_u *p_cink; +static char_u *p_cino; +static char_u *p_cinw; +static char_u *p_com; +static char_u *p_cms; +static char_u *p_cpt; +static char_u *p_cfu; +static char_u *p_ofu; +static char_u *p_tfu; static int p_eol; static int p_fixeol; static int p_et; -static char_u *p_fenc; -static char_u *p_ff; -static char_u *p_fo; -static char_u *p_flp; -static char_u *p_ft; +static char_u *p_fenc; +static char_u *p_ff; +static char_u *p_fo; +static char_u *p_flp; +static char_u *p_ft; static long p_iminsert; static long p_imsearch; -static char_u *p_inex; -static char_u *p_inde; -static char_u *p_indk; -static char_u *p_fex; +static char_u *p_inex; +static char_u *p_inde; +static char_u *p_indk; +static char_u *p_fex; static int p_inf; -static char_u *p_isk; +static char_u *p_isk; static int p_lisp; static int p_ml; static int p_ma; static int p_mod; -static char_u *p_mps; -static char_u *p_nf; +static char_u *p_mps; +static char_u *p_nf; static int p_pi; -static char_u *p_qe; +static char_u *p_qe; static int p_ro; static int p_si; static long p_sts; -static char_u *p_sua; +static char_u *p_sua; static long p_sw; static int p_swf; static long p_smc; -static char_u *p_syn; -static char_u *p_spc; -static char_u *p_spf; -static char_u *p_spl; -static char_u *p_spo; +static char_u *p_syn; +static char_u *p_spc; +static char_u *p_spf; +static char_u *p_spl; +static char_u *p_spo; static long p_ts; static long p_tw; static int p_udf; static long p_wm; static char_u *p_vsts; static char_u *p_vts; -static char_u *p_keymap; +static char_u *p_keymap; // Saved values for when 'bin' is set. static int p_et_nobin; @@ -198,15 +198,15 @@ static long p_wm_nopaste; static char_u *p_vsts_nopaste; typedef struct vimoption { - char *fullname; // full option name - char *shortname; // permissible abbreviation + char *fullname; // full option name + char *shortname; // permissible abbreviation uint32_t flags; // see below - char_u *var; // global option: pointer to variable; - // window-local option: VAR_WIN; - // buffer-local option: global value + char_u *var; // global option: pointer to variable; + // window-local option: VAR_WIN; + // buffer-local option: global value idopt_T indir; // global option: PV_NONE; // local option: indirect option index - char_u *def_val; // default values for variable (neovim!!) + char_u *def_val; // default values for variable (neovim!!) LastSet last_set; // script in which the option was last set } vimoption_T; @@ -314,12 +314,15 @@ static char *(p_csl_values[]) = { "slash", "backslash", NULL }; #endif static char *(p_icm_values[]) = { "nosplit", "split", NULL }; static char *(p_scl_values[]) = { "yes", "no", "auto", "auto:1", "auto:2", - "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", "auto:9", - "yes:1", "yes:2", "yes:3", "yes:4", "yes:5", "yes:6", "yes:7", "yes:8", - "yes:9", "number", NULL }; + "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", + "auto:9", + "yes:1", "yes:2", "yes:3", "yes:4", "yes:5", "yes:6", + "yes:7", "yes:8", + "yes:9", "number", NULL }; static char *(p_fdc_values[]) = { "auto", "auto:1", "auto:2", - "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", "auto:9", - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL }; + "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", + "auto:9", + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL }; /// All possible flags for 'shm'. static char_u SHM_ALL[] = { @@ -371,11 +374,11 @@ void set_init_1(bool clean_arg) * temp files. */ { -# ifdef UNIX - static char *(names[4]) = {"", "TMPDIR", "TEMP", "TMP"}; -# else - static char *(names[3]) = {"TMPDIR", "TEMP", "TMP"}; -# endif +#ifdef UNIX + static char *(names[4]) = { "", "TMPDIR", "TEMP", "TMP" }; +#else + static char *(names[3]) = { "TMPDIR", "TEMP", "TMP" }; +#endif garray_T ga; opt_idx = findoption("backupskip"); @@ -383,16 +386,16 @@ void set_init_1(bool clean_arg) for (size_t n = 0; n < ARRAY_SIZE(names); n++) { bool mustfree = true; char *p; -# ifdef UNIX +#ifdef UNIX if (*names[n] == NUL) { -# ifdef __APPLE__ +# ifdef __APPLE__ p = "/private/tmp"; -# else +# else p = "/tmp"; -# endif +# endif mustfree = false; } else -# endif +#endif { p = vim_getenv(names[n]); } @@ -426,8 +429,8 @@ void set_init_1(bool clean_arg) } { - char_u *cdpath; - char_u *buf; + char_u *cdpath; + char_u *buf; int i; int j; @@ -470,13 +473,13 @@ void set_init_1(bool clean_arg) set_string_default("printexpr", #ifdef UNIX "system(['lpr'] " - "+ (empty(&printdevice)?[]:['-P', &printdevice]) " - "+ [v:fname_in])" + "+ (empty(&printdevice)?[]:['-P', &printdevice]) " + "+ [v:fname_in])" ". delete(v:fname_in)" "+ v:shell_error", #elif defined(MSWIN) "system(['copy', v:fname_in, " - "empty(&printdevice)?'LPT1':&printdevice])" + "empty(&printdevice)?'LPT1':&printdevice])" ". delete(v:fname_in)", #else "", @@ -550,7 +553,7 @@ void set_init_1(bool clean_arg) && options[opt_idx].var != NULL) { p = _(*(char **)options[opt_idx].var); } else { - p = (char *) option_expand(opt_idx, NULL); + p = (char *)option_expand(opt_idx, NULL); } if (p != NULL) { p = xstrdup(p); @@ -584,8 +587,8 @@ void set_init_1(bool clean_arg) // in 'fileencodings' char_u *p = enc_locale(); if (p == NULL) { - // use utf-8 as 'default' if locale encoding can't be detected. - p = (char_u *)xmemdupz(S_LEN("utf-8")); + // use utf-8 as 'default' if locale encoding can't be detected. + p = (char_u *)xmemdupz(S_LEN("utf-8")); } fenc_default = p; @@ -605,15 +608,15 @@ void set_init_1(bool clean_arg) /// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL static void set_option_default(int opt_idx, int opt_flags) { - char_u *varp; // pointer to variable for current option + char_u *varp; // pointer to variable for current option int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; varp = get_varp_scope(&(options[opt_idx]), both ? OPT_LOCAL : opt_flags); uint32_t flags = options[opt_idx].flags; if (varp != NULL) { // skip hidden option, nothing to do for it if (flags & P_STRING) { - /* Use set_string_option_direct() for local options to handle - * freeing and allocating the value. */ + // Use set_string_option_direct() for local options to handle + // freeing and allocating the value. if (options[opt_idx].indir != PV_NONE) { set_string_option_direct(NULL, opt_idx, options[opt_idx].def_val, opt_flags, 0); @@ -624,7 +627,7 @@ static void set_option_default(int opt_idx, int opt_flags) *(char_u **)varp = options[opt_idx].def_val; options[opt_idx].flags &= ~P_ALLOCED; } - } else if (flags & P_NUM) { + } else if (flags & P_NUM) { if (options[opt_idx].indir == PV_SCROLL) { win_comp_scroll(curwin); } else { @@ -667,10 +670,9 @@ static void set_option_default(int opt_idx, int opt_flags) } /// Set all options (except terminal options) to their default value. -static void -set_options_default( - int opt_flags // OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL -) +/// +/// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL +static void set_options_default(int opt_flags) { for (int i = 0; options[i].fullname; i++) { if (!(options[i].flags & P_NODEFAULT)) { @@ -710,8 +712,7 @@ static void set_string_default(const char *name, char *val, bool allocated) // For an option value that contains comma separated items, find "newval" in // "origval". Return NULL if not found. -static char_u *find_dup_item(char_u *origval, const char_u *newval, - uint32_t flags) +static char_u *find_dup_item(char_u *origval, const char_u *newval, uint32_t flags) FUNC_ATTR_NONNULL_ARG(2) { int bs = 0; @@ -827,9 +828,8 @@ void set_init_3(void) // Default for p_sp is "| tee", for p_srr is ">". // For known shells it is changed here to include stderr. // - if ( fnamecmp(p, "csh") == 0 - || fnamecmp(p, "tcsh") == 0 - ) { + if (fnamecmp(p, "csh") == 0 + || fnamecmp(p, "tcsh") == 0) { if (do_sp) { p_sp = (char_u *)"|& tee"; options[idx_sp].def_val = p_sp; @@ -847,8 +847,7 @@ void set_init_3(void) || fnamecmp(p, "bash") == 0 || fnamecmp(p, "fish") == 0 || fnamecmp(p, "ash") == 0 - || fnamecmp(p, "dash") == 0 - ) { + || fnamecmp(p, "dash") == 0) { // Always use POSIX shell style redirection if we reach this if (do_sp) { p_sp = (char_u *)"2>&1| tee"; @@ -933,28 +932,27 @@ void set_title_defaults(void) } } -// Parse 'arg' for option settings. -// -// 'arg' may be IObuff, but only when no errors can be present and option -// does not need to be expanded with option_expand(). -// "opt_flags": -// 0 for ":set" -// OPT_GLOBAL for ":setglobal" -// OPT_LOCAL for ":setlocal" and a modeline -// OPT_MODELINE for a modeline -// OPT_WINONLY to only set window-local options -// OPT_NOWIN to skip setting window-local options -// -// returns FAIL if an error is detected, OK otherwise -int do_set( - char_u *arg, // option string (may be written to!) - int opt_flags -) +/// Parse 'arg' for option settings. +/// +/// 'arg' may be IObuff, but only when no errors can be present and option +/// does not need to be expanded with option_expand(). +/// "opt_flags": +/// 0 for ":set" +/// OPT_GLOBAL for ":setglobal" +/// OPT_LOCAL for ":setlocal" and a modeline +/// OPT_MODELINE for a modeline +/// OPT_WINONLY to only set window-local options +/// OPT_NOWIN to skip setting window-local options +/// +/// @param arg option string (may be written to!) +/// +/// @return FAIL if an error is detected, OK otherwise +int do_set(char_u *arg, int opt_flags) { int opt_idx; - char_u *errmsg; + char_u *errmsg; char_u errbuf[80]; - char_u *startarg; + char_u *startarg; int prefix; // 1: nothing, 0: "no", 2: "inv" in front of name char_u nextchar; // next non-white char after option name int afterchar; // character just after option name @@ -963,7 +961,7 @@ int do_set( varnumber_T value; int key; uint32_t flags; // flags for current option - char_u *varp = NULL; // pointer to variable for current option + char_u *varp = NULL; // pointer to variable for current option int did_show = false; // already showed one value int adding; // "opt+=arg" int prepending; // "opt^=arg" @@ -1096,11 +1094,12 @@ int do_set( flags = P_STRING; } - /* Skip all options that are not window-local (used when showing - * an already loaded buffer in a window). */ + // Skip all options that are not window-local (used when showing + // an already loaded buffer in a window). if ((opt_flags & OPT_WINONLY) - && (opt_idx < 0 || options[opt_idx].var != VAR_WIN)) + && (opt_idx < 0 || options[opt_idx].var != VAR_WIN)) { goto skip; + } // Skip all options that are window-local (used for :vimgrep). if ((opt_flags & OPT_NOWIN) && opt_idx >= 0 @@ -1115,8 +1114,7 @@ int do_set( goto skip; } if ((flags & P_MLE) && !p_mle) { - errmsg = (char_u *)N_( - "E992: Not allowed in a modeline when 'modelineexpr' is off"); + errmsg = (char_u *)N_("E992: Not allowed in a modeline when 'modelineexpr' is off"); goto skip; } // In diff mode some options are overruled. This avoids that @@ -1177,10 +1175,10 @@ int do_set( option_last_set_msg(options[opt_idx].last_set); } else if ((int)options[opt_idx].indir & PV_WIN) { option_last_set_msg(curwin->w_p_script_ctx[ - (int)options[opt_idx].indir & PV_MASK]); + (int)options[opt_idx].indir & PV_MASK]); } else if ((int)options[opt_idx].indir & PV_BUF) { option_last_set_msg(curbuf->b_p_script_ctx[ - (int)options[opt_idx].indir & PV_MASK]); + (int)options[opt_idx].indir & PV_MASK]); } } } else { @@ -1188,8 +1186,9 @@ int do_set( goto skip; } if (nextchar != '?' - && nextchar != NUL && !ascii_iswhite(afterchar)) + && nextchar != NUL && !ascii_iswhite(afterchar)) { errmsg = e_trailing; + } } else { int value_is_replaced = !prepending && !adding && !removing; int value_checked = false; @@ -1260,8 +1259,7 @@ int do_set( if ((long *)varp == &curbuf->b_p_ul && opt_flags == OPT_LOCAL) { value = NO_LOCAL_UNDOLEVEL; } else { - value = *(long *)get_varp_scope( - &(options[opt_idx]), OPT_GLOBAL); + value = *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL); } } else if (((long *)varp == &p_wc || (long *)varp == &p_wcm) @@ -1299,11 +1297,11 @@ int do_set( errbuf, sizeof(errbuf), opt_flags); } else if (opt_idx >= 0) { // String. - char_u *save_arg = NULL; - char_u *s = NULL; - char_u *oldval = NULL; // previous value if *varp - char_u *newval; - char_u *origval = NULL; + char_u *save_arg = NULL; + char_u *s = NULL; + char_u *oldval = NULL; // previous value if *varp + char_u *newval; + char_u *origval = NULL; char *saved_origval = NULL; char *saved_newval = NULL; unsigned newlen; @@ -1314,8 +1312,9 @@ int do_set( * with a local value the local value will be * reset, use the global value here. */ if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0 - && ((int)options[opt_idx].indir & PV_BOTH)) + && ((int)options[opt_idx].indir & PV_BOTH)) { varp = options[opt_idx].var; + } /* The old value is kept until we are sure that the * new value is valid. */ @@ -1349,8 +1348,7 @@ int do_set( newval = (char_u *)xstrdup((char *)newval); } } else if (nextchar == '<') { // set to global val - newval = vim_strsave(*(char_u **)get_varp_scope( - &(options[opt_idx]), OPT_GLOBAL)); + newval = vim_strsave(*(char_u **)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL)); new_value_alloced = true; } else { arg++; // jump to after the '=' or ':' @@ -1378,16 +1376,13 @@ int do_set( *(char_u **)varp = empty_option; break; case 1: - *(char_u **)varp = vim_strsave( - (char_u *)"indent,eol"); + *(char_u **)varp = vim_strsave((char_u *)"indent,eol"); break; case 2: - *(char_u **)varp = vim_strsave( - (char_u *)"indent,eol,start"); + *(char_u **)varp = vim_strsave((char_u *)"indent,eol,start"); break; case 3: - *(char_u **)varp = vim_strsave( - (char_u *)"indent,eol,nostop"); + *(char_u **)varp = vim_strsave((char_u *)"indent,eol,nostop"); break; } xfree(oldval); @@ -1427,9 +1422,9 @@ int do_set( * Remove '>' before 'dir' and 'bdir', for * backwards compatibility with version 3.0 */ - else if ( *arg == '>' - && (varp == (char_u *)&p_dir - || varp == (char_u *)&p_bdir)) { + else if (*arg == '>' + && (varp == (char_u *)&p_dir + || varp == (char_u *)&p_bdir)) { arg++; } @@ -1464,8 +1459,9 @@ int do_set( || (s == newval && arg[2] != '\\'))) #endif - ) + ) { arg++; // remove backslash + } i = utfc_ptr2len(arg); if (i > 1) { // copy multibyte char @@ -1518,8 +1514,8 @@ int do_set( } } - /* concatenate the two strings; add a ',' if - * needed */ + // concatenate the two strings; add a ',' if + // needed if (adding || prepending) { comma = ((flags & P_COMMA) && *origval != NUL && *newval != NUL); @@ -1533,7 +1529,7 @@ int do_set( i--; } memmove(newval + i + comma, newval, - STRLEN(newval) + 1); + STRLEN(newval) + 1); memmove(newval, origval, (size_t)i); } else { i = (int)STRLEN(newval); @@ -1544,8 +1540,8 @@ int do_set( } } - /* Remove newval[] from origval[]. (Note: "i" has - * been set above and is used here). */ + // Remove newval[] from origval[]. (Note: "i" has + // been set above and is used here). if (removing) { STRCPY(newval, origval); if (*s) { @@ -1650,7 +1646,6 @@ int do_set( if (errmsg != NULL) { goto skip; } - } else { // key code option(FIXME(tarruda): Show a warning or something // similar) @@ -1719,15 +1714,13 @@ theend: return OK; } -// Call this when an option has been given a new value through a user command. -// Sets the P_WAS_SET flag and takes care of the P_INSECURE flag. -static void did_set_option( - int opt_idx, - int opt_flags, // possibly with OPT_MODELINE - int new_value, // value was replaced completely - int value_checked // value was checked to be safe, no need to - // set P_INSECURE -) +/// Call this when an option has been given a new value through a user command. +/// Sets the P_WAS_SET flag and takes care of the P_INSECURE flag. +/// +/// @param opt_flags possibly with OPT_MODELINE +/// @param new_value value was replaced completely +/// @param value_checked value was checked to be safe, no need to set P_INSECURE +static void did_set_option(int opt_idx, int opt_flags, int new_value, int value_checked) { options[opt_idx].flags |= P_WAS_SET; @@ -1796,12 +1789,10 @@ static void did_set_title(void) } } -// set_options_bin - called when 'bin' changes value. -void set_options_bin( - int oldval, - int newval, - int opt_flags // OPT_LOCAL and/or OPT_GLOBAL -) +/// set_options_bin - called when 'bin' changes value. +/// +/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL +void set_options_bin(int oldval, int newval, int opt_flags) { /* * The option values that are changed when 'bin' changes are @@ -1859,7 +1850,7 @@ void set_options_bin( /// number, return -1. int get_shada_parameter(int type) { - char_u *p; + char_u *p; p = find_shada_parameter(type); if (p != NULL && ascii_isdigit(*p)) { @@ -1873,7 +1864,7 @@ int get_shada_parameter(int type) /// Return NULL if the parameter is not specified in the string. char_u *find_shada_parameter(int type) { - char_u *p; + char_u *p; for (p = p_shada; *p; p++) { if (*p == type) { @@ -2081,9 +2072,9 @@ static void check_string_option(char_u **pp) /// Return true when option "opt" was set from a modeline or in secure mode. /// Return false when it wasn't. /// Return -1 for an unknown option. -int was_set_insecurely(win_T *const wp, char_u *opt, int opt_flags) +int was_set_insecurely(win_T *const wp, char *opt, int opt_flags) { - int idx = findoption((const char *)opt); + int idx = findoption(opt); if (idx >= 0) { uint32_t *flagp = insecure_flag(wp, idx, opt_flags); @@ -2102,12 +2093,18 @@ static uint32_t *insecure_flag(win_T *const wp, int opt_idx, int opt_flags) if (opt_flags & OPT_LOCAL) { assert(wp != NULL); switch ((int)options[opt_idx].indir) { - case PV_STL: return &wp->w_p_stl_flags; - case PV_FDE: return &wp->w_p_fde_flags; - case PV_FDT: return &wp->w_p_fdt_flags; - case PV_INDE: return &wp->w_buffer->b_p_inde_flags; - case PV_FEX: return &wp->w_buffer->b_p_fex_flags; - case PV_INEX: return &wp->w_buffer->b_p_inex_flags; + case PV_STL: + return &wp->w_p_stl_flags; + case PV_FDE: + return &wp->w_p_fde_flags; + case PV_FDT: + return &wp->w_p_fdt_flags; + case PV_INDE: + return &wp->w_buffer->b_p_inde_flags; + case PV_FEX: + return &wp->w_buffer->b_p_fex_flags; + case PV_INEX: + return &wp->w_buffer->b_p_inex_flags; } } @@ -2125,23 +2122,19 @@ static void redraw_titles(void) static int shada_idx = -1; -// Set a string option to a new value (without checking the effect). -// The string is copied into allocated memory. -// if ("opt_idx" == -1) "name" is used, otherwise "opt_idx" is used. -// When "set_sid" is zero set the scriptID to current_sctx.sc_sid. When -// "set_sid" is SID_NONE don't set the scriptID. Otherwise set the scriptID to -// "set_sid". -void -set_string_option_direct( - const char *name, - int opt_idx, - const char_u *val, - int opt_flags, // OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL - int set_sid -) -{ - char_u *s; - char_u **varp; +/// Set a string option to a new value (without checking the effect). +/// The string is copied into allocated memory. +/// if ("opt_idx" == -1) "name" is used, otherwise "opt_idx" is used. +/// When "set_sid" is zero set the scriptID to current_sctx.sc_sid. When +/// "set_sid" is SID_NONE don't set the scriptID. Otherwise set the scriptID to +/// "set_sid". +/// +/// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL +void set_string_option_direct(const char *name, int opt_idx, const char_u *val, int opt_flags, + int set_sid) +{ + char_u *s; + char_u **varp; int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; int idx = opt_idx; @@ -2158,7 +2151,7 @@ set_string_option_direct( return; } - assert((void *) options[idx].var != (void *) &p_shada); + assert((void *)options[idx].var != (void *)&p_shada); s = vim_strsave(val); { @@ -2198,13 +2191,12 @@ set_string_option_direct( } /// Set global value for string option when it's a local option. -static void -set_string_option_global( - int opt_idx, // option index - char_u **varp // pointer to option variable -) +/// +/// @param opt_idx option index +/// @param varp pointer to option variable +static void set_string_option_global(int opt_idx, char_u **varp) { - char_u **p, *s; + char_u **p, *s; // the global value is always allocated if (options[opt_idx].var == VAR_WIN) { @@ -2227,8 +2219,7 @@ set_string_option_global( /// #OPT_GLOBAL. /// /// @return NULL on success, error message on error. -static char *set_string_option(const int opt_idx, const char *const value, - const int opt_flags) +static char *set_string_option(const int opt_idx, const char *const value, const int opt_flags) FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_WARN_UNUSED_RESULT { if (options[opt_idx].var == NULL) { // don't set hidden option @@ -2236,12 +2227,11 @@ static char *set_string_option(const int opt_idx, const char *const value, } char *const s = xstrdup(value); - char **const varp = (char **)get_varp_scope( - &(options[opt_idx]), - ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0 + char **const varp = (char **)get_varp_scope(&(options[opt_idx]), + ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0 ? (((int)options[opt_idx].indir & PV_BOTH) ? OPT_GLOBAL : OPT_LOCAL) - : opt_flags)); + : opt_flags)); char *const oldval = *varp; *varp = s; @@ -2249,9 +2239,9 @@ static char *set_string_option(const int opt_idx, const char *const value, char *const saved_newval = xstrdup(s); int value_checked = false; - char *const r = (char *)did_set_string_option( - opt_idx, (char_u **)varp, (int)true, (char_u *)oldval, - NULL, 0, opt_flags, &value_checked); + char *const r = (char *)did_set_string_option(opt_idx, (char_u **)varp, (int)true, + (char_u *)oldval, + NULL, 0, opt_flags, &value_checked); if (r == NULL) { did_set_option(opt_idx, opt_flags, true, value_checked); } @@ -2315,23 +2305,23 @@ static bool valid_spellfile(const char_u *val) /// Handle string options that need some action to perform when changed. /// Returns NULL for success, or an error message for an error. -static char_u * -did_set_string_option( - int opt_idx, // index in options[] table - char_u **varp, // pointer to the option variable - bool new_value_alloced, // new value was allocated - char_u *oldval, // previous value of the option - char_u *errbuf, // buffer for errors, or NULL - size_t errbuflen, // length of errors buffer - int opt_flags, // OPT_LOCAL and/or OPT_GLOBAL - int *value_checked // value was checked to be safe, no - // need to set P_INSECURE -) -{ - char_u *errmsg = NULL; - char_u *s, *p; +/// +/// @param opt_idx index in options[] table +/// @param varp pointer to the option variable +/// @param new_value_alloced new value was allocated +/// @param oldval previous value of the option +/// @param errbuf buffer for errors, or NULL +/// @param errbuflen length of errors buffer +/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL +/// @param value_checked value was checked to be safe, no need to set P_INSECURE +static char_u *did_set_string_option(int opt_idx, char_u **varp, bool new_value_alloced, + char_u *oldval, char_u *errbuf, size_t errbuflen, + int opt_flags, int *value_checked) +{ + char_u *errmsg = NULL; + char_u *s, *p; int did_chartab = false; - char_u **gvarp; + char_u **gvarp; bool free_oldval = (options[opt_idx].flags & P_ALLOCED); bool value_changed = false; @@ -2345,7 +2335,7 @@ did_set_string_option( errmsg = e_secure; } else if (((options[opt_idx].flags & P_NFNAME) && vim_strpbrk(*varp, (char_u *)(secure ? "/\\*?[|;&<>\r\n" - : "/\\*?[<>\r\n")) != NULL) + : "/\\*?[<>\r\n")) != NULL) || ((options[opt_idx].flags & P_NDNAME) && vim_strpbrk(*varp, (char_u *)"*?[|;&<>\r\n") != NULL)) { // Check for a "normal" directory or file name in some options. Disallow a @@ -2353,7 +2343,7 @@ did_set_string_option( // are often illegal in a file name. Be more permissive if "secure" is off. errmsg = e_invarg; } else if (gvarp == &p_bkc) { // 'backupcopy' - char_u *bkc = p_bkc; + char_u *bkc = p_bkc; unsigned int *flags = &bkc_flags; if (opt_flags & OPT_LOCAL) { @@ -2407,6 +2397,8 @@ did_set_string_option( os_setenv("VIMRUNTIME", "", 1); didset_vimruntime = false; } + } else if (varp == &p_rtp || varp == &p_pp) { // 'runtimepath' 'packpath' + runtime_search_path_invalidate(); } else if (varp == &curwin->w_p_culopt || gvarp == &curwin->w_allbuf_opt.wo_culopt) { // 'cursorlineopt' if (**varp == NUL || fill_culopt_flags(*varp, curwin) != OK) { @@ -2493,13 +2485,14 @@ ambw_end: check_string_option(&p_bg); init_highlight(false, false); } - } else + } else { errmsg = e_invarg; + } } else if (varp == &p_wim) { // 'wildmode' if (check_opt_wim() == FAIL) { errmsg = e_invarg; } - // 'wildoptions' + // 'wildoptions' } else if (varp == &p_wop) { if (opt_strings_flags(p_wop, p_wop_values, &wop_flags, true) != OK) { errmsg = e_invarg; @@ -2513,7 +2506,7 @@ ambw_end: if (check_ei() == FAIL) { errmsg = e_invarg; } - // 'encoding', 'fileencoding' and 'makeencoding' + // 'encoding', 'fileencoding' and 'makeencoding' } else if (varp == &p_enc || gvarp == &p_fenc || gvarp == &p_menc) { if (gvarp == &p_fenc) { if (!MODIFIABLE(curbuf) && opt_flags != OPT_GLOBAL) { @@ -2684,7 +2677,7 @@ ambw_end: if (*p_vfile != NUL && verbose_open() == FAIL) { errmsg = e_invarg; } - // 'shada' + // 'shada' } else if (varp == &p_shada) { // TODO(ZyX-I): Remove this code in the future, alongside with &viminfo // option. @@ -2692,7 +2685,7 @@ ambw_end: ? (shada_idx == -1 ? ((shada_idx = findoption("shada"))) : shada_idx) - : opt_idx); + : opt_idx); // Update free_oldval now that we have the opt_idx for 'shada', otherwise // there would be a disconnect between the check for P_ALLOCED at the start // of the function and the set of P_ALLOCED at the end of the function. @@ -2721,8 +2714,9 @@ ambw_end: _("E526: Missing number after <%s>"), transchar_byte(*(s - 1))); errmsg = errbuf; - } else + } else { errmsg = (char_u *)""; + } break; } } @@ -2743,8 +2737,7 @@ ambw_end: } else if (gvarp == &p_sbr) { // 'showbreak' for (s = *varp; *s; ) { if (ptr2cells(s) != 1) { - errmsg = (char_u *)N_( - "E595: 'showbreak' contains unprintable or wide character"); + errmsg = (char_u *)N_("E595: 'showbreak' contains unprintable or wide character"); } MB_PTR_ADV(s); } @@ -2769,7 +2762,6 @@ ambw_end: stl_syntax &= ~flagval; } did_set_title(); - } else if (varp == &p_sel) { // 'selection' if (*p_sel == NUL || check_opt_strings(p_sel, p_sel_values, false) != OK) { @@ -2888,8 +2880,9 @@ ambw_end: } else if (gvarp == &p_cpt) { // check if it is a valid value for 'complete' -- Acevedo for (s = *varp; *s; ) { - while (*s == ',' || *s == ' ') + while (*s == ',' || *s == ' ') { s++; + } if (!*s) { break; } @@ -2912,8 +2905,9 @@ ambw_end: _("E535: Illegal character after <%c>"), *--s); errmsg = errbuf; - } else + } else { errmsg = (char_u *)""; + } break; } } @@ -3024,8 +3018,7 @@ ambw_end: } } else if (gvarp == &p_cms) { // 'commentstring' if (**varp != NUL && strstr((char *)(*varp), "%s") == NULL) { - errmsg = (char_u *)N_( - "E537: 'commentstring' must be empty or contain %s"); + errmsg = (char_u *)N_("E537: 'commentstring' must be empty or contain %s"); } } else if (varp == &p_fdo) { // 'foldopen' if (opt_strings_flags(p_fdo, p_fdo_values, &fdo_flags, true) != OK) { @@ -3068,11 +3061,11 @@ ambw_end: } else if (gvarp == &p_cino) { // 'cinoptions' // TODO(vim): recognize errors parse_cino(curbuf); - // inccommand + // inccommand } else if (varp == &p_icm) { - if (check_opt_strings(p_icm, p_icm_values, false) != OK) { - errmsg = e_invarg; - } + if (check_opt_strings(p_icm, p_icm_values, false) != OK) { + errmsg = e_invarg; + } } else if (gvarp == &p_ft) { if (!valid_filetype(*varp)) { errmsg = e_invarg; @@ -3274,7 +3267,7 @@ ambw_end: } if (varp == &(curwin->w_s->b_p_spl)) { char_u fname[200]; - char_u *q = curwin->w_s->b_p_spl; + char_u *q = curwin->w_s->b_p_spl; // Skip the first name if it is "cjk". if (STRNCMP(q, "cjk,", 4) == 0) { @@ -3295,7 +3288,7 @@ ambw_end: if (p > q) { vim_snprintf((char *)fname, sizeof(fname), "spell/%.*s.vim", (int)(p - q), q); - source_runtime(fname, DIP_ALL); + source_runtime((char *)fname, DIP_ALL); } } } @@ -3305,8 +3298,9 @@ ambw_end: } if (curwin->w_curswant != MAXCOL - && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0) + && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0) { curwin->w_set_curswant = true; + } check_redraw(options[opt_idx].flags); @@ -3334,8 +3328,7 @@ int check_signcolumn(char_u *val) && !STRNCMP(val, "auto:", 5) && ascii_isdigit(val[5]) && val[6] == '-' - && ascii_isdigit(val[7]) - ) { + && ascii_isdigit(val[7])) { int min = val[5] - '0'; int max = val[7] - '0'; if (min < 1 || max < 2 || min > 8 || max > 9 || min >= max) { @@ -3352,7 +3345,7 @@ int check_signcolumn(char_u *val) /// @return error message, NULL if it's OK. char_u *check_colorcolumn(win_T *wp) { - char_u *s; + char_u *s; int col; unsigned int count = 0; int color_cols[256]; @@ -3446,9 +3439,9 @@ static char_u *set_chars_option(win_T *wp, char_u **varp, bool set) int multispace_len = 0; // Length of lcs-multispace string struct chars_tab { - int *cp; ///< char value - char *name; ///< char id - int def; ///< default value + int *cp; ///< char value + char *name; ///< char id + int def; ///< default value }; struct chars_tab *tab; @@ -3517,7 +3510,7 @@ static char_u *set_chars_option(win_T *wp, char_u **varp, bool set) xfree(wp->w_p_lcs_chars.multispace); } if (multispace_len > 0) { - wp->w_p_lcs_chars.multispace = xmalloc((size_t)(multispace_len + 1) * sizeof(int)); + wp->w_p_lcs_chars.multispace = xmalloc(((size_t)multispace_len + 1) * sizeof(int)); wp->w_p_lcs_chars.multispace[multispace_len] = NUL; } else { wp->w_p_lcs_chars.multispace = NULL; @@ -3658,8 +3651,9 @@ char_u *check_stl_option(char_u *s) } if (*s == '.') { s++; - while (*s && ascii_isdigit(*s)) + while (*s && ascii_isdigit(*s)) { s++; + } } if (*s == '(') { groupdepth++; @@ -3687,7 +3681,7 @@ char_u *check_stl_option(char_u *s) static char_u *did_set_spell_option(bool is_spellfile) { - char_u *errmsg = NULL; + char_u *errmsg = NULL; if (is_spellfile) { int l = (int)STRLEN(curwin->w_s->b_p_spf); @@ -3714,8 +3708,8 @@ static char_u *did_set_spell_option(bool is_spellfile) static char_u *compile_cap_prog(synblock_T *synblock) FUNC_ATTR_NONNULL_ALL { - regprog_T *rp = synblock->b_cap_prog; - char_u *re; + regprog_T *rp = synblock->b_cap_prog; + char_u *re; if (synblock->b_p_spc == NULL || *synblock->b_p_spc == NUL) { synblock->b_cap_prog = NULL; @@ -3751,7 +3745,7 @@ static bool parse_winhl_opt(win_T *wp) char *hi = colon+1; char *commap = xstrchrnul(hi, ','); int len = (int)(commap-hi); - int hl_id = len ? syn_check_group((char_u *)hi, len) : -1; + int hl_id = len ? syn_check_group(hi, len) : -1; if (strncmp("Normal", p, nlen) == 0) { w_hl_id_normal = hl_id; @@ -3814,8 +3808,7 @@ static void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx) /// @param[in] opt_flags OPT_LOCAL and/or OPT_GLOBAL. /// /// @return NULL on success, error message on error. -static char *set_bool_option(const int opt_idx, char_u *const varp, - const int value, +static char *set_bool_option(const int opt_idx, char_u *const varp, const int value, const int opt_flags) { int old_value = *(int *)varp; @@ -3840,7 +3833,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, if ((int *)varp == &p_force_on && p_force_on == false) { p_force_on = true; return (char *)e_unsupportedoption; - // Ensure that options set to p_force_off cannot be enabled. + // Ensure that options set to p_force_off cannot be enabled. } else if ((int *)varp == &p_force_off && p_force_off == true) { p_force_off = false; return (char *)e_unsupportedoption; @@ -3853,7 +3846,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, } else if ((int *)varp == &curwin->w_p_cul && !value && old_value) { // 'cursorline' reset_cursorline(); - // 'undofile' + // 'undofile' } else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf) { // Only take action when the option was set. When reset we do not // delete the undo file, the option may be set again without making @@ -3906,7 +3899,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, // when 'buflisted' changes, trigger autocommands apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE, NULL, NULL, true, curbuf); - } else if ((int *)varp == (int *)&curbuf->b_p_swf) { + } else if ((int *)varp == &curbuf->b_p_swf) { // when 'swf' is set, create swapfile, when reset remove swapfile if (curbuf->b_p_swf && p_uc) { ml_open_file(curbuf); // create the swap file @@ -3917,7 +3910,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, } } else if ((int *)varp == &p_terse) { // when 'terse' is set change 'shortmess' - char_u *p; + char_u *p; p = vim_strchr(p_shm, SHM_SEARCH); @@ -3954,8 +3947,8 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, // when 'hlsearch' is set or reset: reset no_hlsearch set_no_hlsearch(false); } else if ((int *)varp == &curwin->w_p_scb) { - // when 'scrollbind' is set: snapshot the current position to avoid a jump - // at the end of normal_cmd() + // when 'scrollbind' is set: snapshot the current position to avoid a jump + // at the end of normal_cmd() if (curwin->w_p_scb) { do_check_scrollbind(false); curwin->w_scbind_pos = curwin->w_topline; @@ -4025,7 +4018,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, } } else if ((int *)varp == &curwin->w_p_spell) { // 'spell' if (curwin->w_p_spell) { - char_u *errmsg = did_set_spelllang(curwin); + char_u *errmsg = did_set_spelllang(curwin); if (errmsg != NULL) { EMSG(_(errmsg)); } @@ -4051,11 +4044,10 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, } } - /* Arabic requires a utf-8 encoding, inform the user if its not - * set. */ + // Arabic requires a utf-8 encoding, inform the user if its not + // set. if (STRCMP(p_enc, "utf-8") != 0) { - static char *w_arabic = N_( - "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"); + static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'"); msg_source(HL_ATTR(HLF_W)); msg_attr(_(w_arabic), HL_ATTR(HLF_W)); @@ -4078,12 +4070,12 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, changed_window_setting(); } - /* 'arabicshape' isn't reset, it is a global option and - * another window may still need it "on". */ + // 'arabicshape' isn't reset, it is a global option and + // another window may still need it "on". } - /* 'delcombine' isn't reset, it is a global option and another - * window may still want it "on". */ + // 'delcombine' isn't reset, it is a global option and another + // window may still want it "on". // Revert to the default keymap curbuf->b_p_iminsert = B_IMODE_NONE; @@ -4115,7 +4107,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, set_vim_var_string(VV_OPTION_OLD, buf_old, -1); set_vim_var_string(VV_OPTION_TYPE, buf_type, -1); apply_autocmds(EVENT_OPTIONSET, - (char_u *) options[opt_idx].fullname, + (char_u *)options[opt_idx].fullname, NULL, false, NULL); reset_v_option_vars(); } @@ -4145,13 +4137,13 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, /// @param[in] opt_flags OPT_LOCAL, OPT_GLOBAL or OPT_MODELINE. /// /// @return NULL on success, error message on error. -static char *set_num_option(int opt_idx, char_u *varp, long value, - char_u *errbuf, size_t errbuflen, int opt_flags) +static char *set_num_option(int opt_idx, char_u *varp, long value, char_u *errbuf, size_t errbuflen, + int opt_flags) { - char_u *errmsg = NULL; + char_u *errmsg = NULL; long old_value = *(long *)varp; long old_Rows = Rows; // remember old Rows - long *pp = (long *)varp; + long *pp = (long *)varp; // Disallow changing some options from secure mode. if ((secure || sandbox != 0) @@ -4161,7 +4153,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, // Many number options assume their value is in the signed int range. if (value < INT_MIN || value > INT_MAX) { - return (char *)e_invarg; + return (char *)e_invarg; } // Options that need some validation. @@ -4425,7 +4417,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, if (p_lines < min_rows() && full_screen) { if (errbuf != NULL) { vim_snprintf((char *)errbuf, errbuflen, - _("E593: Need at least %d lines"), min_rows()); + _("E593: Need at least %d lines"), min_rows()); errmsg = errbuf; } p_lines = min_rows(); @@ -4433,7 +4425,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, if (p_columns < MIN_COLUMNS && full_screen) { if (errbuf != NULL) { vim_snprintf((char *)errbuf, errbuflen, - _("E594: Need at least %d columns"), MIN_COLUMNS); + _("E594: Need at least %d columns"), MIN_COLUMNS); errmsg = errbuf; } p_columns = MIN_COLUMNS; @@ -4478,7 +4470,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, } win_comp_scroll(curwin); } else if (curwin->w_p_scr <= 0) { - // If 'scroll' became invalid because of a side effect silently adjust it. + // If 'scroll' became invalid because of a side effect silently adjust it. curwin->w_p_scr = 1; } else { // curwin->w_p_scr > curwin->w_height curwin->w_p_scr = curwin->w_height; @@ -4514,7 +4506,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, set_vim_var_string(VV_OPTION_OLD, buf_old, -1); set_vim_var_string(VV_OPTION_TYPE, buf_type, -1); apply_autocmds(EVENT_OPTIONSET, - (char_u *) options[opt_idx].fullname, + (char_u *)options[opt_idx].fullname, NULL, false, NULL); reset_v_option_vars(); } @@ -4534,8 +4526,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, return (char *)errmsg; } -static void trigger_optionsset_string(int opt_idx, int opt_flags, - char *oldval, char *newval) +static void trigger_optionsset_string(int opt_idx, int opt_flags, char *oldval, char *newval) { // Don't do this recursively. if (oldval != NULL @@ -4658,8 +4649,8 @@ bool is_tty_option(const char *name) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { return (name[0] == 't' && name[1] == '_') - || strequal(name, "term") - || strequal(name, "ttytype"); + || strequal(name, "term") + || strequal(name, "ttytype"); } #define TCO_BUFFER_SIZE 8 @@ -4738,18 +4729,15 @@ static int findoption(const char *const arg) /// Gets the value for an option. /// +/// @param stringval NULL when only checking existence +/// /// @returns: /// Number or Toggle option: 1, *numval gets value. /// String option: 0, *stringval gets allocated string. /// Hidden Number or Toggle option: -1. /// hidden String option: -2. /// unknown option: -3. -int get_option_value( - const char *name, - long *numval, - char_u **stringval, ///< NULL when only checking existence - int opt_flags -) +int get_option_value(const char *name, long *numval, char_u **stringval, int opt_flags) { if (get_tty_option(name, (char **)stringval)) { return 0; @@ -4783,7 +4771,7 @@ int get_option_value( if ((int *)varp == &curbuf->b_changed) { *numval = curbufIsChanged(); } else { - *numval = (long) *(int *)varp; // NOLINT(whitespace/cast) + *numval = (long)*(int *)varp; // NOLINT(whitespace/cast) } } return 1; @@ -4805,11 +4793,7 @@ int get_option_value( // see SOPT_* in option_defs.h for other flags // // Possible opt_type values: see SREQ_* in option_defs.h -int get_option_value_strict(char *name, - int64_t *numval, - char **stringval, - int opt_type, - void *from) +int get_option_value_strict(char *name, int64_t *numval, char **stringval, int opt_type, void *from) { if (get_tty_option(name, stringval)) { return SOPT_STRING | SOPT_GLOBAL; @@ -4925,8 +4909,8 @@ int get_option_value_strict(char *name, /// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both). /// /// @return NULL on success, error message on error. -char *set_option_value(const char *const name, const long number, - const char *const string, const int opt_flags) +char *set_option_value(const char *const name, const long number, const char *const string, + const int opt_flags) FUNC_ATTR_NONNULL_ARG(1) { if (is_tty_option(name)) { @@ -4934,7 +4918,7 @@ char *set_option_value(const char *const name, const long number, } int opt_idx; - char_u *varp; + char_u *varp; opt_idx = findoption(name); if (opt_idx < 0) { @@ -4994,7 +4978,7 @@ int find_key_option_len(const char_u *arg_arg, size_t len, bool has_lt) // add_termcap_entry(). if (len >= 4 && arg[0] == 't' && arg[1] == '_') { key = TERMCAP2KEY(arg[2], arg[3]); - } else if (has_lt) { + } else if (has_lt) { arg--; // put arg at the '<' modifiers = 0; key = find_special_key(&arg, len + 1, &modifiers, true, true, false); @@ -5012,15 +4996,13 @@ static int find_key_option(const char_u *arg, bool has_lt) /// if 'all' == 0: show changed options /// if 'all' == 1: show all normal options -static void -showoptions( - int all, - int opt_flags // OPT_LOCAL and/or OPT_GLOBAL -) +/// +/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL +static void showoptions(int all, int opt_flags) { - vimoption_T *p; + vimoption_T *p; int col; - char_u *varp; + char_u *varp; int item_count; int run; int row, rows; @@ -5155,13 +5137,11 @@ void ui_refresh_options(void) /// showoneopt: show the value of one option /// must not be called with a hidden option! -static void -showoneopt( - vimoption_T *p, - int opt_flags // OPT_LOCAL or OPT_GLOBAL -) +/// +/// @param opt_flags OPT_LOCAL or OPT_GLOBAL +static void showoneopt(vimoption_T *p, int opt_flags) { - char_u *varp; + char_u *varp; int save_silent = silent_mode; silent_mode = false; @@ -5212,11 +5192,11 @@ showoneopt( /// Return FAIL on error, OK otherwise. int makeset(FILE *fd, int opt_flags, int local_only) { - vimoption_T *p; - char_u *varp; // currently used value - char_u *varp_fresh; // local value - char_u *varp_local = NULL; // fresh value - char *cmd; + vimoption_T *p; + char_u *varp; // currently used value + char_u *varp_fresh; // local value + char_u *varp_local = NULL; // fresh value + char *cmd; int round; int pri; @@ -5238,8 +5218,8 @@ int makeset(FILE *fd, int opt_flags, int local_only) continue; } - /* Do not store options like 'bufhidden' and 'syntax' in a vimrc - * file, they are always buffer-specific. */ + // Do not store options like 'bufhidden' and 'syntax' in a vimrc + // file, they are always buffer-specific. if ((opt_flags & OPT_GLOBAL) && (p->flags & P_NOGLOB)) { continue; } @@ -5340,29 +5320,28 @@ int makefoldset(FILE *fd) || put_setnum(fd, "setlocal", "fdl", &curwin->w_p_fdl) == FAIL || put_setnum(fd, "setlocal", "fml", &curwin->w_p_fml) == FAIL || put_setnum(fd, "setlocal", "fdn", &curwin->w_p_fdn) == FAIL - || put_setbool(fd, "setlocal", "fen", curwin->w_p_fen) == FAIL - ) { + || put_setbool(fd, "setlocal", "fen", + curwin->w_p_fen) == FAIL) { return FAIL; } return OK; } -static int put_setstring(FILE *fd, char *cmd, char *name, - char_u **valuep, uint64_t flags) +static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, uint64_t flags) { - char_u *s; - char_u *buf = NULL; - char_u *part = NULL; - char_u *p; + char_u *s; + char_u *buf = NULL; + char_u *part = NULL; + char_u *p; if (fprintf(fd, "%s %s=", cmd, name) < 0) { return FAIL; } if (*valuep != NULL) { - /* Output 'pastetoggle' as key names. For other - * options some characters have to be escaped with - * CTRL-V or backslash */ + // Output 'pastetoggle' as key names. For other + // options some characters have to be escaped with + // CTRL-V or backslash if (valuep == &p_pt) { s = *valuep; while (*s != NUL) { @@ -5380,7 +5359,7 @@ static int put_setstring(FILE *fd, char *cmd, char *name, home_replace(NULL, *valuep, buf, size, false); // If the option value is longer than MAXPATHL, we need to append - // search comma separated part of the option separately, so that it + // each comma separated part of the option separately, so that it // can be expanded when read back. if (size >= MAXPATHL && (flags & P_COMMA) != 0 && vim_strchr(*valuep, ',') != NULL) { @@ -5392,15 +5371,15 @@ static int put_setstring(FILE *fd, char *cmd, char *name, } p = buf; while (*p != NUL) { - // for each comma separated option part, append value to - // the option, :set rtp+=value - if (fprintf(fd, "%s %s+=", cmd, name) < 0) { - goto fail; - } - (void)copy_option_part(&p, part, size, ","); - if (put_escstr(fd, part, 2) == FAIL || put_eol(fd) == FAIL) { - goto fail; - } + // for each comma separated option part, append value to + // the option, :set rtp+=value + if (fprintf(fd, "%s %s+=", cmd, name) < 0) { + goto fail; + } + (void)copy_option_part(&p, part, size, ","); + if (put_escstr(fd, part, 2) == FAIL || put_eol(fd) == FAIL) { + goto fail; + } } xfree(buf); xfree(part); @@ -5516,124 +5495,149 @@ void unset_global_local_option(char *name, void *from) switch ((int)p->indir) { - // global option with local value: use local value if it's been set + // global option with local value: use local value if it's been set + case PV_EP: + clear_string_option(&buf->b_p_ep); + break; + case PV_KP: + clear_string_option(&buf->b_p_kp); + break; + case PV_PATH: + clear_string_option(&buf->b_p_path); + break; + case PV_AR: + buf->b_p_ar = -1; + break; + case PV_BKC: + clear_string_option(&buf->b_p_bkc); + buf->b_bkc_flags = 0; + break; + case PV_TAGS: + clear_string_option(&buf->b_p_tags); + break; + case PV_TC: + clear_string_option(&buf->b_p_tc); + buf->b_tc_flags = 0; + break; + case PV_SISO: + curwin->w_p_siso = -1; + break; + case PV_SO: + curwin->w_p_so = -1; + break; + case PV_DEF: + clear_string_option(&buf->b_p_def); + break; + case PV_INC: + clear_string_option(&buf->b_p_inc); + break; + case PV_DICT: + clear_string_option(&buf->b_p_dict); + break; + case PV_TSR: + clear_string_option(&buf->b_p_tsr); + break; + case PV_FP: + clear_string_option(&buf->b_p_fp); + break; + case PV_EFM: + clear_string_option(&buf->b_p_efm); + break; + case PV_GP: + clear_string_option(&buf->b_p_gp); + break; + case PV_MP: + clear_string_option(&buf->b_p_mp); + break; + case PV_SBR: + clear_string_option(&((win_T *)from)->w_p_sbr); + break; + case PV_STL: + clear_string_option(&((win_T *)from)->w_p_stl); + break; + case PV_UL: + buf->b_p_ul = NO_LOCAL_UNDOLEVEL; + break; + case PV_LW: + clear_string_option(&buf->b_p_lw); + break; + case PV_MENC: + clear_string_option(&buf->b_p_menc); + break; + case PV_LCS: + clear_string_option(&((win_T *)from)->w_p_lcs); + set_chars_option((win_T *)from, &((win_T *)from)->w_p_lcs, true); + redraw_later((win_T *)from, NOT_VALID); + break; + case PV_FCS: + clear_string_option(&((win_T *)from)->w_p_fcs); + set_chars_option((win_T *)from, &((win_T *)from)->w_p_fcs, true); + redraw_later((win_T *)from, NOT_VALID); + break; + } +} + +/// Get pointer to option variable, depending on local or global scope. +static char_u *get_varp_scope(vimoption_T *p, int opt_flags) +{ + if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE) { + if (p->var == VAR_WIN) { + return (char_u *)GLOBAL_WO(get_varp(p)); + } + return p->var; + } + if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH)) { + switch ((int)p->indir) { + case PV_FP: + return (char_u *)&(curbuf->b_p_fp); + case PV_EFM: + return (char_u *)&(curbuf->b_p_efm); + case PV_GP: + return (char_u *)&(curbuf->b_p_gp); + case PV_MP: + return (char_u *)&(curbuf->b_p_mp); case PV_EP: - clear_string_option(&buf->b_p_ep); - break; + return (char_u *)&(curbuf->b_p_ep); case PV_KP: - clear_string_option(&buf->b_p_kp); - break; + return (char_u *)&(curbuf->b_p_kp); case PV_PATH: - clear_string_option(&buf->b_p_path); - break; + return (char_u *)&(curbuf->b_p_path); case PV_AR: - buf->b_p_ar = -1; - break; - case PV_BKC: - clear_string_option(&buf->b_p_bkc); - buf->b_bkc_flags = 0; - break; + return (char_u *)&(curbuf->b_p_ar); case PV_TAGS: - clear_string_option(&buf->b_p_tags); - break; + return (char_u *)&(curbuf->b_p_tags); case PV_TC: - clear_string_option(&buf->b_p_tc); - buf->b_tc_flags = 0; - break; + return (char_u *)&(curbuf->b_p_tc); case PV_SISO: - curwin->w_p_siso = -1; - break; + return (char_u *)&(curwin->w_p_siso); case PV_SO: - curwin->w_p_so = -1; - break; + return (char_u *)&(curwin->w_p_so); case PV_DEF: - clear_string_option(&buf->b_p_def); - break; + return (char_u *)&(curbuf->b_p_def); case PV_INC: - clear_string_option(&buf->b_p_inc); - break; + return (char_u *)&(curbuf->b_p_inc); case PV_DICT: - clear_string_option(&buf->b_p_dict); - break; + return (char_u *)&(curbuf->b_p_dict); case PV_TSR: - clear_string_option(&buf->b_p_tsr); - break; - case PV_FP: - clear_string_option(&buf->b_p_fp); - break; - case PV_EFM: - clear_string_option(&buf->b_p_efm); - break; - case PV_GP: - clear_string_option(&buf->b_p_gp); - break; - case PV_MP: - clear_string_option(&buf->b_p_mp); - break; + return (char_u *)&(curbuf->b_p_tsr); + case PV_TFU: + return (char_u *)&(curbuf->b_p_tfu); case PV_SBR: - clear_string_option(&((win_T *)from)->w_p_sbr); - break; + return (char_u *)&(curwin->w_p_sbr); case PV_STL: - clear_string_option(&((win_T *)from)->w_p_stl); - break; + return (char_u *)&(curwin->w_p_stl); case PV_UL: - buf->b_p_ul = NO_LOCAL_UNDOLEVEL; - break; + return (char_u *)&(curbuf->b_p_ul); case PV_LW: - clear_string_option(&buf->b_p_lw); - break; + return (char_u *)&(curbuf->b_p_lw); + case PV_BKC: + return (char_u *)&(curbuf->b_p_bkc); case PV_MENC: - clear_string_option(&buf->b_p_menc); - break; - case PV_LCS: - clear_string_option(&((win_T *)from)->w_p_lcs); - set_chars_option((win_T *)from, &((win_T *)from)->w_p_lcs, true); - redraw_later((win_T *)from, NOT_VALID); - break; + return (char_u *)&(curbuf->b_p_menc); case PV_FCS: - clear_string_option(&((win_T *)from)->w_p_fcs); - set_chars_option((win_T *)from, &((win_T *)from)->w_p_fcs, true); - redraw_later((win_T *)from, NOT_VALID); - break; - } -} - -/// Get pointer to option variable, depending on local or global scope. -static char_u *get_varp_scope(vimoption_T *p, int opt_flags) -{ - if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE) { - if (p->var == VAR_WIN) { - return (char_u *)GLOBAL_WO(get_varp(p)); - } - return p->var; - } - if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH)) { - switch ((int)p->indir) { - case PV_FP: return (char_u *)&(curbuf->b_p_fp); - case PV_EFM: return (char_u *)&(curbuf->b_p_efm); - case PV_GP: return (char_u *)&(curbuf->b_p_gp); - case PV_MP: return (char_u *)&(curbuf->b_p_mp); - case PV_EP: return (char_u *)&(curbuf->b_p_ep); - case PV_KP: return (char_u *)&(curbuf->b_p_kp); - case PV_PATH: return (char_u *)&(curbuf->b_p_path); - case PV_AR: return (char_u *)&(curbuf->b_p_ar); - case PV_TAGS: return (char_u *)&(curbuf->b_p_tags); - case PV_TC: return (char_u *)&(curbuf->b_p_tc); - case PV_SISO: return (char_u *)&(curwin->w_p_siso); - case PV_SO: return (char_u *)&(curwin->w_p_so); - case PV_DEF: return (char_u *)&(curbuf->b_p_def); - case PV_INC: return (char_u *)&(curbuf->b_p_inc); - case PV_DICT: return (char_u *)&(curbuf->b_p_dict); - case PV_TSR: return (char_u *)&(curbuf->b_p_tsr); - case PV_TFU: return (char_u *)&(curbuf->b_p_tfu); - case PV_SBR: return (char_u *)&(curwin->w_p_sbr); - case PV_STL: return (char_u *)&(curwin->w_p_stl); - case PV_UL: return (char_u *)&(curbuf->b_p_ul); - case PV_LW: return (char_u *)&(curbuf->b_p_lw); - case PV_BKC: return (char_u *)&(curbuf->b_p_bkc); - case PV_MENC: return (char_u *)&(curbuf->b_p_menc); - case PV_FCS: return (char_u *)&(curwin->w_p_fcs); - case PV_LCS: return (char_u *)&(curwin->w_p_lcs); + return (char_u *)&(curwin->w_p_fcs); + case PV_LCS: + return (char_u *)&(curwin->w_p_lcs); } return NULL; // "cannot happen" } @@ -5649,163 +5653,290 @@ static char_u *get_varp(vimoption_T *p) } switch ((int)p->indir) { - case PV_NONE: return p->var; + case PV_NONE: + return p->var; // global option with local value: use local value if it's been set - case PV_EP: return *curbuf->b_p_ep != NUL + case PV_EP: + return *curbuf->b_p_ep != NUL ? (char_u *)&curbuf->b_p_ep : p->var; - case PV_KP: return *curbuf->b_p_kp != NUL + case PV_KP: + return *curbuf->b_p_kp != NUL ? (char_u *)&curbuf->b_p_kp : p->var; - case PV_PATH: return *curbuf->b_p_path != NUL + case PV_PATH: + return *curbuf->b_p_path != NUL ? (char_u *)&(curbuf->b_p_path) : p->var; - case PV_AR: return curbuf->b_p_ar >= 0 + case PV_AR: + return curbuf->b_p_ar >= 0 ? (char_u *)&(curbuf->b_p_ar) : p->var; - case PV_TAGS: return *curbuf->b_p_tags != NUL + case PV_TAGS: + return *curbuf->b_p_tags != NUL ? (char_u *)&(curbuf->b_p_tags) : p->var; - case PV_TC: return *curbuf->b_p_tc != NUL + case PV_TC: + return *curbuf->b_p_tc != NUL ? (char_u *)&(curbuf->b_p_tc) : p->var; - case PV_SISO: return curwin->w_p_siso >= 0 + case PV_SISO: + return curwin->w_p_siso >= 0 ? (char_u *)&(curwin->w_p_siso) : p->var; - case PV_SO: return curwin->w_p_so >= 0 + case PV_SO: + return curwin->w_p_so >= 0 ? (char_u *)&(curwin->w_p_so) : p->var; - case PV_BKC: return *curbuf->b_p_bkc != NUL + case PV_BKC: + return *curbuf->b_p_bkc != NUL ? (char_u *)&(curbuf->b_p_bkc) : p->var; - case PV_DEF: return *curbuf->b_p_def != NUL + case PV_DEF: + return *curbuf->b_p_def != NUL ? (char_u *)&(curbuf->b_p_def) : p->var; - case PV_INC: return *curbuf->b_p_inc != NUL + case PV_INC: + return *curbuf->b_p_inc != NUL ? (char_u *)&(curbuf->b_p_inc) : p->var; - case PV_DICT: return *curbuf->b_p_dict != NUL + case PV_DICT: + return *curbuf->b_p_dict != NUL ? (char_u *)&(curbuf->b_p_dict) : p->var; - case PV_TSR: return *curbuf->b_p_tsr != NUL + case PV_TSR: + return *curbuf->b_p_tsr != NUL ? (char_u *)&(curbuf->b_p_tsr) : p->var; - case PV_FP: return *curbuf->b_p_fp != NUL + case PV_FP: + return *curbuf->b_p_fp != NUL ? (char_u *)&(curbuf->b_p_fp) : p->var; - case PV_EFM: return *curbuf->b_p_efm != NUL + case PV_EFM: + return *curbuf->b_p_efm != NUL ? (char_u *)&(curbuf->b_p_efm) : p->var; - case PV_GP: return *curbuf->b_p_gp != NUL + case PV_GP: + return *curbuf->b_p_gp != NUL ? (char_u *)&(curbuf->b_p_gp) : p->var; - case PV_MP: return *curbuf->b_p_mp != NUL + case PV_MP: + return *curbuf->b_p_mp != NUL ? (char_u *)&(curbuf->b_p_mp) : p->var; - case PV_SBR: return *curwin->w_p_sbr != NUL + case PV_SBR: + return *curwin->w_p_sbr != NUL ? (char_u *)&(curwin->w_p_sbr) : p->var; - case PV_STL: return *curwin->w_p_stl != NUL + case PV_STL: + return *curwin->w_p_stl != NUL ? (char_u *)&(curwin->w_p_stl) : p->var; - case PV_UL: return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL + case PV_UL: + return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL ? (char_u *)&(curbuf->b_p_ul) : p->var; - case PV_LW: return *curbuf->b_p_lw != NUL + case PV_LW: + return *curbuf->b_p_lw != NUL ? (char_u *)&(curbuf->b_p_lw) : p->var; - case PV_MENC: return *curbuf->b_p_menc != NUL + case PV_MENC: + return *curbuf->b_p_menc != NUL ? (char_u *)&(curbuf->b_p_menc) : p->var; - case PV_FCS: return *curwin->w_p_fcs != NUL + case PV_FCS: + return *curwin->w_p_fcs != NUL ? (char_u *)&(curwin->w_p_fcs) : p->var; - case PV_LCS: return *curwin->w_p_lcs != NUL + case PV_LCS: + return *curwin->w_p_lcs != NUL ? (char_u *)&(curwin->w_p_lcs) : p->var; - case PV_ARAB: return (char_u *)&(curwin->w_p_arab); - case PV_LIST: return (char_u *)&(curwin->w_p_list); - case PV_SPELL: return (char_u *)&(curwin->w_p_spell); - case PV_CUC: return (char_u *)&(curwin->w_p_cuc); - case PV_CUL: return (char_u *)&(curwin->w_p_cul); - case PV_CULOPT: return (char_u *)&(curwin->w_p_culopt); - case PV_CC: return (char_u *)&(curwin->w_p_cc); - case PV_DIFF: return (char_u *)&(curwin->w_p_diff); - case PV_FDC: return (char_u *)&(curwin->w_p_fdc); - case PV_FEN: return (char_u *)&(curwin->w_p_fen); - case PV_FDI: return (char_u *)&(curwin->w_p_fdi); - case PV_FDL: return (char_u *)&(curwin->w_p_fdl); - case PV_FDM: return (char_u *)&(curwin->w_p_fdm); - case PV_FML: return (char_u *)&(curwin->w_p_fml); - case PV_FDN: return (char_u *)&(curwin->w_p_fdn); - case PV_FDE: return (char_u *)&(curwin->w_p_fde); - case PV_FDT: return (char_u *)&(curwin->w_p_fdt); - case PV_FMR: return (char_u *)&(curwin->w_p_fmr); - case PV_NU: return (char_u *)&(curwin->w_p_nu); - case PV_RNU: return (char_u *)&(curwin->w_p_rnu); - case PV_NUW: return (char_u *)&(curwin->w_p_nuw); - case PV_WFH: return (char_u *)&(curwin->w_p_wfh); - case PV_WFW: return (char_u *)&(curwin->w_p_wfw); - case PV_PVW: return (char_u *)&(curwin->w_p_pvw); - case PV_RL: return (char_u *)&(curwin->w_p_rl); - case PV_RLC: return (char_u *)&(curwin->w_p_rlc); - case PV_SCROLL: return (char_u *)&(curwin->w_p_scr); - case PV_WRAP: return (char_u *)&(curwin->w_p_wrap); - case PV_LBR: return (char_u *)&(curwin->w_p_lbr); - case PV_BRI: return (char_u *)&(curwin->w_p_bri); - case PV_BRIOPT: return (char_u *)&(curwin->w_p_briopt); - case PV_SCBIND: return (char_u *)&(curwin->w_p_scb); - case PV_CRBIND: return (char_u *)&(curwin->w_p_crb); - case PV_COCU: return (char_u *)&(curwin->w_p_cocu); - case PV_COLE: return (char_u *)&(curwin->w_p_cole); - - case PV_AI: return (char_u *)&(curbuf->b_p_ai); - case PV_BIN: return (char_u *)&(curbuf->b_p_bin); - case PV_BOMB: return (char_u *)&(curbuf->b_p_bomb); - case PV_BH: return (char_u *)&(curbuf->b_p_bh); - case PV_BT: return (char_u *)&(curbuf->b_p_bt); - case PV_BL: return (char_u *)&(curbuf->b_p_bl); - case PV_CHANNEL:return (char_u *)&(curbuf->b_p_channel); - case PV_CI: return (char_u *)&(curbuf->b_p_ci); - case PV_CIN: return (char_u *)&(curbuf->b_p_cin); - case PV_CINK: return (char_u *)&(curbuf->b_p_cink); - case PV_CINO: return (char_u *)&(curbuf->b_p_cino); - case PV_CINW: return (char_u *)&(curbuf->b_p_cinw); - case PV_COM: return (char_u *)&(curbuf->b_p_com); - case PV_CMS: return (char_u *)&(curbuf->b_p_cms); - case PV_CPT: return (char_u *)&(curbuf->b_p_cpt); -# ifdef BACKSLASH_IN_FILENAME - case PV_CSL: return (char_u *)&(curbuf->b_p_csl); -# endif - case PV_CFU: return (char_u *)&(curbuf->b_p_cfu); - case PV_OFU: return (char_u *)&(curbuf->b_p_ofu); - case PV_EOL: return (char_u *)&(curbuf->b_p_eol); - case PV_FIXEOL: return (char_u *)&(curbuf->b_p_fixeol); - case PV_ET: return (char_u *)&(curbuf->b_p_et); - case PV_FENC: return (char_u *)&(curbuf->b_p_fenc); - case PV_FF: return (char_u *)&(curbuf->b_p_ff); - case PV_FT: return (char_u *)&(curbuf->b_p_ft); - case PV_FO: return (char_u *)&(curbuf->b_p_fo); - case PV_FLP: return (char_u *)&(curbuf->b_p_flp); - case PV_IMI: return (char_u *)&(curbuf->b_p_iminsert); - case PV_IMS: return (char_u *)&(curbuf->b_p_imsearch); - case PV_INF: return (char_u *)&(curbuf->b_p_inf); - case PV_ISK: return (char_u *)&(curbuf->b_p_isk); - case PV_INEX: return (char_u *)&(curbuf->b_p_inex); - case PV_INDE: return (char_u *)&(curbuf->b_p_inde); - case PV_INDK: return (char_u *)&(curbuf->b_p_indk); - case PV_FEX: return (char_u *)&(curbuf->b_p_fex); - case PV_LISP: return (char_u *)&(curbuf->b_p_lisp); - case PV_ML: return (char_u *)&(curbuf->b_p_ml); - case PV_MPS: return (char_u *)&(curbuf->b_p_mps); - case PV_MA: return (char_u *)&(curbuf->b_p_ma); - case PV_MOD: return (char_u *)&(curbuf->b_changed); - case PV_NF: return (char_u *)&(curbuf->b_p_nf); - case PV_PI: return (char_u *)&(curbuf->b_p_pi); - case PV_QE: return (char_u *)&(curbuf->b_p_qe); - case PV_RO: return (char_u *)&(curbuf->b_p_ro); - case PV_SCBK: return (char_u *)&(curbuf->b_p_scbk); - case PV_SI: return (char_u *)&(curbuf->b_p_si); - case PV_STS: return (char_u *)&(curbuf->b_p_sts); - case PV_SUA: return (char_u *)&(curbuf->b_p_sua); - case PV_SWF: return (char_u *)&(curbuf->b_p_swf); - case PV_SMC: return (char_u *)&(curbuf->b_p_smc); - case PV_SYN: return (char_u *)&(curbuf->b_p_syn); - case PV_SPC: return (char_u *)&(curwin->w_s->b_p_spc); - case PV_SPF: return (char_u *)&(curwin->w_s->b_p_spf); - case PV_SPL: return (char_u *)&(curwin->w_s->b_p_spl); - case PV_SPO: return (char_u *)&(curwin->w_s->b_p_spo); - case PV_SW: return (char_u *)&(curbuf->b_p_sw); - case PV_TFU: return (char_u *)&(curbuf->b_p_tfu); - case PV_TS: return (char_u *)&(curbuf->b_p_ts); - case PV_TW: return (char_u *)&(curbuf->b_p_tw); - case PV_UDF: return (char_u *)&(curbuf->b_p_udf); - case PV_WM: return (char_u *)&(curbuf->b_p_wm); - case PV_VSTS: return (char_u *)&(curbuf->b_p_vsts); - case PV_VTS: return (char_u *)&(curbuf->b_p_vts); - case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap); - case PV_SCL: return (char_u *)&(curwin->w_p_scl); - case PV_WINHL: return (char_u *)&(curwin->w_p_winhl); - case PV_WINBL: return (char_u *)&(curwin->w_p_winbl); - default: IEMSG(_("E356: get_varp ERROR")); + case PV_ARAB: + return (char_u *)&(curwin->w_p_arab); + case PV_LIST: + return (char_u *)&(curwin->w_p_list); + case PV_SPELL: + return (char_u *)&(curwin->w_p_spell); + case PV_CUC: + return (char_u *)&(curwin->w_p_cuc); + case PV_CUL: + return (char_u *)&(curwin->w_p_cul); + case PV_CULOPT: + return (char_u *)&(curwin->w_p_culopt); + case PV_CC: + return (char_u *)&(curwin->w_p_cc); + case PV_DIFF: + return (char_u *)&(curwin->w_p_diff); + case PV_FDC: + return (char_u *)&(curwin->w_p_fdc); + case PV_FEN: + return (char_u *)&(curwin->w_p_fen); + case PV_FDI: + return (char_u *)&(curwin->w_p_fdi); + case PV_FDL: + return (char_u *)&(curwin->w_p_fdl); + case PV_FDM: + return (char_u *)&(curwin->w_p_fdm); + case PV_FML: + return (char_u *)&(curwin->w_p_fml); + case PV_FDN: + return (char_u *)&(curwin->w_p_fdn); + case PV_FDE: + return (char_u *)&(curwin->w_p_fde); + case PV_FDT: + return (char_u *)&(curwin->w_p_fdt); + case PV_FMR: + return (char_u *)&(curwin->w_p_fmr); + case PV_NU: + return (char_u *)&(curwin->w_p_nu); + case PV_RNU: + return (char_u *)&(curwin->w_p_rnu); + case PV_NUW: + return (char_u *)&(curwin->w_p_nuw); + case PV_WFH: + return (char_u *)&(curwin->w_p_wfh); + case PV_WFW: + return (char_u *)&(curwin->w_p_wfw); + case PV_PVW: + return (char_u *)&(curwin->w_p_pvw); + case PV_RL: + return (char_u *)&(curwin->w_p_rl); + case PV_RLC: + return (char_u *)&(curwin->w_p_rlc); + case PV_SCROLL: + return (char_u *)&(curwin->w_p_scr); + case PV_WRAP: + return (char_u *)&(curwin->w_p_wrap); + case PV_LBR: + return (char_u *)&(curwin->w_p_lbr); + case PV_BRI: + return (char_u *)&(curwin->w_p_bri); + case PV_BRIOPT: + return (char_u *)&(curwin->w_p_briopt); + case PV_SCBIND: + return (char_u *)&(curwin->w_p_scb); + case PV_CRBIND: + return (char_u *)&(curwin->w_p_crb); + case PV_COCU: + return (char_u *)&(curwin->w_p_cocu); + case PV_COLE: + return (char_u *)&(curwin->w_p_cole); + + case PV_AI: + return (char_u *)&(curbuf->b_p_ai); + case PV_BIN: + return (char_u *)&(curbuf->b_p_bin); + case PV_BOMB: + return (char_u *)&(curbuf->b_p_bomb); + case PV_BH: + return (char_u *)&(curbuf->b_p_bh); + case PV_BT: + return (char_u *)&(curbuf->b_p_bt); + case PV_BL: + return (char_u *)&(curbuf->b_p_bl); + case PV_CHANNEL: + return (char_u *)&(curbuf->b_p_channel); + case PV_CI: + return (char_u *)&(curbuf->b_p_ci); + case PV_CIN: + return (char_u *)&(curbuf->b_p_cin); + case PV_CINK: + return (char_u *)&(curbuf->b_p_cink); + case PV_CINO: + return (char_u *)&(curbuf->b_p_cino); + case PV_CINW: + return (char_u *)&(curbuf->b_p_cinw); + case PV_COM: + return (char_u *)&(curbuf->b_p_com); + case PV_CMS: + return (char_u *)&(curbuf->b_p_cms); + case PV_CPT: + return (char_u *)&(curbuf->b_p_cpt); +#ifdef BACKSLASH_IN_FILENAME + case PV_CSL: + return (char_u *)&(curbuf->b_p_csl); +#endif + case PV_CFU: + return (char_u *)&(curbuf->b_p_cfu); + case PV_OFU: + return (char_u *)&(curbuf->b_p_ofu); + case PV_EOL: + return (char_u *)&(curbuf->b_p_eol); + case PV_FIXEOL: + return (char_u *)&(curbuf->b_p_fixeol); + case PV_ET: + return (char_u *)&(curbuf->b_p_et); + case PV_FENC: + return (char_u *)&(curbuf->b_p_fenc); + case PV_FF: + return (char_u *)&(curbuf->b_p_ff); + case PV_FT: + return (char_u *)&(curbuf->b_p_ft); + case PV_FO: + return (char_u *)&(curbuf->b_p_fo); + case PV_FLP: + return (char_u *)&(curbuf->b_p_flp); + case PV_IMI: + return (char_u *)&(curbuf->b_p_iminsert); + case PV_IMS: + return (char_u *)&(curbuf->b_p_imsearch); + case PV_INF: + return (char_u *)&(curbuf->b_p_inf); + case PV_ISK: + return (char_u *)&(curbuf->b_p_isk); + case PV_INEX: + return (char_u *)&(curbuf->b_p_inex); + case PV_INDE: + return (char_u *)&(curbuf->b_p_inde); + case PV_INDK: + return (char_u *)&(curbuf->b_p_indk); + case PV_FEX: + return (char_u *)&(curbuf->b_p_fex); + case PV_LISP: + return (char_u *)&(curbuf->b_p_lisp); + case PV_ML: + return (char_u *)&(curbuf->b_p_ml); + case PV_MPS: + return (char_u *)&(curbuf->b_p_mps); + case PV_MA: + return (char_u *)&(curbuf->b_p_ma); + case PV_MOD: + return (char_u *)&(curbuf->b_changed); + case PV_NF: + return (char_u *)&(curbuf->b_p_nf); + case PV_PI: + return (char_u *)&(curbuf->b_p_pi); + case PV_QE: + return (char_u *)&(curbuf->b_p_qe); + case PV_RO: + return (char_u *)&(curbuf->b_p_ro); + case PV_SCBK: + return (char_u *)&(curbuf->b_p_scbk); + case PV_SI: + return (char_u *)&(curbuf->b_p_si); + case PV_STS: + return (char_u *)&(curbuf->b_p_sts); + case PV_SUA: + return (char_u *)&(curbuf->b_p_sua); + case PV_SWF: + return (char_u *)&(curbuf->b_p_swf); + case PV_SMC: + return (char_u *)&(curbuf->b_p_smc); + case PV_SYN: + return (char_u *)&(curbuf->b_p_syn); + case PV_SPC: + return (char_u *)&(curwin->w_s->b_p_spc); + case PV_SPF: + return (char_u *)&(curwin->w_s->b_p_spf); + case PV_SPL: + return (char_u *)&(curwin->w_s->b_p_spl); + case PV_SPO: + return (char_u *)&(curwin->w_s->b_p_spo); + case PV_SW: + return (char_u *)&(curbuf->b_p_sw); + case PV_TFU: + return (char_u *)&(curbuf->b_p_tfu); + case PV_TS: + return (char_u *)&(curbuf->b_p_ts); + case PV_TW: + return (char_u *)&(curbuf->b_p_tw); + case PV_UDF: + return (char_u *)&(curbuf->b_p_udf); + case PV_WM: + return (char_u *)&(curbuf->b_p_wm); + case PV_VSTS: + return (char_u *)&(curbuf->b_p_vsts); + case PV_VTS: + return (char_u *)&(curbuf->b_p_vts); + case PV_KMAP: + return (char_u *)&(curbuf->b_p_keymap); + case PV_SCL: + return (char_u *)&(curwin->w_p_scl); + case PV_WINHL: + return (char_u *)&(curwin->w_p_winhl); + case PV_WINBL: + return (char_u *)&(curwin->w_p_winbl); + default: + IEMSG(_("E356: get_varp ERROR")); } // always return a valid pointer to avoid a crash! return (char_u *)&(curbuf->b_p_wm); @@ -5963,7 +6094,7 @@ void didset_window_options(win_T *wp) void buf_copy_options(buf_T *buf, int flags) { int should_copy = true; - char_u *save_p_isk = NULL; // init for GCC + char_u *save_p_isk = NULL; // init for GCC int dont_do_help; int did_isk = false; @@ -6008,22 +6139,18 @@ void buf_copy_options(buf_T *buf, int flags) buf->b_p_ro = false; // don't copy readonly buf->b_p_fenc = vim_strsave(p_fenc); switch (*p_ffs) { - case 'm': { - buf->b_p_ff = vim_strsave((char_u *)FF_MAC); - break; - } - case 'd': { - buf->b_p_ff = vim_strsave((char_u *)FF_DOS); - break; - } - case 'u': { - buf->b_p_ff = vim_strsave((char_u *)FF_UNIX); - break; - } - default: { - buf->b_p_ff = vim_strsave(p_ff); - break; - } + case 'm': + buf->b_p_ff = vim_strsave((char_u *)FF_MAC); + break; + case 'd': + buf->b_p_ff = vim_strsave((char_u *)FF_DOS); + break; + case 'u': + buf->b_p_ff = vim_strsave((char_u *)FF_UNIX); + break; + default: + buf->b_p_ff = vim_strsave(p_ff); + break; } buf->b_p_bh = empty_option; buf->b_p_bt = empty_option; @@ -6052,9 +6179,9 @@ void buf_copy_options(buf_T *buf, int flags) buf->b_p_inf = p_inf; buf->b_p_swf = cmdmod.noswapfile ? false : p_swf; buf->b_p_cpt = vim_strsave(p_cpt); -# ifdef BACKSLASH_IN_FILENAME +#ifdef BACKSLASH_IN_FILENAME buf->b_p_csl = vim_strsave(p_csl); -# endif +#endif buf->b_p_cfu = vim_strsave(p_cfu); buf->b_p_ofu = vim_strsave(p_ofu); buf->b_p_tfu = vim_strsave(p_tfu); @@ -6204,21 +6331,17 @@ void set_imsearch_global(void) } static int expand_option_idx = -1; -static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL}; +static char_u expand_option_name[5] = { 't', '_', NUL, NUL, NUL }; static int expand_option_flags = 0; -void -set_context_in_set_cmd( - expand_T *xp, - char_u *arg, - int opt_flags // OPT_GLOBAL and/or OPT_LOCAL -) +/// @param opt_flags OPT_GLOBAL and/or OPT_LOCAL +void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags) { char_u nextchar; uint32_t flags = 0; // init for GCC int opt_idx = 0; // init for GCC - char_u *p; - char_u *s; + char_u *p; + char_u *s; int is_term_option = false; int key; @@ -6342,15 +6465,14 @@ set_context_in_set_cmd( || p == (char_u *)&p_pp || p == (char_u *)&p_rtp || p == (char_u *)&p_cdpath - || p == (char_u *)&p_vdir - ) { + || p == (char_u *)&p_vdir) { xp->xp_context = EXPAND_DIRECTORIES; if (p == (char_u *)&p_path - || p == (char_u *)&p_cdpath - ) + || p == (char_u *)&p_cdpath) { xp->xp_backslash = XP_BS_THREE; - else + } else { xp->xp_backslash = XP_BS_ONE; + } } else if (p == (char_u *)&p_ft) { xp->xp_context = EXPAND_FILETYPE; } else { @@ -6387,8 +6509,6 @@ set_context_in_set_cmd( break; } } - - return; } int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file) @@ -6396,7 +6516,7 @@ int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u *** int num_normal = 0; // Nr of matching non-term-code settings int match; int count = 0; - char_u *str; + char_u *str; int loop; static char *(names[]) = { "all" }; int ic = regmatch->rm_ic; // remember the ignore-case flag @@ -6440,8 +6560,9 @@ int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u *** if (match) { if (loop == 0) { num_normal++; - } else + } else { (*file)[count++] = vim_strsave(str); + } } } @@ -6484,8 +6605,8 @@ void ExpandOldSetting(int *num_file, char_u ***file) char_u *buf = vim_strsave_escaped(var, escape_chars); #ifdef BACKSLASH_IN_FILENAME - /* For MS-Windows et al. we don't double backslashes at the start and - * before a file name character. */ + // For MS-Windows et al. we don't double backslashes at the start and + // before a file name character. for (var = buf; *var != NUL; MB_PTR_ADV(var)) { if (var[0] == '\\' && var[1] == '\\' && expand_option_idx >= 0 @@ -6503,13 +6624,11 @@ void ExpandOldSetting(int *num_file, char_u ***file) /// Get the value for the numeric or string option///opp in a nice format into /// NameBuff[]. Must not be called with a hidden option! -static void -option_value2string( - vimoption_T *opp, - int opt_flags // OPT_GLOBAL and/or OPT_LOCAL -) +/// +/// @param opt_flags OPT_GLOBAL and/or OPT_LOCAL +static void option_value2string(vimoption_T *opp, int opt_flags) { - char_u *varp; + char_u *varp; varp = get_varp_scope(opp, opt_flags); @@ -6532,7 +6651,7 @@ option_value2string( NameBuff[0] = NUL; } else if (opp->flags & P_EXPAND) { home_replace(NULL, varp, NameBuff, MAXPATHL, false); - // Translate 'pastetoggle' into special key names. + // Translate 'pastetoggle' into special key names. } else if ((char_u **)opp->var == &p_pt) { str2specialbuf((const char *)p_pt, (char *)NameBuff, MAXPATHL); } else { @@ -6645,8 +6764,8 @@ static void langmap_init(void) /// changed at any time! static void langmap_set(void) { - char_u *p; - char_u *p2; + char_u *p; + char_u *p2; int from, to; ga_clear(&langmap_mapga); // clear the previous map first @@ -6692,7 +6811,7 @@ static void langmap_set(void) } if (to == NUL) { EMSG2(_("E357: 'langmap': Matching character missing for %s"), - transchar(from)); + transchar(from)); return; } @@ -6711,9 +6830,8 @@ static void langmap_set(void) p = p2; if (p[0] != NUL) { if (p[0] != ',') { - EMSG2(_( - "E358: 'langmap': Extra characters after semicolon: %s"), - p); + EMSG2(_("E358: 'langmap': Extra characters after semicolon: %s"), + p); return; } p++; @@ -6888,15 +7006,15 @@ static void paste_option_changed(void) /// /// Set the values for options that didn't get set yet to the defaults. /// When "fname" is not NULL, use it to set $"envname" when it wasn't set yet. -void vimrc_found(char_u *fname, char_u *envname) +void vimrc_found(char *fname, char *envname) { if (fname != NULL && envname != NULL) { - char *p = vim_getenv((char *)envname); + char *p = vim_getenv(envname); if (p == NULL) { // Set $MYVIMRC to the first vimrc file found. - p = FullName_save((char *)fname, false); + p = FullName_save(fname, false); if (p != NULL) { - os_setenv((char *)envname, p, 1); + os_setenv(envname, p, 1); xfree(p); } } else { @@ -6938,7 +7056,7 @@ void reset_option_was_set(const char *name) /// fill_breakat_flags() -- called when 'breakat' changes value. static void fill_breakat_flags(void) { - char_u *p; + char_u *p; int i; for (i = 0; i < 256; i++) { @@ -6997,13 +7115,10 @@ static int fill_culopt_flags(char_u *val, win_T *wp) /// Check an option that can be a range of string values. /// -/// Return OK for correct value, FAIL otherwise. -/// Empty is always OK. -static int check_opt_strings( - char_u *val, - char **values, - int list // when true: accept a list of values -) +/// @param list when true: accept a list of values +/// +/// @return OK for correct value, FAIL otherwise. Empty is always OK. +static int check_opt_strings(char_u *val, char **values, int list) { return opt_strings_flags(val, values, NULL, list); } @@ -7011,14 +7126,12 @@ static int check_opt_strings( /// Handle an option that can be a range of string values. /// Set a flag in "*flagp" for each string present. /// -/// Return OK for correct value, FAIL otherwise. -/// Empty is always OK. -static int opt_strings_flags( - char_u *val, // new value - char **values, // array of valid string values - unsigned *flagp, - bool list // when true: accept a list of values -) +/// @param val new value +/// @param values array of valid string values +/// @param list when true: accept a list of values +/// +/// @return OK for correct value, FAIL otherwise. Empty is always OK. +static int opt_strings_flags(char_u *val, char **values, unsigned *flagp, bool list) { unsigned int new_flags = 0; @@ -7049,7 +7162,7 @@ static int opt_strings_flags( static int check_opt_wim(void) { char_u new_wim_flags[4]; - char_u *p; + char_u *p; int i; int idx = 0; @@ -7106,10 +7219,14 @@ bool can_bs(int what) return false; } switch (*p_bs) { - case '3': return true; - case '2': return what != BS_NOSTOP; - case '1': return what != BS_START; - case '0': return false; + case '3': + return true; + case '2': + return what != BS_NOSTOP; + case '1': + return what != BS_START; + case '0': + return false; } return vim_strchr(p_bs, what) != NULL; } @@ -7306,11 +7423,7 @@ colnr_T tabstop_start(colnr_T col, long ts, long *vts) // Find the number of tabs and spaces necessary to get from one column // to another. -void tabstop_fromto(colnr_T start_col, - colnr_T end_col, - long ts_arg, - long *vts, - int *ntabs, +void tabstop_fromto(colnr_T start_col, colnr_T end_col, long ts_arg, long *vts, int *ntabs, int *nspcs) { int spaces = end_col - start_col; @@ -7486,18 +7599,13 @@ static bool briopt_check(win_T *wp) while (*p != NUL) { if (STRNCMP(p, "shift:", 6) == 0 - && ((p[6] == '-' && ascii_isdigit(p[7])) || ascii_isdigit(p[6]))) - { + && ((p[6] == '-' && ascii_isdigit(p[7])) || ascii_isdigit(p[6]))) { p += 6; bri_shift = getdigits_int(&p, true, 0); - } - else if (STRNCMP(p, "min:", 4) == 0 && ascii_isdigit(p[4])) - { + } else if (STRNCMP(p, "min:", 4) == 0 && ascii_isdigit(p[4])) { p += 4; bri_min = getdigits_int(&p, true, 0); - } - else if (STRNCMP(p, "sbr", 3) == 0) - { + } else if (STRNCMP(p, "sbr", 3) == 0) { p += 3; bri_sbr = true; } else if (STRNCMP(p, "list:", 5) == 0) { @@ -7590,8 +7698,10 @@ int get_fileformat_force(const buf_T *buf, const exarg_T *eap) int default_fileformat(void) { switch (*p_ffs) { - case 'm': return EOL_MAC; - case 'd': return EOL_DOS; + case 'm': + return EOL_MAC; + case 'd': + return EOL_DOS; } return EOL_UNIX; } @@ -7607,15 +7717,15 @@ void set_fileformat(int eol_style, int opt_flags) char *p = NULL; switch (eol_style) { - case EOL_UNIX: - p = FF_UNIX; - break; - case EOL_MAC: - p = FF_MAC; - break; - case EOL_DOS: - p = FF_DOS; - break; + case EOL_UNIX: + p = FF_UNIX; + break; + case EOL_MAC: + p = FF_MAC; + break; + case EOL_DOS: + p = FF_DOS; + break; } // p is NULL if "eol_style" is EOL_UNKNOWN. @@ -7653,11 +7763,10 @@ char_u *skip_to_option_part(const char_u *p) /// @param[in] sep_chars chars that separate the option parts /// /// @return length of `*option` -size_t copy_option_part(char_u **option, char_u *buf, size_t maxlen, - char *sep_chars) +size_t copy_option_part(char_u **option, char_u *buf, size_t maxlen, char *sep_chars) { size_t len = 0; - char_u *p = *option; + char_u *p = *option; // skip '.' at start of option part, for 'suffixes' if (*p == '.') { @@ -7820,52 +7929,52 @@ Dictionary get_all_vimoptions(void) static Dictionary vimoption2dict(vimoption_T *opt) { - Dictionary dict = ARRAY_DICT_INIT; + Dictionary dict = ARRAY_DICT_INIT; - PUT(dict, "name", CSTR_TO_OBJ(opt->fullname)); - PUT(dict, "shortname", CSTR_TO_OBJ(opt->shortname)); + PUT(dict, "name", CSTR_TO_OBJ(opt->fullname)); + PUT(dict, "shortname", CSTR_TO_OBJ(opt->shortname)); - const char *scope; - if (opt->indir & PV_BUF) { - scope = "buf"; - } else if (opt->indir & PV_WIN) { - scope = "win"; - } else { - scope = "global"; - } - - PUT(dict, "scope", CSTR_TO_OBJ(scope)); - - // welcome to the jungle - PUT(dict, "global_local", BOOL(opt->indir & PV_BOTH)); - PUT(dict, "commalist", BOOL(opt->flags & P_COMMA)); - PUT(dict, "flaglist", BOOL(opt->flags & P_FLAGLIST)); - - PUT(dict, "was_set", BOOL(opt->flags & P_WAS_SET)); - - PUT(dict, "last_set_sid", INTEGER_OBJ(opt->last_set.script_ctx.sc_sid)); - PUT(dict, "last_set_linenr", INTEGER_OBJ(opt->last_set.script_ctx.sc_lnum)); - PUT(dict, "last_set_chan", INTEGER_OBJ((int64_t)opt->last_set.channel_id)); - - const char *type; - Object def; - // TODO(bfredl): do you even nocp? - char_u *def_val = opt->def_val; - if (opt->flags & P_STRING) { - type = "string"; - def = CSTR_TO_OBJ(def_val ? (char *)def_val : ""); - } else if (opt->flags & P_NUM) { - type = "number"; - def = INTEGER_OBJ((Integer)(intptr_t)def_val); - } else if (opt->flags & P_BOOL) { - type = "boolean"; - def = BOOL((intptr_t)def_val); - } else { - type = ""; def = NIL; - } - PUT(dict, "type", CSTR_TO_OBJ(type)); - PUT(dict, "default", def); - PUT(dict, "allows_duplicates", BOOL(!(opt->flags & P_NODUP))); + const char *scope; + if (opt->indir & PV_BUF) { + scope = "buf"; + } else if (opt->indir & PV_WIN) { + scope = "win"; + } else { + scope = "global"; + } + + PUT(dict, "scope", CSTR_TO_OBJ(scope)); + + // welcome to the jungle + PUT(dict, "global_local", BOOL(opt->indir & PV_BOTH)); + PUT(dict, "commalist", BOOL(opt->flags & P_COMMA)); + PUT(dict, "flaglist", BOOL(opt->flags & P_FLAGLIST)); + + PUT(dict, "was_set", BOOL(opt->flags & P_WAS_SET)); + + PUT(dict, "last_set_sid", INTEGER_OBJ(opt->last_set.script_ctx.sc_sid)); + PUT(dict, "last_set_linenr", INTEGER_OBJ(opt->last_set.script_ctx.sc_lnum)); + PUT(dict, "last_set_chan", INTEGER_OBJ((int64_t)opt->last_set.channel_id)); + + const char *type; + Object def; + // TODO(bfredl): do you even nocp? + char_u *def_val = opt->def_val; + if (opt->flags & P_STRING) { + type = "string"; + def = CSTR_TO_OBJ(def_val ? (char *)def_val : ""); + } else if (opt->flags & P_NUM) { + type = "number"; + def = INTEGER_OBJ((Integer)(intptr_t)def_val); + } else if (opt->flags & P_BOOL) { + type = "boolean"; + def = BOOL((intptr_t)def_val); + } else { + type = ""; def = NIL; + } + PUT(dict, "type", CSTR_TO_OBJ(type)); + PUT(dict, "default", def); + PUT(dict, "allows_duplicates", BOOL(!(opt->flags & P_NODUP))); - return dict; + return dict; } diff --git a/src/nvim/option.h b/src/nvim/option.h index c6ee03e052..452494172f 100644 --- a/src/nvim/option.h +++ b/src/nvim/option.h @@ -3,10 +3,10 @@ #include "nvim/ex_cmds_defs.h" // for exarg_T -/* flags for buf_copy_options() */ -#define BCO_ENTER 1 /* going to enter the buffer */ -#define BCO_ALWAYS 2 /* always copy the options */ -#define BCO_NOHELP 4 /* don't touch the help related options */ +// flags for buf_copy_options() +#define BCO_ENTER 1 // going to enter the buffer +#define BCO_ALWAYS 2 // always copy the options +#define BCO_NOHELP 4 // don't touch the help related options /// Flags for option-setting functions /// diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index e588d3f373..441d29cd9f 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -1,9 +1,9 @@ #ifndef NVIM_OPTION_DEFS_H #define NVIM_OPTION_DEFS_H -#include "nvim/types.h" -#include "nvim/macros.h" // For EXTERN #include "eval/typval.h" // For scid_T +#include "nvim/macros.h" // For EXTERN +#include "nvim/types.h" // option_defs.h: definition of global variables for settable options @@ -25,9 +25,11 @@ // The "%f|%l| %m" one is used for when the contents of the quickfix window is // written to a file. #ifdef WIN32 -# define DFLT_EFM "%f(%l) \\=: %t%*\\D%n: %m,%*[^\"]\"%f\"%*\\D%l: %m,%f(%l) \\=: %m,%*[^ ] %f %l: %m,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,%f|%l| %m" +# define DFLT_EFM \ + "%f(%l) \\=: %t%*\\D%n: %m,%*[^\"]\"%f\"%*\\D%l: %m,%f(%l) \\=: %m,%*[^ ] %f %l: %m,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,%f|%l| %m" #else -# define DFLT_EFM "%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%-G%f:%l: (Each undeclared identifier is reported only once,%-G%f:%l: for each function it appears in.),%-GIn file included from %f:%l:%c:,%-GIn file included from %f:%l:%c\\,,%-GIn file included from %f:%l:%c,%-GIn file included from %f:%l,%-G%*[ ]from %f:%l:%c,%-G%*[ ]from %f:%l:,%-G%*[ ]from %f:%l\\,,%-G%*[ ]from %f:%l,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory %*[`']%f',%X%*\\a[%*\\d]: Leaving directory %*[`']%f',%D%*\\a: Entering directory %*[`']%f',%X%*\\a: Leaving directory %*[`']%f',%DMaking %*\\a in %f,%f|%l| %m" +# define DFLT_EFM \ + "%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%-G%f:%l: (Each undeclared identifier is reported only once,%-G%f:%l: for each function it appears in.),%-GIn file included from %f:%l:%c:,%-GIn file included from %f:%l:%c\\,,%-GIn file included from %f:%l:%c,%-GIn file included from %f:%l,%-G%*[ ]from %f:%l:%c,%-G%*[ ]from %f:%l:,%-G%*[ ]from %f:%l\\,,%-G%*[ ]from %f:%l,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory %*[`']%f',%X%*\\a[%*\\d]: Leaving directory %*[`']%f',%D%*\\a: Entering directory %*[`']%f',%X%*\\a: Leaving directory %*[`']%f',%DMaking %*\\a in %f,%f|%l| %m" #endif #define DFLT_GREPFORMAT "%f:%l:%m,%f:%l%m,%f %l%m" @@ -42,17 +44,17 @@ # define DFLT_FFS_VIM "dos,unix" # define DFLT_FFS_VI "dos,unix" // also autodetect in compatible mode #else -# define DFLT_FF "unix" -# define DFLT_FFS_VIM "unix,dos" -# define DFLT_FFS_VI "" +# define DFLT_FF "unix" +# define DFLT_FFS_VIM "unix,dos" +# define DFLT_FFS_VI "" #endif // Possible values for 'encoding' -# define ENC_UCSBOM "ucs-bom" // check for BOM at start of file +#define ENC_UCSBOM "ucs-bom" // check for BOM at start of file // default value for 'encoding' -# define ENC_DFLT "utf-8" +#define ENC_DFLT "utf-8" // end-of-line style #define EOL_UNKNOWN -1 // not defined yet @@ -179,9 +181,9 @@ enum { }; /// Represented by 'a' flag. #define SHM_ALL_ABBREVIATIONS ((char_u[]) { \ - SHM_RO, SHM_MOD, SHM_FILE, SHM_LAST, SHM_TEXT, SHM_LINES, SHM_NEW, SHM_WRI, \ - 0, \ -}) + SHM_RO, SHM_MOD, SHM_FILE, SHM_LAST, SHM_TEXT, SHM_LINES, SHM_NEW, SHM_WRI, \ + 0, \ + }) // characters for p_go: #define GO_ASEL 'a' // autoselect @@ -264,16 +266,16 @@ enum { }; /// C string containing all 'statusline' option flags #define STL_ALL ((char_u[]) { \ - STL_FILEPATH, STL_FULLPATH, STL_FILENAME, STL_COLUMN, STL_VIRTCOL, \ - STL_VIRTCOL_ALT, STL_LINE, STL_NUMLINES, STL_BUFNO, STL_KEYMAP, STL_OFFSET, \ - STL_OFFSET_X, STL_BYTEVAL, STL_BYTEVAL_X, STL_ROFLAG, STL_ROFLAG_ALT, \ - STL_HELPFLAG, STL_HELPFLAG_ALT, STL_FILETYPE, STL_FILETYPE_ALT, \ - STL_PREVIEWFLAG, STL_PREVIEWFLAG_ALT, STL_MODIFIED, STL_MODIFIED_ALT, \ - STL_QUICKFIX, STL_PERCENTAGE, STL_ALTPERCENT, STL_ARGLISTSTAT, STL_PAGENUM, \ - STL_VIM_EXPR, STL_SEPARATE, STL_TRUNCMARK, STL_USER_HL, STL_HIGHLIGHT, \ - STL_TABPAGENR, STL_TABCLOSENR, STL_CLICK_FUNC, \ - 0, \ -}) + STL_FILEPATH, STL_FULLPATH, STL_FILENAME, STL_COLUMN, STL_VIRTCOL, \ + STL_VIRTCOL_ALT, STL_LINE, STL_NUMLINES, STL_BUFNO, STL_KEYMAP, STL_OFFSET, \ + STL_OFFSET_X, STL_BYTEVAL, STL_BYTEVAL_X, STL_ROFLAG, STL_ROFLAG_ALT, \ + STL_HELPFLAG, STL_HELPFLAG_ALT, STL_FILETYPE, STL_FILETYPE_ALT, \ + STL_PREVIEWFLAG, STL_PREVIEWFLAG_ALT, STL_MODIFIED, STL_MODIFIED_ALT, \ + STL_QUICKFIX, STL_PERCENTAGE, STL_ALTPERCENT, STL_ARGLISTSTAT, STL_PAGENUM, \ + STL_VIM_EXPR, STL_SEPARATE, STL_TRUNCMARK, STL_USER_HL, STL_HIGHLIGHT, \ + STL_TABPAGENR, STL_TABCLOSENR, STL_CLICK_FUNC, \ + 0, \ + }) // flags used for parsed 'wildmode' #define WIM_FULL 0x01 @@ -305,36 +307,36 @@ enum { EXTERN long p_aleph; // 'aleph' EXTERN int p_acd; // 'autochdir' -EXTERN char_u *p_ambw; // 'ambiwidth' +EXTERN char_u *p_ambw; // 'ambiwidth' EXTERN int p_ar; // 'autoread' EXTERN int p_aw; // 'autowrite' EXTERN int p_awa; // 'autowriteall' -EXTERN char_u *p_bs; // 'backspace' -EXTERN char_u *p_bg; // 'background' +EXTERN char_u *p_bs; // 'backspace' +EXTERN char_u *p_bg; // 'background' EXTERN int p_bk; // 'backup' -EXTERN char_u *p_bkc; // 'backupcopy' +EXTERN char_u *p_bkc; // 'backupcopy' EXTERN unsigned int bkc_flags; ///< flags from 'backupcopy' #ifdef IN_OPTION_C static char *(p_bkc_values[]) = -{"yes", "auto", "no", "breaksymlink", "breakhardlink", NULL}; +{ "yes", "auto", "no", "breaksymlink", "breakhardlink", NULL }; #endif -# define BKC_YES 0x001 -# define BKC_AUTO 0x002 -# define BKC_NO 0x004 -# define BKC_BREAKSYMLINK 0x008 -# define BKC_BREAKHARDLINK 0x010 +#define BKC_YES 0x001 +#define BKC_AUTO 0x002 +#define BKC_NO 0x004 +#define BKC_BREAKSYMLINK 0x008 +#define BKC_BREAKHARDLINK 0x010 EXTERN char_u *p_bdir; // 'backupdir' EXTERN char_u *p_bex; // 'backupext' EXTERN char_u *p_bo; // 'belloff' EXTERN char breakat_flags[256]; // which characters are in 'breakat' EXTERN unsigned bo_flags; -# ifdef IN_OPTION_C -static char *(p_bo_values[]) = {"all", "backspace", "cursor", "complete", - "copy", "ctrlg", "error", "esc", "ex", - "hangul", "insertmode", "lang", "mess", - "showmatch", "operator", "register", "shell", - "spell", "wildmode", NULL}; -# endif +#ifdef IN_OPTION_C +static char *(p_bo_values[]) = { "all", "backspace", "cursor", "complete", + "copy", "ctrlg", "error", "esc", "ex", + "hangul", "insertmode", "lang", "mess", + "showmatch", "operator", "register", "shell", + "spell", "wildmode", NULL }; +#endif // values for the 'belloff' option #define BO_ALL 0x0001 @@ -357,61 +359,61 @@ static char *(p_bo_values[]) = {"all", "backspace", "cursor", "complete", #define BO_SPELL 0x20000 #define BO_WILD 0x40000 -EXTERN char_u *p_bsk; // 'backupskip' -EXTERN char_u *p_breakat; // 'breakat' -EXTERN char_u *p_cmp; // 'casemap' +EXTERN char_u *p_bsk; // 'backupskip' +EXTERN char_u *p_breakat; // 'breakat' +EXTERN char_u *p_cmp; // 'casemap' EXTERN unsigned cmp_flags; -# ifdef IN_OPTION_C -static char *(p_cmp_values[]) = {"internal", "keepascii", NULL}; -# endif -# define CMP_INTERNAL 0x001 -# define CMP_KEEPASCII 0x002 -EXTERN char_u *p_enc; // 'encoding' +#ifdef IN_OPTION_C +static char *(p_cmp_values[]) = { "internal", "keepascii", NULL }; +#endif +#define CMP_INTERNAL 0x001 +#define CMP_KEEPASCII 0x002 +EXTERN char_u *p_enc; // 'encoding' EXTERN int p_deco; // 'delcombine' -EXTERN char_u *p_ccv; // 'charconvert' -EXTERN char_u *p_cedit; // 'cedit' -EXTERN char_u *p_cb; // 'clipboard' +EXTERN char_u *p_ccv; // 'charconvert' +EXTERN char_u *p_cedit; // 'cedit' +EXTERN char_u *p_cb; // 'clipboard' EXTERN unsigned cb_flags; #ifdef IN_OPTION_C -static char *(p_cb_values[]) = {"unnamed", "unnamedplus", NULL}; +static char *(p_cb_values[]) = { "unnamed", "unnamedplus", NULL }; #endif -# define CB_UNNAMED 0x001 -# define CB_UNNAMEDPLUS 0x002 -# define CB_UNNAMEDMASK (CB_UNNAMED | CB_UNNAMEDPLUS) +#define CB_UNNAMED 0x001 +#define CB_UNNAMEDPLUS 0x002 +#define CB_UNNAMEDMASK (CB_UNNAMED | CB_UNNAMEDPLUS) EXTERN long p_cwh; // 'cmdwinheight' EXTERN long p_ch; // 'cmdheight' EXTERN long p_columns; // 'columns' EXTERN int p_confirm; // 'confirm' -EXTERN char_u *p_cot; // 'completeopt' -# ifdef BACKSLASH_IN_FILENAME -EXTERN char_u *p_csl; // 'completeslash' -# endif +EXTERN char_u *p_cot; // 'completeopt' +#ifdef BACKSLASH_IN_FILENAME +EXTERN char_u *p_csl; // 'completeslash' +#endif EXTERN long p_pb; // 'pumblend' EXTERN long p_ph; // 'pumheight' EXTERN long p_pw; // 'pumwidth' -EXTERN char_u *p_cpo; // 'cpoptions' -EXTERN char_u *p_csprg; // 'cscopeprg' +EXTERN char_u *p_cpo; // 'cpoptions' +EXTERN char_u *p_csprg; // 'cscopeprg' EXTERN int p_csre; // 'cscoperelative' -EXTERN char_u *p_csqf; // 'cscopequickfix' -# define CSQF_CMDS "sgdctefia" -# define CSQF_FLAGS "+-0" +EXTERN char_u *p_csqf; // 'cscopequickfix' +#define CSQF_CMDS "sgdctefia" +#define CSQF_FLAGS "+-0" EXTERN int p_cst; // 'cscopetag' EXTERN long p_csto; // 'cscopetagorder' EXTERN long p_cspc; // 'cscopepathcomp' EXTERN int p_csverbose; // 'cscopeverbose' -EXTERN char_u *p_debug; // 'debug' -EXTERN char_u *p_def; // 'define' -EXTERN char_u *p_inc; -EXTERN char_u *p_dip; // 'diffopt' -EXTERN char_u *p_dex; // 'diffexpr' -EXTERN char_u *p_dict; // 'dictionary' +EXTERN char_u *p_debug; // 'debug' +EXTERN char_u *p_def; // 'define' +EXTERN char_u *p_inc; +EXTERN char_u *p_dip; // 'diffopt' +EXTERN char_u *p_dex; // 'diffexpr' +EXTERN char_u *p_dict; // 'dictionary' EXTERN int p_dg; // 'digraph' -EXTERN char_u *p_dir; // 'directory' -EXTERN char_u *p_dy; // 'display' +EXTERN char_u *p_dir; // 'directory' +EXTERN char_u *p_dy; // 'display' EXTERN unsigned dy_flags; #ifdef IN_OPTION_C static char *(p_dy_values[]) = { "lastline", "truncate", "uhex", "msgsep", - NULL }; + NULL }; #endif #define DY_LASTLINE 0x001 #define DY_TRUNCATE 0x002 @@ -420,72 +422,72 @@ static char *(p_dy_values[]) = { "lastline", "truncate", "uhex", "msgsep", #define DY_MSGSEP 0x008 EXTERN int p_ed; // 'edcompatible' EXTERN int p_emoji; // 'emoji' -EXTERN char_u *p_ead; // 'eadirection' +EXTERN char_u *p_ead; // 'eadirection' EXTERN int p_ea; // 'equalalways' -EXTERN char_u *p_ep; // 'equalprg' +EXTERN char_u *p_ep; // 'equalprg' EXTERN int p_eb; // 'errorbells' -EXTERN char_u *p_ef; // 'errorfile' -EXTERN char_u *p_efm; // 'errorformat' -EXTERN char_u *p_gefm; // 'grepformat' -EXTERN char_u *p_gp; // 'grepprg' -EXTERN char_u *p_ei; // 'eventignore' +EXTERN char_u *p_ef; // 'errorfile' +EXTERN char_u *p_efm; // 'errorformat' +EXTERN char_u *p_gefm; // 'grepformat' +EXTERN char_u *p_gp; // 'grepprg' +EXTERN char_u *p_ei; // 'eventignore' EXTERN int p_exrc; // 'exrc' -EXTERN char_u *p_fencs; // 'fileencodings' -EXTERN char_u *p_ffs; // 'fileformats' +EXTERN char_u *p_fencs; // 'fileencodings' +EXTERN char_u *p_ffs; // 'fileformats' EXTERN int p_fic; // 'fileignorecase' -EXTERN char_u *p_fcl; // 'foldclose' +EXTERN char_u *p_fcl; // 'foldclose' EXTERN long p_fdls; // 'foldlevelstart' -EXTERN char_u *p_fdo; // 'foldopen' +EXTERN char_u *p_fdo; // 'foldopen' EXTERN unsigned fdo_flags; -# ifdef IN_OPTION_C -static char *(p_fdo_values[]) = {"all", "block", "hor", "mark", "percent", - "quickfix", "search", "tag", "insert", - "undo", "jump", NULL}; -# endif -# define FDO_ALL 0x001 -# define FDO_BLOCK 0x002 -# define FDO_HOR 0x004 -# define FDO_MARK 0x008 -# define FDO_PERCENT 0x010 -# define FDO_QUICKFIX 0x020 -# define FDO_SEARCH 0x040 -# define FDO_TAG 0x080 -# define FDO_INSERT 0x100 -# define FDO_UNDO 0x200 -# define FDO_JUMP 0x400 -EXTERN char_u *p_fp; // 'formatprg' +#ifdef IN_OPTION_C +static char *(p_fdo_values[]) = { "all", "block", "hor", "mark", "percent", + "quickfix", "search", "tag", "insert", + "undo", "jump", NULL }; +#endif +#define FDO_ALL 0x001 +#define FDO_BLOCK 0x002 +#define FDO_HOR 0x004 +#define FDO_MARK 0x008 +#define FDO_PERCENT 0x010 +#define FDO_QUICKFIX 0x020 +#define FDO_SEARCH 0x040 +#define FDO_TAG 0x080 +#define FDO_INSERT 0x100 +#define FDO_UNDO 0x200 +#define FDO_JUMP 0x400 +EXTERN char_u *p_fp; // 'formatprg' EXTERN int p_fs; // 'fsync' EXTERN int p_gd; // 'gdefault' -EXTERN char_u *p_pdev; // 'printdevice' -EXTERN char_u *p_penc; // 'printencoding' -EXTERN char_u *p_pexpr; // 'printexpr' -EXTERN char_u *p_pmfn; // 'printmbfont' -EXTERN char_u *p_pmcs; // 'printmbcharset' -EXTERN char_u *p_pfn; // 'printfont' -EXTERN char_u *p_popt; // 'printoptions' -EXTERN char_u *p_header; // 'printheader' -EXTERN char_u *p_guicursor; // 'guicursor' -EXTERN char_u *p_guifont; // 'guifont' -EXTERN char_u *p_guifontwide; // 'guifontwide' -EXTERN char_u *p_hf; // 'helpfile' +EXTERN char_u *p_pdev; // 'printdevice' +EXTERN char_u *p_penc; // 'printencoding' +EXTERN char_u *p_pexpr; // 'printexpr' +EXTERN char_u *p_pmfn; // 'printmbfont' +EXTERN char_u *p_pmcs; // 'printmbcharset' +EXTERN char_u *p_pfn; // 'printfont' +EXTERN char_u *p_popt; // 'printoptions' +EXTERN char_u *p_header; // 'printheader' +EXTERN char_u *p_guicursor; // 'guicursor' +EXTERN char_u *p_guifont; // 'guifont' +EXTERN char_u *p_guifontwide; // 'guifontwide' +EXTERN char_u *p_hf; // 'helpfile' EXTERN long p_hh; // 'helpheight' -EXTERN char_u *p_hlg; // 'helplang' +EXTERN char_u *p_hlg; // 'helplang' EXTERN int p_hid; // 'hidden' -EXTERN char_u *p_hl; // 'highlight' +EXTERN char_u *p_hl; // 'highlight' EXTERN int p_hls; // 'hlsearch' EXTERN long p_hi; // 'history' EXTERN int p_hkmap; // 'hkmap' EXTERN int p_hkmapp; // 'hkmapp' EXTERN int p_arshape; // 'arabicshape' EXTERN int p_icon; // 'icon' -EXTERN char_u *p_iconstring; // 'iconstring' +EXTERN char_u *p_iconstring; // 'iconstring' EXTERN int p_ic; // 'ignorecase' EXTERN int p_is; // 'incsearch' -EXTERN char_u *p_icm; // 'inccommand' +EXTERN char_u *p_icm; // 'inccommand' EXTERN int p_im; // 'insertmode' -EXTERN char_u *p_isf; // 'isfname' -EXTERN char_u *p_isi; // 'isident' -EXTERN char_u *p_isp; // 'isprint' +EXTERN char_u *p_isf; // 'isfname' +EXTERN char_u *p_isi; // 'isident' +EXTERN char_u *p_isp; // 'isprint' EXTERN int p_js; // 'joinspaces' EXTERN char_u *p_jop; // 'jumpooptions' EXTERN unsigned jop_flags; @@ -493,26 +495,26 @@ EXTERN unsigned jop_flags; static char *(p_jop_values[]) = { "stack", NULL }; #endif #define JOP_STACK 0x01 -EXTERN char_u *p_kp; // 'keywordprg' -EXTERN char_u *p_km; // 'keymodel' -EXTERN char_u *p_langmap; // 'langmap' +EXTERN char_u *p_kp; // 'keywordprg' +EXTERN char_u *p_km; // 'keymodel' +EXTERN char_u *p_langmap; // 'langmap' EXTERN int p_lnr; // 'langnoremap' EXTERN int p_lrm; // 'langremap' -EXTERN char_u *p_lm; // 'langmenu' -EXTERN long p_lines; // 'lines' -EXTERN long p_linespace; // 'linespace' -EXTERN char_u *p_lispwords; // 'lispwords' +EXTERN char_u *p_lm; // 'langmenu' +EXTERN long p_lines; // 'lines' +EXTERN long p_linespace; // 'linespace' +EXTERN char_u *p_lispwords; // 'lispwords' EXTERN long p_ls; // 'laststatus' EXTERN long p_stal; // 'showtabline' -EXTERN char_u *p_lcs; // 'listchars' +EXTERN char_u *p_lcs; // 'listchars' EXTERN int p_lz; // 'lazyredraw' EXTERN int p_lpl; // 'loadplugins' EXTERN int p_magic; // 'magic' -EXTERN char_u *p_menc; // 'makeencoding' -EXTERN char_u *p_mef; // 'makeef' -EXTERN char_u *p_mp; // 'makeprg' -EXTERN char_u *p_cc; // 'colorcolumn' +EXTERN char_u *p_menc; // 'makeencoding' +EXTERN char_u *p_mef; // 'makeef' +EXTERN char_u *p_mp; // 'makeprg' +EXTERN char_u *p_cc; // 'colorcolumn' EXTERN int p_cc_cols[256]; // array for 'colorcolumn' columns EXTERN long p_mat; // 'matchtime' EXTERN long p_mco; // 'maxcombine' @@ -520,26 +522,26 @@ EXTERN long p_mfd; // 'maxfuncdepth' EXTERN long p_mmd; // 'maxmapdepth' EXTERN long p_mmp; // 'maxmempattern' EXTERN long p_mis; // 'menuitems' -EXTERN char_u *p_msm; // 'mkspellmem' +EXTERN char_u *p_msm; // 'mkspellmem' EXTERN long p_mle; // 'modelineexpr' EXTERN long p_mls; // 'modelines' -EXTERN char_u *p_mouse; // 'mouse' -EXTERN char_u *p_mousem; // 'mousemodel' +EXTERN char_u *p_mouse; // 'mouse' +EXTERN char_u *p_mousem; // 'mousemodel' EXTERN long p_mousef; // 'mousefocus' EXTERN long p_mouset; // 'mousetime' EXTERN int p_more; // 'more' -EXTERN char_u *p_opfunc; // 'operatorfunc' -EXTERN char_u *p_para; // 'paragraphs' +EXTERN char_u *p_opfunc; // 'operatorfunc' +EXTERN char_u *p_para; // 'paragraphs' EXTERN int p_paste; // 'paste' -EXTERN char_u *p_pt; // 'pastetoggle' -EXTERN char_u *p_pex; // 'patchexpr' -EXTERN char_u *p_pm; // 'patchmode' -EXTERN char_u *p_path; // 'path' -EXTERN char_u *p_cdpath; // 'cdpath' +EXTERN char_u *p_pt; // 'pastetoggle' +EXTERN char_u *p_pex; // 'patchexpr' +EXTERN char_u *p_pm; // 'patchmode' +EXTERN char_u *p_path; // 'path' +EXTERN char_u *p_cdpath; // 'cdpath' EXTERN long p_pyx; // 'pyxversion' EXTERN char_u *p_rdb; // 'redrawdebug' EXTERN unsigned rdb_flags; -# ifdef IN_OPTION_C +#ifdef IN_OPTION_C static char *(p_rdb_values[]) = { "compositor", "nothrottle", @@ -547,11 +549,11 @@ static char *(p_rdb_values[]) = { "nodelta", NULL }; -# endif -# define RDB_COMPOSITOR 0x001 -# define RDB_NOTHROTTLE 0x002 -# define RDB_INVALID 0x004 -# define RDB_NODELTA 0x008 +#endif +#define RDB_COMPOSITOR 0x001 +#define RDB_NOTHROTTLE 0x002 +#define RDB_INVALID 0x004 +#define RDB_NODELTA 0x008 EXTERN long p_rdt; // 'redrawtime' EXTERN int p_remap; // 'remap' @@ -561,21 +563,21 @@ EXTERN long p_pvh; // 'previewheight' EXTERN int p_ari; // 'allowrevins' EXTERN int p_ri; // 'revins' EXTERN int p_ru; // 'ruler' -EXTERN char_u *p_ruf; // 'rulerformat' -EXTERN char_u *p_pp; // 'packpath' -EXTERN char_u *p_qftf; // 'quickfixtextfunc' -EXTERN char_u *p_rtp; // 'runtimepath' +EXTERN char_u *p_ruf; // 'rulerformat' +EXTERN char_u *p_pp; // 'packpath' +EXTERN char_u *p_qftf; // 'quickfixtextfunc' +EXTERN char_u *p_rtp; // 'runtimepath' EXTERN long p_scbk; // 'scrollback' EXTERN long p_sj; // 'scrolljump' EXTERN long p_so; // 'scrolloff' -EXTERN char_u *p_sbo; // 'scrollopt' -EXTERN char_u *p_sections; // 'sections' +EXTERN char_u *p_sbo; // 'scrollopt' +EXTERN char_u *p_sections; // 'sections' EXTERN int p_secure; // 'secure' -EXTERN char_u *p_sel; // 'selection' -EXTERN char_u *p_slm; // 'selectmode' -EXTERN char_u *p_ssop; // 'sessionoptions' +EXTERN char_u *p_sel; // 'selection' +EXTERN char_u *p_slm; // 'selectmode' +EXTERN char_u *p_ssop; // 'sessionoptions' EXTERN unsigned ssop_flags; -# ifdef IN_OPTION_C +#ifdef IN_OPTION_C // Also used for 'viewoptions'! Keep in sync with SSOP_ flags. static char *(p_ssop_values[]) = { "buffers", "winpos", "resize", "winsize", @@ -583,41 +585,41 @@ static char *(p_ssop_values[]) = { "sesdir", "curdir", "folds", "cursor", "tabpages", "terminal", "skiprtp", NULL }; -# endif -# define SSOP_BUFFERS 0x001 -# define SSOP_WINPOS 0x002 -# define SSOP_RESIZE 0x004 -# define SSOP_WINSIZE 0x008 -# define SSOP_LOCALOPTIONS 0x010 -# define SSOP_OPTIONS 0x020 -# define SSOP_HELP 0x040 -# define SSOP_BLANK 0x080 -# define SSOP_GLOBALS 0x100 -# define SSOP_SLASH 0x200 // Deprecated, always set. -# define SSOP_UNIX 0x400 // Deprecated, always set. -# define SSOP_SESDIR 0x800 -# define SSOP_CURDIR 0x1000 -# define SSOP_FOLDS 0x2000 -# define SSOP_CURSOR 0x4000 -# define SSOP_TABPAGES 0x8000 -# define SSOP_TERMINAL 0x10000 -# define SSOP_SKIP_RTP 0x20000 - -EXTERN char_u *p_sh; // 'shell' -EXTERN char_u *p_shcf; // 'shellcmdflag' -EXTERN char_u *p_sp; // 'shellpipe' -EXTERN char_u *p_shq; // 'shellquote' -EXTERN char_u *p_sxq; // 'shellxquote' -EXTERN char_u *p_sxe; // 'shellxescape' -EXTERN char_u *p_srr; // 'shellredir' +#endif +#define SSOP_BUFFERS 0x001 +#define SSOP_WINPOS 0x002 +#define SSOP_RESIZE 0x004 +#define SSOP_WINSIZE 0x008 +#define SSOP_LOCALOPTIONS 0x010 +#define SSOP_OPTIONS 0x020 +#define SSOP_HELP 0x040 +#define SSOP_BLANK 0x080 +#define SSOP_GLOBALS 0x100 +#define SSOP_SLASH 0x200 // Deprecated, always set. +#define SSOP_UNIX 0x400 // Deprecated, always set. +#define SSOP_SESDIR 0x800 +#define SSOP_CURDIR 0x1000 +#define SSOP_FOLDS 0x2000 +#define SSOP_CURSOR 0x4000 +#define SSOP_TABPAGES 0x8000 +#define SSOP_TERMINAL 0x10000 +#define SSOP_SKIP_RTP 0x20000 + +EXTERN char_u *p_sh; // 'shell' +EXTERN char_u *p_shcf; // 'shellcmdflag' +EXTERN char_u *p_sp; // 'shellpipe' +EXTERN char_u *p_shq; // 'shellquote' +EXTERN char_u *p_sxq; // 'shellxquote' +EXTERN char_u *p_sxe; // 'shellxescape' +EXTERN char_u *p_srr; // 'shellredir' EXTERN int p_stmp; // 'shelltemp' #ifdef BACKSLASH_IN_FILENAME EXTERN int p_ssl; // 'shellslash' #endif -EXTERN char_u *p_stl; // 'statusline' +EXTERN char_u *p_stl; // 'statusline' EXTERN int p_sr; // 'shiftround' -EXTERN char_u *p_shm; // 'shortmess' -EXTERN char_u *p_sbr; // 'showbreak' +EXTERN char_u *p_shm; // 'shortmess' +EXTERN char_u *p_sbr; // 'showbreak' EXTERN int p_sc; // 'showcmd' EXTERN int p_sft; // 'showfulltag' EXTERN int p_sm; // 'showmatch' @@ -628,29 +630,29 @@ EXTERN int p_scs; // 'smartcase' EXTERN int p_sta; // 'smarttab' EXTERN int p_sb; // 'splitbelow' EXTERN long p_tpm; // 'tabpagemax' -EXTERN char_u *p_tal; // 'tabline' -EXTERN char_u *p_tpf; // 'termpastefilter' +EXTERN char_u *p_tal; // 'tabline' +EXTERN char_u *p_tpf; // 'termpastefilter' EXTERN unsigned int tpf_flags; ///< flags from 'termpastefilter' #ifdef IN_OPTION_C static char *(p_tpf_values[]) = - { "BS", "HT", "FF", "ESC", "DEL", "C0", "C1", NULL }; +{ "BS", "HT", "FF", "ESC", "DEL", "C0", "C1", NULL }; #endif -# define TPF_BS 0x001 -# define TPF_HT 0x002 -# define TPF_FF 0x004 -# define TPF_ESC 0x008 -# define TPF_DEL 0x010 -# define TPF_C0 0x020 -# define TPF_C1 0x040 -EXTERN char_u *p_sps; // 'spellsuggest' +#define TPF_BS 0x001 +#define TPF_HT 0x002 +#define TPF_FF 0x004 +#define TPF_ESC 0x008 +#define TPF_DEL 0x010 +#define TPF_C0 0x020 +#define TPF_C1 0x040 +EXTERN char_u *p_sps; // 'spellsuggest' EXTERN int p_spr; // 'splitright' EXTERN int p_sol; // 'startofline' -EXTERN char_u *p_su; // 'suffixes' -EXTERN char_u *p_swb; // 'switchbuf' +EXTERN char_u *p_su; // 'suffixes' +EXTERN char_u *p_swb; // 'switchbuf' EXTERN unsigned swb_flags; #ifdef IN_OPTION_C static char *(p_swb_values[]) = - { "useopen", "usetab", "split", "newtab", "vsplit", "uselast", NULL }; +{ "useopen", "usetab", "split", "newtab", "vsplit", "uselast", NULL }; #endif #define SWB_USEOPEN 0x001 #define SWB_USETAB 0x002 @@ -663,7 +665,7 @@ EXTERN char_u *p_tc; ///< 'tagcase' EXTERN unsigned tc_flags; ///< flags from 'tagcase' #ifdef IN_OPTION_C static char *(p_tc_values[]) = - { "followic", "ignore", "match", "followscs", "smart", NULL }; +{ "followic", "ignore", "match", "followscs", "smart", NULL }; #endif #define TC_FOLLOWIC 0x01 #define TC_IGNORE 0x02 @@ -701,35 +703,35 @@ EXTERN unsigned vop_flags; ///< uses SSOP_ flags EXTERN int p_vb; ///< 'visualbell' EXTERN char_u *p_ve; ///< 'virtualedit' EXTERN unsigned ve_flags; -# ifdef IN_OPTION_C -static char *(p_ve_values[]) = {"block", "insert", "all", "onemore", NULL}; -# endif -# define VE_BLOCK 5 // includes "all" -# define VE_INSERT 6 // includes "all" -# define VE_ALL 4 -# define VE_ONEMORE 8 +#ifdef IN_OPTION_C +static char *(p_ve_values[]) = { "block", "insert", "all", "onemore", NULL }; +#endif +#define VE_BLOCK 5 // includes "all" +#define VE_INSERT 6 // includes "all" +#define VE_ALL 4 +#define VE_ONEMORE 8 EXTERN long p_verbose; // 'verbose' #ifdef IN_OPTION_C char_u *p_vfile = (char_u *)""; // used before options are initialized #else -extern char_u *p_vfile; // 'verbosefile' +extern char_u *p_vfile; // 'verbosefile' #endif EXTERN int p_warn; // 'warn' -EXTERN char_u *p_wop; // 'wildoptions' +EXTERN char_u *p_wop; // 'wildoptions' EXTERN unsigned wop_flags; -# ifdef IN_OPTION_C +#ifdef IN_OPTION_C static char *(p_wop_values[]) = { "tagfile", "pum", NULL }; #endif #define WOP_TAGFILE 0x01 #define WOP_PUM 0x02 EXTERN long p_window; // 'window' -EXTERN char_u *p_wak; // 'winaltkeys' -EXTERN char_u *p_wig; // 'wildignore' -EXTERN char_u *p_ww; // 'whichwrap' +EXTERN char_u *p_wak; // 'winaltkeys' +EXTERN char_u *p_wig; // 'wildignore' +EXTERN char_u *p_ww; // 'whichwrap' EXTERN long p_wc; // 'wildchar' EXTERN long p_wcm; // 'wildcharm' EXTERN int p_wic; // 'wildignorecase' -EXTERN char_u *p_wim; // 'wildmode' +EXTERN char_u *p_wim; // 'wildmode' EXTERN int p_wmnu; // 'wildmenu' EXTERN long p_wh; // 'winheight' EXTERN long p_wmh; // 'winminheight' @@ -750,91 +752,91 @@ EXTERN int p_force_off; ///< options that cannot be turned on. // b_p_scriptID[]. // enum { - BV_AI = 0 - , BV_AR - , BV_BH - , BV_BKC - , BV_BT - , BV_EFM - , BV_GP - , BV_MP - , BV_BIN - , BV_BL - , BV_BOMB - , BV_CHANNEL - , BV_CI - , BV_CIN - , BV_CINK - , BV_CINO - , BV_CINW - , BV_CM - , BV_CMS - , BV_COM - , BV_CPT - , BV_DICT - , BV_TSR - , BV_CSL - , BV_CFU - , BV_DEF - , BV_INC - , BV_EOL - , BV_FIXEOL - , BV_EP - , BV_ET - , BV_FENC - , BV_FP - , BV_BEXPR - , BV_FEX - , BV_FF - , BV_FLP - , BV_FO - , BV_FT - , BV_IMI - , BV_IMS - , BV_INDE - , BV_INDK - , BV_INEX - , BV_INF - , BV_ISK - , BV_KMAP - , BV_KP - , BV_LISP - , BV_LW - , BV_MENC - , BV_MA - , BV_ML - , BV_MOD - , BV_MPS - , BV_NF - , BV_OFU - , BV_PATH - , BV_PI - , BV_QE - , BV_RO - , BV_SCBK - , BV_SI - , BV_SMC - , BV_SYN - , BV_SPC - , BV_SPF - , BV_SPL - , BV_SPO - , BV_STS - , BV_SUA - , BV_SW - , BV_SWF - , BV_TFU - , BV_TAGS - , BV_TC - , BV_TS - , BV_TW - , BV_TX - , BV_UDF - , BV_UL - , BV_WM - , BV_VSTS - , BV_VTS - , BV_COUNT // must be the last one + BV_AI = 0, + BV_AR, + BV_BH, + BV_BKC, + BV_BT, + BV_EFM, + BV_GP, + BV_MP, + BV_BIN, + BV_BL, + BV_BOMB, + BV_CHANNEL, + BV_CI, + BV_CIN, + BV_CINK, + BV_CINO, + BV_CINW, + BV_CM, + BV_CMS, + BV_COM, + BV_CPT, + BV_DICT, + BV_TSR, + BV_CSL, + BV_CFU, + BV_DEF, + BV_INC, + BV_EOL, + BV_FIXEOL, + BV_EP, + BV_ET, + BV_FENC, + BV_FP, + BV_BEXPR, + BV_FEX, + BV_FF, + BV_FLP, + BV_FO, + BV_FT, + BV_IMI, + BV_IMS, + BV_INDE, + BV_INDK, + BV_INEX, + BV_INF, + BV_ISK, + BV_KMAP, + BV_KP, + BV_LISP, + BV_LW, + BV_MENC, + BV_MA, + BV_ML, + BV_MOD, + BV_MPS, + BV_NF, + BV_OFU, + BV_PATH, + BV_PI, + BV_QE, + BV_RO, + BV_SCBK, + BV_SI, + BV_SMC, + BV_SYN, + BV_SPC, + BV_SPF, + BV_SPL, + BV_SPO, + BV_STS, + BV_SUA, + BV_SW, + BV_SWF, + BV_TFU, + BV_TAGS, + BV_TC, + BV_TS, + BV_TW, + BV_TX, + BV_UDF, + BV_UL, + BV_WM, + BV_VSTS, + BV_VTS, + BV_COUNT // must be the last one }; /* @@ -843,51 +845,51 @@ enum { * window structure. */ enum { - WV_LIST = 0 - , WV_ARAB - , WV_COCU - , WV_COLE - , WV_CRBIND - , WV_BRI - , WV_BRIOPT - , WV_DIFF - , WV_FDC - , WV_FEN - , WV_FDI - , WV_FDL - , WV_FDM - , WV_FML - , WV_FDN - , WV_FDE - , WV_FDT - , WV_FMR - , WV_LBR - , WV_NU - , WV_RNU - , WV_NUW - , WV_PVW - , WV_RL - , WV_RLC - , WV_SCBIND - , WV_SCROLL - , WV_SISO - , WV_SO - , WV_SPELL - , WV_CUC - , WV_CUL - , WV_CULOPT - , WV_CC - , WV_SBR - , WV_STL - , WV_WFH - , WV_WFW - , WV_WRAP - , WV_SCL - , WV_WINHL - , WV_FCS - , WV_LCS - , WV_WINBL - , WV_COUNT // must be the last one + WV_LIST = 0, + WV_ARAB, + WV_COCU, + WV_COLE, + WV_CRBIND, + WV_BRI, + WV_BRIOPT, + WV_DIFF, + WV_FDC, + WV_FEN, + WV_FDI, + WV_FDL, + WV_FDM, + WV_FML, + WV_FDN, + WV_FDE, + WV_FDT, + WV_FMR, + WV_LBR, + WV_NU, + WV_RNU, + WV_NUW, + WV_PVW, + WV_RL, + WV_RLC, + WV_SCBIND, + WV_SCROLL, + WV_SISO, + WV_SO, + WV_SPELL, + WV_CUC, + WV_CUL, + WV_CULOPT, + WV_CC, + WV_SBR, + WV_STL, + WV_WFH, + WV_WFW, + WV_WRAP, + WV_SCL, + WV_WINHL, + WV_FCS, + WV_LCS, + WV_WINBL, + WV_COUNT // must be the last one }; // Value for b_p_ul indicating the global value must be used. diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 0fc3f35ffc..0f363ecfc3 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -22,15 +22,15 @@ #include "nvim/vim.h" #ifdef WIN32 -#include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 +# include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 #endif #ifdef HAVE__NSGETENVIRON -#include <crt_externs.h> +# include <crt_externs.h> #endif #ifdef HAVE_SYS_UTSNAME_H -#include <sys/utsname.h> +# include <sys/utsname.h> #endif // Because `uv_os_getenv` requires allocating, we must manage a map to maintain @@ -1146,7 +1146,7 @@ size_t home_replace(const buf_T *const buf, const char_u *src, char_u *const dst /// Like home_replace, store the replaced string in allocated memory. /// @param buf When not NULL, check for help files /// @param src Input file name -char_u * home_replace_save(buf_T *buf, char_u *src) FUNC_ATTR_NONNULL_RET +char_u *home_replace_save(buf_T *buf, char_u *src) FUNC_ATTR_NONNULL_RET { size_t len = 3; // space for "~/" and trailing NUL if (src != NULL) { // just in case @@ -1161,7 +1161,7 @@ char_u * home_replace_save(buf_T *buf, char_u *src) FUNC_ATTR_NONNULL_RET /// Function given to ExpandGeneric() to obtain an environment variable name. char_u *get_env_name(expand_T *xp, int idx) { -# define ENVNAMELEN 100 +#define ENVNAMELEN 100 // this static buffer is needed to avoid a memory leak in ExpandGeneric static char_u name[ENVNAMELEN]; assert(idx >= 0); diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index d50d68c99e..9675cfbb0f 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -29,7 +29,7 @@ #include "nvim/strings.h" #ifdef WIN32 -#include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 +# include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 #endif #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -134,7 +134,7 @@ bool os_isdir(const char_u *name) bool os_isdir_executable(const char *name) FUNC_ATTR_NONNULL_ALL { - int32_t mode = os_getperm((const char *)name); + int32_t mode = os_getperm(name); if (mode < 0) { return false; } @@ -1226,12 +1226,12 @@ char *os_resolve_shortcut(const char *fname) goto shortcut_errorw; } -# if 0 // This makes Vim wait a long time if the target does not exist. +# if 0 // This makes Vim wait a long time if the target does not exist. hr = pslw->lpVtbl->Resolve(pslw, NULL, SLR_NO_UI); if (hr != S_OK) { goto shortcut_errorw; } -# endif +# endif // Get the path to the link target. ZeroMemory(wsz, MAX_PATH * sizeof(wchar_t)); @@ -1262,7 +1262,7 @@ shortcut_end: return rfname; } -#define is_path_sep(c) ((c) == L'\\' || (c) == L'/') +# define is_path_sep(c) ((c) == L'\\' || (c) == L'/') /// Returns true if the path contains a reparse point (junction or symbolic /// link). Otherwise false in returned. bool os_is_reparse_point_include(const char *path) diff --git a/src/nvim/os/input.h b/src/nvim/os/input.h index d571965408..7026781407 100644 --- a/src/nvim/os/input.h +++ b/src/nvim/os/input.h @@ -1,8 +1,8 @@ #ifndef NVIM_OS_INPUT_H #define NVIM_OS_INPUT_H -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include "nvim/api/private/defs.h" #include "nvim/event/multiqueue.h" diff --git a/src/nvim/os/os.h b/src/nvim/os/os.h index 3e89e5a94a..bff2936f8e 100644 --- a/src/nvim/os/os.h +++ b/src/nvim/os/os.h @@ -9,11 +9,11 @@ #include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS +# include "os/env.h.generated.h" # include "os/fs.h.generated.h" # include "os/mem.h.generated.h" -# include "os/env.h.generated.h" -# include "os/users.h.generated.h" # include "os/stdpaths.h.generated.h" +# include "os/users.h.generated.h" #endif #endif // NVIM_OS_OS_H diff --git a/src/nvim/os/os_defs.h b/src/nvim/os/os_defs.h index 1b7859b0d3..8049b3b80e 100644 --- a/src/nvim/os/os_defs.h +++ b/src/nvim/os/os_defs.h @@ -16,7 +16,7 @@ #define BASENAMELEN (NAME_MAX - 5) // Use the system path length if it makes sense. -# define DEFAULT_MAXPATHL 4096 +#define DEFAULT_MAXPATHL 4096 #if defined(PATH_MAX) && (PATH_MAX > DEFAULT_MAXPATHL) # define MAXPATHL PATH_MAX #else diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c index 2c9cb699fc..18e2e02b81 100644 --- a/src/nvim/os/os_win_console.c +++ b/src/nvim/os/os_win_console.c @@ -46,29 +46,3 @@ void os_replace_stdout_and_stderr_to_conout(void) const int conerr_fd = _open_osfhandle((intptr_t)conout_handle, 0); assert(conerr_fd == STDERR_FILENO); } - -void os_set_vtp(bool enable) -{ - static TriState is_legacy = kNone; - if (is_legacy == kNone) { - uv_tty_vtermstate_t state; - uv_tty_get_vterm_state(&state); - is_legacy = (state == UV_TTY_UNSUPPORTED) ? kTrue : kFalse; - } - if (!is_legacy && !os_has_vti()) { - uv_tty_set_vterm_state(enable ? UV_TTY_SUPPORTED : UV_TTY_UNSUPPORTED); - } -} - -static bool os_has_vti(void) -{ - static TriState has_vti = kNone; - if (has_vti == kNone) { - HANDLE handle = (HANDLE)_get_osfhandle(input_global_fd()); - DWORD dwMode; - if (handle != INVALID_HANDLE_VALUE && GetConsoleMode(handle, &dwMode)) { - has_vti = !!(dwMode & ENABLE_VIRTUAL_TERMINAL_INPUT) ? kTrue : kFalse; - } - } - return has_vti == kTrue; -} diff --git a/src/nvim/os/process.h b/src/nvim/os/process.h index 1722d56bd3..faa4762cf1 100644 --- a/src/nvim/os/process.h +++ b/src/nvim/os/process.h @@ -2,6 +2,7 @@ #define NVIM_OS_PROCESS_H #include <stddef.h> + #include "nvim/api/private/defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c index d94de2e397..24ecf5c24f 100644 --- a/src/nvim/os/pty_process_unix.c +++ b/src/nvim/os/pty_process_unix.c @@ -157,7 +157,7 @@ static void init_child(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL { #if defined(HAVE__NSGETENVIRON) -#define environ (*_NSGetEnviron()) +# define environ (*_NSGetEnviron()) #else extern char **environ; #endif diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index f0d446b4c5..2bff65b241 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -873,10 +873,10 @@ static void system_data_cb(Stream *stream, RBuffer *buf, size_t count, void *dat /// Returns the previous decision if size=0. static bool out_data_decide_throttle(size_t size) { - static uint64_t started = 0; // Start time of the current throttle. - static size_t received = 0; // Bytes observed since last throttle. - static size_t visit = 0; // "Pulse" count of the current throttle. - static char pulse_msg[] = { ' ', ' ', ' ', '\0' }; + static uint64_t started = 0; // Start time of the current throttle. + static size_t received = 0; // Bytes observed since last throttle. + static size_t visit = 0; // "Pulse" count of the current throttle. + static char pulse_msg[] = { ' ', ' ', ' ', '\0' }; if (!size) { bool previous_decision = (visit > 0); @@ -933,8 +933,8 @@ static bool out_data_decide_throttle(size_t size) static void out_data_ring(char *output, size_t size) { #define MAX_CHUNK_SIZE (OUT_DATA_THRESHOLD / 2) - static char last_skipped[MAX_CHUNK_SIZE]; // Saved output. - static size_t last_skipped_len = 0; + static char last_skipped[MAX_CHUNK_SIZE]; // Saved output. + static size_t last_skipped_len = 0; assert(output != NULL || (size == 0 || size == SIZE_MAX)); diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c index 65b1845d01..0d125ec964 100644 --- a/src/nvim/os/signal.c +++ b/src/nvim/os/signal.c @@ -119,7 +119,7 @@ void signal_accept_deadly(void) rejecting_deadly = false; } -static char * signal_name(int signum) +static char *signal_name(int signum) { switch (signum) { #ifdef SIGPWR diff --git a/src/nvim/os/time.h b/src/nvim/os/time.h index ad4886446a..1b6c667dbb 100644 --- a/src/nvim/os/time.h +++ b/src/nvim/os/time.h @@ -1,8 +1,8 @@ #ifndef NVIM_OS_TIME_H #define NVIM_OS_TIME_H -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include <time.h> typedef uint64_t Timestamp; diff --git a/src/nvim/os/tty.c b/src/nvim/os/tty.c index c80ef99084..126b1b0044 100644 --- a/src/nvim/os/tty.c +++ b/src/nvim/os/tty.c @@ -23,15 +23,6 @@ /// @param out_fd stdout file descriptor void os_tty_guess_term(const char **term, int out_fd) { - bool winpty = (os_getenv("NVIM") != NULL); - - if (winpty) { - // Force TERM=win32con when running in winpty. - *term = "win32con"; - uv_tty_set_vterm_state(UV_TTY_UNSUPPORTED); - return; - } - bool conemu_ansi = strequal(os_getenv("ConEmuANSI"), "ON"); bool vtp = false; diff --git a/src/nvim/os/unix_defs.h b/src/nvim/os/unix_defs.h index 60a2dfa882..4ed3b51694 100644 --- a/src/nvim/os/unix_defs.h +++ b/src/nvim/os/unix_defs.h @@ -1,8 +1,8 @@ #ifndef NVIM_OS_UNIX_DEFS_H #define NVIM_OS_UNIX_DEFS_H -#include <unistd.h> #include <sys/param.h> +#include <unistd.h> // POSIX.1-2008 says that NAME_MAX should be in here #include <limits.h> diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c index 2687c66f24..fd7ead68da 100644 --- a/src/nvim/os/users.c +++ b/src/nvim/os/users.c @@ -43,7 +43,7 @@ int os_get_usernames(garray_T *users) } ga_init(users, sizeof(char *), 20); -# if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H) +#if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H) { struct passwd *pw; @@ -53,7 +53,7 @@ int os_get_usernames(garray_T *users) } endpwent(); } -# elif defined(WIN32) +#elif defined(WIN32) { DWORD nusers = 0, ntotal = 0, i; PUSER_INFO_0 uinfo; @@ -73,8 +73,8 @@ int os_get_usernames(garray_T *users) NetApiBufferFree(uinfo); } } -# endif -# if defined(HAVE_GETPWNAM) +#endif +#if defined(HAVE_GETPWNAM) { const char *user_env = os_getenv("USER"); @@ -104,7 +104,7 @@ int os_get_usernames(garray_T *users) } } } -# endif +#endif return OK; } diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h index 66d72de08d..efef77be7b 100644 --- a/src/nvim/os/win_defs.h +++ b/src/nvim/os/win_defs.h @@ -7,11 +7,14 @@ // winsock2.h must be first to avoid incompatibilities // with winsock.h (included by windows.h) + +// uncrustify:off #include <winsock2.h> -#include <windows.h> -#include <sys/stat.h> +// uncrustify:on #include <io.h> #include <stdio.h> +#include <sys/stat.h> +#include <windows.h> // Windows does not have S_IFLNK but libuv defines it // and sets the flag for us when calling uv_fs_stat. diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 44274e8f1d..9396a5896a 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -7,14 +7,13 @@ #include <stdbool.h> #include <string.h> -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/os_unix.h" #include "nvim/buffer.h" #include "nvim/charset.h" #include "nvim/eval.h" #include "nvim/ex_cmds.h" #include "nvim/fileio.h" +#include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/main.h" #include "nvim/mbyte.h" @@ -23,19 +22,20 @@ #include "nvim/message.h" #include "nvim/misc1.h" #include "nvim/mouse.h" -#include "nvim/garray.h" +#include "nvim/msgpack_rpc/helpers.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" +#include "nvim/os/shell.h" +#include "nvim/os/signal.h" +#include "nvim/os/time.h" +#include "nvim/os_unix.h" #include "nvim/path.h" #include "nvim/screen.h" #include "nvim/strings.h" #include "nvim/syntax.h" -#include "nvim/ui.h" #include "nvim/types.h" -#include "nvim/os/os.h" -#include "nvim/os/time.h" -#include "nvim/os/input.h" -#include "nvim/os/shell.h" -#include "nvim/os/signal.h" -#include "nvim/msgpack_rpc/helpers.h" +#include "nvim/ui.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os_unix.c.generated.h" @@ -61,13 +61,15 @@ vim_acl_T mch_get_acl(const char_u *fname) // Set the ACL of file "fname" to "acl" (unless it's NULL). void mch_set_acl(const char_u *fname, vim_acl_T aclent) { - if (aclent == NULL) + if (aclent == NULL) { return; + } } void mch_free_acl(vim_acl_T aclent) { - if (aclent == NULL) + if (aclent == NULL) { return; + } } #endif diff --git a/src/nvim/os_unix.h b/src/nvim/os_unix.h index d627b16ec0..aae05f7fcc 100644 --- a/src/nvim/os_unix.h +++ b/src/nvim/os_unix.h @@ -1,8 +1,8 @@ #ifndef NVIM_OS_UNIX_H #define NVIM_OS_UNIX_H -#include "nvim/types.h" // for vim_acl_T #include "nvim/os/shell.h" +#include "nvim/types.h" // for vim_acl_T #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os_unix.h.generated.h" diff --git a/src/nvim/path.c b/src/nvim/path.c index 5d14eba0a5..5b1793b111 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -6,15 +6,13 @@ #include <stdbool.h> #include <stdlib.h> -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/path.h" #include "nvim/charset.h" #include "nvim/eval.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" -#include "nvim/fileio.h" #include "nvim/file_search.h" +#include "nvim/fileio.h" #include "nvim/garray.h" #include "nvim/memfile.h" #include "nvim/memline.h" @@ -22,20 +20,22 @@ #include "nvim/message.h" #include "nvim/misc1.h" #include "nvim/option.h" +#include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/os/shell.h" #include "nvim/os_unix.h" +#include "nvim/path.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" #include "nvim/screen.h" #include "nvim/strings.h" #include "nvim/tag.h" #include "nvim/types.h" -#include "nvim/os/input.h" +#include "nvim/vim.h" #include "nvim/window.h" -#define URL_SLASH 1 /* path_is_url() has found "://" */ -#define URL_BACKSLASH 2 /* path_is_url() has found ":\\" */ +#define URL_SLASH 1 // path_is_url() has found "://" +#define URL_BACKSLASH 2 // path_is_url() has found ":\\" #ifdef gen_expand_wildcards # undef gen_expand_wildcards @@ -53,8 +53,8 @@ /// @param checkname When both files don't exist, only compare their names. /// @param expandenv Whether to expand environment variables in file names. /// @return Enum of type FileComparison. @see FileComparison. -FileComparison path_full_compare(char_u *const s1, char_u *const s2, - const bool checkname, const bool expandenv) +FileComparison path_full_compare(char_u *const s1, char_u *const s2, const bool checkname, + const bool expandenv) { assert(s1 && s2); char_u exp1[MAXPATHL]; @@ -63,9 +63,9 @@ FileComparison path_full_compare(char_u *const s1, char_u *const s2, FileID file_id_1, file_id_2; if (expandenv) { - expand_env(s1, exp1, MAXPATHL); + expand_env(s1, exp1, MAXPATHL); } else { - xstrlcpy((char *)exp1, (const char *)s1, MAXPATHL); + xstrlcpy((char *)exp1, (const char *)s1, MAXPATHL); } bool id_ok_1 = os_fileid((char *)exp1, &file_id_1); bool id_ok_2 = os_fileid((char *)s2, &file_id_2); @@ -146,7 +146,7 @@ char_u *path_tail_with_sep(char_u *fname) const char_u *invocation_path_tail(const char_u *invocation, size_t *len) FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1) { - const char_u *tail = get_past_head((char_u *) invocation); + const char_u *tail = get_past_head((char_u *)invocation); const char_u *p = tail; while (*p != NUL && *p != ' ') { bool was_sep = vim_ispathsep_nocolon(*p); @@ -266,7 +266,7 @@ int vim_ispathlistsep(int c) #ifdef UNIX return c == ':'; #else - return c == ';'; /* might not be right for every system... */ + return c == ';'; // might not be right for every system... #endif } @@ -280,11 +280,12 @@ char_u *shorten_dir(char_u *str) char_u *d = str; bool skip = false; for (char_u *s = str;; ++s) { - if (s >= tail) { /* copy the whole tail */ + if (s >= tail) { // copy the whole tail *d++ = *s; - if (*s == NUL) + if (*s == NUL) { break; - } else if (vim_ispathsep(*s)) { /* copy '/' and next char */ + } + } else if (vim_ispathsep(*s)) { // copy '/' and next char *d++ = *s; skip = false; } else if (!skip) { @@ -348,8 +349,7 @@ int path_fnamecmp(const char *fname1, const char *fname2) /// @param[in] len Compare at most len bytes. /// /// @return 0 if they are equal, non-zero otherwise. -int path_fnamencmp(const char *const fname1, const char *const fname2, - size_t len) +int path_fnamencmp(const char *const fname1, const char *const fname2, size_t len) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { #ifdef BACKSLASH_IN_FILENAME @@ -389,9 +389,8 @@ int path_fnamencmp(const char *const fname1, const char *const fname2, /// add a path separator before fname2. /// /// @return fname1 -static inline char *do_concat_fnames(char *fname1, const size_t len1, - const char *fname2, const size_t len2, - const bool sep) +static inline char *do_concat_fnames(char *fname1, const size_t len1, const char *fname2, + const size_t len2, const bool sep) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET { if (sep && *fname1 && !after_pathsep(fname1, fname1 + len1)) { @@ -548,7 +547,7 @@ bool path_has_exp_wildcard(const char_u *p) #else const char *wildcards = "*?["; // Windows. #endif - if (vim_strchr((char_u *) wildcards, *p) != NULL) { + if (vim_strchr((char_u *)wildcards, *p) != NULL) { return true; } } @@ -590,8 +589,8 @@ static const char *scandir_next_with_dots(Directory *dir) /// Implementation of path_expand(). /// /// Chars before `path + wildoff` do not get expanded. -static size_t do_path_expand(garray_T *gap, const char_u *path, - size_t wildoff, int flags, bool didstar) +static size_t do_path_expand(garray_T *gap, const char_u *path, size_t wildoff, int flags, + bool didstar) FUNC_ATTR_NONNULL_ALL { int start_len = gap->ga_len; @@ -599,11 +598,12 @@ static size_t do_path_expand(garray_T *gap, const char_u *path, bool starstar = false; static int stardepth = 0; // depth for "**" expansion - /* Expanding "**" may take a long time, check for CTRL-C. */ + // Expanding "**" may take a long time, check for CTRL-C. if (stardepth > 0) { os_breakcheck(); - if (got_int) + if (got_int) { return 0; + } } // Make room for file name. When doing encoding conversion the actual @@ -633,7 +633,7 @@ static size_t do_path_expand(garray_T *gap, const char_u *path, || (!p_fic && (flags & EW_ICASE) && isalpha(PTR2CHAR(path_end))) #endif - )) { + )) { e = p; } len = (size_t)(utfc_ptr2len(path_end)); @@ -644,20 +644,23 @@ static size_t do_path_expand(garray_T *gap, const char_u *path, e = p; *e = NUL; - /* Now we have one wildcard component between "s" and "e". */ + // Now we have one wildcard component between "s" and "e". /* Remove backslashes between "wildoff" and the start of the wildcard * component. */ - for (p = buf + wildoff; p < s; ++p) + for (p = buf + wildoff; p < s; ++p) { if (rem_backslash(p)) { STRMOVE(p, p + 1); --e; --s; } + } - /* Check for "**" between "s" and "e". */ - for (p = s; p < e; ++p) - if (p[0] == '*' && p[1] == '*') + // Check for "**" between "s" and "e". + for (p = s; p < e; ++p) { + if (p[0] == '*' && p[1] == '*') { starstar = true; + } + } // convert the file pattern to a regexp pattern int starts_with_dot = *s == '.'; @@ -675,11 +678,13 @@ static size_t do_path_expand(garray_T *gap, const char_u *path, #else regmatch.rm_ic = true; // Always ignore case on Windows. #endif - if (flags & (EW_NOERROR | EW_NOTWILD)) + if (flags & (EW_NOERROR | EW_NOTWILD)) { ++emsg_silent; + } regmatch.regprog = vim_regcomp(pat, RE_MAGIC); - if (flags & (EW_NOERROR | EW_NOTWILD)) + if (flags & (EW_NOERROR | EW_NOTWILD)) { --emsg_silent; + } xfree(pat); if (regmatch.regprog == NULL && (flags & EW_NOTWILD) == 0) { @@ -727,9 +732,9 @@ static size_t do_path_expand(garray_T *gap, const char_u *path, } STRCPY(buf + len, path_end); - if (path_has_exp_wildcard(path_end)) { /* handle more wildcards */ - /* need to expand another component of the path */ - /* remove backslashes for the remaining components only */ + if (path_has_exp_wildcard(path_end)) { // handle more wildcards + // need to expand another component of the path + // remove backslashes for the remaining components only (void)do_path_expand(gap, buf, len + 1, flags, false); } else { FileInfo file_info; @@ -741,7 +746,7 @@ static size_t do_path_expand(garray_T *gap, const char_u *path, } // add existing file or symbolic link if ((flags & EW_ALLLINKS) ? os_fileinfo_link((char *)buf, &file_info) - : os_path_exists(buf)) { + : os_path_exists(buf)) { addfile(gap, buf, flags); } } @@ -767,14 +772,16 @@ static size_t do_path_expand(garray_T *gap, const char_u *path, */ static int find_previous_pathsep(char_u *path, char_u **psep) { - /* skip the current separator */ - if (*psep > path && vim_ispathsep(**psep)) + // skip the current separator + if (*psep > path && vim_ispathsep(**psep)) { --*psep; + } - /* find the previous separator */ + // find the previous separator while (*psep > path) { - if (vim_ispathsep(**psep)) + if (vim_ispathsep(**psep)) { return OK; + } MB_PTR_BACK(path, *psep); } @@ -828,8 +835,9 @@ static void expand_path_option(char_u *curdir, garray_T *gap) /* Relative to current buffer: * "/path/file" + "." -> "/path/" * "/path/file" + "./subdir" -> "/path/subdir" */ - if (curbuf->b_ffname == NULL) + if (curbuf->b_ffname == NULL) { continue; + } char_u *p = path_tail(curbuf->b_ffname); size_t len = (size_t)(p - curbuf->b_ffname); if (len + STRLEN(buf) >= MAXPATHL) { @@ -870,13 +878,13 @@ static void expand_path_option(char_u *curdir, garray_T *gap) * * path: /foo/bar/baz * fname: /foo/bar/baz/quux.txt - * returns: ^this + * returns: ^this */ static char_u *get_path_cutoff(char_u *fname, garray_T *gap) { int maxlen = 0; - char_u **path_part = (char_u **)gap->ga_data; - char_u *cutoff = NULL; + char_u **path_part = (char_u **)gap->ga_data; + char_u *cutoff = NULL; for (int i = 0; i < gap->ga_len; i++) { int j = 0; @@ -932,14 +940,16 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern) STRCAT(file_pattern, pattern); char_u *pat = file_pat_to_reg_pat(file_pattern, NULL, NULL, true); xfree(file_pattern); - if (pat == NULL) + if (pat == NULL) { return; + } - regmatch.rm_ic = TRUE; /* always ignore case */ + regmatch.rm_ic = TRUE; // always ignore case regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); xfree(pat); - if (regmatch.regprog == NULL) + if (regmatch.regprog == NULL) { return; + } char_u *curdir = xmalloc(MAXPATHL); os_dirname(curdir, MAXPATHL); @@ -951,16 +961,17 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern) char_u *path = fnames[i]; int is_in_curdir; char_u *dir_end = (char_u *)gettail_dir((const char *)path); - char_u *pathsep_p; - char_u *path_cutoff; + char_u *pathsep_p; + char_u *path_cutoff; len = STRLEN(path); is_in_curdir = fnamencmp(curdir, path, dir_end - path) == 0 && curdir[dir_end - path] == NUL; - if (is_in_curdir) + if (is_in_curdir) { in_curdir[i] = vim_strsave(path); + } - /* Shorten the filename while maintaining its uniqueness */ + // Shorten the filename while maintaining its uniqueness path_cutoff = get_path_cutoff(path, &path_ga); // Don't assume all files can be reached without path when search @@ -1010,19 +1021,21 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern) os_breakcheck(); } - /* Shorten filenames in /in/current/directory/{filename} */ + // Shorten filenames in /in/current/directory/{filename} for (int i = 0; i < gap->ga_len && !got_int; i++) { char_u *rel_path; char_u *path = in_curdir[i]; - if (path == NULL) + if (path == NULL) { continue; + } /* If the {filename} is not unique, change it to ./{filename}. * Else reduce it to {filename} */ short_name = path_shorten_fname(path, curdir); - if (short_name == NULL) + if (short_name == NULL) { short_name = path; + } if (is_unique(short_name, gap, i)) { STRCPY(fnames[i], short_name); continue; @@ -1040,14 +1053,16 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern) } xfree(curdir); - for (int i = 0; i < gap->ga_len; i++) + for (int i = 0; i < gap->ga_len; i++) { xfree(in_curdir[i]); + } xfree(in_curdir); ga_clear_strings(&path_ga); vim_regfree(regmatch.regprog); - if (sort_again) + if (sort_again) { ga_remove_duplicate_strings(gap); + } } /// Find end of the directory name @@ -1072,8 +1087,9 @@ const char *gettail_dir(const char *const fname) look_for_sep = false; } } else { - if (!look_for_sep) + if (!look_for_sep) { dir_end = next_dir_end; + } look_for_sep = true; } MB_PTR_ADV(p); @@ -1082,16 +1098,12 @@ const char *gettail_dir(const char *const fname) } -/* - * Calls globpath() with 'path' values for the given pattern and stores the - * result in "gap". - * Returns the total number of matches. - */ -static int expand_in_path( - garray_T *const gap, - char_u *const pattern, - const int flags // EW_* flags -) +/// Calls globpath() with 'path' values for the given pattern and stores the +/// result in "gap". +/// Returns the total number of matches. +/// +/// @param flags EW_* flags +static int expand_in_path(garray_T *const gap, char_u *const pattern, const int flags) { garray_T path_ga; @@ -1131,7 +1143,7 @@ static bool has_env_var(char_u *p) for (; *p; MB_PTR_ADV(p)) { if (*p == '\\' && p[1] != NUL) { p++; - } else if (vim_strchr((char_u *) "$" , *p) != NULL) { + } else if (vim_strchr((char_u *)"$", *p) != NULL) { return true; } } @@ -1186,8 +1198,7 @@ static bool has_special_wildchar(char_u *p) /// If FAIL is returned, *num_file and *file are either /// unchanged or *num_file is set to 0 and *file is set /// to NULL or points to "". -int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file, - char_u ***file, int flags) +int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u ***file, int flags) { garray_T ga; char_u *p; @@ -1203,9 +1214,9 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file, */ if (recursive) #ifdef SPECIAL_WILDCHAR - return os_expand_wildcards(num_pat, pat, num_file, file, flags); + { return os_expand_wildcards(num_pat, pat, num_file, file, flags); } #else - return FAIL; + { return FAIL; } #endif #ifdef SPECIAL_WILDCHAR @@ -1247,8 +1258,9 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file, // First expand environment variables, "~/" and "~user/". if ((has_env_var(p) && !(flags & EW_NOTENV)) || *p == '~') { p = expand_env_save_opt(p, true); - if (p == NULL) + if (p == NULL) { p = pat[i]; + } #ifdef UNIX /* * On Unix, if expand_env() can't expand an environment @@ -1278,8 +1290,8 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file, && !path_is_absolute(p) && !(p[0] == '.' && (vim_ispathsep(p[1]) - || (p[1] == '.' && vim_ispathsep(p[2])))) - ) { + || (p[1] == '.' && + vim_ispathsep(p[2]))))) { /* :find completion where 'path' is used. * Recursiveness is OK here. */ recursive = false; @@ -1295,7 +1307,7 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file, } if (add_pat == -1 || (add_pat == 0 && (flags & EW_NOTFOUND))) { - char_u *t = backslash_halve_save(p); + char_u *t = backslash_halve_save(p); /* When EW_NOTFOUND is used, always add files and dirs. Makes * "vim c:/" work. */ @@ -1310,10 +1322,12 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file, } } - if (did_expand_in_path && !GA_EMPTY(&ga) && (flags & EW_PATH)) + if (did_expand_in_path && !GA_EMPTY(&ga) && (flags & EW_PATH)) { uniquefy_paths(&ga, p); - if (p != pat[i]) + } + if (p != pat[i]) { xfree(p); + } } *num_file = ga.ga_len; @@ -1333,14 +1347,12 @@ static int vim_backtick(char_u *p) return *p == '`' && *(p + 1) != NUL && *(p + STRLEN(p) - 1) == '`'; } -// Expand an item in `backticks` by executing it as a command. -// Currently only works when pat[] starts and ends with a `. -// Returns number of file names found, -1 if an error is encountered. -static int expand_backtick( - garray_T *gap, - char_u *pat, - int flags /* EW_* flags */ -) +/// Expand an item in `backticks` by executing it as a command. +/// Currently only works when pat[] starts and ends with a `. +/// Returns number of file names found, -1 if an error is encountered. +/// +/// @param flags EW_* flags +static int expand_backtick(garray_T *gap, char_u *pat, int flags) { char_u *p; char_u *buffer; @@ -1361,11 +1373,12 @@ static int expand_backtick( cmd = buffer; while (*cmd != NUL) { - cmd = skipwhite(cmd); /* skip over white space */ + cmd = skipwhite(cmd); // skip over white space p = cmd; - while (*p != NUL && *p != '\r' && *p != '\n') /* skip over entry */ + while (*p != NUL && *p != '\r' && *p != '\n') { // skip over entry ++p; - /* add an entry if it is not empty */ + } + // add an entry if it is not empty if (p > cmd) { char_u i = *p; *p = NUL; @@ -1374,8 +1387,9 @@ static int expand_backtick( ++cnt; } cmd = p; - while (*cmd != NUL && (*cmd == '\r' || *cmd == '\n')) + while (*cmd != NUL && (*cmd == '\r' || *cmd == '\n')) { ++cmd; + } } xfree(buffer); @@ -1414,18 +1428,16 @@ void slash_adjust(char_u *p) } #endif -// Add a file to a file list. Accepted flags: -// EW_DIR add directories -// EW_FILE add files -// EW_EXEC add executable files -// EW_NOTFOUND add even when it doesn't exist -// EW_ADDSLASH add slash after directory name -// EW_ALLLINKS add symlink also when the referred file does not exist -void addfile( - garray_T *gap, - char_u *f, /* filename */ - int flags -) +/// Add a file to a file list. Accepted flags: +/// EW_DIR add directories +/// EW_FILE add files +/// EW_EXEC add executable files +/// EW_NOTFOUND add even when it doesn't exist +/// EW_ADDSLASH add slash after directory name +/// EW_ALLLINKS add symlink also when the referred file does not exist +/// +/// @param f filename +void addfile(garray_T *gap, char_u *f, int flags) { bool isdir; FileInfo file_info; @@ -1439,14 +1451,16 @@ void addfile( } #ifdef FNAME_ILLEGAL - /* if the file/dir contains illegal characters, don't add it */ - if (vim_strpbrk(f, (char_u *)FNAME_ILLEGAL) != NULL) + // if the file/dir contains illegal characters, don't add it + if (vim_strpbrk(f, (char_u *)FNAME_ILLEGAL) != NULL) { return; + } #endif isdir = os_isdir(f); - if ((isdir && !(flags & EW_DIR)) || (!isdir && !(flags & EW_FILE))) + if ((isdir && !(flags & EW_DIR)) || (!isdir && !(flags & EW_FILE))) { return; + } // If the file isn't executable, may not add it. Do accept directories. // When invoked from expand_shellcmd() do not use $PATH. @@ -1464,8 +1478,9 @@ void addfile( /* * Append a slash or backslash after directory names if none is present. */ - if (isdir && (flags & EW_ADDSLASH)) + if (isdir && (flags & EW_ADDSLASH)) { add_pathsep((char *)p); + } GA_APPEND(char_u *, gap, p); } @@ -1478,14 +1493,15 @@ void addfile( void simplify_filename(char_u *filename) { int components = 0; - char_u *p, *tail, *start; + char_u *p, *tail, *start; bool stripping_disabled = false; bool relative = true; p = filename; #ifdef BACKSLASH_IN_FILENAME - if (p[1] == ':') /* skip "x:" */ + if (p[1] == ':') { // skip "x:" p += 2; + } #endif if (vim_ispathsep(*p)) { @@ -1494,17 +1510,18 @@ void simplify_filename(char_u *filename) ++p; while (vim_ispathsep(*p)); } - start = p; /* remember start after "c:/" or "/" or "///" */ + start = p; // remember start after "c:/" or "/" or "///" do { /* At this point "p" is pointing to the char following a single "/" * or "p" is at the "start" of the (absolute or relative) path name. */ - if (vim_ispathsep(*p)) - STRMOVE(p, p + 1); /* remove duplicate "/" */ - else if (p[0] == '.' && (vim_ispathsep(p[1]) || p[1] == NUL)) { - if (p == start && relative) - p += 1 + (p[1] != NUL); /* keep single "." or leading "./" */ - else { + if (vim_ispathsep(*p)) { + STRMOVE(p, p + 1); // remove duplicate "/" + } else if (p[0] == '.' && + (vim_ispathsep(p[1]) || p[1] == NUL)) { + if (p == start && relative) { + p += 1 + (p[1] != NUL); // keep single "." or leading "./" + } else { /* Strip "./" or ".///". If we are at the end of the file name * and there is no trailing path separator, either strip "/." if * we are after "start", or strip "." if we are at the beginning @@ -1527,11 +1544,11 @@ void simplify_filename(char_u *filename) MB_PTR_ADV(tail); } - if (components > 0) { /* strip one preceding component */ + if (components > 0) { // strip one preceding component bool do_strip = false; char_u saved_char; - /* Don't strip for an erroneous file name. */ + // Don't strip for an erroneous file name. if (!stripping_disabled) { /* If the preceding component does not exist in the file * system, we strip it. On Unix, we don't accept a symbolic @@ -1613,21 +1630,22 @@ void simplify_filename(char_u *filename) *p++ = '.'; *p = NUL; } else { - if (p > start && tail[-1] == '.') + if (p > start && tail[-1] == '.') { --p; - STRMOVE(p, tail); /* strip previous component */ + } + STRMOVE(p, tail); // strip previous component } --components; } - } else if (p == start && !relative) /* leading "/.." or "/../" */ - STRMOVE(p, tail); /* strip ".." or "../" */ - else { - if (p == start + 2 && p[-2] == '.') { /* leading "./../" */ - STRMOVE(p - 2, p); /* strip leading "./" */ + } else if (p == start && !relative) { // leading "/.." or "/../" + STRMOVE(p, tail); // strip ".." or "../" + } else { + if (p == start + 2 && p[-2] == '.') { // leading "./../" + STRMOVE(p - 2, p); // strip leading "./" tail -= 2; } - p = tail; /* skip to char after ".." or "../" */ + p = tail; // skip to char after ".." or "../" } } else { components++; // Simple path component. @@ -1639,31 +1657,23 @@ void simplify_filename(char_u *filename) static char *eval_includeexpr(const char *const ptr, const size_t len) { set_vim_var_string(VV_FNAME, ptr, (ptrdiff_t)len); - char *res = (char *)eval_to_string_safe( - curbuf->b_p_inex, NULL, - was_set_insecurely(curwin, (char_u *)"includeexpr", OPT_LOCAL)); + char *res = (char *)eval_to_string_safe(curbuf->b_p_inex, NULL, + was_set_insecurely(curwin, "includeexpr", OPT_LOCAL)); set_vim_var_string(VV_FNAME, NULL, 0); return res; } -/* - * Return the name of the file ptr[len] in 'path'. - * Otherwise like file_name_at_cursor(). - */ -char_u * -find_file_name_in_path ( - char_u *ptr, - size_t len, - int options, - long count, - char_u *rel_fname /* file we are searching relative to */ -) +/// Return the name of the file ptr[len] in 'path'. +/// Otherwise like file_name_at_cursor(). +/// +/// @param rel_fname file we are searching relative to +char_u *find_file_name_in_path(char_u *ptr, size_t len, int options, long count, char_u *rel_fname) { char_u *file_name; char_u *tofree = NULL; if ((options & FNAME_INCL) && *curbuf->b_p_inex != NUL) { - tofree = (char_u *) eval_includeexpr((char *) ptr, len); + tofree = (char_u *)eval_includeexpr((char *)ptr, len); if (tofree != NULL) { ptr = tofree; len = STRLEN(ptr); @@ -1680,7 +1690,7 @@ find_file_name_in_path ( */ if (file_name == NULL && !(options & FNAME_INCL) && *curbuf->b_p_inex != NUL) { - tofree = (char_u *) eval_includeexpr((char *) ptr, len); + tofree = (char_u *)eval_includeexpr((char *)ptr, len); if (tofree != NULL) { ptr = tofree; len = STRLEN(ptr); @@ -1701,8 +1711,9 @@ find_file_name_in_path ( xfree(file_name); file_name = find_file_in_path(ptr, len, options, FALSE, rel_fname); } - } else + } else { file_name = vim_strnsave(ptr, len); + } xfree(tofree); @@ -1714,10 +1725,11 @@ find_file_name_in_path ( // URL_BACKSLASH. int path_is_url(const char *p) { - if (strncmp(p, "://", 3) == 0) + if (strncmp(p, "://", 3) == 0) { return URL_SLASH; - else if (strncmp(p, ":\\\\", 3) == 0) + } else if (strncmp(p, ":\\\\", 3) == 0) { return URL_BACKSLASH; + } return 0; } @@ -1735,7 +1747,9 @@ int path_with_url(const char *fname) bool path_with_extension(const char *path, const char *extension) { const char *last_dot = strrchr(path, '.'); - if (!last_dot) { return false; } + if (!last_dot) { + return false; + } return strcmp(last_dot + 1, extension) == 0; } @@ -1809,8 +1823,9 @@ char *fix_fname(const char *fname) # ifdef BACKSLASH_IN_FILENAME || strstr(fname, "\\\\") != NULL # endif - ) + ) { return FullName_save(fname, false); + } fname = xstrdup(fname); @@ -1845,7 +1860,7 @@ void path_fix_case(char_u *name) tail = name; } else { *slash = NUL; - ok = os_scandir(&dir, (char *) name); + ok = os_scandir(&dir, (char *)name); *slash = '/'; tail = slash + 1; } @@ -1855,7 +1870,7 @@ void path_fix_case(char_u *name) } char_u *entry; - while ((entry = (char_u *) os_scandir_next(&dir))) { + while ((entry = (char_u *)os_scandir_next(&dir))) { // Only accept names that differ in case and are the same byte // length. TODO: accept different length name. if (STRICMP(tail, entry) == 0 && STRLEN(tail) == STRLEN(entry)) { @@ -1895,12 +1910,13 @@ int after_pathsep(const char *b, const char *p) bool same_directory(char_u *f1, char_u *f2) { char_u ffname[MAXPATHL]; - char_u *t1; - char_u *t2; + char_u *t1; + char_u *t2; - /* safety check */ - if (f1 == NULL || f2 == NULL) + // safety check + if (f1 == NULL || f2 == NULL) { return false; + } (void)vim_FullName((char *)f1, (char *)ffname, MAXPATHL, FALSE); t1 = path_tail_with_sep(ffname); @@ -1918,22 +1934,23 @@ int pathcmp(const char *p, const char *q, int maxlen) { int i, j; int c1, c2; - const char *s = NULL; + const char *s = NULL; for (i = 0, j = 0; maxlen < 0 || (i < maxlen && j < maxlen);) { c1 = PTR2CHAR((char_u *)p + i); c2 = PTR2CHAR((char_u *)q + j); - /* End of "p": check if "q" also ends or just has a slash. */ + // End of "p": check if "q" also ends or just has a slash. if (c1 == NUL) { - if (c2 == NUL) /* full match */ + if (c2 == NUL) { // full match return 0; + } s = q; i = j; break; } - /* End of "q": check if "p" just has a slash. */ + // End of "q": check if "p" just has a slash. if (c2 == NUL) { s = p; break; @@ -1941,15 +1958,17 @@ int pathcmp(const char *p, const char *q, int maxlen) if ((p_fic ? mb_toupper(c1) != mb_toupper(c2) : c1 != c2) #ifdef BACKSLASH_IN_FILENAME - /* consider '/' and '\\' to be equal */ + // consider '/' and '\\' to be equal && !((c1 == '/' && c2 == '\\') || (c1 == '\\' && c2 == '/')) #endif ) { - if (vim_ispathsep(c1)) + if (vim_ispathsep(c1)) { return -1; - if (vim_ispathsep(c2)) + } + if (vim_ispathsep(c2)) { return 1; + } return p_fic ? mb_toupper(c1) - mb_toupper(c2) : c1 - c2; // no match } @@ -2018,7 +2037,7 @@ char_u *path_shorten_fname(char_u *full_path, char_u *dir_name) } assert(dir_name != NULL); - size_t len = strlen((char *)dir_name); + size_t len = STRLEN(dir_name); // If dir_name is a path head, full_path can always be made relative. if (len == (size_t)path_head_length() && is_path_head(dir_name)) { @@ -2057,26 +2076,27 @@ char_u *path_shorten_fname(char_u *full_path, char_u *dir_name) /// If FAIL is returned, *num_file and *file are either /// unchanged or *num_file is set to 0 and *file is set /// to NULL or points to "". -int expand_wildcards_eval(char_u **pat, int *num_file, char_u ***file, - int flags) +int expand_wildcards_eval(char_u **pat, int *num_file, char_u ***file, int flags) { int ret = FAIL; - char_u *eval_pat = NULL; - char_u *exp_pat = *pat; - char_u *ignored_msg; + char_u *eval_pat = NULL; + char_u *exp_pat = *pat; + char_u *ignored_msg; size_t usedlen; if (*exp_pat == '%' || *exp_pat == '#' || *exp_pat == '<') { ++emsg_off; eval_pat = eval_vars(exp_pat, exp_pat, &usedlen, - NULL, &ignored_msg, NULL); + NULL, &ignored_msg, NULL); --emsg_off; - if (eval_pat != NULL) + if (eval_pat != NULL) { exp_pat = concat_str(eval_pat, exp_pat + usedlen); + } } - if (exp_pat != NULL) + if (exp_pat != NULL) { ret = expand_wildcards(1, &exp_pat, num_file, file, flags); + } if (eval_pat != NULL) { xfree(exp_pat); @@ -2100,25 +2120,25 @@ int expand_wildcards_eval(char_u **pat, int *num_file, char_u ***file, /// If FAIL is returned, *num_file and *file are either /// unchanged or *num_file is set to 0 and *file is set to /// NULL or points to "". -int expand_wildcards(int num_pat, char_u **pat, int *num_files, char_u ***files, - int flags) +int expand_wildcards(int num_pat, char_u **pat, int *num_files, char_u ***files, int flags) { int retval; int i, j; - char_u *p; - int non_suf_match; /* number without matching suffix */ + char_u *p; + int non_suf_match; // number without matching suffix retval = gen_expand_wildcards(num_pat, pat, num_files, files, flags); - /* When keeping all matches, return here */ - if ((flags & EW_KEEPALL) || retval == FAIL) + // When keeping all matches, return here + if ((flags & EW_KEEPALL) || retval == FAIL) { return retval; + } /* * Remove names that match 'wildignore'. */ if (*p_wig) { - char_u *ffname; + char_u *ffname; // check all files in (*files)[] assert(*num_files == 0 || *files != NULL); @@ -2183,7 +2203,7 @@ int match_suffix(char_u *fname) if (setsuflen == 0) { char_u *tail = path_tail(fname); - /* empty entry: match name without a '.' */ + // empty entry: match name without a '.' if (vim_strchr(tail, '.') == NULL) { setsuflen = 1; break; @@ -2209,13 +2229,13 @@ int path_full_dir_name(char *directory, char *buffer, size_t len) int retval = OK; if (STRLEN(directory) == 0) { - return os_dirname((char_u *) buffer, len); + return os_dirname((char_u *)buffer, len); } char old_dir[MAXPATHL]; // Get current directory name. - if (os_dirname((char_u *) old_dir, MAXPATHL) == FAIL) { + if (os_dirname((char_u *)old_dir, MAXPATHL) == FAIL) { return FAIL; } @@ -2229,7 +2249,7 @@ int path_full_dir_name(char *directory, char *buffer, size_t len) retval = FAIL; } - if (retval == FAIL || os_dirname((char_u *) buffer, len) == FAIL) { + if (retval == FAIL || os_dirname((char_u *)buffer, len) == FAIL) { // Do not return immediately since we are in the wrong directory. retval = FAIL; } @@ -2283,14 +2303,13 @@ int append_path(char *path, const char *to_append, size_t max_len) /// @param force also expand when "fname" is already absolute. /// /// @return FAIL for failure, OK for success. -static int path_to_absolute(const char_u *fname, char_u *buf, size_t len, - int force) +static int path_to_absolute(const char_u *fname, char_u *buf, size_t len, int force) { char_u *p; *buf = NUL; char *relative_directory = xmalloc(len); - char *end_of_path = (char *) fname; + char *end_of_path = (char *)fname; // expand it if forced or not an absolute path if (force || !path_is_absolute(fname)) { @@ -2311,13 +2330,13 @@ static int path_to_absolute(const char_u *fname, char_u *buf, size_t len, memcpy(relative_directory, fname, (size_t)(p - fname)); relative_directory[p-fname] = NUL; } - end_of_path = (char *) (p + 1); + end_of_path = (char *)(p + 1); } else { relative_directory[0] = NUL; - end_of_path = (char *) fname; + end_of_path = (char *)fname; } - if (FAIL == path_full_dir_name(relative_directory, (char *) buf, len)) { + if (FAIL == path_full_dir_name(relative_directory, (char *)buf, len)) { xfree(relative_directory); return FAIL; } diff --git a/src/nvim/path.h b/src/nvim/path.h index 15abd19646..5d81e68caa 100644 --- a/src/nvim/path.h +++ b/src/nvim/path.h @@ -2,22 +2,22 @@ #define NVIM_PATH_H #include "nvim/func_attr.h" -#include "nvim/types.h" #include "nvim/garray.h" +#include "nvim/types.h" -/* Flags for expand_wildcards() */ -#define EW_DIR 0x01 /* include directory names */ -#define EW_FILE 0x02 /* include file names */ -#define EW_NOTFOUND 0x04 /* include not found names */ -#define EW_ADDSLASH 0x08 /* append slash to directory name */ -#define EW_KEEPALL 0x10 /* keep all matches */ -#define EW_SILENT 0x20 /* don't print "1 returned" from shell */ -#define EW_EXEC 0x40 /* executable files */ -#define EW_PATH 0x80 /* search in 'path' too */ -#define EW_ICASE 0x100 /* ignore case */ -#define EW_NOERROR 0x200 /* no error for bad regexp */ -#define EW_NOTWILD 0x400 /* add match with literal name if exists */ -#define EW_KEEPDOLLAR 0x800 /* do not escape $, $var is expanded */ +// Flags for expand_wildcards() +#define EW_DIR 0x01 // include directory names +#define EW_FILE 0x02 // include file names +#define EW_NOTFOUND 0x04 // include not found names +#define EW_ADDSLASH 0x08 // append slash to directory name +#define EW_KEEPALL 0x10 // keep all matches +#define EW_SILENT 0x20 // don't print "1 returned" from shell +#define EW_EXEC 0x40 // executable files +#define EW_PATH 0x80 // search in 'path' too +#define EW_ICASE 0x100 // ignore case +#define EW_NOERROR 0x200 // no error for bad regexp +#define EW_NOTWILD 0x400 // add match with literal name if exists +#define EW_KEEPDOLLAR 0x800 // do not escape $, $var is expanded /* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND * is used when executing commands and EW_SILENT for interactive expanding. */ #define EW_ALLLINKS 0x1000 // also links not pointing to existing file diff --git a/src/nvim/plines.c b/src/nvim/plines.c index a656686a95..5b0418ed92 100644 --- a/src/nvim/plines.c +++ b/src/nvim/plines.c @@ -5,18 +5,18 @@ #include <assert.h> #include <inttypes.h> +#include <limits.h> #include <stdbool.h> #include <string.h> -#include <limits.h> -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/plines.h" +#include "nvim/buffer.h" #include "nvim/charset.h" #include "nvim/cursor.h" +#include "nvim/decoration.h" #include "nvim/diff.h" -#include "nvim/func_attr.h" #include "nvim/fold.h" +#include "nvim/func_attr.h" #include "nvim/indent.h" #include "nvim/main.h" #include "nvim/mbyte.h" @@ -24,10 +24,11 @@ #include "nvim/memory.h" #include "nvim/move.h" #include "nvim/option.h" +#include "nvim/plines.h" #include "nvim/screen.h" #include "nvim/strings.h" +#include "nvim/vim.h" #include "nvim/window.h" -#include "nvim/buffer.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "plines.c.generated.h" @@ -41,7 +42,34 @@ int plines_win(win_T *wp, linenr_T lnum, bool winheight) { // Check for filler lines above this buffer line. When folded the result // is one line anyway. - return plines_win_nofill(wp, lnum, winheight) + diff_check_fill(wp, lnum); + return plines_win_nofill(wp, lnum, winheight) + win_get_fill(wp, lnum); +} + + +/// Return the number of filler lines above "lnum". +/// +/// @param wp +/// @param lnum +/// +/// @return Number of filler lines above lnum +int win_get_fill(win_T *wp, linenr_T lnum) +{ + int virt_lines = decor_virtual_lines(wp, lnum); + + // be quick when there are no filler lines + if (diffopt_filler()) { + int n = diff_check(wp, lnum); + + if (n > 0) { + return virt_lines+n; + } + } + return virt_lines; +} + +bool win_may_fill(win_T *wp) +{ + return (wp->w_p_diff && diffopt_filler()) || wp->w_buffer->b_virt_line_mark; } /// @param winheight when true limit to window height @@ -71,7 +99,7 @@ int plines_win_nofill(win_T *wp, linenr_T lnum, bool winheight) /// "wp". Does not care about folding, 'wrap' or 'diff'. int plines_win_nofold(win_T *wp, linenr_T lnum) { - char_u *s; + char_u *s; unsigned int col; int width; @@ -107,7 +135,7 @@ int plines_win_col(win_T *wp, linenr_T lnum, long column) { // Check for filler lines above this buffer line. When folded the result // is one line anyway. - int lines = diff_check_fill(wp, lnum); + int lines = win_get_fill(wp, lnum); if (!wp->w_p_wrap) { return lines + 1; @@ -159,8 +187,8 @@ int plines_win_col(win_T *wp, linenr_T lnum, long column) /// @param[in] cache whether to use the window's cache for folds /// /// @return the total number of screen lines -int plines_win_full(win_T *wp, linenr_T lnum, linenr_T *const nextp, - bool *const foldedp, const bool cache) +int plines_win_full(win_T *wp, linenr_T lnum, linenr_T *const nextp, bool *const foldedp, + const bool cache) { bool folded = hasFoldingWin(wp, lnum, NULL, nextp, cache, NULL); if (foldedp) { @@ -302,8 +330,7 @@ int lbr_chartabsize_adv(char_u *line, char_u **s, colnr_T col) /// @param headp /// /// @return The number of characters taken up on the screen. -int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, - colnr_T col, int *headp) +int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *headp) { colnr_T col2; colnr_T col_adj = 0; // col + screen size of tab @@ -326,7 +353,7 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, int size = win_chartabsize(wp, s, col); int c = *s; if (*s == TAB) { - col_adj = size - 1; + col_adj = size - 1; } // If 'linebreak' set check at a blank before a non-blank if the line @@ -343,8 +370,8 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colmax = (colnr_T)(wp->w_width_inner - numberextra - col_adj); if (col >= colmax) { - colmax += col_adj; - n = colmax + win_col_off2(wp); + colmax += col_adj; + n = colmax + win_col_off2(wp); if (n > 0) { colmax += (((col - colmax) / n) + 1) * n - col_adj; diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index 1705ea0c12..606c03f838 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -9,27 +9,27 @@ #include <inttypes.h> #include <stdbool.h> -#include "nvim/buffer.h" -#include "nvim/vim.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii.h" -#include "nvim/eval/typval.h" -#include "nvim/popupmnu.h" +#include "nvim/buffer.h" #include "nvim/charset.h" +#include "nvim/edit.h" +#include "nvim/eval/typval.h" #include "nvim/ex_cmds.h" #include "nvim/memline.h" +#include "nvim/memory.h" #include "nvim/move.h" #include "nvim/option.h" +#include "nvim/popupmnu.h" #include "nvim/screen.h" -#include "nvim/ui_compositor.h" #include "nvim/search.h" #include "nvim/strings.h" -#include "nvim/memory.h" -#include "nvim/window.h" -#include "nvim/edit.h" #include "nvim/ui.h" +#include "nvim/ui_compositor.h" +#include "nvim/vim.h" +#include "nvim/window.h" -static pumitem_T *pum_array = NULL; // items of displayed pum +static pumitem_T *pum_array = NULL; // items of displayed pum static int pum_size; // nr of items in "pum_array" static int pum_selected; // index of selected item or -1 static int pum_first = 0; // index of top item @@ -98,8 +98,7 @@ static void pum_compute_size(void) /// if false, a new item is selected, but the array /// is the same /// @param cmd_startcol only for cmdline mode: column of completed match -void pum_display(pumitem_T *array, int size, int selected, bool array_changed, - int cmd_startcol) +void pum_display(pumitem_T *array, int size, int selected, bool array_changed, int cmd_startcol) { int context_lines; int above_row; @@ -234,7 +233,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, context_lines = 3; } else { context_lines = curwin->w_cline_row - + curwin->w_cline_height - curwin->w_wrow; + + curwin->w_cline_height - curwin->w_wrow; } pum_row = pum_win_row + context_lines; @@ -488,17 +487,17 @@ void pum_redraw(void) s = NULL; switch (round) { - case 1: - p = pum_array[idx].pum_text; - break; + case 1: + p = pum_array[idx].pum_text; + break; - case 2: - p = pum_array[idx].pum_kind; - break; + case 2: + p = pum_array[idx].pum_kind; + break; - case 3: - p = pum_array[idx].pum_extra; - break; + case 3: + p = pum_array[idx].pum_extra; + break; } if (p != NULL) { @@ -515,7 +514,7 @@ void pum_redraw(void) char_u saved = *p; *p = NUL; - st = (char_u *)transstr((const char *)s); + st = (char_u *)transstr((const char *)s, true); *p = saved; if (pum_rl) { diff --git a/src/nvim/popupmnu.h b/src/nvim/popupmnu.h index 7956e50a93..7d3f4c6f51 100644 --- a/src/nvim/popupmnu.h +++ b/src/nvim/popupmnu.h @@ -1,10 +1,10 @@ #ifndef NVIM_POPUPMNU_H #define NVIM_POPUPMNU_H -#include "nvim/vim.h" -#include "nvim/macros.h" #include "nvim/grid_defs.h" +#include "nvim/macros.h" #include "nvim/types.h" +#include "nvim/vim.h" /// Used for popup menu items. typedef struct { diff --git a/src/nvim/pos.h b/src/nvim/pos.h index b7c4b6ef92..2fbd049aa0 100644 --- a/src/nvim/pos.h +++ b/src/nvim/pos.h @@ -26,8 +26,8 @@ enum { MINCOL = 1 }; * position in file or buffer */ typedef struct { - linenr_T lnum; /* line number */ - colnr_T col; /* column number */ + linenr_T lnum; // line number + colnr_T col; // column number colnr_T coladd; } pos_T; @@ -36,8 +36,8 @@ typedef struct { * Same, but without coladd. */ typedef struct { - linenr_T lnum; /* line number */ - colnr_T col; /* column number */ + linenr_T lnum; // line number + colnr_T col; // column number } lpos_T; #endif // NVIM_POS_H diff --git a/src/nvim/profile.c b/src/nvim/profile.c index f9b0bb0a2b..fe7bd2e912 100644 --- a/src/nvim/profile.c +++ b/src/nvim/profile.c @@ -1,17 +1,16 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com -#include <stdio.h> -#include <math.h> #include <assert.h> +#include <math.h> +#include <stdio.h> #include "nvim/assert.h" -#include "nvim/profile.h" -#include "nvim/os/time.h" #include "nvim/func_attr.h" -#include "nvim/os/os_defs.h" - #include "nvim/globals.h" // for the global `time_fd` (startuptime) +#include "nvim/os/os_defs.h" +#include "nvim/os/time.h" +#include "nvim/profile.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "profile.c.generated.h" @@ -97,7 +96,7 @@ proftime_T profile_divide(proftime_T tm, int count) FUNC_ATTR_CONST return profile_zero(); } - return (proftime_T) round((double) tm / (double) count); + return (proftime_T)round((double)tm / (double)count); } /// Adds time `tm2` to `tm1`. diff --git a/src/nvim/profile.h b/src/nvim/profile.h index 7b378577ce..17c35c5eb7 100644 --- a/src/nvim/profile.h +++ b/src/nvim/profile.h @@ -7,8 +7,8 @@ typedef uint64_t proftime_T; #define TIME_MSG(s) do { \ - if (time_fd != NULL) time_msg(s, NULL); \ - } while (0) + if (time_fd != NULL) time_msg(s, NULL); \ +} while (0) #ifdef INCLUDE_GENERATED_DECLARATIONS # include "profile.h.generated.h" diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index e1ee5dc28f..a8d4996340 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -8,9 +8,8 @@ #include <stdbool.h> #include <string.h> -#include "nvim/vim.h" +#include "nvim/api/private/helpers.h" #include "nvim/ascii.h" -#include "nvim/quickfix.h" #include "nvim/buffer.h" #include "nvim/charset.h" #include "nvim/cursor.h" @@ -26,29 +25,30 @@ #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" +#include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/memory.h" #include "nvim/move.h" #include "nvim/normal.h" #include "nvim/option.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" #include "nvim/os_unix.h" #include "nvim/path.h" +#include "nvim/quickfix.h" #include "nvim/regexp.h" #include "nvim/screen.h" #include "nvim/search.h" #include "nvim/strings.h" #include "nvim/syntax.h" #include "nvim/ui.h" +#include "nvim/vim.h" #include "nvim/window.h" -#include "nvim/os/os.h" -#include "nvim/os/input.h" -#include "nvim/api/private/helpers.h" struct dir_stack_T { - struct dir_stack_T *next; - char_u *dirname; + struct dir_stack_T *next; + char_u *dirname; }; // For each error the next struct is allocated and linked in a list. @@ -67,7 +67,7 @@ struct qfline_S { char_u *qf_pattern; ///< search pattern for the error char_u *qf_text; ///< description of the error char_u qf_viscol; ///< set to TRUE if qf_col and qf_end_col is - // screen column + // screen column char_u qf_cleared; ///< set to TRUE if line has been deleted char_u qf_type; ///< type of the error (mostly 'E'); 1 for :helpgrep char_u qf_valid; ///< valid error message detected @@ -83,7 +83,7 @@ typedef enum QFLT_QUICKFIX, ///< Quickfix list - global list QFLT_LOCATION, ///< Location list - per window list QFLT_INTERNAL ///< Internal - Temporary list used by - // getqflist()/getloclist() + // getqflist()/getloclist() } qfltype_T; /// Quickfix/Location list definition @@ -93,17 +93,17 @@ typedef enum /// information and entries can be added later using setqflist()/setloclist(). typedef struct qf_list_S { unsigned qf_id; ///< Unique identifier for this list - qfltype_T qfl_type; - qfline_T *qf_start; ///< pointer to the first error - qfline_T *qf_last; ///< pointer to the last error - qfline_T *qf_ptr; ///< pointer to the current error + qfltype_T qfl_type; + qfline_T *qf_start; ///< pointer to the first error + qfline_T *qf_last; ///< pointer to the last error + qfline_T *qf_ptr; ///< pointer to the current error int qf_count; ///< number of errors (0 means empty list) int qf_index; ///< current index in the error list int qf_nonevalid; ///< TRUE if not a single valid entry found - char_u *qf_title; ///< title derived from the command that created - ///< the error list or set by setqflist - typval_T *qf_ctx; ///< context set by setqflist/setloclist - Callback qftf_cb; ///< 'quickfixtextfunc' callback function + char_u *qf_title; ///< title derived from the command that created + ///< the error list or set by setqflist + typval_T *qf_ctx; ///< context set by setqflist/setloclist + Callback qftf_cb; ///< 'quickfixtextfunc' callback function struct dir_stack_T *qf_dir_stack; char_u *qf_directory; @@ -137,8 +137,8 @@ static unsigned last_qf_id = 0; // Last Used quickfix list id // Structure used to hold the info of one part of 'errorformat' typedef struct efm_S efm_T; struct efm_S { - regprog_T *prog; // pre-formatted part of 'errorformat' - efm_T *next; // pointer to next (NULL if last) + regprog_T *prog; // pre-formatted part of 'errorformat' + efm_T *next; // pointer to next (NULL if last) char_u addr[FMT_PATTERNS]; // indices of used % patterns char_u prefix; // prefix of this format line: // 'D' enter directory @@ -183,12 +183,12 @@ typedef struct { size_t linelen; char_u *growbuf; size_t growbufsiz; - FILE *fd; - typval_T *tv; - char_u *p_str; - list_T *p_list; + FILE *fd; + typval_T *tv; + char_u *p_str; + list_T *p_list; listitem_T *p_li; - buf_T *buf; + buf_T *buf; linenr_T buflnum; linenr_T lnumlast; vimconv_T vc; @@ -201,13 +201,13 @@ typedef struct { size_t errmsglen; long lnum; long end_lnum; - int col; + int col; int end_col; bool use_viscol; char_u *pattern; - int enr; + int enr; char_u type; - bool valid; + bool valid; } qffields_T; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -236,7 +236,7 @@ static char_u *e_no_more_items = (char_u *)N_("E553: No more items"); // Macro to loop through all the items in a quickfix list // Quickfix item index starts from 1, so i below starts at 1 #define FOR_ALL_QFL_ITEMS(qfl, qfp, i) \ - for (i = 1, qfp = qfl->qf_start; /* NOLINT(readability/braces) */ \ + for (i = 1, qfp = qfl->qf_start; /* NOLINT(readability/braces) */ \ !got_int && i <= qfl->qf_count && qfp != NULL; \ i++, qfp = qfp->qf_next) @@ -244,7 +244,7 @@ static char_u *e_no_more_items = (char_u *)N_("E553: No more items"); // Looking up a buffer can be slow if there are many. Remember the last one // to make this a lot faster if there are multiple matches in the same file. static char_u *qf_last_bufname = NULL; -static bufref_T qf_last_bufref = { NULL, 0, 0 }; +static bufref_T qf_last_bufref = { NULL, 0, 0 }; static char *e_current_quickfix_list_was_changed = N_("E925: Current quickfix list was changed"); @@ -258,9 +258,7 @@ static qf_delq_T *qf_delq_head = NULL; /// Process the next line from a file/buffer/list/string and add it /// to the quickfix list 'qfl'. -static int qf_init_process_nextline(qf_list_T *qfl, - efm_T *fmt_first, - qfstate_T *state, +static int qf_init_process_nextline(qf_list_T *qfl, efm_T *fmt_first, qfstate_T *state, qffields_T *fields) { int status; @@ -308,11 +306,10 @@ static int qf_init_process_nextline(qf_list_T *qfl, /// @params enc If non-NULL, encoding used to parse errors /// /// @returns -1 for error, number of errors for success. -int qf_init(win_T *wp, const char_u *restrict efile, - char_u *restrict errorformat, int newlist, +int qf_init(win_T *wp, const char_u *restrict efile, char_u *restrict errorformat, int newlist, const char_u *restrict qf_title, char_u *restrict enc) { - qf_info_T *qi = &ql_info; + qf_info_T *qi = &ql_info; if (wp != NULL) { qi = ll_get_or_alloc_list(wp); @@ -338,7 +335,7 @@ static struct fmtpattern { 't', "." }, { 'm', ".\\+" }, { 'r', ".*" }, - { 'p', "[- .]*" }, // NOLINT(whitespace/tab) + { 'p', "[- .]*"}, // NOLINT(whitespace/tab) { 'v', "\\d\\+" }, { 's', ".\\+" }, { 'o', ".\\+" } @@ -348,14 +345,8 @@ static struct fmtpattern /// See fmt_pat definition above for the list of supported patterns. The /// pattern specifier is supplied in "efmpat". The converted pattern is stored /// in "regpat". Returns a pointer to the location after the pattern. -static char_u * efmpat_to_regpat( - const char_u *efmpat, - char_u *regpat, - efm_T *efminfo, - int idx, - int round, - char_u *errmsg, - size_t errmsglen) +static char_u *efmpat_to_regpat(const char_u *efmpat, char_u *regpat, efm_T *efminfo, int idx, + int round, char_u *errmsg, size_t errmsglen) FUNC_ATTR_NONNULL_ALL { if (efminfo->addr[idx]) { @@ -374,7 +365,7 @@ static char_u * efmpat_to_regpat( EMSG(errmsg); return NULL; } - efminfo->addr[idx] = (char_u)++round; + efminfo->addr[idx] = (char_u)++ round; *regpat++ = '\\'; *regpat++ = '('; #ifdef BACKSLASH_IN_FILENAME @@ -415,13 +406,8 @@ static char_u * efmpat_to_regpat( /// Convert a scanf like format in 'errorformat' to a regular expression. /// Returns a pointer to the location after the pattern. -static char_u * scanf_fmt_to_regpat( - const char_u **pefmp, - const char_u *efm, - int len, - char_u *regpat, - char_u *errmsg, - size_t errmsglen) +static char_u *scanf_fmt_to_regpat(const char_u **pefmp, const char_u *efm, int len, char_u *regpat, + char_u *errmsg, size_t errmsglen) FUNC_ATTR_NONNULL_ALL { const char_u *efmp = *pefmp; @@ -459,8 +445,8 @@ static char_u * scanf_fmt_to_regpat( } /// Analyze/parse an errorformat prefix. -static const char_u *efm_analyze_prefix(const char_u *efmp, efm_T *efminfo, - char_u *errmsg, size_t errmsglen) +static const char_u *efm_analyze_prefix(const char_u *efmp, efm_T *efminfo, char_u *errmsg, + size_t errmsglen) FUNC_ATTR_NONNULL_ALL { if (vim_strchr((char_u *)"+-", *efmp) != NULL) { @@ -480,8 +466,8 @@ static const char_u *efm_analyze_prefix(const char_u *efmp, efm_T *efminfo, // Converts a 'errorformat' string to regular expression pattern -static int efm_to_regpat(const char_u *efm, int len, efm_T *fmt_ptr, - char_u *regpat, char_u *errmsg, size_t errmsglen) +static int efm_to_regpat(const char_u *efm, int len, efm_T *fmt_ptr, char_u *regpat, char_u *errmsg, + size_t errmsglen) FUNC_ATTR_NONNULL_ALL { // Build regexp pattern from current 'errorformat' option @@ -598,7 +584,7 @@ static int efm_option_part_len(char_u *efm) /// Parse the 'errorformat' option. Multiple parts in the 'errorformat' option /// are parsed and converted to regular expressions. Returns information about /// the parsed 'errorformat' option. -static efm_T * parse_efm_option(char_u *efm) +static efm_T *parse_efm_option(char_u *efm) { efm_T *fmt_ptr = NULL; efm_T *fmt_first = NULL; @@ -769,7 +755,7 @@ retry: errno = 0; if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL) { if (errno == EINTR) { - goto retry; + goto retry; } return QF_END_OF_INPUT; } @@ -915,7 +901,7 @@ static bool qf_list_has_valid_entries(qf_list_T *qfl) } /// Return a pointer to a list in the specified quickfix stack -static qf_list_T * qf_get_list(qf_info_T *qi, int idx) +static qf_list_T *qf_get_list(qf_info_T *qi, int idx) FUNC_ATTR_NONNULL_ALL { return &qi->qf_lists[idx]; @@ -923,11 +909,11 @@ static qf_list_T * qf_get_list(qf_info_T *qi, int idx) /// Parse a line and get the quickfix fields. /// Return the QF_ status. -static int qf_parse_line(qf_list_T *qfl, char_u *linebuf, - size_t linelen, efm_T *fmt_first, qffields_T *fields) +static int qf_parse_line(qf_list_T *qfl, char_u *linebuf, size_t linelen, efm_T *fmt_first, + qffields_T *fields) { efm_T *fmt_ptr; - int idx = 0; + int idx = 0; char_u *tail = NULL; int status; @@ -1030,14 +1016,8 @@ static void qf_free_fields(qffields_T *pfields) // Setup the state information used for parsing lines and populating a // quickfix list. -static int qf_setup_state( - qfstate_T *pstate, - char_u *restrict enc, - const char_u *restrict efile, - typval_T *tv, - buf_T *buf, - linenr_T lnumfirst, - linenr_T lnumlast) +static int qf_setup_state(qfstate_T *pstate, char_u *restrict enc, const char_u *restrict efile, + typval_T *tv, buf_T *buf, linenr_T lnumfirst, linenr_T lnumlast) FUNC_ATTR_NONNULL_ARG(1) { pstate->vc.vc_type = CONV_NONE; @@ -1080,38 +1060,32 @@ static void qf_cleanup_state(qfstate_T *pstate) } } -// Read the errorfile "efile" into memory, line by line, building the error -// list. -// Alternative: when "efile" is NULL read errors from buffer "buf". -// Alternative: when "tv" is not NULL get errors from the string or list. -// Always use 'errorformat' from "buf" if there is a local value. -// Then "lnumfirst" and "lnumlast" specify the range of lines to use. -// Set the title of the list to "qf_title". -// Return -1 for error, number of errors for success. -static int -qf_init_ext( - qf_info_T *qi, - int qf_idx, - const char_u *restrict efile, - buf_T *buf, - typval_T *tv, - char_u *restrict errorformat, - bool newlist, // true: start a new error list - linenr_T lnumfirst, // first line number to use - linenr_T lnumlast, // last line number to use - const char_u *restrict qf_title, - char_u *restrict enc -) +/// Read the errorfile "efile" into memory, line by line, building the error +/// list. +/// Alternative: when "efile" is NULL read errors from buffer "buf". +/// Alternative: when "tv" is not NULL get errors from the string or list. +/// Always use 'errorformat' from "buf" if there is a local value. +/// Then "lnumfirst" and "lnumlast" specify the range of lines to use. +/// Set the title of the list to "qf_title". +/// +/// @param newlist true: start a new error list +/// @param lnumfirst first line number to use +/// @param lnumlast last line number to use +/// +/// @return -1 for error, number of errors for success. +static int qf_init_ext(qf_info_T *qi, int qf_idx, const char_u *restrict efile, buf_T *buf, + typval_T *tv, char_u *restrict errorformat, bool newlist, linenr_T lnumfirst, + linenr_T lnumlast, const char_u *restrict qf_title, char_u *restrict enc) FUNC_ATTR_NONNULL_ARG(1) { qf_list_T *qfl; qfstate_T state = { 0 }; qffields_T fields = { 0 }; - qfline_T *old_last = NULL; + qfline_T *old_last = NULL; bool adding = false; - static efm_T *fmt_first = NULL; - char_u *efm; - static char_u *last_efm = NULL; + static efm_T *fmt_first = NULL; + char_u *efm; + static char_u *last_efm = NULL; int retval = -1; // default: return error flag int status; @@ -1237,7 +1211,7 @@ static void qf_store_title(qf_list_T *qfl, const char_u *title) /// that created the quickfix list with the ":" prefix. /// Create a quickfix list title string by prepending ":" to a user command. /// Returns a pointer to a static buffer with the title. -static char_u * qf_cmdtitle(char_u *cmd) +static char_u *qf_cmdtitle(char_u *cmd) { static char_u qftitle_str[IOSIZE]; @@ -1247,7 +1221,7 @@ static char_u * qf_cmdtitle(char_u *cmd) } /// Return a pointer to the current list in the specified quickfix stack -static qf_list_T * qf_get_curlist(qf_info_T *qi) +static qf_list_T *qf_get_curlist(qf_info_T *qi) FUNC_ATTR_NONNULL_ALL { return qf_get_list(qi, qi->qf_curlist); @@ -1263,7 +1237,7 @@ static void qf_new_list(qf_info_T *qi, const char_u *qf_title) // If the current entry is not the last entry, delete entries beyond // the current entry. This makes it possible to browse in a tree-like - // way with ":grep'. + // way with ":grep". while (qi->qf_listcount > qi->qf_curlist + 1) { qf_free(&qi->qf_lists[--qi->qf_listcount]); } @@ -1276,8 +1250,9 @@ static void qf_new_list(qf_info_T *qi, const char_u *qf_title) qi->qf_lists[i - 1] = qi->qf_lists[i]; } qi->qf_curlist = LISTCOUNT - 1; - } else + } else { qi->qf_curlist = qi->qf_listcount++; + } qfl = qf_get_curlist(qi); memset(qfl, 0, sizeof(qf_list_T)); qf_store_title(qfl, qf_title); @@ -1287,10 +1262,7 @@ static void qf_new_list(qf_info_T *qi, const char_u *qf_title) /// Parse the match for filename ('%f') pattern in regmatch. /// Return the matched value in "fields->namebuf". -static int qf_parse_fmt_f(regmatch_T *rmp, - int midx, - qffields_T *fields, - int prefix) +static int qf_parse_fmt_f(regmatch_T *rmp, int midx, qffields_T *fields, int prefix) { char_u c; @@ -1360,9 +1332,7 @@ static int qf_parse_fmt_t(regmatch_T *rmp, int midx, qffields_T *fields) /// Parse the match for '%+' format pattern. The whole matching line is included /// in the error string. Return the matched line in "fields->errmsg". -static void qf_parse_fmt_plus(const char_u *linebuf, - size_t linelen, - qffields_T *fields) +static void qf_parse_fmt_plus(const char_u *linebuf, size_t linelen, qffields_T *fields) FUNC_ATTR_NONNULL_ALL { if (linelen >= fields->errmsglen) { @@ -1499,9 +1469,8 @@ static int (*qf_parse_fmt[FMT_PATTERNS])(regmatch_T *, int, qffields_T *) = { /// fmt_ptr contains the 'efm' format specifiers/prefixes that have a match. /// Returns QF_OK if all the matches are successfully parsed. On failure, /// returns QF_FAIL or QF_NOMEM. -static int qf_parse_match(char_u *linebuf, size_t linelen, efm_T *fmt_ptr, - regmatch_T *regmatch, qffields_T *fields, - int qf_multiline, int qf_multiscan, char_u **tail) +static int qf_parse_match(char_u *linebuf, size_t linelen, efm_T *fmt_ptr, regmatch_T *regmatch, + qffields_T *fields, int qf_multiline, int qf_multiscan, char_u **tail) { char_u idx = fmt_ptr->prefix; int i; @@ -1549,9 +1518,8 @@ static int qf_parse_match(char_u *linebuf, size_t linelen, efm_T *fmt_ptr, /// 'fmt_ptr->prog' and return the matching values in 'fields'. /// Returns QF_OK if the efm format matches completely and the fields are /// successfully copied. Otherwise returns QF_FAIL or QF_NOMEM. -static int qf_parse_get_fields(char_u *linebuf, size_t linelen, efm_T *fmt_ptr, - qffields_T *fields, int qf_multiline, - int qf_multiscan, char_u **tail) +static int qf_parse_get_fields(char_u *linebuf, size_t linelen, efm_T *fmt_ptr, qffields_T *fields, + int qf_multiline, int qf_multiscan, char_u **tail) { regmatch_T regmatch; int status = QF_FAIL; @@ -1611,8 +1579,7 @@ static int qf_parse_dir_pfx(int idx, qffields_T *fields, qf_list_T *qfl) } /// Parse global file name error format prefixes (%O, %P and %Q). -static int qf_parse_file_pfx(int idx, qffields_T *fields, qf_list_T *qfl, - char_u *tail) +static int qf_parse_file_pfx(int idx, qffields_T *fields, qf_list_T *qfl, char_u *tail) { fields->valid = false; if (*fields->namebuf == NUL || os_path_exists(fields->namebuf)) { @@ -1635,8 +1602,7 @@ static int qf_parse_file_pfx(int idx, qffields_T *fields, qf_list_T *qfl, /// Parse a non-error line (a line which doesn't match any of the error /// format in 'efm'). -static int qf_parse_line_nomatch(char_u *linebuf, size_t linelen, - qffields_T *fields) +static int qf_parse_line_nomatch(char_u *linebuf, size_t linelen, qffields_T *fields) { fields->namebuf[0] = NUL; // no match found, remove file name fields->lnum = 0; // don't jump to this line @@ -1662,8 +1628,8 @@ static int qf_parse_multiline_pfx(int idx, qf_list_T *qfl, qffields_T *fields) return QF_FAIL; } if (*fields->errmsg) { - size_t textlen = strlen((char *)qfprev->qf_text); - size_t errlen = strlen((char *)fields->errmsg); + size_t textlen = STRLEN(qfprev->qf_text); + size_t errlen = STRLEN(fields->errmsg); qfprev->qf_text = xrealloc(qfprev->qf_text, textlen + errlen + 2); qfprev->qf_text[textlen] = '\n'; STRCPY(qfprev->qf_text + textlen + 1, fields->errmsg); @@ -1714,11 +1680,12 @@ static void locstack_queue_delreq(qf_info_T *qi) static void ll_free_all(qf_info_T **pqi) { int i; - qf_info_T *qi; + qf_info_T *qi; qi = *pqi; - if (qi == NULL) + if (qi == NULL) { return; + } *pqi = NULL; // Remove reference to this list qi->qf_refcount--; @@ -1741,7 +1708,7 @@ static void ll_free_all(qf_info_T **pqi) void qf_free_all(win_T *wp) { int i; - qf_info_T *qi = &ql_info; + qf_info_T *qi = &ql_info; if (wp != NULL) { // location list @@ -1761,7 +1728,7 @@ void qf_free_all(win_T *wp) /// Must always call decr_quickfix_busy() exactly once after this. static void incr_quickfix_busy(void) { - quickfix_busy++; + quickfix_busy++; } /// Safe to free location list stacks. Process any delayed delete requests. @@ -1818,11 +1785,9 @@ void check_quickfix_busy(void) /// @param valid valid entry /// /// @returns QF_OK or QF_FAIL. -static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname, - char_u *module, int bufnum, char_u *mesg, - long lnum, long end_lnum, int col, int end_col, - char_u vis_col, char_u *pattern, int nr, - char_u type, char_u valid) +static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname, char_u *module, int bufnum, + char_u *mesg, long lnum, long end_lnum, int col, int end_col, + char_u vis_col, char_u *pattern, int nr, char_u type, char_u valid) { qfline_T *qfp = xmalloc(sizeof(qfline_T)); qfline_T **lastp; // pointer to qf_last or NULL @@ -1858,7 +1823,7 @@ static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname, if (type != 1 && !vim_isprintc(type)) { // only printable chars allowed type = 0; } - qfp->qf_type = (char_u)type; + qfp->qf_type = type; qfp->qf_valid = valid; lastp = &qfl->qf_last; @@ -1921,7 +1886,7 @@ static qf_info_T *ll_get_or_alloc_list(win_T *wp) /// For a location list command, returns the stack for the current window. If /// the location list is not found, then returns NULL and prints an error /// message if 'print_emsg' is TRUE. -static qf_info_T * qf_cmd_get_stack(exarg_T *eap, int print_emsg) +static qf_info_T *qf_cmd_get_stack(exarg_T *eap, int print_emsg) { qf_info_T *qi = &ql_info; @@ -2140,10 +2105,9 @@ static int qf_get_fnum(qf_list_T *qfl, char_u *directory, char_u *fname ) // Push dirbuf onto the directory stack and return pointer to actual dir or // NULL on error. -static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, - bool is_file_stack) +static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, bool is_file_stack) { - struct dir_stack_T *ds_ptr; + struct dir_stack_T *ds_ptr; // allocate new stack element and hook it in struct dir_stack_T *ds_new = xmalloc(sizeof(struct dir_stack_T)); @@ -2165,9 +2129,10 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, while (ds_new) { xfree((*stackptr)->dirname); (*stackptr)->dirname = (char_u *)concat_fnames((char *)ds_new->dirname, - (char *)dirbuf, TRUE); - if (os_isdir((*stackptr)->dirname)) + (char *)dirbuf, TRUE); + if (os_isdir((*stackptr)->dirname)) { break; + } ds_new = ds_new->next; } @@ -2187,9 +2152,9 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, } } - if ((*stackptr)->dirname != NULL) + if ((*stackptr)->dirname != NULL) { return (*stackptr)->dirname; - else { + } else { ds_ptr = *stackptr; *stackptr = (*stackptr)->next; xfree(ds_ptr); @@ -2202,7 +2167,7 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, // stack is empty static char_u *qf_pop_dir(struct dir_stack_T **stackptr) { - struct dir_stack_T *ds_ptr; + struct dir_stack_T *ds_ptr; // TODO(vim): Should we check if dirbuf is the directory on top of the stack? // What to do if it isn't? @@ -2222,7 +2187,7 @@ static char_u *qf_pop_dir(struct dir_stack_T **stackptr) // clean up directory stack static void qf_clean_dir_stack(struct dir_stack_T **stackptr) { - struct dir_stack_T *ds_ptr; + struct dir_stack_T *ds_ptr; while ((ds_ptr = *stackptr) != NULL) { *stackptr = (*stackptr)->next; @@ -2251,9 +2216,9 @@ static void qf_clean_dir_stack(struct dir_stack_T **stackptr) /// qf_guess_filepath will return NULL. static char_u *qf_guess_filepath(qf_list_T *qfl, char_u *filename) { - struct dir_stack_T *ds_ptr; - struct dir_stack_T *ds_tmp; - char_u *fullname; + struct dir_stack_T *ds_ptr; + struct dir_stack_T *ds_tmp; + char_u *fullname; // no dirs on the stack - there's nothing we can do if (qfl->qf_dir_stack == NULL) { @@ -2332,8 +2297,7 @@ static bool is_qf_entry_present(qf_list_T *qfl, qfline_T *qf_ptr) /// Get the next valid entry in the current quickfix/location list. The search /// starts from the current entry. Returns NULL on failure. -static qfline_T *get_next_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr, - int *qf_index, int dir) +static qfline_T *get_next_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr, int *qf_index, int dir) { int idx = *qf_index; int old_qf_fnum = qf_ptr->qf_fnum; @@ -2353,8 +2317,7 @@ static qfline_T *get_next_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr, /// Get the previous valid entry in the current quickfix/location list. The /// search starts from the current entry. Returns NULL on failure. -static qfline_T *get_prev_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr, - int *qf_index, int dir) +static qfline_T *get_prev_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr, int *qf_index, int dir) { int idx = *qf_index; int old_qf_fnum = qf_ptr->qf_fnum; @@ -2376,8 +2339,7 @@ static qfline_T *get_prev_valid_entry(qf_list_T *qfl, qfline_T *qf_ptr, /// the quickfix list. /// dir == FORWARD or FORWARD_FILE: next valid entry /// dir == BACKWARD or BACKWARD_FILE: previous valid entry -static qfline_T *get_nth_valid_entry(qf_list_T *qfl, int errornr, - int dir, int *new_qfidx) +static qfline_T *get_nth_valid_entry(qf_list_T *qfl, int errornr, int dir, int *new_qfidx) { qfline_T *qf_ptr = qfl->qf_ptr; int qf_idx = qfl->qf_index; @@ -2442,20 +2404,19 @@ static qfline_T *get_nth_entry(qf_list_T *qfl, int errornr, int *new_qfidx) /// specifies the direction (FORWARD/BACKWARD/FORWARD_FILE/BACKWARD_FILE). /// Returns a pointer to the entry and the index of the new entry is stored in /// 'new_qfidx'. -static qfline_T * qf_get_entry(qf_list_T *qfl, int errornr, - int dir, int *new_qfidx) +static qfline_T *qf_get_entry(qf_list_T *qfl, int errornr, int dir, int *new_qfidx) { - qfline_T *qf_ptr = qfl->qf_ptr; - int qfidx = qfl->qf_index; + qfline_T *qf_ptr = qfl->qf_ptr; + int qfidx = qfl->qf_index; - if (dir != 0) { // next/prev valid entry - qf_ptr = get_nth_valid_entry(qfl, errornr, dir, &qfidx); - } else if (errornr != 0) { // go to specified number - qf_ptr = get_nth_entry(qfl, errornr, &qfidx); - } + if (dir != 0) { // next/prev valid entry + qf_ptr = get_nth_valid_entry(qfl, errornr, dir, &qfidx); + } else if (errornr != 0) { // go to specified number + qf_ptr = get_nth_entry(qfl, errornr, &qfidx); + } - *new_qfidx = qfidx; - return qf_ptr; + *new_qfidx = qfidx; + return qf_ptr; } // Find a window displaying a Vim help file. @@ -2596,8 +2557,7 @@ static int qf_open_new_file_win(qf_info_T *ll_ref) // to the window just above the location list window. This is used for opening // a file from a location window and not from a quickfix window. If some usable // window is previously found, then it is supplied in 'use_win'. -static void qf_goto_win_with_ll_file(win_T *use_win, int qf_fnum, - qf_info_T *ll_ref) +static void qf_goto_win_with_ll_file(win_T *use_win, int qf_fnum, qf_info_T *ll_ref) { win_T *win = use_win; @@ -2684,8 +2644,7 @@ static void qf_goto_win_with_qfl_file(int qf_fnum) // window, jump to it. Otherwise open a new window to display the file. If // 'newwin' is true, then always open a new window. This is called from either // a quickfix or a location list window. -static int qf_jump_to_usable_window(int qf_fnum, bool newwin, - int *opened_window) +static int qf_jump_to_usable_window(int qf_fnum, bool newwin, int *opened_window) { win_T *usable_wp = NULL; bool usable_win = false; @@ -2735,8 +2694,8 @@ static int qf_jump_to_usable_window(int qf_fnum, bool newwin, } /// Edit the selected file or help file. -static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, - win_T *oldwin, int *opened_window) +static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, win_T *oldwin, + int *opened_window) { qf_list_T *qfl = qf_get_curlist(qi); long old_changetick = qfl->qf_changedtick; @@ -2789,8 +2748,7 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, /// Go to the error line in the current file using either line/column number or /// a search pattern. -static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char_u qf_viscol, - char_u *qf_pattern) +static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char_u qf_viscol, char_u *qf_pattern) { linenr_T i; @@ -2826,8 +2784,8 @@ static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char_u qf_viscol, } /// Display quickfix list index and size message -static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, - buf_T *old_curbuf, linenr_T old_lnum) +static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, buf_T *old_curbuf, + linenr_T old_lnum) { // Update the screen before showing the message, unless the screen // scrolled up. @@ -2862,15 +2820,14 @@ static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, /// Returns OK if successfully jumped or opened a window. Returns FAIL if not /// able to jump/open a window. Returns NOTDONE if a file is not associated /// with the entry. -static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, - int *opened_window) +static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, int *opened_window) { qf_list_T *qfl = qf_get_curlist(qi); long old_changetick = qfl->qf_changedtick; int old_qf_curlist = qi->qf_curlist; qfltype_T qfl_type = qfl->qfl_type; - // For ":helpgrep" find a help window or open one. + // For ":helpgrep" find a help window or open one. if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) { if (jump_to_help_window(qi, newwin, opened_window) == FAIL) { return FAIL; @@ -2921,9 +2878,8 @@ static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, /// Returns OK on success and FAIL on failing to open the file/buffer. Returns /// NOTDONE if the quickfix/location list is freed by an autocmd when opening /// the file. -static int qf_jump_to_buffer(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, - int forceit, win_T *oldwin, int *opened_window, - int openfold, int print_message) +static int qf_jump_to_buffer(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, int forceit, + win_T *oldwin, int *opened_window, int openfold, int print_message) { buf_T *old_curbuf; linenr_T old_lnum; @@ -2975,8 +2931,7 @@ void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit) // else if "errornr" is zero, redisplay the same line // If 'forceit' is true, then can discard changes to the current buffer. // If 'newwin' is true, then open the file in a new window. -static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, - bool newwin) +static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, bool newwin) { qf_list_T *qfl; qfline_T *qf_ptr; @@ -2991,8 +2946,9 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, const bool old_KeyTyped = KeyTyped; // getting file may reset it int retval = OK; - if (qi == NULL) + if (qi == NULL) { qi = &ql_info; + } if (qf_stack_empty(qi) || qf_list_empty(qf_get_curlist(qi))) { EMSG(_(e_quickfix)); @@ -3042,8 +2998,8 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, win_close(curwin, true); // Close opened window } if (qf_ptr != NULL && qf_ptr->qf_fnum != 0) { - // Couldn't open file, so put index back where it was. This could - // happen if the file was readonly and we changed something. + // Couldn't open file, so put index back where it was. This could + // happen if the file was readonly and we changed something. failed: qf_ptr = old_qf_ptr; qf_index = old_qf_index; @@ -3158,9 +3114,9 @@ void qf_list(exarg_T *eap) int i; int idx1 = 1; int idx2 = -1; - char_u *arg = eap->arg; - int all = eap->forceit; // if not :cl!, only show - // recognised errors + char_u *arg = eap->arg; + int all = eap->forceit; // if not :cl!, only show + // recognised errors qf_info_T *qi; if ((qi = qf_cmd_get_stack(eap, true)) == NULL) { @@ -3203,15 +3159,15 @@ void qf_list(exarg_T *eap) // that this depends on syntax items defined in the qf.vim syntax file qfFileAttr = syn_name2attr((char_u *)"qfFileName"); if (qfFileAttr == 0) { - qfFileAttr = HL_ATTR(HLF_D); + qfFileAttr = HL_ATTR(HLF_D); } qfSepAttr = syn_name2attr((char_u *)"qfSeparator"); if (qfSepAttr == 0) { - qfSepAttr = HL_ATTR(HLF_D); + qfSepAttr = HL_ATTR(HLF_D); } qfLineAttr = syn_name2attr((char_u *)"qfLineNr"); if (qfLineAttr == 0) { - qfLineAttr = HL_ATTR(HLF_N); + qfLineAttr = HL_ATTR(HLF_N); } if (qfl->qf_nonevalid) { @@ -3227,8 +3183,7 @@ void qf_list(exarg_T *eap) // Remove newlines and leading whitespace from an error message. // Put the result in "buf[bufsize]". -static void qf_fmt_text(const char_u *restrict text, char_u *restrict buf, - int bufsize) +static void qf_fmt_text(const char_u *restrict text, char_u *restrict buf, int bufsize) FUNC_ATTR_NONNULL_ALL { int i; @@ -3237,11 +3192,14 @@ static void qf_fmt_text(const char_u *restrict text, char_u *restrict buf, for (i = 0; *p != NUL && i < bufsize - 1; ++i) { if (*p == '\n') { buf[i] = ' '; - while (*++p != NUL) - if (!ascii_iswhite(*p) && *p != '\n') + while (*++p != NUL) { + if (!ascii_iswhite(*p) && *p != '\n') { break; - } else + } + } + } else { buf[i] = *p++; + } } buf[i] = NUL; } @@ -3290,8 +3248,8 @@ static void qf_msg(qf_info_T *qi, int which, char *lead) size_t len = STRLEN(buf); if (len < 34) { - memset(buf + len, ' ', 34 - len); - buf[34] = NUL; + memset(buf + len, ' ', 34 - len); + buf[34] = NUL; } xstrlcat((char *)buf, title, IOSIZE); } @@ -3374,8 +3332,8 @@ void qf_history(exarg_T *eap) /// associated with the list like context and title are not freed. static void qf_free_items(qf_list_T *qfl) { - qfline_T *qfp; - qfline_T *qfpnext; + qfline_T *qfp; + qfline_T *qfpnext; bool stop = false; while (qfl->qf_count && qfl->qf_start != NULL) { @@ -3430,13 +3388,12 @@ static void qf_free(qf_list_T *qfl) } // qf_mark_adjust: adjust marks -bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, - long amount_after) +bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after) { int i; - qfline_T *qfp; + qfline_T *qfp; int idx; - qf_info_T *qi = &ql_info; + qf_info_T *qi = &ql_info; bool found_one = false; int buf_has_flag = wp == NULL ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY; @@ -3457,12 +3414,14 @@ bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, if (qfp->qf_fnum == curbuf->b_fnum) { found_one = true; if (qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2) { - if (amount == MAXLNUM) + if (amount == MAXLNUM) { qfp->qf_cleared = TRUE; - else + } else { qfp->qf_lnum += amount; - } else if (amount_after && qfp->qf_lnum > line2) + } + } else if (amount_after && qfp->qf_lnum > line2) { qfp->qf_lnum += amount_after; + } } } } @@ -3490,7 +3449,7 @@ static char_u *qf_types(int c, int nr) { static char_u buf[20]; static char_u cc[3]; - char_u *p; + char_u *p; if (c == 'W' || c == 'w') { p = (char_u *)" warning"; @@ -3509,8 +3468,9 @@ static char_u *qf_types(int c, int nr) p = cc; } - if (nr <= 0) + if (nr <= 0) { return p; + } sprintf((char *)buf, "%s %3d", (char *)p, nr); return buf; @@ -3520,7 +3480,7 @@ static char_u *qf_types(int c, int nr) // When "split" is true: Open the entry/result under the cursor in a new window. void qf_view_result(bool split) { - qf_info_T *qi = &ql_info; + qf_info_T *qi = &ql_info; if (!bt_quickfix(curbuf)) { return; @@ -3549,9 +3509,9 @@ void qf_view_result(bool split) // close it if not. void ex_cwindow(exarg_T *eap) { - qf_info_T *qi; - qf_list_T *qfl; - win_T *win; + qf_info_T *qi; + qf_list_T *qfl; + win_T *win; if ((qi = qf_cmd_get_stack(eap, true)) == NULL) { return; @@ -3596,8 +3556,7 @@ void ex_cclose(exarg_T *eap) // Goto a quickfix or location list window (if present). // Returns OK if the window is found, FAIL otherwise. -static int qf_goto_cwindow(const qf_info_T *qi, bool resize, int sz, - bool vertsplit) +static int qf_goto_cwindow(const qf_info_T *qi, bool resize, int sz, bool vertsplit) { win_T *const win = qf_find_win(qi); if (win == NULL) { @@ -3725,8 +3684,8 @@ static void qf_set_title_var(qf_list_T *qfl) /// ":lopen": open a window that shows the location list. void ex_copen(exarg_T *eap) { - qf_info_T *qi; - qf_list_T *qfl; + qf_info_T *qi; + qf_list_T *qfl; int height; int status = FAIL; int lnum; @@ -3812,7 +3771,7 @@ void ex_cbottom(exarg_T *eap) // window). linenr_T qf_current_entry(win_T *wp) { - qf_info_T *qi = &ql_info; + qf_info_T *qi = &ql_info; if (IS_LL_WINDOW(wp)) { // In the location list window, use the referenced location list @@ -3822,14 +3781,13 @@ linenr_T qf_current_entry(win_T *wp) return qf_get_curlist(qi)->qf_index; } -// Update the cursor position in the quickfix window to the current error. -// Return TRUE if there is a quickfix window. -static int qf_win_pos_update( - qf_info_T *qi, - int old_qf_index // previous qf_index or zero -) +/// Update the cursor position in the quickfix window to the current error. +/// Return TRUE if there is a quickfix window. +/// +/// @param old_qf_index previous qf_index or zero +static int qf_win_pos_update(qf_info_T *qi, int old_qf_index) { - win_T *win; + win_T *win; int qf_index = qf_get_curlist(qi)->qf_index; // Put the cursor on the current error in the quickfix window, so that @@ -3954,8 +3912,8 @@ static void qf_update_win_titlevar(qf_info_T *qi) // Find the quickfix buffer. If it exists, update the contents. static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last) { - buf_T *buf; - win_T *win; + buf_T *buf; + win_T *win; aco_save_T aco; // Check if a buffer for the quickfix list exists. Update it. @@ -4002,9 +3960,8 @@ static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last) } // Add an error line to the quickfix buffer. -static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, - const qfline_T *qfp, char_u *dirname, - char_u *qftf_str, bool first_bufline) +static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfline_T *qfp, + char_u *dirname, char_u *qftf_str, bool first_bufline) FUNC_ATTR_NONNULL_ARG(1, 2, 4, 5) { int len; @@ -4076,10 +4033,7 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, // Call the 'quickfixtextfunc' function to get the list of lines to display in // the quickfix window for the entries 'start_idx' to 'end_idx'. -static list_T *call_qftf_func(qf_list_T *qfl, - int qf_winid, - long start_idx, - long end_idx) +static list_T *call_qftf_func(qf_list_T *qfl, int qf_winid, long start_idx, long end_idx) { Callback *cb = &qftf_cb; list_T *qftf_list = NULL; @@ -4126,12 +4080,11 @@ static list_T *call_qftf_func(qf_list_T *qfl, /// If "old_last" is not NULL append the items after this one. /// When "old_last" is NULL then "buf" must equal "curbuf"! Because ml_delete() /// is used and autocommands will be triggered. -static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, - int qf_winid) +static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int qf_winid) FUNC_ATTR_NONNULL_ARG(2) { linenr_T lnum; - qfline_T *qfp; + qfline_T *qfp; const bool old_KeyTyped = KeyTyped; list_T *qftf_list = NULL; listitem_T *qftf_li = NULL; @@ -4150,11 +4103,11 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, // Check if there is anything to display if (qfl != NULL) { - char_u dirname[MAXPATHL]; - int prev_bufnr = -1; - bool invalid_val = false; + char_u dirname[MAXPATHL]; + int prev_bufnr = -1; + bool invalid_val = false; - *dirname = NUL; + *dirname = NUL; // Add one line for each error if (old_last == NULL) { @@ -4235,7 +4188,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, static void qf_list_changed(qf_list_T *qfl) { - qfl->qf_changedtick++; + qfl->qf_changedtick++; } /// Return the quickfix/location list number with the given identifier. @@ -4291,7 +4244,7 @@ int grep_internal(cmdidx_T cmdidx) || cmdidx == CMD_grepadd || cmdidx == CMD_lgrepadd) && STRCMP("internal", - *curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) == 0; + *curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) == 0; } // Return the make/grep autocmd name. @@ -4299,20 +4252,20 @@ static char_u *make_get_auname(cmdidx_T cmdidx) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { switch (cmdidx) { - case CMD_make: - return (char_u *)"make"; - case CMD_lmake: - return (char_u *)"lmake"; - case CMD_grep: - return (char_u *)"grep"; - case CMD_lgrep: - return (char_u *)"lgrep"; - case CMD_grepadd: - return (char_u *)"grepadd"; - case CMD_lgrepadd: - return (char_u *)"lgrepadd"; - default: - return NULL; + case CMD_make: + return (char_u *)"make"; + case CMD_lmake: + return (char_u *)"lmake"; + case CMD_grep: + return (char_u *)"grep"; + case CMD_lgrep: + return (char_u *)"lgrep"; + case CMD_grepadd: + return (char_u *)"grepadd"; + case CMD_lgrepadd: + return (char_u *)"lgrepadd"; + default: + return NULL; } } @@ -4349,9 +4302,9 @@ static char *make_get_fullcmd(const char_u *makecmd, const char_u *fname) // Used for ":make", ":lmake", ":grep", ":lgrep", ":grepadd", and ":lgrepadd" void ex_make(exarg_T *eap) { - char_u *fname; - win_T *wp = NULL; - qf_info_T *qi = &ql_info; + char_u *fname; + win_T *wp = NULL; + qf_info_T *qi = &ql_info; int res; char_u *enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc; @@ -4375,8 +4328,9 @@ void ex_make(exarg_T *eap) autowrite_all(); fname = get_mef_name(); - if (fname == NULL) + if (fname == NULL) { return; + } os_remove((char *)fname); // in case it's not unique char *const cmd = make_get_fullcmd(eap->arg, fname); @@ -4422,24 +4376,28 @@ cleanup: // Returns NULL for error. static char_u *get_mef_name(void) { - char_u *p; - char_u *name; + char_u *p; + char_u *name; static int start = -1; static int off = 0; if (*p_mef == NUL) { name = vim_tempname(); - if (name == NULL) + if (name == NULL) { EMSG(_(e_notmp)); + } return name; } - for (p = p_mef; *p; ++p) - if (p[0] == '#' && p[1] == '#') + for (p = p_mef; *p; ++p) { + if (p[0] == '#' && p[1] == '#') { break; + } + } - if (*p == NUL) + if (*p == NUL) { return vim_strsave(p_mef); + } // Keep trying until the name doesn't exist yet. for (;; ) { @@ -4613,7 +4571,7 @@ static size_t qf_get_nth_valid_entry(qf_list_T *qfl, size_t n, int fdo) /// ":cdo", ":ldo", ":cfdo" and ":lfdo". void ex_cc(exarg_T *eap) { - qf_info_T *qi; + qf_info_T *qi; if ((qi = qf_cmd_get_stack(eap, true)) == NULL) { return; @@ -4624,19 +4582,19 @@ void ex_cc(exarg_T *eap) errornr = (int)eap->line2; } else { switch (eap->cmdidx) { - case CMD_cc: - case CMD_ll: - errornr = 0; - break; - case CMD_crewind: - case CMD_lrewind: - case CMD_cfirst: - case CMD_lfirst: - errornr = 1; - break; - default: - errornr = 32767; - break; + case CMD_cc: + case CMD_ll: + errornr = 0; + break; + case CMD_crewind: + case CMD_lrewind: + case CMD_cfirst: + case CMD_lfirst: + errornr = 1; + break; + default: + errornr = 32767; + break; } } @@ -4651,9 +4609,8 @@ void ex_cc(exarg_T *eap) } else { n = 1; } - size_t valid_entry = qf_get_nth_valid_entry( - qf_get_curlist(qi), n, - eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo); + size_t valid_entry = qf_get_nth_valid_entry(qf_get_curlist(qi), n, + eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo); assert(valid_entry <= INT_MAX); errornr = (int)valid_entry; } @@ -4666,7 +4623,7 @@ void ex_cc(exarg_T *eap) /// ":cdo", ":ldo", ":cfdo" and ":lfdo". void ex_cnext(exarg_T *eap) { - qf_info_T *qi; + qf_info_T *qi; if ((qi = qf_cmd_get_stack(eap, true)) == NULL) { return; @@ -4684,31 +4641,31 @@ void ex_cnext(exarg_T *eap) // Depending on the command jump to either next or previous entry/file. Direction dir; switch (eap->cmdidx) { - case CMD_cprevious: - case CMD_lprevious: - case CMD_cNext: - case CMD_lNext: - dir = BACKWARD; - break; - case CMD_cnfile: - case CMD_lnfile: - case CMD_cfdo: - case CMD_lfdo: - dir = FORWARD_FILE; - break; - case CMD_cpfile: - case CMD_lpfile: - case CMD_cNfile: - case CMD_lNfile: - dir = BACKWARD_FILE; - break; - case CMD_cnext: - case CMD_lnext: - case CMD_cdo: - case CMD_ldo: - default: - dir = FORWARD; - break; + case CMD_cprevious: + case CMD_lprevious: + case CMD_cNext: + case CMD_lNext: + dir = BACKWARD; + break; + case CMD_cnfile: + case CMD_lnfile: + case CMD_cfdo: + case CMD_lfdo: + dir = FORWARD_FILE; + break; + case CMD_cpfile: + case CMD_lpfile: + case CMD_cNfile: + case CMD_lNfile: + dir = BACKWARD_FILE; + break; + case CMD_cnext: + case CMD_lnext: + case CMD_cdo: + case CMD_ldo: + default: + dir = FORWARD; + break; } qf_jump(qi, dir, errornr, eap->forceit); @@ -4717,9 +4674,7 @@ void ex_cnext(exarg_T *eap) /// Find the first entry in the quickfix list 'qfl' from buffer 'bnr'. /// The index of the entry is stored in 'errornr'. /// Returns NULL if an entry is not found. -static qfline_T *qf_find_first_entry_in_buf(qf_list_T *qfl, - int bnr, - int *errornr) +static qfline_T *qf_find_first_entry_in_buf(qf_list_T *qfl, int bnr, int *errornr) { qfline_T *qfp = NULL; int idx = 0; @@ -4738,7 +4693,7 @@ static qfline_T *qf_find_first_entry_in_buf(qf_list_T *qfl, /// Find the first quickfix entry on the same line as 'entry'. Updates 'errornr' /// with the error number for the first entry. Assumes the entries are sorted in /// the quickfix list by line number. -static qfline_T * qf_find_first_entry_on_line(qfline_T *entry, int *errornr) +static qfline_T *qf_find_first_entry_on_line(qfline_T *entry, int *errornr) { while (!got_int && entry->qf_prev != NULL @@ -4754,7 +4709,7 @@ static qfline_T * qf_find_first_entry_on_line(qfline_T *entry, int *errornr) /// Find the last quickfix entry on the same line as 'entry'. Updates 'errornr' /// with the error number for the last entry. Assumes the entries are sorted in /// the quickfix list by line number. -static qfline_T * qf_find_last_entry_on_line(qfline_T *entry, int *errornr) +static qfline_T *qf_find_last_entry_on_line(qfline_T *entry, int *errornr) { while (!got_int && entry->qf_next != NULL @@ -4770,57 +4725,53 @@ static qfline_T * qf_find_last_entry_on_line(qfline_T *entry, int *errornr) // Returns true if the specified quickfix entry is // after the given line (linewise is true) // or after the line and column. -static bool qf_entry_after_pos(const qfline_T *qfp, const pos_T *pos, - bool linewise) +static bool qf_entry_after_pos(const qfline_T *qfp, const pos_T *pos, bool linewise) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { if (linewise) { return qfp->qf_lnum > pos->lnum; } return qfp->qf_lnum > pos->lnum - || (qfp->qf_lnum == pos->lnum && qfp->qf_col > pos->col); + || (qfp->qf_lnum == pos->lnum && qfp->qf_col > pos->col); } // Returns true if the specified quickfix entry is // before the given line (linewise is true) // or before the line and column. -static bool qf_entry_before_pos(const qfline_T *qfp, const pos_T *pos, - bool linewise) +static bool qf_entry_before_pos(const qfline_T *qfp, const pos_T *pos, bool linewise) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { if (linewise) { return qfp->qf_lnum < pos->lnum; } return qfp->qf_lnum < pos->lnum - || (qfp->qf_lnum == pos->lnum && qfp->qf_col < pos->col); + || (qfp->qf_lnum == pos->lnum && qfp->qf_col < pos->col); } // Returns true if the specified quickfix entry is // on or after the given line (linewise is true) // or on or after the line and column. -static bool qf_entry_on_or_after_pos(const qfline_T *qfp, const pos_T *pos, - bool linewise) +static bool qf_entry_on_or_after_pos(const qfline_T *qfp, const pos_T *pos, bool linewise) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { if (linewise) { return qfp->qf_lnum >= pos->lnum; } return qfp->qf_lnum > pos->lnum - || (qfp->qf_lnum == pos->lnum && qfp->qf_col >= pos->col); + || (qfp->qf_lnum == pos->lnum && qfp->qf_col >= pos->col); } // Returns true if the specified quickfix entry is // on or before the given line (linewise is true) // or on or before the line and column. -static bool qf_entry_on_or_before_pos(const qfline_T *qfp, const pos_T *pos, - bool linewise) +static bool qf_entry_on_or_before_pos(const qfline_T *qfp, const pos_T *pos, bool linewise) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { if (linewise) { return qfp->qf_lnum <= pos->lnum; } return qfp->qf_lnum < pos->lnum - || (qfp->qf_lnum == pos->lnum && qfp->qf_col <= pos->col); + || (qfp->qf_lnum == pos->lnum && qfp->qf_col <= pos->col); } /// Find the first quickfix entry after position 'pos' in buffer 'bnr'. @@ -4830,13 +4781,8 @@ static bool qf_entry_on_or_before_pos(const qfline_T *qfp, const pos_T *pos, /// 'qfp' points to the very first entry in the buffer and 'errornr' is the /// index of the very first entry in the quickfix list. /// Returns NULL if an entry is not found after 'pos'. -static qfline_T *qf_find_entry_after_pos( - int bnr, - const pos_T *pos, - bool linewise, - qfline_T *qfp, - int *errornr -) +static qfline_T *qf_find_entry_after_pos(int bnr, const pos_T *pos, bool linewise, qfline_T *qfp, + int *errornr) FUNC_ATTR_NONNULL_ALL { if (qf_entry_after_pos(qfp, pos, linewise)) { @@ -4871,13 +4817,8 @@ static qfline_T *qf_find_entry_after_pos( /// 'qfp' points to the very first entry in the buffer and 'errornr' is the /// index of the very first entry in the quickfix list. /// Returns NULL if an entry is not found before 'pos'. -static qfline_T *qf_find_entry_before_pos( - int bnr, - const pos_T *pos, - bool linewise, - qfline_T *qfp, - int *errornr -) +static qfline_T *qf_find_entry_before_pos(int bnr, const pos_T *pos, bool linewise, qfline_T *qfp, + int *errornr) FUNC_ATTR_NONNULL_ALL { // Find the entry just before the position 'pos' @@ -4902,14 +4843,8 @@ static qfline_T *qf_find_entry_before_pos( /// Find a quickfix entry in 'qfl' closest to position 'pos' in buffer 'bnr' in /// the direction 'dir'. -static qfline_T *qf_find_closest_entry( - qf_list_T *qfl, - int bnr, - const pos_T *pos, - Direction dir, - bool linewise, - int *errornr -) +static qfline_T *qf_find_closest_entry(qf_list_T *qfl, int bnr, const pos_T *pos, Direction dir, + bool linewise, int *errornr) FUNC_ATTR_NONNULL_ALL { qfline_T *qfp; @@ -4934,8 +4869,7 @@ static qfline_T *qf_find_closest_entry( /// Get the nth quickfix entry below the specified entry. Searches forward in /// the list. If linewise is true, then treat multiple entries on a single line /// as one. -static void qf_get_nth_below_entry(qfline_T *entry, linenr_T n, - bool linewise, int *errornr) +static void qf_get_nth_below_entry(qfline_T *entry, linenr_T n, bool linewise, int *errornr) FUNC_ATTR_NONNULL_ALL { while (n-- > 0 && !got_int) { @@ -4966,8 +4900,7 @@ static void qf_get_nth_below_entry(qfline_T *entry, linenr_T n, /// Get the nth quickfix entry above the specified entry. Searches backwards in /// the list. If linewise is TRUE, then treat multiple entries on a single line /// as one. -static void qf_get_nth_above_entry(qfline_T *entry, linenr_T n, - bool linewise, int *errornr) +static void qf_get_nth_above_entry(qfline_T *entry, linenr_T n, bool linewise, int *errornr) FUNC_ATTR_NONNULL_ALL { while (n-- > 0 && !got_int) { @@ -4988,14 +4921,8 @@ static void qf_get_nth_above_entry(qfline_T *entry, linenr_T n, /// Find the n'th quickfix entry adjacent to position 'pos' in buffer 'bnr' in /// the specified direction. Returns the error number in the quickfix list or 0 /// if an entry is not found. -static int qf_find_nth_adj_entry( - qf_list_T *qfl, - int bnr, - pos_T *pos, - linenr_T n, - Direction dir, - bool linewise -) +static int qf_find_nth_adj_entry(qf_list_T *qfl, int bnr, pos_T *pos, linenr_T n, Direction dir, + bool linewise) FUNC_ATTR_NONNULL_ALL { int errornr; @@ -5072,16 +4999,15 @@ void ex_cbelow(exarg_T *eap) // A quickfix entry column number is 1 based whereas cursor column // number is 0 based. Adjust the column number. pos.col++; - const int errornr = qf_find_nth_adj_entry( - qfl, - curbuf->b_fnum, - &pos, - eap->addr_count > 0 ? eap->line2 : 0, - dir, - eap->cmdidx == CMD_cbelow - || eap->cmdidx == CMD_lbelow - || eap->cmdidx == CMD_cabove - || eap->cmdidx == CMD_labove); + const int errornr = qf_find_nth_adj_entry(qfl, + curbuf->b_fnum, + &pos, + eap->addr_count > 0 ? eap->line2 : 0, + dir, + eap->cmdidx == CMD_cbelow + || eap->cmdidx == CMD_lbelow + || eap->cmdidx == CMD_cabove + || eap->cmdidx == CMD_labove); if (errornr > 0) { qf_jump(qi, 0, errornr, false); @@ -5092,16 +5018,23 @@ void ex_cbelow(exarg_T *eap) /// Return the autocmd name for the :cfile Ex commands -static char_u * cfile_get_auname(cmdidx_T cmdidx) +static char_u *cfile_get_auname(cmdidx_T cmdidx) { switch (cmdidx) { - case CMD_cfile: return (char_u *)"cfile"; - case CMD_cgetfile: return (char_u *)"cgetfile"; - case CMD_caddfile: return (char_u *)"caddfile"; - case CMD_lfile: return (char_u *)"lfile"; - case CMD_lgetfile: return (char_u *)"lgetfile"; - case CMD_laddfile: return (char_u *)"laddfile"; - default: return NULL; + case CMD_cfile: + return (char_u *)"cfile"; + case CMD_cgetfile: + return (char_u *)"cgetfile"; + case CMD_caddfile: + return (char_u *)"caddfile"; + case CMD_lfile: + return (char_u *)"lfile"; + case CMD_lgetfile: + return (char_u *)"lgetfile"; + case CMD_laddfile: + return (char_u *)"laddfile"; + default: + return NULL; } } @@ -5110,9 +5043,9 @@ static char_u * cfile_get_auname(cmdidx_T cmdidx) // ":lfile"/":lgetfile"/":laddfile" commands. void ex_cfile(exarg_T *eap) { - win_T *wp = NULL; - qf_info_T *qi = &ql_info; - char_u *au_name = NULL; + win_T *wp = NULL; + qf_info_T *qi = &ql_info; + char_u *au_name = NULL; au_name = cfile_get_auname(eap->cmdidx); if (au_name != NULL @@ -5173,15 +5106,24 @@ void ex_cfile(exarg_T *eap) static char_u *vgr_get_auname(cmdidx_T cmdidx) { switch (cmdidx) { - case CMD_vimgrep: return (char_u *)"vimgrep"; - case CMD_lvimgrep: return (char_u *)"lvimgrep"; - case CMD_vimgrepadd: return (char_u *)"vimgrepadd"; - case CMD_lvimgrepadd: return (char_u *)"lvimgrepadd"; - case CMD_grep: return (char_u *)"grep"; - case CMD_lgrep: return (char_u *)"lgrep"; - case CMD_grepadd: return (char_u *)"grepadd"; - case CMD_lgrepadd: return (char_u *)"lgrepadd"; - default: return NULL; + case CMD_vimgrep: + return (char_u *)"vimgrep"; + case CMD_lvimgrep: + return (char_u *)"lvimgrep"; + case CMD_vimgrepadd: + return (char_u *)"vimgrepadd"; + case CMD_lvimgrepadd: + return (char_u *)"lvimgrepadd"; + case CMD_grep: + return (char_u *)"grep"; + case CMD_lgrep: + return (char_u *)"lgrep"; + case CMD_grepadd: + return (char_u *)"grepadd"; + case CMD_lgrepadd: + return (char_u *)"lgrepadd"; + default: + return NULL; } } @@ -5226,8 +5168,7 @@ static void vgr_display_fname(char_u *fname) } /// Load a dummy buffer to search for a pattern using vimgrep. -static buf_T *vgr_load_dummy_buf(char_u *fname, char_u *dirname_start, - char_u *dirname_now) +static buf_T *vgr_load_dummy_buf(char_u *fname, char_u *dirname_start, char_u *dirname_now) { // Don't do Filetype autocommands to avoid loading syntax and // indent scripts, a great speed improvement. @@ -5249,8 +5190,7 @@ static buf_T *vgr_load_dummy_buf(char_u *fname, char_u *dirname_start, /// Check whether a quickfix/location list is valid. Autocmds may remove or /// change a quickfix list when vimgrep is running. If the list is not found, /// create a new list. -static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid, - char_u *title) +static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid, char_u *title) { // Verify that the quickfix/location list was not freed by an autocmd if (!qflist_valid(wp, qfid)) { @@ -5274,9 +5214,8 @@ static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid, /// Search for a pattern in all the lines in a buffer and add the matching lines /// to a quickfix list. -static bool vgr_match_buflines(qf_list_T *qfl, char_u *fname, buf_T *buf, - regmmatch_T *regmatch, long *tomatch, - int duplicate_name, int flags) +static bool vgr_match_buflines(qf_list_T *qfl, char_u *fname, buf_T *buf, regmmatch_T *regmatch, + long *tomatch, int duplicate_name, int flags) FUNC_ATTR_NONNULL_ARG(1, 3, 4, 5) { bool found_match = false; @@ -5373,27 +5312,27 @@ void ex_vimgrep(exarg_T *eap) { regmmatch_T regmatch; int fcount; - char_u **fnames; - char_u *fname; - char_u *s; - char_u *p; + char_u **fnames; + char_u *fname; + char_u *s; + char_u *p; int fi; - qf_list_T *qfl; + qf_list_T *qfl; win_T *wp = NULL; - buf_T *buf; + buf_T *buf; int duplicate_name = FALSE; int using_dummy; int redraw_for_dummy = FALSE; int found_match; - buf_T *first_match_buf = NULL; + buf_T *first_match_buf = NULL; time_t seconds = 0; aco_save_T aco; int flags = 0; long tomatch; - char_u *dirname_start = NULL; - char_u *dirname_now = NULL; - char_u *target_dir = NULL; - char_u *au_name = NULL; + char_u *dirname_start = NULL; + char_u *dirname_now = NULL; + char_u *target_dir = NULL; + char_u *au_name = NULL; au_name = vgr_get_auname(eap->cmdidx); if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, @@ -5405,10 +5344,11 @@ void ex_vimgrep(exarg_T *eap) qf_info_T *qi = qf_cmd_get_or_alloc_stack(eap, &wp); - if (eap->addr_count > 0) + if (eap->addr_count > 0) { tomatch = eap->line2; - else + } else { tomatch = MAXLNUM; + } // Get the search pattern: either white-separated or enclosed in // regmatch.regprog = NULL; @@ -5492,8 +5432,9 @@ void ex_vimgrep(exarg_T *eap) save_qfid = qf_get_curlist(qi)->qf_id; if (buf == NULL) { - if (!got_int) + if (!got_int) { smsg(_("Cannot open file \"%s\""), fname); + } } else { // Try for a match in all lines of the buffer. // For ":1vimgrep" look for first match only. @@ -5502,8 +5443,9 @@ void ex_vimgrep(exarg_T *eap) duplicate_name, flags); if (using_dummy) { - if (found_match && first_match_buf == NULL) + if (found_match && first_match_buf == NULL) { first_match_buf = buf; + } if (duplicate_name) { // Never keep a dummy buffer if there is another buffer // with the same name. @@ -5585,8 +5527,9 @@ void ex_vimgrep(exarg_T *eap) vgr_jump_to_match(qi, eap->forceit, &redraw_for_dummy, first_match_buf, target_dir); } - } else + } else { EMSG2(_(e_nomatch2), s); + } decr_quickfix_busy(); @@ -5624,24 +5567,22 @@ static void restore_start_dir(char_u *dirname_start) xfree(dirname_now); } -// Load file "fname" into a dummy buffer and return the buffer pointer, -// placing the directory resulting from the buffer load into the -// "resulting_dir" pointer. "resulting_dir" must be allocated by the caller -// prior to calling this function. Restores directory to "dirname_start" prior -// to returning, if autocmds or the 'autochdir' option have changed it. -// -// If creating the dummy buffer does not fail, must call unload_dummy_buffer() -// or wipe_dummy_buffer() later! -// -// Returns NULL if it fails. -static buf_T * -load_dummy_buffer ( - char_u *fname, - char_u *dirname_start, // in: old directory - char_u *resulting_dir // out: new directory -) -{ - buf_T *newbuf; +/// Load file "fname" into a dummy buffer and return the buffer pointer, +/// placing the directory resulting from the buffer load into the +/// "resulting_dir" pointer. "resulting_dir" must be allocated by the caller +/// prior to calling this function. Restores directory to "dirname_start" prior +/// to returning, if autocmds or the 'autochdir' option have changed it. +/// +/// If creating the dummy buffer does not fail, must call unload_dummy_buffer() +/// or wipe_dummy_buffer() later! +/// +/// @param dirname_start in: old directory +/// @param resulting_dir out: new directory +/// +/// @return NULL if it fails. +static buf_T *load_dummy_buffer(char_u *fname, char_u *dirname_start, char_u *resulting_dir) +{ + buf_T *newbuf; bufref_T newbufref; bufref_T newbuf_to_wipe; int failed = true; @@ -5807,17 +5748,14 @@ static int get_qfline_items(qfline_T *qfp, list_T *list) || (tv_dict_add_nr(dict, S_LEN("vcol"), (varnumber_T)qfp->qf_viscol) == FAIL) || (tv_dict_add_nr(dict, S_LEN("nr"), (varnumber_T)qfp->qf_nr) == FAIL) - || (tv_dict_add_str( - dict, S_LEN("module"), - (qfp->qf_module == NULL ? "" : (const char *)qfp->qf_module)) + || (tv_dict_add_str(dict, S_LEN("module"), + (qfp->qf_module == NULL ? "" : (const char *)qfp->qf_module)) == FAIL) - || (tv_dict_add_str( - dict, S_LEN("pattern"), - (qfp->qf_pattern == NULL ? "" : (const char *)qfp->qf_pattern)) + || (tv_dict_add_str(dict, S_LEN("pattern"), + (qfp->qf_pattern == NULL ? "" : (const char *)qfp->qf_pattern)) == FAIL) - || (tv_dict_add_str( - dict, S_LEN("text"), - (qfp->qf_text == NULL ? "" : (const char *)qfp->qf_text)) + || (tv_dict_add_str(dict, S_LEN("text"), + (qfp->qf_text == NULL ? "" : (const char *)qfp->qf_text)) == FAIL) || (tv_dict_add_str(dict, S_LEN("type"), (const char *)buf) == FAIL) || (tv_dict_add_nr(dict, S_LEN("valid"), (varnumber_T)qfp->qf_valid) @@ -5834,12 +5772,11 @@ static int get_qfline_items(qfline_T *qfp, list_T *list) /// If qf_idx is -1, use the current list. Otherwise, use the specified list. /// If eidx is not 0, then return only the specified entry. Otherwise return /// all the entries. -int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, int eidx, - list_T *list) +int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, int eidx, list_T *list) { qf_info_T *qi = qi_arg; qf_list_T *qfl; - qfline_T *qfp; + qfline_T *qfp; int i; if (qi == NULL) { @@ -5875,7 +5812,7 @@ int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, int eidx, return get_qfline_items(qfp, list); } } else if (get_qfline_items(qfp, list) == FAIL) { - return FAIL; + return FAIL; } } @@ -6051,10 +5988,7 @@ static int qf_getprop_qfidx(qf_info_T *qi, dict_T *what) } /// Return default values for quickfix list properties in retdict. -static int qf_getprop_defaults(qf_info_T *qi, - int flags, - int locstack, - dict_T *retdict) +static int qf_getprop_defaults(qf_info_T *qi, int flags, int locstack, dict_T *retdict) { int status = OK; @@ -6099,15 +6033,14 @@ static int qf_getprop_defaults(qf_info_T *qi, /// Return the quickfix list title as 'title' in retdict static int qf_getprop_title(qf_list_T *qfl, dict_T *retdict) { - return tv_dict_add_str(retdict, S_LEN("title"), - (const char *)qfl->qf_title); + return tv_dict_add_str(retdict, S_LEN("title"), + (const char *)qfl->qf_title); } // Returns the identifier of the window used to display files from a location // list. If there is no associated window, then returns 0. Useful only when // called from a location list window. -static int qf_getprop_filewinid(const win_T *wp, const qf_info_T *qi, - dict_T *retdict) +static int qf_getprop_filewinid(const win_T *wp, const qf_info_T *qi, dict_T *retdict) FUNC_ATTR_NONNULL_ARG(3) { handle_T winid = 0; @@ -6124,8 +6057,7 @@ static int qf_getprop_filewinid(const win_T *wp, const qf_info_T *qi, /// Return the quickfix list items/entries as 'items' in retdict. /// If eidx is not 0, then return the item at the specified index. -static int qf_getprop_items(qf_info_T *qi, int qf_idx, int eidx, - dict_T *retdict) +static int qf_getprop_items(qf_info_T *qi, int qf_idx, int eidx, dict_T *retdict) { list_T *l = tv_list_alloc(kListLenMayKnow); get_errorlist(qi, NULL, qf_idx, eidx, l); @@ -6284,11 +6216,8 @@ static int qf_setprop_qftf(qf_list_T *qfl, dictitem_T *di) /// Add a new quickfix entry to list at 'qf_idx' in the stack 'qi' from the /// items in the dict 'd'. If it is a valid error entry, then set 'valid_entry' /// to true. -static int qf_add_entry_from_dict( - qf_list_T *qfl, - const dict_T *d, - bool first_entry, - bool *valid_entry) +static int qf_add_entry_from_dict(qf_list_T *qfl, const dict_T *d, bool first_entry, + bool *valid_entry) FUNC_ATTR_NONNULL_ALL { static bool did_bufnr_emsg; @@ -6364,8 +6293,7 @@ static int qf_add_entry_from_dict( /// Add list of entries to quickfix/location list. Each list entry is /// a dictionary with item information. -static int qf_add_entries(qf_info_T *qi, int qf_idx, list_T *list, - char_u *title, int action) +static int qf_add_entries(qf_info_T *qi, int qf_idx, list_T *list, char_u *title, int action) { qf_list_T *qfl = qf_get_list(qi, qf_idx); qfline_T *old_last = NULL; @@ -6428,11 +6356,7 @@ static int qf_add_entries(qf_info_T *qi, int qf_idx, list_T *list, } /// Get the quickfix list index from 'nr' or 'id' -static int qf_setprop_get_qfidx( - const qf_info_T *qi, - const dict_T *what, - int action, - bool *newlist) +static int qf_setprop_get_qfidx(const qf_info_T *qi, const dict_T *what, int action, bool *newlist) FUNC_ATTR_NONNULL_ALL { dictitem_T *di; @@ -6483,8 +6407,7 @@ static int qf_setprop_get_qfidx( } // Set the quickfix list title. -static int qf_setprop_title(qf_info_T *qi, int qf_idx, const dict_T *what, - const dictitem_T *di) +static int qf_setprop_title(qf_info_T *qi, int qf_idx, const dict_T *what, const dictitem_T *di) FUNC_ATTR_NONNULL_ALL { qf_list_T *qfl = qf_get_list(qi, qf_idx); @@ -6502,8 +6425,7 @@ static int qf_setprop_title(qf_info_T *qi, int qf_idx, const dict_T *what, } // Set quickfix list items/entries. -static int qf_setprop_items(qf_info_T *qi, int qf_idx, dictitem_T *di, - int action) +static int qf_setprop_items(qf_info_T *qi, int qf_idx, dictitem_T *di, int action) FUNC_ATTR_NONNULL_ALL { if (di->di_tv.v_type != VAR_LIST) { @@ -6520,17 +6442,13 @@ static int qf_setprop_items(qf_info_T *qi, int qf_idx, dictitem_T *di, } // Set quickfix list items/entries from a list of lines. -static int qf_setprop_items_from_lines( - qf_info_T *qi, - int qf_idx, - const dict_T *what, - dictitem_T *di, - int action) +static int qf_setprop_items_from_lines(qf_info_T *qi, int qf_idx, const dict_T *what, + dictitem_T *di, int action) FUNC_ATTR_NONNULL_ALL { char_u *errorformat = p_efm; dictitem_T *efm_di; - int retval = FAIL; + int retval = FAIL; // Use the user supplied errorformat settings (if present) if ((efm_di = tv_dict_find(what, S_LEN("efm"))) != NULL) { @@ -6570,11 +6488,10 @@ static int qf_setprop_context(qf_list_T *qfl, dictitem_T *di) } // Set the current index in the specified quickfix list -static int qf_setprop_curidx(qf_info_T *qi, qf_list_T *qfl, - const dictitem_T *di) +static int qf_setprop_curidx(qf_info_T *qi, qf_list_T *qfl, const dictitem_T *di) FUNC_ATTR_NONNULL_ALL { - int newidx; + int newidx; // If the specified index is '$', then use the last entry if (di->di_tv.v_type == VAR_STRING @@ -6615,13 +6532,12 @@ static int qf_setprop_curidx(qf_info_T *qi, qf_list_T *qfl, /// Set quickfix/location list properties (title, items, context). /// Also used to add items from parsing a list of lines. /// Used by the setqflist() and setloclist() Vim script functions. -static int qf_set_properties(qf_info_T *qi, const dict_T *what, int action, - char_u *title) +static int qf_set_properties(qf_info_T *qi, const dict_T *what, int action, char_u *title) FUNC_ATTR_NONNULL_ALL { qf_list_T *qfl; dictitem_T *di; - int retval = FAIL; + int retval = FAIL; bool newlist = action == ' ' || qf_stack_empty(qi); int qf_idx = qf_setprop_get_qfidx(qi, what, action, &newlist); if (qf_idx == INVALID_QFIDX) { // List not found @@ -6727,8 +6643,7 @@ static void qf_free_stack(win_T *wp, qf_info_T *qi) // of dictionaries. "title" will be copied to w:quickfix_title // "action" is 'a' for add, 'r' for replace. Otherwise create a new list. // When "what" is not NULL then only set some properties. -int set_errorlist(win_T *wp, list_T *list, int action, char_u *title, - dict_T *what) +int set_errorlist(win_T *wp, list_T *list, int action, char_u *title, dict_T *what) { qf_info_T *qi = &ql_info; int retval = OK; @@ -6813,32 +6728,37 @@ bool set_ref_in_quickfix(int copyID) } /// Return the autocmd name for the :cbuffer Ex commands -static char_u * cbuffer_get_auname(cmdidx_T cmdidx) +static char_u *cbuffer_get_auname(cmdidx_T cmdidx) { switch (cmdidx) { - case CMD_cbuffer: return (char_u *)"cbuffer"; - case CMD_cgetbuffer: return (char_u *)"cgetbuffer"; - case CMD_caddbuffer: return (char_u *)"caddbuffer"; - case CMD_lbuffer: return (char_u *)"lbuffer"; - case CMD_lgetbuffer: return (char_u *)"lgetbuffer"; - case CMD_laddbuffer: return (char_u *)"laddbuffer"; - default: return NULL; + case CMD_cbuffer: + return (char_u *)"cbuffer"; + case CMD_cgetbuffer: + return (char_u *)"cgetbuffer"; + case CMD_caddbuffer: + return (char_u *)"caddbuffer"; + case CMD_lbuffer: + return (char_u *)"lbuffer"; + case CMD_lgetbuffer: + return (char_u *)"lgetbuffer"; + case CMD_laddbuffer: + return (char_u *)"laddbuffer"; + default: + return NULL; } } /// Process and validate the arguments passed to the :cbuffer, :caddbuffer, /// :cgetbuffer, :lbuffer, :laddbuffer, :lgetbuffer Ex commands. -static int cbuffer_process_args(exarg_T *eap, - buf_T **bufp, - linenr_T *line1, - linenr_T *line2) +static int cbuffer_process_args(exarg_T *eap, buf_T **bufp, linenr_T *line1, linenr_T *line2) { buf_T *buf = NULL; - if (*eap->arg == NUL) + if (*eap->arg == NUL) { buf = curbuf; - else if (*skipwhite(skipdigits(eap->arg)) == NUL) + } else if (*skipwhite(skipdigits(eap->arg)) == NUL) { buf = buflist_findnr(atoi((char *)eap->arg)); + } if (buf == NULL) { EMSG(_(e_invarg)); @@ -6944,16 +6864,23 @@ void ex_cbuffer(exarg_T *eap) } /// Return the autocmd name for the :cexpr Ex commands. -static char_u * cexpr_get_auname(cmdidx_T cmdidx) +static char_u *cexpr_get_auname(cmdidx_T cmdidx) { switch (cmdidx) { - case CMD_cexpr: return (char_u *)"cexpr"; - case CMD_cgetexpr: return (char_u *)"cgetexpr"; - case CMD_caddexpr: return (char_u *)"caddexpr"; - case CMD_lexpr: return (char_u *)"lexpr"; - case CMD_lgetexpr: return (char_u *)"lgetexpr"; - case CMD_laddexpr: return (char_u *)"laddexpr"; - default: return NULL; + case CMD_cexpr: + return (char_u *)"cexpr"; + case CMD_cgetexpr: + return (char_u *)"cgetexpr"; + case CMD_caddexpr: + return (char_u *)"caddexpr"; + case CMD_lexpr: + return (char_u *)"lexpr"; + case CMD_lgetexpr: + return (char_u *)"lgetexpr"; + case CMD_laddexpr: + return (char_u *)"laddexpr"; + default: + return NULL; } } @@ -7047,10 +6974,7 @@ static qf_info_T *hgr_get_ll(bool *new_ll) } // Search for a pattern in a help file. -static void hgr_search_file( - qf_list_T *qfl, - char_u *fname, - regmatch_T *p_regmatch) +static void hgr_search_file(qf_list_T *qfl, char_u *fname, regmatch_T *p_regmatch) FUNC_ATTR_NONNULL_ARG(1, 3) { FILE *const fd = os_fopen((char *)fname, "r"); @@ -7105,11 +7029,8 @@ static void hgr_search_file( // Search for a pattern in all the help files in the doc directory under // the given directory. -static void hgr_search_files_in_dir( - qf_list_T *qfl, - char_u *dirname, - regmatch_T *p_regmatch, - const char_u *lang) +static void hgr_search_files_in_dir(qf_list_T *qfl, char_u *dirname, regmatch_T *p_regmatch, + const char_u *lang) FUNC_ATTR_NONNULL_ARG(1, 2, 3) { int fcount; @@ -7141,8 +7062,7 @@ static void hgr_search_files_in_dir( // and add the matches to a quickfix list. // 'lang' is the language specifier. If supplied, then only matches in the // specified language are found. -static void hgr_search_in_rtp(qf_list_T *qfl, regmatch_T *p_regmatch, - const char_u *lang) +static void hgr_search_in_rtp(qf_list_T *qfl, regmatch_T *p_regmatch, const char_u *lang) FUNC_ATTR_NONNULL_ARG(1, 2) { // Go through all directories in 'runtimepath' @@ -7162,9 +7082,12 @@ void ex_helpgrep(exarg_T *eap) char_u *au_name = NULL; switch (eap->cmdidx) { - case CMD_helpgrep: au_name = (char_u *)"helpgrep"; break; - case CMD_lhelpgrep: au_name = (char_u *)"lhelpgrep"; break; - default: break; + case CMD_helpgrep: + au_name = (char_u *)"helpgrep"; break; + case CMD_lhelpgrep: + au_name = (char_u *)"lhelpgrep"; break; + default: + break; } if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, curbuf->b_fname, true, curbuf)) { diff --git a/src/nvim/quickfix.h b/src/nvim/quickfix.h index fdeb8d1a2f..f5178e332a 100644 --- a/src/nvim/quickfix.h +++ b/src/nvim/quickfix.h @@ -1,10 +1,10 @@ #ifndef NVIM_QUICKFIX_H #define NVIM_QUICKFIX_H -#include "nvim/types.h" #include "nvim/ex_cmds_defs.h" +#include "nvim/types.h" -/* flags for skip_vimgrep_pat() */ +// flags for skip_vimgrep_pat() #define VGR_GLOBAL 1 #define VGR_NOJUMP 2 diff --git a/src/nvim/rbuffer.c b/src/nvim/rbuffer.c index df9394fbb2..4ac50095b3 100644 --- a/src/nvim/rbuffer.c +++ b/src/nvim/rbuffer.c @@ -6,8 +6,8 @@ #include <string.h> #include "nvim/memory.h" -#include "nvim/vim.h" #include "nvim/rbuffer.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "rbuffer.c.generated.h" @@ -144,7 +144,7 @@ void rbuffer_consumed(RBuffer *buf, size_t count) buf->read_ptr += count; if (buf->read_ptr >= buf->end_ptr) { - buf->read_ptr -= rbuffer_capacity(buf); + buf->read_ptr -= rbuffer_capacity(buf); } bool was_full = buf->size == rbuffer_capacity(buf); diff --git a/src/nvim/rbuffer.h b/src/nvim/rbuffer.h index a8dfcac580..cc690050ab 100644 --- a/src/nvim/rbuffer.h +++ b/src/nvim/rbuffer.h @@ -38,17 +38,17 @@ // create infinite loops #define RBUFFER_UNTIL_EMPTY(buf, rptr, rcnt) \ for (size_t rcnt = 0, _r = 1; _r; _r = 0) /* NOLINT(readability/braces) */ \ - for ( /* NOLINT(readability/braces) */ \ - char *rptr = rbuffer_read_ptr(buf, &rcnt); \ - buf->size; \ - rptr = rbuffer_read_ptr(buf, &rcnt)) + for ( /* NOLINT(readability/braces) */ \ + char *rptr = rbuffer_read_ptr(buf, &rcnt); \ + buf->size; \ + rptr = rbuffer_read_ptr(buf, &rcnt)) #define RBUFFER_UNTIL_FULL(buf, wptr, wcnt) \ for (size_t wcnt = 0, _r = 1; _r; _r = 0) /* NOLINT(readability/braces) */ \ - for ( /* NOLINT(readability/braces) */ \ - char *wptr = rbuffer_write_ptr(buf, &wcnt); \ - rbuffer_space(buf); \ - wptr = rbuffer_write_ptr(buf, &wcnt)) + for ( /* NOLINT(readability/braces) */ \ + char *wptr = rbuffer_write_ptr(buf, &wcnt); \ + rbuffer_space(buf); \ + wptr = rbuffer_write_ptr(buf, &wcnt)) // Iteration @@ -56,23 +56,23 @@ for (size_t i = 0; /* NOLINT(readability/braces) */ \ i < buf->size; \ i = buf->size) \ - for (char c = 0; /* NOLINT(readability/braces) */ \ - i < buf->size ? ((int)(c = *rbuffer_get(buf, i))) || 1 : 0; \ - i++) + for (char c = 0; /* NOLINT(readability/braces) */ \ + i < buf->size ? ((int)(c = *rbuffer_get(buf, i))) || 1 : 0; \ + i++) #define RBUFFER_EACH_REVERSE(buf, c, i) \ for (size_t i = buf->size; /* NOLINT(readability/braces) */ \ i != SIZE_MAX; \ i = SIZE_MAX) \ - for (char c = 0; /* NOLINT(readability/braces) */ \ - i-- > 0 ? ((int)(c = *rbuffer_get(buf, i))) || 1 : 0; \ - ) + for (char c = 0; /* NOLINT(readability/braces) */ \ + i-- > 0 ? ((int)(c = *rbuffer_get(buf, i))) || 1 : 0; \ + ) typedef struct rbuffer RBuffer; /// Type of function invoked during certain events: /// - When the RBuffer switches to the full state /// - When the RBuffer switches to the non-full state -typedef void(*rbuffer_callback)(RBuffer *buf, void *data); +typedef void (*rbuffer_callback)(RBuffer *buf, void *data); struct rbuffer { rbuffer_callback full_cb, nonfull_cb; diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 98a46cf781..24dc86e034 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -1,6 +1,8 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +// uncrustify:off + /* * Handling of regular expressions: vim_regcomp(), vim_regexec(), vim_regsub() * @@ -3003,8 +3005,8 @@ static void ungetchr(void) at_start = prev_at_start; prev_at_start = false; - /* Backup regparse, so that it's at the same position as before the - * getchr(). */ + // Backup regparse, so that it's at the same position as before the + // getchr(). regparse -= prevchr_len; } @@ -6412,8 +6414,8 @@ static int cstrncmp(char_u *s1, char_u *s2, int *n) int c1, c2, c11, c12; int junk; - /* we have to handle the strcmp ourselves, since it is necessary to - * deal with the composing characters by ignoring them: */ + // we have to handle the strcmp ourselves, since it is necessary to + // deal with the composing characters by ignoring them: str1 = s1; str2 = s2; c1 = c2 = 0; @@ -7184,8 +7186,8 @@ static regengine_T nfa_regengine = (char_u *)"" }; -/* Which regexp engine to use? Needed for vim_regcomp(). - * Must match with 'regexpengine'. */ +// Which regexp engine to use? Needed for vim_regcomp(). +// Must match with 'regexpengine'. static int regexp_engine = 0; #ifdef REGEXP_DEBUG diff --git a/src/nvim/regexp.h b/src/nvim/regexp.h index 74ed34188c..9527afed58 100644 --- a/src/nvim/regexp.h +++ b/src/nvim/regexp.h @@ -1,9 +1,9 @@ #ifndef NVIM_REGEXP_H #define NVIM_REGEXP_H -#include "nvim/types.h" #include "nvim/buffer_defs.h" #include "nvim/regexp_defs.h" +#include "nvim/types.h" // Second argument for vim_regcomp(). #define RE_MAGIC 1 ///< 'magic' option diff --git a/src/nvim/regexp_defs.h b/src/nvim/regexp_defs.h index a729a91555..1d112bd64a 100644 --- a/src/nvim/regexp_defs.h +++ b/src/nvim/regexp_defs.h @@ -15,8 +15,8 @@ #include <stdbool.h> #include "nvim/pos.h" -#include "nvim/types.h" #include "nvim/profile.h" +#include "nvim/types.h" /* * The number of sub-matches is limited to 10. @@ -53,7 +53,7 @@ typedef struct reg_extmatch reg_extmatch_T; /// always 0. /// When there is no match, the line number is -1. typedef struct { - regprog_T *regprog; + regprog_T *regprog; lpos_T startpos[NSUBEXP]; lpos_T endpos[NSUBEXP]; int rmm_ic; @@ -90,7 +90,7 @@ typedef struct { int regstart; char_u reganch; - char_u *regmust; + char_u *regmust; int regmlen; char_u reghasz; char_u program[1]; // actually longer.. @@ -101,8 +101,8 @@ typedef struct { typedef struct nfa_state nfa_state_T; struct nfa_state { int c; - nfa_state_T *out; - nfa_state_T *out1; + nfa_state_T *out; + nfa_state_T *out1; int id; int lastlist[2]; // 0: normal, 1: recursive int val; @@ -119,16 +119,16 @@ typedef struct { unsigned re_flags; bool re_in_use; - nfa_state_T *start; // points into state[] + nfa_state_T *start; // points into state[] int reganch; // pattern starts with ^ int regstart; // char at start of pattern - char_u *match_text; // plain text to match with + char_u *match_text; // plain text to match with int has_zend; // pattern contains \ze int has_backref; // pattern contains \1 .. \9 int reghasz; - char_u *pattern; + char_u *pattern; int nsubexp; // number of () int nstate; nfa_state_T state[1]; // actually longer.. @@ -140,10 +140,10 @@ typedef struct { * When there is no match, the pointer is NULL. */ typedef struct { - regprog_T *regprog; - char_u *startp[NSUBEXP]; - char_u *endp[NSUBEXP]; - bool rm_ic; + regprog_T *regprog; + char_u *startp[NSUBEXP]; + char_u *endp[NSUBEXP]; + bool rm_ic; } regmatch_T; /* @@ -153,16 +153,16 @@ typedef struct { */ struct reg_extmatch { int16_t refcnt; - char_u *matches[NSUBEXP]; + char_u *matches[NSUBEXP]; }; struct regengine { - regprog_T *(*regcomp)(char_u *, int); + regprog_T *(*regcomp)(char_u *, int); void (*regfree)(regprog_T *); int (*regexec_nl)(regmatch_T *, char_u *, colnr_T, bool); long (*regexec_multi)(regmmatch_T *, win_T *, buf_T *, linenr_T, colnr_T, proftime_T *, int *); - char_u *expr; + char_u *expr; }; #endif // NVIM_REGEXP_DEFS_H diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 039f9b4675..c8b7190b4a 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -1,6 +1,8 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +// uncrustify:off + /* * NFA regular expression implementation. * @@ -372,8 +374,8 @@ nfa_regcomp_start ( /* A reasonable estimation for maximum size */ nstate_max = (STRLEN(expr) + 1) * 25; - /* Some items blow up in size, such as [A-z]. Add more space for that. - * When it is still not enough realloc_post_list() will be used. */ + // Some items blow up in size, such as [A-z]. Add more space for that. + // When it is still not enough realloc_post_list() will be used. nstate_max += 1000; /* Size for postfix representation of expr. */ @@ -1424,8 +1426,8 @@ static int nfa_regatom(void) } break; - /* Catch \%^ and \%$ regardless of where they appear in the - * pattern -- regardless of whether or not it makes sense. */ + // Catch \%^ and \%$ regardless of where they appear in the + // pattern -- regardless of whether or not it makes sense. case '^': EMIT(NFA_BOF); break; @@ -1466,13 +1468,13 @@ static int nfa_regatom(void) EMIT(NFA_OPT_CHARS); EMIT(n); - /* Emit as "\%(\%[abc]\)" to be able to handle - * "\%[abc]*" which would cause the empty string to be - * matched an unlimited number of times. NFA_NOPEN is - * added only once at a position, while NFA_SPLIT is - * added multiple times. This is more efficient than - * not allowing NFA_SPLIT multiple times, it is used - * a lot. */ + // Emit as "\%(\%[abc]\)" to be able to handle + // "\%[abc]*" which would cause the empty string to be + // matched an unlimited number of times. NFA_NOPEN is + // added only once at a position, while NFA_SPLIT is + // added multiple times. This is more efficient than + // not allowing NFA_SPLIT multiple times, it is used + // a lot. EMIT(NFA_NOPEN); break; } @@ -1882,8 +1884,8 @@ static int nfa_regpiece(void) int my_post_start; int quest; - /* Save the current parse state, so that we can use it if <atom>{m,n} is - * next. */ + // Save the current parse state, so that we can use it if <atom>{m,n} is + // next. save_parse_state(&old_state); /* store current pos in the postfix form, for \{m,n} involving 0s */ @@ -1967,12 +1969,11 @@ static int nfa_regpiece(void) break; case Magic('{'): - /* a{2,5} will expand to 'aaa?a?a?' - * a{-1,3} will expand to 'aa??a??', where ?? is the nongreedy - * version of '?' - * \v(ab){2,3} will expand to '(ab)(ab)(ab)?', where all the - * parenthesis have the same id - */ + // a{2,5} will expand to 'aaa?a?a?' + // a{-1,3} will expand to 'aa??a??', where ?? is the nongreedy + // version of '?' + // \v(ab){2,3} will expand to '(ab)(ab)(ab)?', where all the + // parenthesis have the same id greedy = true; c2 = peekchr(); @@ -1983,8 +1984,8 @@ static int nfa_regpiece(void) if (!read_limits(&minval, &maxval)) EMSG_RET_FAIL(_("E870: (NFA regexp) Error reading repetition limits")); - /* <atom>{0,inf}, <atom>{0,} and <atom>{} are equivalent to - * <atom>* */ + // <atom>{0,inf}, <atom>{0,} and <atom>{} are equivalent to + // <atom>* if (minval == 0 && maxval == MAX_LIMIT) { if (greedy) /* \{}, \{0,} */ @@ -3327,10 +3328,10 @@ static nfa_state_T *post2nfa(int *postfix, int *end, int nfa_calc_size) break; } - /* Allow "NFA_MOPEN" as a valid postfix representation for - * the empty regexp "". In this case, the NFA will be - * NFA_MOPEN -> NFA_MCLOSE. Note that this also allows - * empty groups of parenthesis, and empty mbyte chars */ + // Allow "NFA_MOPEN" as a valid postfix representation for + // the empty regexp "". In this case, the NFA will be + // NFA_MOPEN -> NFA_MCLOSE. Note that this also allows + // empty groups of parenthesis, and empty mbyte chars if (stackp == stack) { s = alloc_state(mopen, NULL, NULL); if (s == NULL) @@ -3343,8 +3344,8 @@ static nfa_state_T *post2nfa(int *postfix, int *end, int nfa_calc_size) break; } - /* At least one node was emitted before NFA_MOPEN, so - * at least one node will be between NFA_MOPEN and NFA_MCLOSE */ + // At least one node was emitted before NFA_MOPEN, so + // at least one node will be between NFA_MOPEN and NFA_MCLOSE e = POP(); s = alloc_state(mopen, e.start, NULL); /* `(' */ if (s == NULL) @@ -3501,14 +3502,14 @@ static void nfa_postprocess(nfa_regprog_T *prog) int ch_invisible = failure_chance(prog->state[i].out, 0); int ch_follows = failure_chance(prog->state[i].out1->out, 0); - /* Postpone when the invisible match is expensive or has a - * lower chance of failing. */ + // Postpone when the invisible match is expensive or has a + // lower chance of failing. if (c == NFA_START_INVISIBLE_BEFORE || c == NFA_START_INVISIBLE_BEFORE_NEG) { - /* "before" matches are very expensive when - * unbounded, always prefer what follows then, - * unless what follows will always match. - * Otherwise strongly prefer what follows. */ + // "before" matches are very expensive when + // unbounded, always prefer what follows then, + // unless what follows will always match. + // Otherwise strongly prefer what follows. if (prog->state[i].val <= 0 && ch_follows > 0) { directly = false; } else { @@ -3527,9 +3528,9 @@ static void nfa_postprocess(nfa_regprog_T *prog) } } -/**************************************************************** -* NFA execution code. -****************************************************************/ +///////////////////////////////////////////////////////////////// +// NFA execution code. +///////////////////////////////////////////////////////////////// /* Values for done in nfa_pim_T. */ #define NFA_PIM_UNUSED 0 /* pim not used */ @@ -4195,8 +4196,8 @@ skip_add: save_ptr = NULL; memset(&save_multipos, 0, sizeof(save_multipos)); - /* Set the position (with "off" added) in the subexpression. Save - * and restore it when it was in use. Otherwise fill any gap. */ + // Set the position (with "off" added) in the subexpression. Save + // and restore it when it was in use. Otherwise fill any gap. if (REG_MULTI) { if (subidx < sub->in_use) { save_multipos = sub->list.multi[subidx]; @@ -4295,8 +4296,8 @@ skip_add: sub = &subs->norm; } - /* We don't fill in gaps here, there must have been an MOPEN that - * has done that. */ + // We don't fill in gaps here, there must have been an MOPEN that + // has done that. save_in_use = sub->in_use; if (sub->in_use <= subidx) sub->in_use = subidx + 1; diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index d4191cff6b..5ade6244f9 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -5,21 +5,26 @@ /// /// Management of runtime files (including packages) -#include "nvim/vim.h" +#include "nvim/api/private/helpers.h" #include "nvim/ascii.h" #include "nvim/charset.h" #include "nvim/eval.h" -#include "nvim/option.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds2.h" +#include "nvim/lua/executor.h" #include "nvim/misc1.h" +#include "nvim/option.h" #include "nvim/os/os.h" #include "nvim/runtime.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "runtime.c.generated.h" #endif +static bool runtime_search_path_valid = false; +static int *runtime_search_path_ref = NULL; +static RuntimeSearchPath runtime_search_path; /// ":runtime [what] {name}" void ex_runtime(exarg_T *eap) @@ -43,13 +48,13 @@ void ex_runtime(exarg_T *eap) arg = skipwhite(arg + len); } - source_runtime(arg, flags); + source_runtime((char *)arg, flags); } static void source_callback(char_u *fname, void *cookie) { - (void)do_source(fname, false, DOSO_NONE); + (void)do_source((char *)fname, false, DOSO_NONE); } /// Find the file "name" in all directories in "path" and invoke @@ -60,12 +65,11 @@ static void source_callback(char_u *fname, void *cookie) /// When "flags" has DIP_ERR: give an error message if there is no match. /// /// return FAIL when no file could be sourced, OK otherwise. -int do_in_path(char_u *path, char_u *name, int flags, - DoInRuntimepathCB callback, void *cookie) +int do_in_path(char_u *path, char *name, int flags, DoInRuntimepathCB callback, void *cookie) { - char_u *tail; + char_u *tail; int num_files; - char_u **files; + char_u **files; int i; bool did_one = false; @@ -76,8 +80,7 @@ int do_in_path(char_u *path, char_u *name, int flags, { if (p_verbose > 10 && name != NULL) { verbose_enter(); - smsg(_("Searching for \"%s\" in \"%s\""), - (char *)name, (char *)path); + smsg(_("Searching for \"%s\" in \"%s\""), name, (char *)path); verbose_leave(); } @@ -90,8 +93,7 @@ int do_in_path(char_u *path, char_u *name, int flags, // Skip after or non-after directories. if (flags & (DIP_NOAFTER | DIP_AFTER)) { - bool is_after = buflen >= 5 - && STRCMP(buf + buflen - 5, "after") == 0; + bool is_after = path_is_after(buf, buflen); if ((is_after && (flags & DIP_NOAFTER)) || (!is_after && (flags & DIP_AFTER))) { @@ -107,7 +109,7 @@ int do_in_path(char_u *path, char_u *name, int flags, tail = buf + STRLEN(buf); // Loop over all patterns in "name" - char_u *np = name; + char_u *np = (char_u *)name; while (*np != NUL && ((flags & DIP_ALL) || !did_one)) { // Append the pattern from "name" to buf[]. assert(MAXPATHL >= (tail - buf)); @@ -156,6 +158,188 @@ int do_in_path(char_u *path, char_u *name, int flags, return did_one ? OK : FAIL; } +RuntimeSearchPath runtime_search_path_get_cached(int *ref) + FUNC_ATTR_NONNULL_ALL +{ + runtime_search_path_validate(); + + *ref = 0; + if (runtime_search_path_ref == NULL) { + // cached path was unreferenced. keep a ref to + // prevent runtime_search_path() to freeing it too early + (*ref)++; + runtime_search_path_ref = ref; + } + return runtime_search_path; +} + +void runtime_search_path_unref(RuntimeSearchPath path, int *ref) + FUNC_ATTR_NONNULL_ALL +{ + if (*ref) { + if (runtime_search_path_ref == ref) { + runtime_search_path_ref = NULL; + } else { + runtime_search_path_free(path); + } + } +} + + +/// Find the file "name" in all directories in "path" and invoke +/// "callback(fname, cookie)". +/// "name" can contain wildcards. +/// When "flags" has DIP_ALL: source all files, otherwise only the first one. +/// When "flags" has DIP_DIR: find directories instead of files. +/// When "flags" has DIP_ERR: give an error message if there is no match. +/// +/// return FAIL when no file could be sourced, OK otherwise. +int do_in_cached_path(char_u *name, int flags, DoInRuntimepathCB callback, void *cookie) +{ + char_u *tail; + int num_files; + char_u **files; + int i; + bool did_one = false; + + char_u buf[MAXPATHL]; + + if (p_verbose > 10 && name != NULL) { + verbose_enter(); + smsg(_("Searching for \"%s\" in runtime path"), (char *)name); + verbose_leave(); + } + + int ref; + RuntimeSearchPath path = runtime_search_path_get_cached(&ref); + + // Loop over all entries in cached path + for (size_t j = 0; j < kv_size(path); j++) { + SearchPathItem item = kv_A(path, j); + size_t buflen = strlen(item.path); + + // Skip after or non-after directories. + if (flags & (DIP_NOAFTER | DIP_AFTER)) { + if ((item.after && (flags & DIP_NOAFTER)) + || (!item.after && (flags & DIP_AFTER))) { + continue; + } + } + + if (name == NULL) { + (*callback)((char_u *)item.path, cookie); + } else if (buflen + STRLEN(name) + 2 < MAXPATHL) { + STRCPY(buf, item.path); + add_pathsep((char *)buf); + tail = buf + STRLEN(buf); + + // Loop over all patterns in "name" + char_u *np = name; + while (*np != NUL && ((flags & DIP_ALL) || !did_one)) { + // Append the pattern from "name" to buf[]. + assert(MAXPATHL >= (tail - buf)); + copy_option_part(&np, tail, (size_t)(MAXPATHL - (tail - buf)), + "\t "); + + if (p_verbose > 10) { + verbose_enter(); + smsg(_("Searching for \"%s\""), buf); + verbose_leave(); + } + + int ew_flags = ((flags & DIP_DIR) ? EW_DIR : EW_FILE) + | (flags & DIP_DIRFILE) ? (EW_DIR|EW_FILE) : 0; + + // Expand wildcards, invoke the callback for each match. + char_u *(pat[]) = { buf }; + if (gen_expand_wildcards(1, pat, &num_files, &files, ew_flags) == OK) { + for (i = 0; i < num_files; i++) { + (*callback)(files[i], cookie); + did_one = true; + if (!(flags & DIP_ALL)) { + break; + } + } + FreeWild(num_files, files); + } + } + } + } + + if (!did_one && name != NULL) { + if (flags & DIP_ERR) { + EMSG3(_(e_dirnotf), "runtime path", name); + } else if (p_verbose > 0) { + verbose_enter(); + smsg(_("not found in runtime path: \"%s\""), name); + verbose_leave(); + } + } + + runtime_search_path_unref(path, &ref); + + return did_one ? OK : FAIL; +} + +Array runtime_inspect(void) +{ + RuntimeSearchPath path = runtime_search_path; + Array rv = ARRAY_DICT_INIT; + + for (size_t i = 0; i < kv_size(path); i++) { + SearchPathItem *item = &kv_A(path, i); + Array entry = ARRAY_DICT_INIT; + ADD(entry, STRING_OBJ(cstr_to_string(item->path))); + ADD(entry, BOOLEAN_OBJ(item->after)); + if (item->has_lua != kNone) { + ADD(entry, BOOLEAN_OBJ(item->has_lua == kTrue)); + } + ADD(rv, ARRAY_OBJ(entry)); + } + return rv; +} + +ArrayOf(String) runtime_get_named(bool lua, Array pat, bool all) +{ + int ref; + RuntimeSearchPath path = runtime_search_path_get_cached(&ref); + ArrayOf(String) rv = ARRAY_DICT_INIT; + static char buf[MAXPATHL]; + + for (size_t i = 0; i < kv_size(path); i++) { + SearchPathItem *item = &kv_A(path, i); + if (lua) { + if (item->has_lua == kNone) { + size_t size = (size_t)snprintf(buf, sizeof buf, "%s/lua/", item->path); + item->has_lua = (size < sizeof buf && os_isdir((char_u *)buf)) ? kTrue : kFalse; + } + if (item->has_lua == kFalse) { + continue; + } + } + + for (size_t j = 0; j < pat.size; j++) { + Object pat_item = pat.items[j]; + if (pat_item.type == kObjectTypeString) { + size_t size = (size_t)snprintf(buf, sizeof buf, "%s/%s", + item->path, pat_item.data.string.data); + if (size < sizeof buf) { + if (os_file_is_readable(buf)) { + ADD(rv, STRING_OBJ(cstr_to_string(buf))); + if (!all) { + goto done; + } + } + } + } + } + } + +done: + runtime_search_path_unref(path, &ref); + return rv; +} + /// Find "name" in "path". When found, invoke the callback function for /// it: callback(fname, "cookie") /// When "flags" has DIP_ALL repeat for all matches, otherwise only the first @@ -164,29 +348,22 @@ int do_in_path(char_u *path, char_u *name, int flags, /// If "name" is NULL calls callback for each entry in "path". Cookie is /// passed by reference in this case, setting it to NULL indicates that callback /// has done its job. -int do_in_path_and_pp(char_u *path, char_u *name, int flags, - DoInRuntimepathCB callback, void *cookie) +int do_in_path_and_pp(char_u *path, char_u *name, int flags, DoInRuntimepathCB callback, + void *cookie) { int done = FAIL; - if (!(flags & (DIP_NOAFTER | DIP_AFTER))) { - done = do_in_path_and_pp(path, name, flags | DIP_NOAFTER, callback, cookie); - if (done == OK && !(flags & DIP_ALL)) { - return done; - } - flags |= DIP_AFTER; - } if ((flags & DIP_NORTP) == 0) { - done |= do_in_path(path, (name && !*name) ? NULL : name, flags, callback, cookie); + done |= do_in_path(path, (char *)((name && !*name) ? NULL : name), flags, callback, cookie); } if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_START)) { char *start_dir = "pack/*/start/*/%s%s"; // NOLINT size_t len = STRLEN(start_dir) + STRLEN(name) + 6; - char_u *s = xmallocz(len); // TODO(bfredl): get rid of random allocations + char *s = xmallocz(len); // TODO(bfredl): get rid of random allocations char *suffix = (flags & DIP_AFTER) ? "after/" : ""; - vim_snprintf((char *)s, len, start_dir, suffix, name); + vim_snprintf(s, len, start_dir, suffix, name); done |= do_in_path(p_pp, s, flags & ~DIP_AFTER, callback, cookie); xfree(s); @@ -196,7 +373,7 @@ int do_in_path_and_pp(char_u *path, char_u *name, int flags, len = STRLEN(start_dir) + STRLEN(name) + 6; s = xmallocz(len); - vim_snprintf((char *)s, len, start_dir, suffix, name); + vim_snprintf(s, len, start_dir, suffix, name); done |= do_in_path(p_pp, s, flags & ~DIP_AFTER, callback, cookie); xfree(s); @@ -206,9 +383,9 @@ int do_in_path_and_pp(char_u *path, char_u *name, int flags, if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_OPT)) { char *opt_dir = "pack/*/opt/*/%s"; // NOLINT size_t len = STRLEN(opt_dir) + STRLEN(name); - char_u *s = xmallocz(len); + char *s = xmallocz(len); - vim_snprintf((char *)s, len, opt_dir, name); + vim_snprintf(s, len, opt_dir, name); done |= do_in_path(p_pp, s, flags, callback, cookie); xfree(s); @@ -218,7 +395,7 @@ int do_in_path_and_pp(char_u *path, char_u *name, int flags, len = STRLEN(opt_dir) + STRLEN(name); s = xmallocz(len); - vim_snprintf((char *)s, len, opt_dir, name); + vim_snprintf(s, len, opt_dir, name); done |= do_in_path(p_pp, s, flags, callback, cookie); xfree(s); @@ -228,10 +405,189 @@ int do_in_path_and_pp(char_u *path, char_u *name, int flags, return done; } +static void push_path(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used, char *entry, + bool after) +{ + handle_T h = map_get(String, handle_T)(rtp_used, cstr_as_string(entry)); + if (h == 0) { + char *allocated = xstrdup(entry); + map_put(String, handle_T)(rtp_used, cstr_as_string(allocated), 1); + kv_push(*search_path, ((SearchPathItem){ allocated, after, kNone })); + } +} + +static void expand_rtp_entry(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used, + char *entry, bool after) +{ + if (map_get(String, handle_T)(rtp_used, cstr_as_string(entry))) { + return; + } + + if (!*entry) { + push_path(search_path, rtp_used, entry, after); + } + + int num_files; + char_u **files; + char_u *(pat[]) = { (char_u *)entry }; + if (gen_expand_wildcards(1, pat, &num_files, &files, EW_DIR) == OK) { + for (int i = 0; i < num_files; i++) { + push_path(search_path, rtp_used, (char *)files[i], after); + } + FreeWild(num_files, files); + } +} + +static void expand_pack_entry(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used, + CharVec *after_path, char_u *pack_entry) +{ + static char buf[MAXPATHL]; + char *(start_pat[]) = { "/pack/*/start/*", "/start/*" }; // NOLINT + for (int i = 0; i < 2; i++) { + if (STRLEN(pack_entry) + STRLEN(start_pat[i]) + 1 > MAXPATHL) { + continue; + } + STRLCPY(buf, pack_entry, MAXPATHL); + xstrlcat(buf, start_pat[i], sizeof buf); + expand_rtp_entry(search_path, rtp_used, buf, false); + size_t after_size = STRLEN(buf)+7; + char *after = xmallocz(after_size); + xstrlcpy(after, buf, after_size); + xstrlcat(after, "/after", after_size); + kv_push(*after_path, after); + } +} + +static bool path_is_after(char_u *buf, size_t buflen) +{ + // NOTE: we only consider dirs exactly matching "after" to be an AFTER dir. + // vim8 considers all dirs like "foo/bar_after", "Xafter" etc, as an + // "after" dir in SOME codepaths not not in ALL codepaths. + return buflen >= 5 + && (!(buflen >= 6) || vim_ispathsep(buf[buflen-6])) + && STRCMP(buf + buflen - 5, "after") == 0; +} + +RuntimeSearchPath runtime_search_path_build(void) +{ + kvec_t(String) pack_entries = KV_INITIAL_VALUE; + // TODO(bfredl): these should just be sets, when Set(String) is do merge to + // master. + Map(String, handle_T) pack_used = MAP_INIT; + Map(String, handle_T) rtp_used = MAP_INIT; + RuntimeSearchPath search_path = KV_INITIAL_VALUE; + CharVec after_path = KV_INITIAL_VALUE; + + static char_u buf[MAXPATHL]; + for (char *entry = (char *)p_pp; *entry != NUL; ) { + char *cur_entry = entry; + copy_option_part((char_u **)&entry, buf, MAXPATHL, ","); + + String the_entry = { .data = cur_entry, .size = STRLEN(buf) }; + + kv_push(pack_entries, the_entry); + map_put(String, handle_T)(&pack_used, the_entry, 0); + } + + + char *rtp_entry; + for (rtp_entry = (char *)p_rtp; *rtp_entry != NUL; ) { + char *cur_entry = rtp_entry; + copy_option_part((char_u **)&rtp_entry, buf, MAXPATHL, ","); + size_t buflen = STRLEN(buf); + + if (path_is_after(buf, buflen)) { + rtp_entry = cur_entry; + break; + } + + // fact: &rtp entries can contain wild chars + expand_rtp_entry(&search_path, &rtp_used, (char *)buf, false); + + handle_T *h = map_ref(String, handle_T)(&pack_used, cstr_as_string((char *)buf), false); + if (h) { + (*h)++; + expand_pack_entry(&search_path, &rtp_used, &after_path, buf); + } + } + + for (size_t i = 0; i < kv_size(pack_entries); i++) { + handle_T h = map_get(String, handle_T)(&pack_used, kv_A(pack_entries, i)); + if (h == 0) { + expand_pack_entry(&search_path, &rtp_used, &after_path, (char_u *)kv_A(pack_entries, i).data); + } + } + + // "after" packages + for (size_t i = 0; i < kv_size(after_path); i++) { + expand_rtp_entry(&search_path, &rtp_used, kv_A(after_path, i), true); + xfree(kv_A(after_path, i)); + } + + // "after" dirs in rtp + for (; *rtp_entry != NUL;) { + copy_option_part((char_u **)&rtp_entry, buf, MAXPATHL, ","); + expand_rtp_entry(&search_path, &rtp_used, (char *)buf, path_is_after(buf, STRLEN(buf))); + } + + // strings are not owned + kv_destroy(pack_entries); + kv_destroy(after_path); + map_destroy(String, handle_T)(&pack_used); + map_destroy(String, handle_T)(&rtp_used); + + return search_path; +} + +void runtime_search_path_invalidate(void) +{ + runtime_search_path_valid = false; +} + +void runtime_search_path_free(RuntimeSearchPath path) +{ + for (size_t j = 0; j < kv_size(path); j++) { + SearchPathItem item = kv_A(path, j); + xfree(item.path); + } + kv_destroy(path); +} + +void runtime_search_path_validate(void) +{ + if (!nlua_is_deferred_safe()) { + // Cannot rebuild search path in an async context. As a plugin will invoke + // itself asynchronously from sync code in the same plugin, the sought + // after lua/autoload module will most likely already be in the cached path. + // Thus prefer using the stale cache over erroring out in this situation. + return; + } + if (!runtime_search_path_valid) { + if (!runtime_search_path_ref) { + runtime_search_path_free(runtime_search_path); + } + runtime_search_path = runtime_search_path_build(); + runtime_search_path_valid = true; + runtime_search_path_ref = NULL; // initially unowned + } +} + + + /// Just like do_in_path_and_pp(), using 'runtimepath' for "path". int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback, void *cookie) { - return do_in_path_and_pp(p_rtp, name, flags | DIP_START, callback, cookie); + int success = FAIL; + if (!(flags & DIP_NORTP)) { + success |= do_in_cached_path((name && !*name) ? NULL : name, flags, callback, cookie); + flags = (flags & ~DIP_START) | DIP_NORTP; + } + // TODO(bfredl): we could integrate disabled OPT dirs into the cached path + // which would effectivize ":packadd myoptpack" as well + if ((flags & (DIP_START|DIP_OPT)) && (success == FAIL || (flags & DIP_ALL))) { + success |= do_in_path_and_pp(p_rtp, name, flags, callback, cookie); + } + return success; } /// Source the file "name" from all directories in 'runtimepath'. @@ -239,10 +595,9 @@ int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback, void /// When "flags" has DIP_ALL: source all files, otherwise only the first one. /// /// return FAIL when no file could be sourced, OK otherwise. -int source_runtime(char_u *name, int flags) +int source_runtime(char *name, int flags) { - flags |= (flags & DIP_NORTP) ? 0 : DIP_START; - return source_in_path(p_rtp, name, flags); + return do_in_runtimepath((char_u *)name, flags, source_callback, NULL); } /// Just like source_runtime(), but use "path" instead of 'runtimepath'. @@ -260,14 +615,17 @@ static void source_all_matches(char_u *pat) if (gen_expand_wildcards(1, &pat, &num_files, &files, EW_FILE) == OK) { for (int i = 0; i < num_files; i++) { - (void)do_source(files[i], false, DOSO_NONE); + (void)do_source((char *)files[i], false, DOSO_NONE); } FreeWild(num_files, files); } } /// Add the package directory to 'runtimepath' -static int add_pack_dir_to_rtp(char_u *fname) +/// +/// @param fname the package path +/// @param is_pack whether the added dir is a "pack/*/start/*/" style package +static int add_pack_dir_to_rtp(char_u *fname, bool is_pack) { char_u *p4, *p3, *p2, *p1, *p; char_u *buf = NULL; @@ -345,7 +703,7 @@ static int add_pack_dir_to_rtp(char_u *fname) // check if rtp/pack/name/start/name/after exists afterdir = concat_fnames((char *)fname, "after", true); size_t afterlen = 0; - if (os_isdir((char_u *)afterdir)) { + if (is_pack ? pack_has_entries((char_u *)afterdir) : os_isdir((char_u *)afterdir)) { afterlen = strlen(afterdir) + 1; // add one for comma } @@ -466,7 +824,7 @@ static void add_pack_plugin(bool opt, char_u *fname, void *cookie) xfree(buf); if (!found) { // directory is not yet in 'runtimepath', add it - if (add_pack_dir_to_rtp(fname) == FAIL) { + if (add_pack_dir_to_rtp(fname, false) == FAIL) { return; } } @@ -487,13 +845,48 @@ static void add_opt_pack_plugin(char_u *fname, void *cookie) add_pack_plugin(true, fname, cookie); } + +/// Add all packages in the "start" directory to 'runtimepath'. +void add_pack_start_dirs(void) +{ + do_in_path(p_pp, NULL, DIP_ALL + DIP_DIR, add_pack_start_dir, NULL); +} + +static bool pack_has_entries(char_u *buf) +{ + int num_files; + char_u **files; + char_u *(pat[]) = { buf }; + if (gen_expand_wildcards(1, pat, &num_files, &files, EW_DIR) == OK) { + FreeWild(num_files, files); + } + return num_files > 0; +} + +static void add_pack_start_dir(char_u *fname, void *cookie) +{ + static char_u buf[MAXPATHL]; + char *(start_pat[]) = { "/start/*", "/pack/*/start/*" }; // NOLINT + for (int i = 0; i < 2; i++) { + if (STRLEN(fname) + STRLEN(start_pat[i]) + 1 > MAXPATHL) { + continue; + } + STRLCPY(buf, fname, MAXPATHL); + xstrlcat((char *)buf, start_pat[i], sizeof buf); + if (pack_has_entries(buf)) { + add_pack_dir_to_rtp(buf, true); + } + } +} + + /// Load plugins from all packages in the "start" directory. void load_start_packages(void) { did_source_packages = true; - do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT + do_in_path(p_pp, "pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT add_start_pack_plugin, &APP_LOAD); - do_in_path(p_pp, (char_u *)"start/*", DIP_ALL + DIP_DIR, // NOLINT + do_in_path(p_pp, "start/*", DIP_ALL + DIP_DIR, // NOLINT add_start_pack_plugin, &APP_LOAD); } @@ -505,10 +898,43 @@ void ex_packloadall(exarg_T *eap) // First do a round to add all directories to 'runtimepath', then load // the plugins. This allows for plugins to use an autoload directory // of another plugin. + add_pack_start_dirs(); load_start_packages(); } } +/// Read all the plugin files at startup +void load_plugins(void) +{ + if (p_lpl) { + char_u *rtp_copy = p_rtp; + char_u *const plugin_pattern_vim = (char_u *)"plugin/**/*.vim"; // NOLINT + char_u *const plugin_pattern_lua = (char_u *)"plugin/**/*.lua"; // NOLINT + + if (!did_source_packages) { + rtp_copy = vim_strsave(p_rtp); + add_pack_start_dirs(); + } + + // don't use source_runtime() yet so we can check for :packloadall below + source_in_path(rtp_copy, plugin_pattern_vim, DIP_ALL | DIP_NOAFTER); + source_in_path(rtp_copy, plugin_pattern_lua, DIP_ALL | DIP_NOAFTER); + TIME_MSG("loading rtp plugins"); + + // Only source "start" packages if not done already with a :packloadall + // command. + if (!did_source_packages) { + xfree(rtp_copy); + load_start_packages(); + } + TIME_MSG("loading packages"); + + source_runtime((char *)plugin_pattern_vim, DIP_ALL | DIP_AFTER); + source_runtime((char *)plugin_pattern_lua, DIP_ALL | DIP_AFTER); + TIME_MSG("loading after plugins"); + } +} + /// ":packadd[!] {name}" void ex_packadd(exarg_T *eap) { @@ -527,9 +953,7 @@ void ex_packadd(exarg_T *eap) vim_snprintf(pat, len, plugpat, round == 1 ? "start" : "opt", eap->arg); // The first round don't give a "not found" error, in the second round // only when nothing was found in the first round. - res = do_in_path(p_pp, (char_u *)pat, - DIP_ALL + DIP_DIR - + (round == 2 && res == FAIL ? DIP_ERR : 0), + res = do_in_path(p_pp, pat, DIP_ALL + DIP_DIR + (round == 2 && res == FAIL ? DIP_ERR : 0), round == 1 ? add_start_pack_plugin : add_opt_pack_plugin, eap->forceit ? &APP_ADD_DIR : &APP_BOTH); xfree(pat); @@ -564,8 +988,7 @@ static char *strcpy_comma_escaped(char *dest, const char *src, const size_t len) /// (common_suf is present after each new item, single_suf is present /// after half of the new items) and with commas after each item, commas /// inside the values are escaped. -static inline size_t compute_double_env_sep_len(const char *const val, - const size_t common_suf_len, +static inline size_t compute_double_env_sep_len(const char *const val, const size_t common_suf_len, const size_t single_suf_len) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE { @@ -608,9 +1031,8 @@ static inline size_t compute_double_env_sep_len(const char *const val, /// Otherwise in reverse. /// /// @return (dest + appended_characters_length) -static inline char *add_env_sep_dirs(char *dest, const char *const val, - const char *const suf1, const size_t len1, - const char *const suf2, const size_t len2, +static inline char *add_env_sep_dirs(char *dest, const char *const val, const char *const suf1, + const size_t len1, const char *const suf2, const size_t len2, const bool forward) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1) { @@ -669,9 +1091,8 @@ static inline char *add_env_sep_dirs(char *dest, const char *const val, /// Otherwise in reverse. /// /// @return (dest + appended_characters_length) -static inline char *add_dir(char *dest, const char *const dir, - const size_t dir_len, const XDGVarType type, - const char *const suf1, const size_t len1, +static inline char *add_dir(char *dest, const char *const dir, const size_t dir_len, + const XDGVarType type, const char *const suf1, const size_t len1, const char *const suf2, const size_t len2) FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT { diff --git a/src/nvim/runtime.h b/src/nvim/runtime.h index b40c2b670e..4337a0b3cd 100644 --- a/src/nvim/runtime.h +++ b/src/nvim/runtime.h @@ -7,10 +7,31 @@ typedef void (*DoInRuntimepathCB)(char_u *, void *); +typedef struct { + char *path; + bool after; + TriState has_lua; +} SearchPathItem; + +typedef kvec_t(SearchPathItem) RuntimeSearchPath; +typedef kvec_t(char *) CharVec; + // last argument for do_source() #define DOSO_NONE 0 #define DOSO_VIMRC 1 // loading vimrc file +// Used for flags in do_in_path() +#define DIP_ALL 0x01 // all matches, not just the first one +#define DIP_DIR 0x02 // find directories instead of files +#define DIP_ERR 0x04 // give an error message when none found +#define DIP_START 0x08 // also use "start" directory in 'packpath' +#define DIP_OPT 0x10 // also use "opt" directory in 'packpath' +#define DIP_NORTP 0x20 // do not use 'runtimepath' +#define DIP_NOAFTER 0x40 // skip "after" directories +#define DIP_AFTER 0x80 // only use "after" directories +#define DIP_LUA 0x100 // also use ".lua" files +#define DIP_DIRFILE 0x200 // find both files and directories + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "runtime.h.generated.h" diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 79e960fe8b..32eb28e761 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -166,7 +166,7 @@ static bool resizing = false; #endif #define SEARCH_HL_PRIORITY 0 -static char * provider_err = NULL; +static char *provider_err = NULL; static bool provider_invoke(NS ns_id, const char *name, LuaRef ref, Array args, bool default_true) { @@ -1003,8 +1003,7 @@ static void win_update(win_T *wp, Providers *providers) i = plines_m_win(wp, wp->w_topline, wp->w_lines[0].wl_lnum - 1); // insert extra lines for previously invisible filler lines if (wp->w_lines[0].wl_lnum != wp->w_topline) { - i += diff_check_fill(wp, wp->w_lines[0].wl_lnum) - - wp->w_old_topfill; + i += win_get_fill(wp, wp->w_lines[0].wl_lnum) - wp->w_old_topfill; } if (i != 0 && i < wp->w_grid.Rows - 2) { // less than a screen off // Try to insert the correct number of lines. @@ -1067,7 +1066,7 @@ static void win_update(win_T *wp, Providers *providers) if (wp->w_lines[0].wl_lnum == wp->w_topline) { row += wp->w_old_topfill; } else { - row += diff_check_fill(wp, wp->w_topline); + row += win_get_fill(wp, wp->w_topline); } // ... but don't delete new filler lines. row -= wp->w_topfill; @@ -1101,12 +1100,12 @@ static void win_update(win_T *wp, Providers *providers) break; } } - /* Correct the first entry for filler lines at the top - * when it won't get updated below. */ - if (wp->w_p_diff && bot_start > 0) { - wp->w_lines[0].wl_size = - plines_win_nofill(wp, wp->w_topline, true) - + wp->w_topfill; + + // Correct the first entry for filler lines at the top + // when it won't get updated below. + if (win_may_fill(wp) && bot_start > 0) { + wp->w_lines[0].wl_size = (plines_win_nofill(wp, wp->w_topline, true) + + wp->w_topfill); } } } @@ -1564,7 +1563,7 @@ static void win_update(win_T *wp, Providers *providers) && lnum > wp->w_topline && !(dy_flags & (DY_LASTLINE | DY_TRUNCATE)) && srow + wp->w_lines[idx].wl_size > wp->w_grid.Rows - && diff_check_fill(wp, lnum) == 0) { + && win_get_fill(wp, lnum) == 0) { // This line is not going to fit. Don't draw anything here, // will draw "@ " lines below. row = wp->w_grid.Rows + 1; @@ -1664,7 +1663,7 @@ static void win_update(win_T *wp, Providers *providers) * Don't overwrite it, it can be edited. */ wp->w_botline = lnum + 1; - } else if (diff_check_fill(wp, lnum) >= wp->w_grid.Rows - srow) { + } else if (win_get_fill(wp, lnum) >= wp->w_grid.Rows - srow) { // Window ends in filler lines. wp->w_botline = lnum; wp->w_filler_rows = wp->w_grid.Rows - srow; @@ -1691,7 +1690,7 @@ static void win_update(win_T *wp, Providers *providers) } else { if (eof) { // we hit the end of the file wp->w_botline = buf->b_ml.ml_line_count + 1; - j = diff_check_fill(wp, wp->w_botline); + j = win_get_fill(wp, wp->w_botline); if (j > 0 && !wp->w_botfill) { // Display filler text below last line. win_line() will check // for ml_line_count+1 and only draw filler lines @@ -1866,7 +1865,7 @@ static int compute_foldcolumn(win_T *wp, int col) /// Put a single char from an UTF-8 buffer into a line buffer. /// /// Handles composing chars and arabic shaping state. -static int line_putchar(LineState *s, schar_T *dest, int maxcells, bool rl) +static int line_putchar(buf_T *buf, LineState *s, schar_T *dest, int maxcells, bool rl, int vcol) { const char_u *p = (char_u *)s->p; int cells = utf_ptr2cells(p); @@ -1876,7 +1875,13 @@ static int line_putchar(LineState *s, schar_T *dest, int maxcells, bool rl) return -1; } u8c = utfc_ptr2char(p, u8cc); - if (*p < 0x80 && u8cc[0] == 0) { + if (*p == TAB) { + cells = MIN(tabstop_padding(vcol, buf->b_p_ts, buf->b_p_vts_array), maxcells); + for (int c = 0; c < cells; c++) { + schar_from_ascii(dest[c], ' '); + } + goto done; + } else if (*p < 0x80 && u8cc[0] == 0) { schar_from_ascii(dest[0], *p); s->prev_c = u8c; } else { @@ -1909,6 +1914,7 @@ static int line_putchar(LineState *s, schar_T *dest, int maxcells, bool rl) if (cells > 1) { dest[1][0] = 0; } +done: s->p += c_len; return cells; } @@ -2055,7 +2061,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc bool draw_color_col = false; // highlight colorcolumn int *color_cols = NULL; // pointer to according columns array bool has_spell = false; // this buffer has spell checking -# define SPWORDLEN 150 +#define SPWORDLEN 150 char_u nextline[SPWORDLEN * 2]; // text with start of the next line int nextlinecol = 0; // column where nextline[] starts int nextline_idx = 0; /* index in nextline[] where next line @@ -2118,12 +2124,12 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc // draw_state: items that are drawn in sequence: #define WL_START 0 // nothing done yet -# define WL_CMDLINE WL_START + 1 // cmdline window column -# define WL_FOLD WL_CMDLINE + 1 // 'foldcolumn' -# define WL_SIGN WL_FOLD + 1 // column for signs +#define WL_CMDLINE WL_START + 1 // cmdline window column +#define WL_FOLD WL_CMDLINE + 1 // 'foldcolumn' +#define WL_SIGN WL_FOLD + 1 // column for signs #define WL_NR WL_SIGN + 1 // line number -# define WL_BRI WL_NR + 1 // 'breakindent' -# define WL_SBR WL_BRI + 1 // 'showbreak' or 'diff' +#define WL_BRI WL_NR + 1 // 'breakindent' +#define WL_SBR WL_BRI + 1 // 'showbreak' or 'diff' #define WL_LINE WL_SBR + 1 // text in the line int draw_state = WL_START; // what to draw next @@ -2138,8 +2144,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc int did_wcol = false; int match_conc = 0; ///< cchar for match functions int old_boguscols = 0; -# define VCOL_HLC (vcol - vcol_off) -# define FIX_FOR_BOGUSCOLS \ +#define VCOL_HLC (vcol - vcol_off) +#define FIX_FOR_BOGUSCOLS \ { \ n_extra += vcol_off; \ vcol -= vcol_off; \ @@ -2202,7 +2208,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc if (provider_err) { Decoration err_decor = DECORATION_INIT; - int hl_err = syn_check_group((char_u *)S_LEN("ErrorMsg")); + int hl_err = syn_check_group(S_LEN("ErrorMsg")); kv_push(err_decor.virt_text, ((VirtTextChunk){ .text = provider_err, .hl_id = hl_err })); @@ -2366,8 +2372,11 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc filler_lines = 0; area_highlighting = true; } + int virtual_lines = decor_virtual_lines(wp, lnum); + filler_lines += virtual_lines; if (lnum == wp->w_topline) { filler_lines = wp->w_topfill; + virtual_lines = MIN(virtual_lines, filler_lines); } filler_todo = filler_lines; @@ -2409,7 +2418,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc // If this line has a sign with line highlighting set line_attr. // TODO(bfredl, vigoux): this should not take priority over decoration! - sign_attrs_T * sattr = sign_get_attr(SIGN_LINEHL, sattrs, 0, 1); + sign_attrs_T *sattr = sign_get_attr(SIGN_LINEHL, sattrs, 0, 1); if (sattr != NULL) { line_attr = sattr->sat_linehl; } @@ -2895,7 +2904,18 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc if (draw_state == WL_SBR - 1 && n_extra == 0) { draw_state = WL_SBR; - if (filler_todo > 0) { + if (filler_todo > filler_lines - virtual_lines) { + // TODO(bfredl): check this doesn't inhibit TUI-style + // clear-to-end-of-line. + c_extra = ' '; + c_final = NUL; + if (wp->w_p_rl) { + n_extra = col + 1; + } else { + n_extra = grid->Columns - col; + } + char_attr = 0; + } else if (filler_todo > 0) { // draw "deleted" diff line(s) if (char2cells(wp->w_p_fcs_chars.diff) > 1) { c_extra = '-'; @@ -3667,8 +3687,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc n_extra = tab_len; } else { char_u *p; - int i; - int saved_nextra = n_extra; + int i; + int saved_nextra = n_extra; if (vcol_off > 0) { // there are characters to conceal @@ -4402,7 +4422,19 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc && !wp->w_p_rl; // Not right-to-left. int draw_col = col - boguscols; - draw_virt_text(buf, win_col_offset, &draw_col, grid->Columns); + if (filler_todo > 0) { + int index = filler_todo - (filler_lines - virtual_lines); + if (index > 0) { + int fpos = kv_size(buf->b_virt_lines) - index; + assert(fpos >= 0); + int offset = buf->b_virt_line_leftcol ? 0 : win_col_offset; + draw_virt_text_item(buf, offset, kv_A(buf->b_virt_lines, fpos), + kHlModeReplace, grid->Columns, offset); + } + } else { + draw_virt_text(buf, win_col_offset, &draw_col, grid->Columns); + } + grid_put_linebuf(grid, row, 0, draw_col, grid->Columns, wp->w_p_rl, wp, wp->w_hl_attr_normal, wrap); if (wrap) { @@ -4485,67 +4517,80 @@ void draw_virt_text(buf_T *buf, int col_off, int *end_col, int max_col) bool do_eol = state->eol_col > -1; for (size_t i = 0; i < kv_size(state->active); i++) { DecorRange *item = &kv_A(state->active, i); - if (item->start_row == state->row && kv_size(item->decor.virt_text)) { - if (item->win_col == -1) { - if (item->decor.virt_text_pos == kVTRightAlign) { - right_pos -= item->decor.virt_text_width; - item->win_col = right_pos; - } else if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) { - item->win_col = state->eol_col; - state->eol_col += item->decor.virt_text_width; - } else if (item->decor.virt_text_pos == kVTWinCol) { - item->win_col = MAX(item->decor.col+col_off, 0); - } - } - if (item->win_col < 0) { - continue; - } - VirtText vt = item->decor.virt_text; - HlMode hl_mode = item->decor.hl_mode; - LineState s = LINE_STATE(""); - int virt_attr = 0; - int col = item->win_col; - size_t virt_pos = 0; - item->win_col = -2; // deactivate - - while (col < max_col) { - if (!*s.p) { - if (virt_pos >= kv_size(vt)) { - break; - } - virt_attr = 0; - do { - s.p = kv_A(vt, virt_pos).text; - int hl_id = kv_A(vt, virt_pos).hl_id; - virt_attr = hl_combine_attr(virt_attr, - hl_id > 0 ? syn_id2attr(hl_id) : 0); - virt_pos++; - } while (!s.p && virt_pos < kv_size(vt)); - if (!s.p) { - break; - } - } - int attr; - bool through = false; - if (hl_mode == kHlModeCombine) { - attr = hl_combine_attr(linebuf_attr[col], virt_attr); - } else if (hl_mode == kHlModeBlend) { - through = (*s.p == ' '); - attr = hl_blend_attrs(linebuf_attr[col], virt_attr, &through); - } else { - attr = virt_attr; - } - schar_T dummy[2]; - int cells = line_putchar(&s, through ? dummy : &linebuf_char[col], - max_col-col, false); - linebuf_attr[col++] = attr; - if (cells > 1) { - linebuf_attr[col++] = attr; - } + if (!(item->start_row == state->row && kv_size(item->decor.virt_text))) { + continue; + } + if (item->win_col == -1) { + if (item->decor.virt_text_pos == kVTRightAlign) { + right_pos -= item->decor.virt_text_width; + item->win_col = right_pos; + } else if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) { + item->win_col = state->eol_col; + } else if (item->decor.virt_text_pos == kVTWinCol) { + item->win_col = MAX(item->decor.col+col_off, 0); + } + } + if (item->win_col < 0) { + continue; + } + + int col = draw_virt_text_item(buf, item->win_col, item->decor.virt_text, + item->decor.hl_mode, max_col, item->win_col-col_off); + item->win_col = -2; // deactivate + if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) { + state->eol_col = col+1; + } + + *end_col = MAX(*end_col, col); + } +} + +static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode, int max_col, + int vcol) +{ + LineState s = LINE_STATE(""); + int virt_attr = 0; + size_t virt_pos = 0; + + while (col < max_col) { + if (!*s.p) { + if (virt_pos >= kv_size(vt)) { + break; + } + virt_attr = 0; + do { + s.p = kv_A(vt, virt_pos).text; + int hl_id = kv_A(vt, virt_pos).hl_id; + virt_attr = hl_combine_attr(virt_attr, + hl_id > 0 ? syn_id2attr(hl_id) : 0); + virt_pos++; + } while (!s.p && virt_pos < kv_size(vt)); + if (!s.p) { + break; } - *end_col = MAX(*end_col, col); } + int attr; + bool through = false; + if (hl_mode == kHlModeCombine) { + attr = hl_combine_attr(linebuf_attr[col], virt_attr); + } else if (hl_mode == kHlModeBlend) { + through = (*s.p == ' '); + attr = hl_blend_attrs(linebuf_attr[col], virt_attr, &through); + } else { + attr = virt_attr; + } + schar_T dummy[2]; + int cells = line_putchar(buf, &s, through ? dummy : &linebuf_char[col], + max_col-col, false, vcol); + // if we failed to emit a char, we still need to advance + cells = MAX(cells, 1); + + for (int c = 0; c < cells; c++) { + linebuf_attr[col++] = attr; + } + vcol += cells; } + return col; } /// Determine if dedicated window grid should be used or the default_grid @@ -5119,8 +5164,8 @@ void win_redr_status_matches(expand_T *xp, int num_matches, char_u **matches, in if (row >= 0) { if (wild_menu_showing == 0 || wild_menu_showing == WM_LIST) { if (msg_scrolled > 0) { - /* Put the wildmenu just above the command line. If there is - * no room, scroll the screen one line up. */ + // Put the wildmenu just above the command line. If there is + // no room, scroll the screen one line up. if (cmdline_row == Rows - 1) { msg_scroll_up(false); msg_scrolled++; @@ -5420,7 +5465,7 @@ static void win_redr_custom(win_T *wp, bool draw_ruler) fillchar = ' '; attr = HL_ATTR(HLF_TPF); maxwidth = Columns; - use_sandbox = was_set_insecurely(wp, (char_u *)"tabline", 0); + use_sandbox = was_set_insecurely(wp, "tabline", 0); } else { row = W_ENDROW(wp); fillchar = fillchar_status(&attr, wp); @@ -5455,15 +5500,14 @@ static void win_redr_custom(win_T *wp, bool draw_ruler) attr = HL_ATTR(HLF_MSG); } - use_sandbox = was_set_insecurely(wp, (char_u *)"rulerformat", 0); + use_sandbox = was_set_insecurely(wp, "rulerformat", 0); } else { if (*wp->w_p_stl != NUL) { stl = wp->w_p_stl; } else { stl = p_stl; } - use_sandbox = was_set_insecurely(wp, (char_u *)"statusline", - *wp->w_p_stl == NUL ? 0 : OPT_LOCAL); + use_sandbox = was_set_insecurely(wp, "statusline", *wp->w_p_stl == NUL ? 0 : OPT_LOCAL); } col += wp->w_wincol; @@ -5489,7 +5533,7 @@ static void win_redr_custom(win_T *wp, bool draw_ruler) ewp->w_p_crb = p_crb_save; // Make all characters printable. - p = (char_u *)transstr((const char *)buf); + p = (char_u *)transstr((const char *)buf, true); len = STRLCPY(buf, p, sizeof(buf)); len = (size_t)len < sizeof(buf) ? len : (int)sizeof(buf) - 1; xfree(p); @@ -6987,8 +7031,8 @@ int showmode(void) if (VIsual_active) { char *p; - /* Don't concatenate separate words to avoid translation - * problems. */ + // Don't concatenate separate words to avoid translation + // problems. switch ((VIsual_select ? 4 : 0) + (VIsual_mode == Ctrl_V) * 2 + (VIsual_mode == 'V')) { @@ -7335,7 +7379,7 @@ void get_trans_bufname(buf_T *buf) /* * Get the character to use in a status line. Get its attributes in "*attr". */ -static int fillchar_status(int *attr, win_T *wp) +int fillchar_status(int *attr, win_T *wp) { int fill; bool is_curwin = (wp == curwin); diff --git a/src/nvim/screen.h b/src/nvim/screen.h index 5f339b9ae2..d704a6eb8a 100644 --- a/src/nvim/screen.h +++ b/src/nvim/screen.h @@ -3,10 +3,10 @@ #include <stdbool.h> -#include "nvim/types.h" #include "nvim/buffer_defs.h" #include "nvim/grid_defs.h" #include "nvim/pos.h" +#include "nvim/types.h" /* * flags for update_screen() @@ -14,12 +14,12 @@ */ #define VALID 10 /* buffer not changed, or changes marked with b_mod_* */ -#define INVERTED 20 /* redisplay inverted part that changed */ -#define INVERTED_ALL 25 /* redisplay whole inverted part */ -#define REDRAW_TOP 30 /* display first w_upd_rows screen lines */ -#define SOME_VALID 35 /* like NOT_VALID but may scroll */ -#define NOT_VALID 40 /* buffer needs complete redraw */ -#define CLEAR 50 /* screen messed up, clear it */ +#define INVERTED 20 // redisplay inverted part that changed +#define INVERTED_ALL 25 // redisplay whole inverted part +#define REDRAW_TOP 30 // display first w_upd_rows screen lines +#define SOME_VALID 35 // like NOT_VALID but may scroll +#define NOT_VALID 40 // buffer needs complete redraw +#define CLEAR 50 // screen messed up, clear it /// By default, all widows are draw on a single rectangular grid, represented by /// this ScreenGrid instance. In multigrid mode each window will have its own diff --git a/src/nvim/search.c b/src/nvim/search.c index 4be2402f1d..1b54d12042 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -839,14 +839,14 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, } } - /* With the SEARCH_END option move to the last character - * of the match. Don't do it for an empty match, end - * should be same as start then. */ + // With the SEARCH_END option move to the last character + // of the match. Don't do it for an empty match, end + // should be same as start then. if ((options & SEARCH_END) && !(options & SEARCH_NOOF) && !(matchpos.lnum == endpos.lnum && matchpos.col == endpos.col)) { - /* For a match in the first column, set the position - * on the NUL in the previous line. */ + // For a match in the first column, set the position + // on the NUL in the previous line. pos->lnum = lnum + endpos.lnum; pos->col = endpos.col; if (endpos.col == 0) { @@ -1046,8 +1046,8 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, char_u *strcopy = NULL; char_u *ps; char_u *msgbuf = NULL; - size_t len; - bool has_offset = false; + size_t len; + bool has_offset = false; /* * A line offset is not remembered, this is vi compatible. @@ -1182,8 +1182,8 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, if ((options & SEARCH_ECHO) && messaging() && !msg_silent && (!cmd_silent || !shortmess(SHM_SEARCHCOUNT))) { char_u *trunc; - char_u off_buf[40]; - size_t off_len = 0; + char_u off_buf[40]; + size_t off_len = 0; // Compute msg_row early. msg_start(); @@ -1498,8 +1498,8 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat) p = skipwhite(ptr); pos->col = (colnr_T)(p - ptr); - /* when adding lines the matching line may be empty but it is not - * ignored because we are interested in the next line -- Acevedo */ + // when adding lines the matching line may be empty but it is not + // ignored because we are interested in the next line -- Acevedo if ((compl_cont_status & CONT_ADDING) && !(compl_cont_status & CONT_SOL)) { if (mb_strcmp_ic((bool)p_ic, (const char *)p, (const char *)pat) == 0) { @@ -1566,9 +1566,9 @@ int searchc(cmdarg_T *cap, int t_cmd) c = *lastc; // For multi-byte re-use last lastc_bytes[] and lastc_bytelen. - /* Force a move of at least one char, so ";" and "," will move the - * cursor, even if the cursor is right in front of char we are looking - * at. */ + // Force a move of at least one char, so ";" and "," will move the + // cursor, even if the cursor is right in front of char we are looking + // at. if (vim_strchr(p_cpo, CPO_SCOLON) == NULL && count == 1 && t_cmd) { stop = false; } @@ -2084,10 +2084,10 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) if (linep[pos.col - 1] == 'R' && linep[pos.col] == '"' && vim_strchr(linep + pos.col + 1, '(') != NULL) { - /* Possible start of raw string. Now that we have the - * delimiter we can check if it ends before where we - * started searching, or before the previously found - * raw string start. */ + // Possible start of raw string. Now that we have the + // delimiter we can check if it ends before where we + // started searching, or before the previously found + // raw string start. if (!find_rawstring_end(linep, &pos, count > 0 ? &match_pos : &curwin->w_cursor)) { count++; @@ -2208,8 +2208,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) break; case '"': - /* a quote that is preceded with an odd number of backslashes is - * ignored */ + // a quote that is preceded with an odd number of backslashes is + // ignored if (do_quotes) { int col; @@ -2282,8 +2282,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) bslcnt++; } } - /* Only accept a match when 'M' is in 'cpo' or when escaping - * is what we expect. */ + // Only accept a match when 'M' is in 'cpo' or when escaping + // is what we expect. if (cpo_bsl || (bslcnt & 1) == match_escaped) { if (c == initc) { count++; @@ -2459,7 +2459,7 @@ int findsent(Direction dir, long count) { pos_T pos, tpos; int c; - int (*func)(pos_T *); + int (*func)(pos_T *); bool noskip = false; // do not skip blanks pos = curwin->w_cursor; @@ -3505,8 +3505,8 @@ int current_block(oparg_T *oap, long count, int include, int what, int other) // Include the character under the cursor. oap->inclusive = true; } else { - /* End is before the start (no text in between <>, [], etc.): don't - * operate on any text. */ + // End is before the start (no text in between <>, [], etc.): don't + // operate on any text. curwin->w_cursor = start_pos; } } @@ -4044,8 +4044,8 @@ bool current_quote(oparg_T *oap, long count, bool include, int quotechar) } if (!vis_empty) { - /* Check if the existing selection exactly spans the text inside - * quotes. */ + // Check if the existing selection exactly spans the text inside + // quotes. if (vis_bef_curs) { inside_quotes = VIsual.col > 0 && line[VIsual.col - 1] == quotechar @@ -4072,11 +4072,11 @@ bool current_quote(oparg_T *oap, long count, bool include, int quotechar) } if (!vis_empty && line[col_start] == quotechar) { - /* Already selecting something and on a quote character. Find the - * next quoted string. */ + // Already selecting something and on a quote character. Find the + // next quoted string. if (vis_bef_curs) { - /* Assume we are on a closing quote: move to after the next - * opening quote. */ + // Assume we are on a closing quote: move to after the next + // opening quote. col_start = find_next_quote(line, col_start + 1, quotechar, NULL); if (col_start < 0) { goto abort_search; @@ -4474,7 +4474,7 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool sh update_search_stat(dirc, pos, cursor_pos, &stat, recompute, maxcount, timeout); if (stat.cur > 0) { - char t[SEARCH_STAT_BUF_LEN]; + char t[SEARCH_STAT_BUF_LEN]; if (curwin->w_p_rl && *curwin->w_p_rlc == 's') { if (stat.incomplete == 1) { @@ -4534,19 +4534,19 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool sh static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchstat_T *stat, bool recompute, int maxcount, long timeout) { - int save_ws = p_ws; - bool wraparound = false; - pos_T p = (*pos); - static pos_T lastpos = { 0, 0, 0 }; - static int cur = 0; - static int cnt = 0; - static bool exact_match = false; - static int incomplete = 0; - static int last_maxcount = SEARCH_STAT_DEF_MAX_COUNT; - static int chgtick = 0; + int save_ws = p_ws; + bool wraparound = false; + pos_T p = (*pos); + static pos_T lastpos = { 0, 0, 0 }; + static int cur = 0; + static int cnt = 0; + static bool exact_match = false; + static int incomplete = 0; + static int last_maxcount = SEARCH_STAT_DEF_MAX_COUNT; + static int chgtick = 0; static char_u *lastpat = NULL; static buf_T *lbuf = NULL; - proftime_T start; + proftime_T start; memset(stat, 0, sizeof(searchstat_T)); @@ -4636,12 +4636,12 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst // "searchcount()" function void f_searchcount(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - pos_T pos = curwin->w_cursor; + pos_T pos = curwin->w_cursor; char_u *pattern = NULL; - int maxcount = SEARCH_STAT_DEF_MAX_COUNT; - long timeout = SEARCH_STAT_DEF_TIMEOUT; - bool recompute = true; - searchstat_T stat; + int maxcount = SEARCH_STAT_DEF_MAX_COUNT; + long timeout = SEARCH_STAT_DEF_TIMEOUT; + bool recompute = true; + searchstat_T stat; tv_dict_alloc_ret(rettv); @@ -4800,8 +4800,8 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo file_line = xmalloc(LSIZE); if (type != CHECK_PATH && type != FIND_DEFINE - /* when CONT_SOL is set compare "ptr" with the beginning of the line - * is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo */ + // when CONT_SOL is set compare "ptr" with the beginning of the line + // is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo && !(compl_cont_status & CONT_SOL)) { pat = xmalloc(len + 5); assert(len <= INT_MAX); @@ -4946,10 +4946,9 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo // Nothing found, use the rest of the line. p = incl_regmatch.endp[0]; i = (int)STRLEN(p); - } - /* Avoid checking before the start of the line, can - * happen if \zs appears in the regexp. */ - else if (p > line) { + } else if (p > line) { + // Avoid checking before the start of the line, can + // happen if \zs appears in the regexp. if (p[-1] == '"' || p[-1] == '<') { --p; ++i; @@ -5129,9 +5128,9 @@ search_line: // IOSIZE > compl_length, so the STRNCPY works STRNCPY(IObuff, aux, i); - /* Get the next line: when "depth" < 0 from the current - * buffer, otherwise from the included file. Jump to - * exit_matched when past the last line. */ + // Get the next line: when "depth" < 0 from the current + // buffer, otherwise from the included file. Jump to + // exit_matched when past the last line. if (depth < 0) { if (lnum >= end_lnum) { goto exit_matched; @@ -5142,9 +5141,9 @@ search_line: goto exit_matched; } - /* we read a line, set "already" to check this "line" later - * if depth >= 0 we'll increase files[depth].lnum far - * bellow -- Acevedo */ + // we read a line, set "already" to check this "line" later + // if depth >= 0 we'll increase files[depth].lnum far + // bellow -- Acevedo already = aux = p = skipwhite(line); p = find_word_start(p); p = find_word_end(p); @@ -5195,8 +5194,8 @@ search_line: if (did_show) { msg_putchar('\n'); // cursor below last one } - if (!got_int) { /* don't display if 'q' typed - at "--more--" message */ + if (!got_int) { // don't display if 'q' typed + // at "--more--" message msg_home_replace_hl(curr_fname); } prev_fname = curr_fname; @@ -5209,10 +5208,10 @@ search_line: match_count++); } - /* Set matched flag for this file and all the ones that - * include it */ - for (i = 0; i <= depth; ++i) { - files[i].matched = TRUE; + // Set matched flag for this file and all the ones that + // include it + for (i = 0; i <= depth; i++) { + files[i].matched = true; } } else if (--count <= 0) { found = true; diff --git a/src/nvim/search.h b/src/nvim/search.h index 0dbaf79c37..85bcda84a4 100644 --- a/src/nvim/search.h +++ b/src/nvim/search.h @@ -4,14 +4,14 @@ #include <stdbool.h> #include <stdint.h> -#include "nvim/vim.h" #include "nvim/buffer_defs.h" #include "nvim/eval/funcs.h" #include "nvim/eval/typval.h" #include "nvim/normal.h" #include "nvim/os/time.h" +#include "nvim/vim.h" -/* Values for the find_pattern_in_path() function args 'type' and 'action': */ +// Values for the find_pattern_in_path() function args 'type' and 'action': #define FIND_ANY 1 #define FIND_DEFINE 2 #define CHECK_PATH 3 @@ -37,18 +37,18 @@ #define SEARCH_PEEK 0x800 ///< peek for typed char, cancel search #define SEARCH_COL 0x1000 ///< start at specified column instead of zero -/* Values for flags argument for findmatchlimit() */ -#define FM_BACKWARD 0x01 /* search backwards */ -#define FM_FORWARD 0x02 /* search forwards */ -#define FM_BLOCKSTOP 0x04 /* stop at start/end of block */ -#define FM_SKIPCOMM 0x08 /* skip comments */ +// Values for flags argument for findmatchlimit() +#define FM_BACKWARD 0x01 // search backwards +#define FM_FORWARD 0x02 // search forwards +#define FM_BLOCKSTOP 0x04 // stop at start/end of block +#define FM_SKIPCOMM 0x08 // skip comments -/* Values for sub_cmd and which_pat argument for search_regcomp() */ -/* Also used for which_pat argument for searchit() */ -#define RE_SEARCH 0 /* save/use pat in/from search_pattern */ -#define RE_SUBST 1 /* save/use pat in/from subst_pattern */ -#define RE_BOTH 2 /* save pat in both patterns */ -#define RE_LAST 2 /* use last used pattern if "pat" is NULL */ +// Values for sub_cmd and which_pat argument for search_regcomp() +// Also used for which_pat argument for searchit() +#define RE_SEARCH 0 // save/use pat in/from search_pattern +#define RE_SUBST 1 // save/use pat in/from subst_pattern +#define RE_BOTH 2 // save pat in both patterns +#define RE_LAST 2 // use last used pattern if "pat" is NULL // Values for searchcount() #define SEARCH_STAT_DEF_TIMEOUT 40L @@ -78,21 +78,21 @@ typedef struct spat { /// Optional extra arguments for searchit(). typedef struct { - linenr_T sa_stop_lnum; ///< stop after this line number when != 0 - proftime_T *sa_tm; ///< timeout limit or NULL - int sa_timed_out; ///< set when timed out - int sa_wrapped; ///< search wrapped around + linenr_T sa_stop_lnum; ///< stop after this line number when != 0 + proftime_T *sa_tm; ///< timeout limit or NULL + int sa_timed_out; ///< set when timed out + int sa_wrapped; ///< search wrapped around } searchit_arg_T; typedef struct searchstat { - int cur; // current position of found words - int cnt; // total count of found words - bool exact_match; // true if matched exactly on specified position - int incomplete; // 0: search was fully completed - // 1: recomputing was timed out - // 2: max count exceeded - int last_maxcount; // the max count of the last search + int cur; // current position of found words + int cnt; // total count of found words + bool exact_match; // true if matched exactly on specified position + int incomplete; // 0: search was fully completed + // 1: recomputing was timed out + // 2: max count exceeded + int last_maxcount; // the max count of the last search } searchstat_T; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/sha256.c b/src/nvim/sha256.c index a2378cc202..9d6a2f2c41 100644 --- a/src/nvim/sha256.c +++ b/src/nvim/sha256.c @@ -51,8 +51,7 @@ void sha256_start(context_sha256_T *ctx) ctx->state[7] = 0x5BE0CD19; } -static void sha256_process(context_sha256_T *ctx, - const char_u data[SHA256_BUFFER_SIZE]) +static void sha256_process(context_sha256_T *ctx, const char_u data[SHA256_BUFFER_SIZE]) { uint32_t temp1, temp2, W[SHA256_BUFFER_SIZE]; uint32_t A, B, C, D, E, F, G, H; @@ -88,7 +87,7 @@ static void sha256_process(context_sha256_T *ctx, #define R(t) \ (W[t] = S1(W[t - 2]) + W[t - 7] + \ - S0(W[t - 15]) + W[t - 16]) + S0(W[t - 15]) + W[t - 16]) #define P(a, b, c, d, e, f, g, h, x, K) { \ temp1 = h + S3(e) + F1(e, f, g) + K + x; \ @@ -188,7 +187,7 @@ void sha256_update(context_sha256_T *ctx, const char_u *input, size_t length) uint32_t left = ctx->total[0] & (SHA256_BUFFER_SIZE-1); // left < buf size - ctx->total[0] += (uint32_t) length; + ctx->total[0] += (uint32_t)length; ctx->total[0] &= 0xFFFFFFFF; if (ctx->total[0] < length) { @@ -262,8 +261,8 @@ void sha256_finish(context_sha256_T *ctx, char_u digest[SHA256_SUM_SIZE]) /// /// @returns hex digest of "buf[buf_len]" in a static array. /// if "salt" is not NULL also do "salt[salt_len]". -const char *sha256_bytes(const uint8_t *restrict buf, size_t buf_len, - const uint8_t *restrict salt, size_t salt_len) +const char *sha256_bytes(const uint8_t *restrict buf, size_t buf_len, const uint8_t *restrict salt, + size_t salt_len) { char_u sha256sum[SHA256_SUM_SIZE]; static char hexit[SHA256_BUFFER_SIZE + 1]; // buf size + NULL diff --git a/src/nvim/sha256.h b/src/nvim/sha256.h index deb881a288..b52d300de6 100644 --- a/src/nvim/sha256.h +++ b/src/nvim/sha256.h @@ -1,8 +1,8 @@ #ifndef NVIM_SHA256_H #define NVIM_SHA256_H -#include <stdint.h> // for uint32_t #include <stddef.h> +#include <stdint.h> // for uint32_t #include "nvim/types.h" // for char_u diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 7d277fe5c8..10f93913ad 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -1,51 +1,50 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com -#include <stdlib.h> -#include <stddef.h> -#include <stdbool.h> -#include <string.h> -#include <inttypes.h> -#include <errno.h> #include <assert.h> - +#include <errno.h> +#include <inttypes.h> #include <msgpack.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> #include <uv.h> -#include "nvim/os/os.h" -#include "nvim/os/time.h" -#include "nvim/vim.h" -#include "nvim/pos.h" -#include "nvim/ascii.h" -#include "nvim/shada.h" -#include "nvim/message.h" -#include "nvim/globals.h" -#include "nvim/memory.h" -#include "nvim/mark.h" -#include "nvim/macros.h" -#include "nvim/ops.h" -#include "nvim/garray.h" -#include "nvim/option.h" -#include "nvim/msgpack_rpc/helpers.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" +#include "nvim/ascii.h" #include "nvim/buffer.h" #include "nvim/buffer_defs.h" +#include "nvim/eval/decode.h" +#include "nvim/eval/encode.h" +#include "nvim/eval/typval.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" -#include "nvim/search.h" -#include "nvim/regexp.h" -#include "nvim/eval/typval.h" -#include "nvim/version.h" -#include "nvim/path.h" #include "nvim/fileio.h" -#include "nvim/os/fileio.h" -#include "nvim/strings.h" -#include "nvim/quickfix.h" -#include "nvim/eval/encode.h" -#include "nvim/eval/decode.h" +#include "nvim/garray.h" +#include "nvim/globals.h" #include "nvim/lib/khash.h" #include "nvim/lib/kvec.h" +#include "nvim/macros.h" +#include "nvim/mark.h" +#include "nvim/memory.h" +#include "nvim/message.h" +#include "nvim/msgpack_rpc/helpers.h" +#include "nvim/ops.h" +#include "nvim/option.h" +#include "nvim/os/fileio.h" +#include "nvim/os/os.h" +#include "nvim/os/time.h" +#include "nvim/path.h" +#include "nvim/pos.h" +#include "nvim/quickfix.h" +#include "nvim/regexp.h" +#include "nvim/search.h" +#include "nvim/shada.h" +#include "nvim/strings.h" +#include "nvim/version.h" +#include "nvim/vim.h" #ifdef HAVE_BE64TOH # define _BSD_SOURCE 1 @@ -66,26 +65,6 @@ KHASH_SET_INIT_INT64(bufset) KHASH_MAP_INIT_STR(fnamebufs, buf_T *) KHASH_SET_INIT_STR(strset) -#define copy_option_part(src, dest, ...) \ - ((char *) copy_option_part((char_u **) src, (char_u *) dest, __VA_ARGS__)) -#define find_shada_parameter(...) \ - ((const char *) find_shada_parameter(__VA_ARGS__)) -#define home_replace_save(a, b) \ - ((char *)home_replace_save(a, (char_u *)b)) -#define home_replace(a, b, c, d, e) \ - home_replace(a, (char_u *)b, (char_u *)c, d, e) -#define vim_rename(a, b) \ - (vim_rename((char_u *)a, (char_u *)b)) -#define mb_strnicmp(a, b, c) \ - (mb_strnicmp((char_u *)a, (char_u *)b, c)) -#define path_try_shorten_fname(b) \ - ((char *)path_try_shorten_fname((char_u *)b)) -#define buflist_new(ffname, sfname, ...) \ - (buflist_new((char_u *)ffname, (char_u *)sfname, __VA_ARGS__)) -#define os_isdir(f) (os_isdir((char_u *) f)) -#define regtilde(s, m) ((char *) regtilde((char_u *) s, m)) -#define path_tail_with_sep(f) ((char *) path_tail_with_sep((char_u *)f)) - #define SEARCH_KEY_MAGIC "sm" #define SEARCH_KEY_SMARTCASE "sc" #define SEARCH_KEY_HAS_LINE_OFFSET "sl" @@ -172,7 +151,7 @@ typedef enum { kSDItemBufferList = 9, ///< Buffer list. kSDItemLocalMark = 10, ///< Buffer-local mark. kSDItemChange = 11, ///< Item from buffer change list. -#define SHADA_LAST_ENTRY ((uint64_t) kSDItemChange) +#define SHADA_LAST_ENTRY ((uint64_t)kSDItemChange) } ShadaEntryType; /// Possible results when reading ShaDa file @@ -202,11 +181,11 @@ enum SRNIFlags { kSDReadHeader = (1 << kSDItemHeader), ///< Determines whether header should ///< be read (it is usually ignored). kSDReadUndisableableData = ( - (1 << kSDItemSearchPattern) - | (1 << kSDItemSubString) - | (1 << kSDItemJump)), ///< Data reading which cannot be disabled by - ///< &shada or other options except for disabling - ///< reading ShaDa as a whole. + (1 << kSDItemSearchPattern) + | (1 << kSDItemSubString) + | (1 << kSDItemJump)), ///< Data reading which cannot be disabled by + ///< &shada or other options except for disabling + ///< reading ShaDa as a whole. kSDReadRegisters = (1 << kSDItemRegister), ///< Determines whether registers ///< should be read (may only be ///< disabled when writing, but @@ -434,13 +413,13 @@ typedef struct sd_write_def { #endif #define DEF_SDE(name, attr, ...) \ - [kSDItem##name] = { \ - .timestamp = 0, \ - .type = kSDItem##name, \ - .data = { \ - .attr = { __VA_ARGS__ } \ - } \ - } + [kSDItem##name] = { \ + .timestamp = 0, \ + .type = kSDItem##name, \ + .data = { \ + .attr = { __VA_ARGS__ } \ + } \ + } #define DEFAULT_POS { 1, 0, 0 } static const pos_T default_pos = DEFAULT_POS; static const ShadaEntry sd_default_values[] = { @@ -475,9 +454,9 @@ static const ShadaEntry sd_default_values[] = { DEF_SDE(Variable, global_var, .name = NULL, .value = { - .v_type = VAR_UNKNOWN, - .vval = { .v_string = NULL } - }, + .v_type = VAR_UNKNOWN, + .vval = { .v_string = NULL } + }, .additional_elements = NULL), DEF_SDE(GlobalMark, filemark, .name = '"', @@ -533,17 +512,16 @@ static inline void hmll_init(HMLList *const hmll, const size_t size) /// /// @return `for` cycle header (use `HMLL_FORALL(hmll, cur_entry) {body}`). #define HMLL_FORALL(hmll, cur_entry, code) \ - for (HMLListEntry *cur_entry = (hmll)->first; cur_entry != NULL; \ - cur_entry = cur_entry->next) { \ - code \ - } \ + for (HMLListEntry *cur_entry = (hmll)->first; cur_entry != NULL; \ + cur_entry = cur_entry->next) { \ + code \ + } \ /// Remove entry from the linked list /// /// @param hmll List to remove from. /// @param hmll_entry Entry to remove. -static inline void hmll_remove(HMLList *const hmll, - HMLListEntry *const hmll_entry) +static inline void hmll_remove(HMLList *const hmll, HMLListEntry *const hmll_entry) FUNC_ATTR_NONNULL_ALL { if (hmll_entry == hmll->last_free_entry - 1) { @@ -580,9 +558,7 @@ static inline void hmll_remove(HMLList *const hmll, /// to insert at the first entry. /// @param[in] data Data to insert. /// @param[in] can_free_entry True if data can be freed. -static inline void hmll_insert(HMLList *const hmll, - HMLListEntry *hmll_entry, - const ShadaEntry data, +static inline void hmll_insert(HMLList *const hmll, HMLListEntry *hmll_entry, const ShadaEntry data, const bool can_free_entry) FUNC_ATTR_NONNULL_ARG(1) { @@ -595,11 +571,11 @@ static inline void hmll_insert(HMLList *const hmll, } HMLListEntry *target_entry; if (hmll->free_entry == NULL) { - assert((size_t) (hmll->last_free_entry - hmll->entries) + assert((size_t)(hmll->last_free_entry - hmll->entries) == hmll->num_entries); target_entry = hmll->last_free_entry++; } else { - assert((size_t) (hmll->last_free_entry - hmll->entries) - 1 + assert((size_t)(hmll->last_free_entry - hmll->entries) - 1 == hmll->num_entries); target_entry = hmll->free_entry; hmll->free_entry = NULL; @@ -628,20 +604,6 @@ static inline void hmll_insert(HMLList *const hmll, } } -/// Iterate over HMLList in backward direction -/// -/// @param hmll Pointer to the list. -/// @param cur_entry Name of the variable to iterate over, must be already -/// defined. -/// @param code Code to execute on each iteration. -/// -/// @return `for` cycle header (use `HMLL_FORALL(hmll, cur_entry) {body}`). -#define HMLL_ITER_BACK(hmll, cur_entry, code) \ - for (cur_entry = (hmll)->last; cur_entry != NULL; \ - cur_entry = cur_entry->prev) { \ - code \ - } - /// Free linked list /// /// @param[in] hmll List to free. @@ -655,8 +617,7 @@ static inline void hmll_dealloc(HMLList *const hmll) /// Wrapper for reading from file descriptors /// /// @return -1 or number of bytes read. -static ptrdiff_t read_file(ShaDaReadDef *const sd_reader, void *const dest, - const size_t size) +static ptrdiff_t read_file(ShaDaReadDef *const sd_reader, void *const dest, const size_t size) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { const ptrdiff_t ret = file_read(sd_reader->cookie, dest, size); @@ -678,14 +639,13 @@ static int read_char(ShaDaReadDef *const sd_reader) if (read_bytes != 1) { return EOF; } - return (int) ret; + return (int)ret; } /// Wrapper for writing to file descriptors /// /// @return -1 or number of bytes written. -static ptrdiff_t write_file(ShaDaWriteDef *const sd_writer, - const void *const dest, +static ptrdiff_t write_file(ShaDaWriteDef *const sd_writer, const void *const dest, const size_t size) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { @@ -720,8 +680,7 @@ static void close_sd_writer(ShaDaWriteDef *const sd_writer) /// /// @return FAIL in case of failure, OK in case of success. May set /// sd_reader->eof or sd_reader->error. -static int sd_reader_skip_read(ShaDaReadDef *const sd_reader, - const size_t offset) +static int sd_reader_skip_read(ShaDaReadDef *const sd_reader, const size_t offset) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { const ptrdiff_t skip_bytes = file_skip(sd_reader->cookie, offset); @@ -749,8 +708,7 @@ static int sd_reader_skip_read(ShaDaReadDef *const sd_reader, /// /// @return kSDReadStatusReadError, kSDReadStatusNotShaDa or /// kSDReadStatusSuccess. -static ShaDaReadResult sd_reader_skip(ShaDaReadDef *const sd_reader, - const size_t offset) +static ShaDaReadResult sd_reader_skip(ShaDaReadDef *const sd_reader, const size_t offset) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { if (sd_reader->skip(sd_reader, offset) != OK) { @@ -762,7 +720,7 @@ static ShaDaReadResult sd_reader_skip(ShaDaReadDef *const sd_reader, emsgf(_(RCERR "Error while reading ShaDa file: " "last entry specified that it occupies %" PRIu64 " bytes, " "but file ended earlier"), - (uint64_t) offset); + (uint64_t)offset); return kSDReadStatusNotShaDa; } abort(); @@ -776,8 +734,7 @@ static ShaDaReadResult sd_reader_skip(ShaDaReadDef *const sd_reader, /// @param[out] sd_reader Location where reader structure will be saved. /// /// @return libuv error in case of error, 0 otherwise. -static int open_shada_file_for_reading(const char *const fname, - ShaDaReadDef *sd_reader) +static int open_shada_file_for_reading(const char *const fname, ShaDaReadDef *sd_reader) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { int error; @@ -819,7 +776,7 @@ static void close_file(void *cookie) static inline bool in_bufset(const khash_t(bufset) *const set, const buf_T *buf) FUNC_ATTR_PURE { - return kh_get(bufset, set, (uintptr_t) buf) != kh_end(set); + return kh_get(bufset, set, (uintptr_t)buf) != kh_end(set); } /// Check whether string is in the given set @@ -837,7 +794,7 @@ static inline bool in_strset(const khash_t(strset) *const set, char *str) /// Msgpack callback for writing to ShaDaWriteDef* static int msgpack_sd_writer_write(void *data, const char *buf, size_t len) { - ShaDaWriteDef *const sd_writer = (ShaDaWriteDef *) data; + ShaDaWriteDef *const sd_writer = (ShaDaWriteDef *)data; ptrdiff_t written_bytes = sd_writer->write(sd_writer, buf, len); if (written_bytes == -1) { emsgf(_(SERR "System error while writing ShaDa file: %s"), @@ -910,10 +867,8 @@ static int shada_read_file(const char *const file, const int flags) /// @param[out] hist Location where iteration results should be saved. /// /// @return Next iteration state. -static const void *shada_hist_iter(const void *const iter, - const uint8_t history_type, - const bool zero, - ShadaEntry *const hist) +static const void *shada_hist_iter(const void *const iter, const uint8_t history_type, + const bool zero, ShadaEntry *const hist) FUNC_ATTR_NONNULL_ARG(4) FUNC_ATTR_WARN_UNUSED_RESULT { histentry_T hist_he; @@ -927,9 +882,9 @@ static const void *shada_hist_iter(const void *const iter, .data = { .history_item = { .histtype = history_type, - .string = (char *) hist_he.hisstr, - .sep = (char) (history_type == HIST_SEARCH - ? (char) hist_he.hisstr[STRLEN(hist_he.hisstr) + 1] + .string = (char *)hist_he.hisstr, + .sep = (char)(history_type == HIST_SEARCH + ? (char)hist_he.hisstr[STRLEN(hist_he.hisstr) + 1] : 0), .additional_elements = hist_he.additional_elements, } @@ -954,8 +909,8 @@ static const void *shada_hist_iter(const void *const iter, /// be used. Must be true only if inserting /// entry from current Neovim history. /// @param[in] can_free_entry True if entry can be freed. -static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry, - const bool do_iter, const bool can_free_entry) +static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry, const bool do_iter, + const bool can_free_entry) FUNC_ATTR_NONNULL_ALL { if (do_iter) { @@ -992,11 +947,12 @@ static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry, } } HMLListEntry *insert_after; - HMLL_ITER_BACK(hmll, insert_after, { + // Iterate over HMLList in backward direction + for (insert_after = hmll->last; insert_after != NULL; insert_after = insert_after->prev) { if (insert_after->data.timestamp <= entry.timestamp) { break; } - }) + } hmll_insert(hmll, insert_after, entry, can_free_entry); } @@ -1008,11 +964,8 @@ static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry, /// @param[in] do_merge Prepare structure for merging elements. /// @param[in] reading If true, then merger is reading history for use /// in Neovim. -static inline void hms_init(HistoryMergerState *const hms_p, - const uint8_t history_type, - const size_t num_elements, - const bool do_merge, - const bool reading) +static inline void hms_init(HistoryMergerState *const hms_p, const uint8_t history_type, + const size_t num_elements, const bool do_merge, const bool reading) FUNC_ATTR_NONNULL_ALL { hmll_init(&hms_p->hmll, num_elements); @@ -1027,8 +980,7 @@ static inline void hms_init(HistoryMergerState *const hms_p, /// /// @param[in,out] hms_p Merger structure into which history should be /// inserted. -static inline void hms_insert_whole_neovim_history( - HistoryMergerState *const hms_p) +static inline void hms_insert_whole_neovim_history(HistoryMergerState *const hms_p) FUNC_ATTR_NONNULL_ALL { while (hms_p->last_hist_entry.type != kSDItemMissing) { @@ -1048,21 +1000,20 @@ static inline void hms_insert_whole_neovim_history( /// @param[out] new_hisidx New last history entry index. /// @param[out] new_hisnum Amount of history items in merger structure. static inline void hms_to_he_array(const HistoryMergerState *const hms_p, - histentry_T *const hist_array, - int *const new_hisidx, + histentry_T *const hist_array, int *const new_hisidx, int *const new_hisnum) FUNC_ATTR_NONNULL_ALL { histentry_T *hist = hist_array; HMLL_FORALL(&hms_p->hmll, cur_entry, { hist->timestamp = cur_entry->data.timestamp; - hist->hisnum = (int) (hist - hist_array) + 1; - hist->hisstr = (char_u *) cur_entry->data.data.history_item.string; + hist->hisnum = (int)(hist - hist_array) + 1; + hist->hisstr = (char_u *)cur_entry->data.data.history_item.string; hist->additional_elements = - cur_entry->data.data.history_item.additional_elements; + cur_entry->data.data.history_item.additional_elements; hist++; }) - *new_hisnum = (int) (hist - hist_array); + *new_hisnum = (int)(hist - hist_array); *new_hisidx = *new_hisnum - 1; } @@ -1083,7 +1034,7 @@ static inline void hms_dealloc(HistoryMergerState *const hms_p) /// /// @return for cycle header. Use `HMS_ITER(hms_p, cur_entry) {body}`. #define HMS_ITER(hms_p, cur_entry, code) \ - HMLL_FORALL(&((hms_p)->hmll), cur_entry, code) + HMLL_FORALL(&((hms_p)->hmll), cur_entry, code) /// Find buffer for given buffer name (cached) /// @@ -1091,8 +1042,7 @@ static inline void hms_dealloc(HistoryMergerState *const hms_p) /// @param[in] fname File name to find. /// /// @return Pointer to the buffer or NULL. -static buf_T *find_buffer(khash_t(fnamebufs) *const fname_bufs, - const char *const fname) +static buf_T *find_buffer(khash_t(fnamebufs) *const fname_bufs, const char *const fname) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { int kh_ret; @@ -1123,7 +1073,7 @@ static inline bool marks_equal(const pos_T a, const pos_T b) entry, fname_cond, free_func, fin_func, \ idxadj_func, afterfree_func) \ do { \ - const int jl_len = (int) jumps_size; \ + const int jl_len = (int)jumps_size; \ int i; \ for (i = jl_len; i > 0; i--) { \ const jumps_type jl_entry = jumps[i - 1]; \ @@ -1140,17 +1090,17 @@ static inline bool marks_equal(const pos_T a, const pos_T b) free_func(jumps[0]); \ i--; \ if (i > 0) { \ - memmove(&jumps[0], &jumps[1], sizeof(jumps[1]) * (size_t) i); \ + memmove(&jumps[0], &jumps[1], sizeof(jumps[1]) * (size_t)i); \ } \ } else if (i != jl_len) { \ memmove(&jumps[i + 1], &jumps[i], \ - sizeof(jumps[0]) * (size_t) (jl_len - i)); \ + sizeof(jumps[0]) * (size_t)(jl_len - i)); \ } \ } else if (i == 0) { \ if (jl_len == JUMPLISTSIZE) { \ i = -1; \ } else if (jl_len > 0) { \ - memmove(&jumps[1], &jumps[0], sizeof(jumps[0]) * (size_t) jl_len); \ + memmove(&jumps[1], &jumps[0], sizeof(jumps[0]) * (size_t)jl_len); \ } \ } \ if (i != -1) { \ @@ -1177,8 +1127,8 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) const bool get_old_files = (flags & (kShaDaGetOldfiles | kShaDaForceit) && (force || tv_list_len(oldfiles_list) == 0)); const bool want_marks = flags & kShaDaWantMarks; - const unsigned srni_flags = (unsigned) ( - (flags & kShaDaWantInfo + const unsigned srni_flags = (unsigned)( + (flags & kShaDaWantInfo ? (kSDReadUndisableableData | kSDReadRegisters | kSDReadGlobalMarks @@ -1190,11 +1140,11 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) && ARGCOUNT == 0 ? kSDReadBufferList : 0)) - : 0) - | (want_marks && get_shada_parameter('\'') > 0 + : 0) + | (want_marks && get_shada_parameter('\'') > 0 ? kSDReadLocalMarks | kSDReadChanges : 0) - | (get_old_files + | (get_old_files ? kSDReadLocalMarks : 0)); if (srni_flags == 0) { @@ -1204,7 +1154,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) HistoryMergerState hms[HIST_COUNT]; if (srni_flags & kSDReadHistory) { for (uint8_t i = 0; i < HIST_COUNT; i++) { - hms_init(&hms[i], i, (size_t) p_hi, true, true); + hms_init(&hms[i], i, (size_t)p_hi, true, true); } } ShadaEntry cur_entry; @@ -1219,253 +1169,239 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) while ((srni_ret = shada_read_next_item(sd_reader, &cur_entry, srni_flags, 0)) != kSDReadStatusFinished) { switch (srni_ret) { - case kSDReadStatusSuccess: { - break; - } - case kSDReadStatusFinished: { - // Should be handled by the while condition. - abort(); - } - case kSDReadStatusNotShaDa: - case kSDReadStatusReadError: { - goto shada_read_main_cycle_end; - } - case kSDReadStatusMalformed: { - continue; - } + case kSDReadStatusSuccess: + break; + case kSDReadStatusFinished: + // Should be handled by the while condition. + abort(); + case kSDReadStatusNotShaDa: + case kSDReadStatusReadError: + goto shada_read_main_cycle_end; + case kSDReadStatusMalformed: + continue; } switch (cur_entry.type) { - case kSDItemMissing: { - abort(); - } - case kSDItemUnknown: { - break; - } - case kSDItemHeader: { - shada_free_shada_entry(&cur_entry); - break; - } - case kSDItemSearchPattern: { - if (!force) { - SearchPattern pat; - (cur_entry.data.search_pattern.is_substitute_pattern + case kSDItemMissing: + abort(); + case kSDItemUnknown: + break; + case kSDItemHeader: + shada_free_shada_entry(&cur_entry); + break; + case kSDItemSearchPattern: + if (!force) { + SearchPattern pat; + (cur_entry.data.search_pattern.is_substitute_pattern ? &get_substitute_pattern : &get_search_pattern)(&pat); - if (pat.pat != NULL && pat.timestamp >= cur_entry.timestamp) { - shada_free_shada_entry(&cur_entry); - break; - } + if (pat.pat != NULL && pat.timestamp >= cur_entry.timestamp) { + shada_free_shada_entry(&cur_entry); + break; } - (cur_entry.data.search_pattern.is_substitute_pattern + } + (cur_entry.data.search_pattern.is_substitute_pattern ? &set_substitute_pattern : &set_search_pattern)((SearchPattern) { - .magic = cur_entry.data.search_pattern.magic, - .no_scs = !cur_entry.data.search_pattern.smartcase, - .off = { - .dir = cur_entry.data.search_pattern.search_backward ? '?' : '/', - .line = cur_entry.data.search_pattern.has_line_offset, - .end = cur_entry.data.search_pattern.place_cursor_at_end, - .off = cur_entry.data.search_pattern.offset, - }, - .pat = (char_u *) cur_entry.data.search_pattern.pat, - .additional_data = cur_entry.data.search_pattern.additional_data, - .timestamp = cur_entry.timestamp, - }); - if (cur_entry.data.search_pattern.is_last_used) { - set_last_used_pattern( - cur_entry.data.search_pattern.is_substitute_pattern); - set_no_hlsearch(!cur_entry.data.search_pattern.highlighted); - } - // Do not free shada entry: its allocated memory was saved above. - break; - } - case kSDItemSubString: { - if (!force) { - SubReplacementString sub; - sub_get_replacement(&sub); - if (sub.sub != NULL && sub.timestamp >= cur_entry.timestamp) { - shada_free_shada_entry(&cur_entry); - break; - } - } - sub_set_replacement((SubReplacementString) { - .sub = cur_entry.data.sub_string.sub, - .timestamp = cur_entry.timestamp, - .additional_elements = cur_entry.data.sub_string.additional_elements, - }); - // Without using regtilde and without / &cpo flag previous substitute - // string is close to useless: you can only use it with :& or :~ and - // that’s all because s//~ is not available until the first call to - // regtilde. Vim was not calling this for some reason. - (void) regtilde(cur_entry.data.sub_string.sub, p_magic); - // Do not free shada entry: its allocated memory was saved above. - break; + .magic = cur_entry.data.search_pattern.magic, + .no_scs = !cur_entry.data.search_pattern.smartcase, + .off = { + .dir = cur_entry.data.search_pattern.search_backward ? '?' : '/', + .line = cur_entry.data.search_pattern.has_line_offset, + .end = cur_entry.data.search_pattern.place_cursor_at_end, + .off = cur_entry.data.search_pattern.offset, + }, + .pat = (char_u *)cur_entry.data.search_pattern.pat, + .additional_data = cur_entry.data.search_pattern.additional_data, + .timestamp = cur_entry.timestamp, + }); + if (cur_entry.data.search_pattern.is_last_used) { + set_last_used_pattern(cur_entry.data.search_pattern.is_substitute_pattern); + set_no_hlsearch(!cur_entry.data.search_pattern.highlighted); } - case kSDItemHistoryEntry: { - if (cur_entry.data.history_item.histtype >= HIST_COUNT) { + // Do not free shada entry: its allocated memory was saved above. + break; + case kSDItemSubString: + if (!force) { + SubReplacementString sub; + sub_get_replacement(&sub); + if (sub.sub != NULL && sub.timestamp >= cur_entry.timestamp) { shada_free_shada_entry(&cur_entry); break; } - hms_insert(hms + cur_entry.data.history_item.histtype, cur_entry, true, - true); - // Do not free shada entry: its allocated memory was saved above. + } + sub_set_replacement((SubReplacementString) { + .sub = cur_entry.data.sub_string.sub, + .timestamp = cur_entry.timestamp, + .additional_elements = cur_entry.data.sub_string.additional_elements, + }); + // Without using regtilde and without / &cpo flag previous substitute + // string is close to useless: you can only use it with :& or :~ and + // that’s all because s//~ is not available until the first call to + // regtilde. Vim was not calling this for some reason. + (void)(char *)regtilde((char_u *)cur_entry.data.sub_string.sub, p_magic); + // Do not free shada entry: its allocated memory was saved above. + break; + case kSDItemHistoryEntry: + if (cur_entry.data.history_item.histtype >= HIST_COUNT) { + shada_free_shada_entry(&cur_entry); + break; + } + hms_insert(hms + cur_entry.data.history_item.histtype, cur_entry, true, + true); + // Do not free shada entry: its allocated memory was saved above. + break; + case kSDItemRegister: + if (cur_entry.data.reg.type != kMTCharWise + && cur_entry.data.reg.type != kMTLineWise + && cur_entry.data.reg.type != kMTBlockWise) { + shada_free_shada_entry(&cur_entry); break; } - case kSDItemRegister: { - if (cur_entry.data.reg.type != kMTCharWise - && cur_entry.data.reg.type != kMTLineWise - && cur_entry.data.reg.type != kMTBlockWise) { + if (!force) { + const yankreg_T *const reg = op_reg_get(cur_entry.data.reg.name); + if (reg == NULL || reg->timestamp >= cur_entry.timestamp) { shada_free_shada_entry(&cur_entry); break; } - if (!force) { - const yankreg_T *const reg = op_reg_get(cur_entry.data.reg.name); - if (reg == NULL || reg->timestamp >= cur_entry.timestamp) { - shada_free_shada_entry(&cur_entry); - break; - } - } - if (!op_reg_set(cur_entry.data.reg.name, (yankreg_T) { - .y_array = (char_u **)cur_entry.data.reg.contents, - .y_size = cur_entry.data.reg.contents_size, - .y_type = cur_entry.data.reg.type, - .y_width = (colnr_T) cur_entry.data.reg.width, - .timestamp = cur_entry.timestamp, - .additional_data = cur_entry.data.reg.additional_data, - }, cur_entry.data.reg.is_unnamed)) { - shada_free_shada_entry(&cur_entry); - } - // Do not free shada entry: its allocated memory was saved above. - break; } - case kSDItemVariable: { - var_set_global(cur_entry.data.global_var.name, - cur_entry.data.global_var.value); - cur_entry.data.global_var.value.v_type = VAR_UNKNOWN; + if (!op_reg_set(cur_entry.data.reg.name, (yankreg_T) { + .y_array = (char_u **)cur_entry.data.reg.contents, + .y_size = cur_entry.data.reg.contents_size, + .y_type = cur_entry.data.reg.type, + .y_width = (colnr_T)cur_entry.data.reg.width, + .timestamp = cur_entry.timestamp, + .additional_data = cur_entry.data.reg.additional_data, + }, cur_entry.data.reg.is_unnamed)) { shada_free_shada_entry(&cur_entry); - break; } - case kSDItemJump: - case kSDItemGlobalMark: { - buf_T *buf = find_buffer(&fname_bufs, cur_entry.data.filemark.fname); - if (buf != NULL) { - XFREE_CLEAR(cur_entry.data.filemark.fname); - } - xfmark_T fm = (xfmark_T) { - .fname = (char_u *) (buf == NULL + // Do not free shada entry: its allocated memory was saved above. + break; + case kSDItemVariable: + var_set_global(cur_entry.data.global_var.name, + cur_entry.data.global_var.value); + cur_entry.data.global_var.value.v_type = VAR_UNKNOWN; + shada_free_shada_entry(&cur_entry); + break; + case kSDItemJump: + case kSDItemGlobalMark: { + buf_T *buf = find_buffer(&fname_bufs, cur_entry.data.filemark.fname); + if (buf != NULL) { + XFREE_CLEAR(cur_entry.data.filemark.fname); + } + xfmark_T fm = (xfmark_T) { + .fname = (char_u *)(buf == NULL ? cur_entry.data.filemark.fname : NULL), - .fmark = { - .mark = cur_entry.data.filemark.mark, - .fnum = (buf == NULL ? 0 : buf->b_fnum), - .timestamp = cur_entry.timestamp, - .additional_data = cur_entry.data.filemark.additional_data, - }, - }; - if (cur_entry.type == kSDItemGlobalMark) { - if (!mark_set_global(cur_entry.data.filemark.name, fm, !force)) { - shada_free_shada_entry(&cur_entry); - break; - } - } else { + .fmark = { + .mark = cur_entry.data.filemark.mark, + .fnum = (buf == NULL ? 0 : buf->b_fnum), + .timestamp = cur_entry.timestamp, + .additional_data = cur_entry.data.filemark.additional_data, + }, + }; + if (cur_entry.type == kSDItemGlobalMark) { + if (!mark_set_global(cur_entry.data.filemark.name, fm, !force)) { + shada_free_shada_entry(&cur_entry); + break; + } + } else { #define SDE_TO_XFMARK(entry) fm #define ADJUST_IDX(i) \ - if (curwin->w_jumplistidx >= i \ - && curwin->w_jumplistidx + 1 <= curwin->w_jumplistlen) { \ - curwin->w_jumplistidx++; \ - } + if (curwin->w_jumplistidx >= i \ + && curwin->w_jumplistidx + 1 <= curwin->w_jumplistlen) { \ + curwin->w_jumplistidx++; \ + } #define DUMMY_AFTERFREE(entry) - MERGE_JUMPS(curwin->w_jumplistlen, curwin->w_jumplist, xfmark_T, - fmark.timestamp, fmark.mark, cur_entry, - (buf == NULL + MERGE_JUMPS(curwin->w_jumplistlen, curwin->w_jumplist, xfmark_T, + fmark.timestamp, fmark.mark, cur_entry, + (buf == NULL ? (jl_entry.fname != NULL && STRCMP(fm.fname, jl_entry.fname) == 0) : fm.fmark.fnum == jl_entry.fmark.fnum), - free_xfmark, SDE_TO_XFMARK, ADJUST_IDX, DUMMY_AFTERFREE); + free_xfmark, SDE_TO_XFMARK, ADJUST_IDX, DUMMY_AFTERFREE); #undef SDE_TO_XFMARK #undef ADJUST_IDX #undef DUMMY_AFTERFREE - } - // Do not free shada entry: its allocated memory was saved above. - break; } - case kSDItemBufferList: { - for (size_t i = 0; i < cur_entry.data.buffer_list.size; i++) { - char *const sfname = path_try_shorten_fname( - cur_entry.data.buffer_list.buffers[i].fname); - buf_T *const buf = buflist_new( - cur_entry.data.buffer_list.buffers[i].fname, sfname, 0, - BLN_LISTED); - if (buf != NULL) { - RESET_FMARK(&buf->b_last_cursor, - cur_entry.data.buffer_list.buffers[i].pos, 0); - buflist_setfpos(buf, curwin, buf->b_last_cursor.mark.lnum, - buf->b_last_cursor.mark.col, false); - buf->additional_data = - cur_entry.data.buffer_list.buffers[i].additional_data; - cur_entry.data.buffer_list.buffers[i].additional_data = NULL; - } + // Do not free shada entry: its allocated memory was saved above. + break; + } + case kSDItemBufferList: + for (size_t i = 0; i < cur_entry.data.buffer_list.size; i++) { + char *const sfname = + (char *)path_try_shorten_fname((char_u *)cur_entry.data.buffer_list.buffers[i].fname); + buf_T *const buf = + buflist_new((char_u *)cur_entry.data.buffer_list.buffers[i].fname, (char_u *)sfname, 0, + BLN_LISTED); + if (buf != NULL) { + RESET_FMARK(&buf->b_last_cursor, + cur_entry.data.buffer_list.buffers[i].pos, 0); + buflist_setfpos(buf, curwin, buf->b_last_cursor.mark.lnum, + buf->b_last_cursor.mark.col, false); + buf->additional_data = + cur_entry.data.buffer_list.buffers[i].additional_data; + cur_entry.data.buffer_list.buffers[i].additional_data = NULL; } - shada_free_shada_entry(&cur_entry); - break; } - case kSDItemChange: - case kSDItemLocalMark: { - if (get_old_files && !in_strset(&oldfiles_set, - cur_entry.data.filemark.fname)) { - char *fname = cur_entry.data.filemark.fname; - if (want_marks) { - // Do not bother with allocating memory for the string if already - // allocated string from cur_entry can be used. It cannot be used if - // want_marks is set because this way it may be used for a mark. - fname = xstrdup(fname); - } - int kh_ret; - (void)kh_put(strset, &oldfiles_set, fname, &kh_ret); - tv_list_append_allocated_string(oldfiles_list, fname); - if (!want_marks) { - // Avoid free because this string was already used. - cur_entry.data.filemark.fname = NULL; - } + shada_free_shada_entry(&cur_entry); + break; + case kSDItemChange: + case kSDItemLocalMark: { + if (get_old_files && !in_strset(&oldfiles_set, + cur_entry.data.filemark.fname)) { + char *fname = cur_entry.data.filemark.fname; + if (want_marks) { + // Do not bother with allocating memory for the string if already + // allocated string from cur_entry can be used. It cannot be used if + // want_marks is set because this way it may be used for a mark. + fname = xstrdup(fname); } + int kh_ret; + (void)kh_put(strset, &oldfiles_set, fname, &kh_ret); + tv_list_append_allocated_string(oldfiles_list, fname); if (!want_marks) { - shada_free_shada_entry(&cur_entry); - break; + // Avoid free because this string was already used. + cur_entry.data.filemark.fname = NULL; } - buf_T *buf = find_buffer(&fname_bufs, cur_entry.data.filemark.fname); - if (buf == NULL) { + } + if (!want_marks) { + shada_free_shada_entry(&cur_entry); + break; + } + buf_T *buf = find_buffer(&fname_bufs, cur_entry.data.filemark.fname); + if (buf == NULL) { + shada_free_shada_entry(&cur_entry); + break; + } + const fmark_T fm = (fmark_T) { + .mark = cur_entry.data.filemark.mark, + .fnum = 0, + .timestamp = cur_entry.timestamp, + .additional_data = cur_entry.data.filemark.additional_data, + }; + if (cur_entry.type == kSDItemLocalMark) { + if (!mark_set_local(cur_entry.data.filemark.name, buf, fm, !force)) { shada_free_shada_entry(&cur_entry); break; } - const fmark_T fm = (fmark_T) { - .mark = cur_entry.data.filemark.mark, - .fnum = 0, - .timestamp = cur_entry.timestamp, - .additional_data = cur_entry.data.filemark.additional_data, - }; - if (cur_entry.type == kSDItemLocalMark) { - if (!mark_set_local(cur_entry.data.filemark.name, buf, fm, !force)) { - shada_free_shada_entry(&cur_entry); - break; - } - } else { - int kh_ret; - (void) kh_put(bufset, &cl_bufs, (uintptr_t) buf, &kh_ret); + } else { + int kh_ret; + (void)kh_put(bufset, &cl_bufs, (uintptr_t)buf, &kh_ret); #define SDE_TO_FMARK(entry) fm #define AFTERFREE(entry) (entry).data.filemark.fname = NULL #define DUMMY_IDX_ADJ(i) - MERGE_JUMPS(buf->b_changelistlen, buf->b_changelist, fmark_T, - timestamp, mark, cur_entry, true, - free_fmark, SDE_TO_FMARK, DUMMY_IDX_ADJ, AFTERFREE); + MERGE_JUMPS(buf->b_changelistlen, buf->b_changelist, fmark_T, + timestamp, mark, cur_entry, true, + free_fmark, SDE_TO_FMARK, DUMMY_IDX_ADJ, AFTERFREE); #undef SDE_TO_FMARK #undef AFTERFREE #undef DUMMY_IDX_ADJ - } - // Do not free shada entry: except for fname, its allocated memory (i.e. - // additional_data attribute contents if non-NULL) was saved above. - xfree(cur_entry.data.filemark.fname); - break; } + // Do not free shada entry: except for fname, its allocated memory (i.e. + // additional_data attribute contents if non-NULL) was saved above. + xfree(cur_entry.data.filemark.fname); + break; + } } } shada_read_main_cycle_end: @@ -1490,7 +1426,7 @@ shada_read_main_cycle_end: } if (cl_bufs.n_occupied) { FOR_ALL_TAB_WINDOWS(tp, wp) { - (void) tp; + (void)tp; if (in_bufset(&cl_bufs, wp->w_buffer)) { wp->w_changelistidx = wp->w_buffer->b_changelistlen; } @@ -1499,7 +1435,7 @@ shada_read_main_cycle_end: kh_dealloc(bufset, &cl_bufs); const char *key; kh_foreach_key(&fname_bufs, key, { - xfree((void *) key); + xfree((void *)key); }) kh_dealloc(fnamebufs, &fname_bufs); kh_dealloc(strset, &oldfiles_set); @@ -1535,7 +1471,7 @@ static char *shada_filename(const char *file) if (p_shadafile != NULL && *p_shadafile != NUL) { file = p_shadafile; } else { - if ((file = find_shada_parameter('n')) == NULL || *file == NUL) { + if ((file = (char *)find_shada_parameter('n')) == NULL || *file == NUL) { file = shada_get_default_file(); } // XXX It used to be one level lower, so that whatever is in @@ -1544,33 +1480,25 @@ static char *shada_filename(const char *file) // If shell is not performing them then they should be done in main.c // where arguments are parsed, *not here*. expand_env((char_u *)file, &(NameBuff[0]), MAXPATHL); - file = (const char *) &(NameBuff[0]); + file = (const char *)&(NameBuff[0]); } } return xstrdup(file); } #define PACK_STATIC_STR(s) \ - do { \ - msgpack_pack_str(spacker, sizeof(s) - 1); \ - msgpack_pack_str_body(spacker, s, sizeof(s) - 1); \ - } while (0) -#define PACK_STRING(s) \ - do { \ - const String s_ = (s); \ - msgpack_pack_str(spacker, s_.size); \ - if (s_.size) { \ - msgpack_pack_str_body(spacker, s_.data, s_.size); \ - } \ - } while (0) + do { \ + msgpack_pack_str(spacker, sizeof(s) - 1); \ + msgpack_pack_str_body(spacker, s, sizeof(s) - 1); \ + } while (0) #define PACK_BIN(s) \ - do { \ - const String s_ = (s); \ - msgpack_pack_bin(spacker, s_.size); \ - if (s_.size > 0) { \ - msgpack_pack_bin_body(spacker, s_.data, s_.size); \ - } \ - } while (0) + do { \ + const String s_ = (s); \ + msgpack_pack_bin(spacker, s_.size); \ + if (s_.size > 0) { \ + msgpack_pack_bin_body(spacker, s_.data, s_.size); \ + } \ + } while (0) /// Write single ShaDa entry /// @@ -1580,8 +1508,7 @@ static char *shada_filename(const char *file) /// restrictions. /// /// @return kSDWriteSuccessfull, kSDWriteFailed or kSDWriteIgnError. -static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer, - ShadaEntry entry, +static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer, ShadaEntry entry, const size_t max_kbyte) FUNC_ATTR_NONNULL_ALL { @@ -1625,244 +1552,243 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer, #define CHECK_DEFAULT(entry, attr) \ (sd_default_values[entry.type].data.attr == entry.data.attr) #define ONE_IF_NOT_DEFAULT(entry, attr) \ - ((size_t) (!CHECK_DEFAULT(entry, attr))) + ((size_t)(!CHECK_DEFAULT(entry, attr))) switch (entry.type) { - case kSDItemMissing: { - abort(); - } - case kSDItemUnknown: { - if (spacker->callback(spacker->data, entry.data.unknown_item.contents, - (unsigned) entry.data.unknown_item.size) == -1) { - goto shada_pack_entry_error; - } - break; + case kSDItemMissing: + abort(); + case kSDItemUnknown: + if (spacker->callback(spacker->data, entry.data.unknown_item.contents, + (unsigned)entry.data.unknown_item.size) == -1) { + goto shada_pack_entry_error; } - case kSDItemHistoryEntry: { - const bool is_hist_search = - entry.data.history_item.histtype == HIST_SEARCH; - const size_t arr_size = 2 + (size_t)is_hist_search + (size_t)( - tv_list_len(entry.data.history_item.additional_elements)); - msgpack_pack_array(spacker, arr_size); - msgpack_pack_uint8(spacker, entry.data.history_item.histtype); - PACK_BIN(cstr_as_string(entry.data.history_item.string)); - if (is_hist_search) { - msgpack_pack_uint8(spacker, (uint8_t)entry.data.history_item.sep); - } - DUMP_ADDITIONAL_ELEMENTS(entry.data.history_item.additional_elements, - "history entry item"); - break; + break; + case kSDItemHistoryEntry: { + const bool is_hist_search = + entry.data.history_item.histtype == HIST_SEARCH; + const size_t arr_size = 2 + (size_t)is_hist_search + (size_t)( + tv_list_len(entry.data. + history_item. + additional_elements)); + msgpack_pack_array(spacker, arr_size); + msgpack_pack_uint8(spacker, entry.data.history_item.histtype); + PACK_BIN(cstr_as_string(entry.data.history_item.string)); + if (is_hist_search) { + msgpack_pack_uint8(spacker, (uint8_t)entry.data.history_item.sep); } - case kSDItemVariable: { - if (entry.data.global_var.value.v_type == VAR_TYPE_BLOB) { - // Strings and Blobs both pack as msgpack BINs; differentiate them by - // storing an additional VAR_TYPE_BLOB element alongside Blobs - list_T *const list = tv_list_alloc(1); - tv_list_append_number(list, VAR_TYPE_BLOB); - entry.data.global_var.additional_elements = list; - } - const size_t arr_size = 2 + (size_t)( - tv_list_len(entry.data.global_var.additional_elements)); - msgpack_pack_array(spacker, arr_size); - const String varname = cstr_as_string(entry.data.global_var.name); - PACK_BIN(varname); - char vardesc[256] = "variable g:"; - memcpy(&vardesc[sizeof("variable g:") - 1], varname.data, - varname.size + 1); - if (encode_vim_to_msgpack(spacker, &entry.data.global_var.value, vardesc) - == FAIL) { - ret = kSDWriteIgnError; - EMSG2(_(WERR "Failed to write variable %s"), - entry.data.global_var.name); - goto shada_pack_entry_error; - } - DUMP_ADDITIONAL_ELEMENTS(entry.data.global_var.additional_elements, - "variable item"); - break; + DUMP_ADDITIONAL_ELEMENTS(entry.data.history_item.additional_elements, + "history entry item"); + break; + } + case kSDItemVariable: { + if (entry.data.global_var.value.v_type == VAR_TYPE_BLOB) { + // Strings and Blobs both pack as msgpack BINs; differentiate them by + // storing an additional VAR_TYPE_BLOB element alongside Blobs + list_T *const list = tv_list_alloc(1); + tv_list_append_number(list, VAR_TYPE_BLOB); + entry.data.global_var.additional_elements = list; } - case kSDItemSubString: { - const size_t arr_size = 1 + (size_t)( - tv_list_len(entry.data.sub_string.additional_elements)); - msgpack_pack_array(spacker, arr_size); - PACK_BIN(cstr_as_string(entry.data.sub_string.sub)); - DUMP_ADDITIONAL_ELEMENTS(entry.data.sub_string.additional_elements, - "sub string item"); - break; + const size_t arr_size = 2 + (size_t)( + tv_list_len(entry.data.global_var.additional_elements)); + msgpack_pack_array(spacker, arr_size); + const String varname = cstr_as_string(entry.data.global_var.name); + PACK_BIN(varname); + char vardesc[256] = "variable g:"; + memcpy(&vardesc[sizeof("variable g:") - 1], varname.data, + varname.size + 1); + if (encode_vim_to_msgpack(spacker, &entry.data.global_var.value, vardesc) + == FAIL) { + ret = kSDWriteIgnError; + EMSG2(_(WERR "Failed to write variable %s"), + entry.data.global_var.name); + goto shada_pack_entry_error; } - case kSDItemSearchPattern: { - const size_t map_size = (size_t) ( - 1 // Search pattern is always present - + ONE_IF_NOT_DEFAULT(entry, search_pattern.magic) - + ONE_IF_NOT_DEFAULT(entry, search_pattern.is_last_used) - + ONE_IF_NOT_DEFAULT(entry, search_pattern.smartcase) - + ONE_IF_NOT_DEFAULT(entry, search_pattern.has_line_offset) - + ONE_IF_NOT_DEFAULT(entry, search_pattern.place_cursor_at_end) - + ONE_IF_NOT_DEFAULT(entry, search_pattern.is_substitute_pattern) - + ONE_IF_NOT_DEFAULT(entry, search_pattern.highlighted) - + ONE_IF_NOT_DEFAULT(entry, search_pattern.offset) - + ONE_IF_NOT_DEFAULT(entry, search_pattern.search_backward) - // finally, additional data: - + (size_t) ( - entry.data.search_pattern.additional_data + DUMP_ADDITIONAL_ELEMENTS(entry.data.global_var.additional_elements, + "variable item"); + break; + } + case kSDItemSubString: { + const size_t arr_size = 1 + (size_t)( + tv_list_len(entry.data.sub_string.additional_elements)); + msgpack_pack_array(spacker, arr_size); + PACK_BIN(cstr_as_string(entry.data.sub_string.sub)); + DUMP_ADDITIONAL_ELEMENTS(entry.data.sub_string.additional_elements, + "sub string item"); + break; + } + case kSDItemSearchPattern: { + const size_t map_size = (size_t)( + 1 // Search pattern is always present + + ONE_IF_NOT_DEFAULT(entry, search_pattern.magic) + + ONE_IF_NOT_DEFAULT(entry, search_pattern.is_last_used) + + ONE_IF_NOT_DEFAULT(entry, search_pattern.smartcase) + + ONE_IF_NOT_DEFAULT(entry, search_pattern.has_line_offset) + + ONE_IF_NOT_DEFAULT(entry, search_pattern.place_cursor_at_end) + + ONE_IF_NOT_DEFAULT(entry, + search_pattern.is_substitute_pattern) + + ONE_IF_NOT_DEFAULT(entry, search_pattern.highlighted) + + ONE_IF_NOT_DEFAULT(entry, search_pattern.offset) + + ONE_IF_NOT_DEFAULT(entry, search_pattern.search_backward) + // finally, additional data: + + (size_t)( + entry.data.search_pattern.additional_data ? entry.data.search_pattern.additional_data->dv_hashtab.ht_used : 0)); - msgpack_pack_map(spacker, map_size); - PACK_STATIC_STR(SEARCH_KEY_PAT); - PACK_BIN(cstr_as_string(entry.data.search_pattern.pat)); + msgpack_pack_map(spacker, map_size); + PACK_STATIC_STR(SEARCH_KEY_PAT); + PACK_BIN(cstr_as_string(entry.data.search_pattern.pat)); #define PACK_BOOL(entry, name, attr) \ - do { \ - if (!CHECK_DEFAULT(entry, search_pattern.attr)) { \ - PACK_STATIC_STR(name); \ - if (sd_default_values[entry.type].data.search_pattern.attr) { \ - msgpack_pack_false(spacker); \ - } else { \ - msgpack_pack_true(spacker); \ - } \ - } \ - } while (0) - PACK_BOOL(entry, SEARCH_KEY_MAGIC, magic); - PACK_BOOL(entry, SEARCH_KEY_IS_LAST_USED, is_last_used); - PACK_BOOL(entry, SEARCH_KEY_SMARTCASE, smartcase); - PACK_BOOL(entry, SEARCH_KEY_HAS_LINE_OFFSET, has_line_offset); - PACK_BOOL(entry, SEARCH_KEY_PLACE_CURSOR_AT_END, place_cursor_at_end); - PACK_BOOL(entry, SEARCH_KEY_IS_SUBSTITUTE_PATTERN, is_substitute_pattern); - PACK_BOOL(entry, SEARCH_KEY_HIGHLIGHTED, highlighted); - PACK_BOOL(entry, SEARCH_KEY_BACKWARD, search_backward); - if (!CHECK_DEFAULT(entry, search_pattern.offset)) { - PACK_STATIC_STR(SEARCH_KEY_OFFSET); - msgpack_pack_int64(spacker, entry.data.search_pattern.offset); - } -#undef PACK_BOOL - DUMP_ADDITIONAL_DATA(entry.data.search_pattern.additional_data, - "search pattern item"); - break; + do { \ + if (!CHECK_DEFAULT(entry, search_pattern.attr)) { \ + PACK_STATIC_STR(name); \ + if (sd_default_values[entry.type].data.search_pattern.attr) { \ + msgpack_pack_false(spacker); \ + } else { \ + msgpack_pack_true(spacker); \ + } \ + } \ + } while (0) + PACK_BOOL(entry, SEARCH_KEY_MAGIC, magic); + PACK_BOOL(entry, SEARCH_KEY_IS_LAST_USED, is_last_used); + PACK_BOOL(entry, SEARCH_KEY_SMARTCASE, smartcase); + PACK_BOOL(entry, SEARCH_KEY_HAS_LINE_OFFSET, has_line_offset); + PACK_BOOL(entry, SEARCH_KEY_PLACE_CURSOR_AT_END, place_cursor_at_end); + PACK_BOOL(entry, SEARCH_KEY_IS_SUBSTITUTE_PATTERN, is_substitute_pattern); + PACK_BOOL(entry, SEARCH_KEY_HIGHLIGHTED, highlighted); + PACK_BOOL(entry, SEARCH_KEY_BACKWARD, search_backward); + if (!CHECK_DEFAULT(entry, search_pattern.offset)) { + PACK_STATIC_STR(SEARCH_KEY_OFFSET); + msgpack_pack_int64(spacker, entry.data.search_pattern.offset); } - case kSDItemChange: - case kSDItemGlobalMark: - case kSDItemLocalMark: - case kSDItemJump: { - const size_t map_size = (size_t) ( - 1 // File name - + ONE_IF_NOT_DEFAULT(entry, filemark.mark.lnum) - + ONE_IF_NOT_DEFAULT(entry, filemark.mark.col) - + ONE_IF_NOT_DEFAULT(entry, filemark.name) - // Additional entries, if any: - + (size_t) ( - entry.data.filemark.additional_data == NULL +#undef PACK_BOOL + DUMP_ADDITIONAL_DATA(entry.data.search_pattern.additional_data, + "search pattern item"); + break; + } + case kSDItemChange: + case kSDItemGlobalMark: + case kSDItemLocalMark: + case kSDItemJump: { + const size_t map_size = (size_t)( + 1 // File name + + ONE_IF_NOT_DEFAULT(entry, filemark.mark.lnum) + + ONE_IF_NOT_DEFAULT(entry, filemark.mark.col) + + ONE_IF_NOT_DEFAULT(entry, filemark.name) + // Additional entries, if any: + + (size_t)( + entry.data.filemark.additional_data == NULL ? 0 : entry.data.filemark.additional_data->dv_hashtab.ht_used)); - msgpack_pack_map(spacker, map_size); - PACK_STATIC_STR(KEY_FILE); - PACK_BIN(cstr_as_string(entry.data.filemark.fname)); - if (!CHECK_DEFAULT(entry, filemark.mark.lnum)) { - PACK_STATIC_STR(KEY_LNUM); - msgpack_pack_long(spacker, entry.data.filemark.mark.lnum); - } - if (!CHECK_DEFAULT(entry, filemark.mark.col)) { - PACK_STATIC_STR(KEY_COL); - msgpack_pack_long(spacker, entry.data.filemark.mark.col); - } - assert(entry.type == kSDItemJump || entry.type == kSDItemChange + msgpack_pack_map(spacker, map_size); + PACK_STATIC_STR(KEY_FILE); + PACK_BIN(cstr_as_string(entry.data.filemark.fname)); + if (!CHECK_DEFAULT(entry, filemark.mark.lnum)) { + PACK_STATIC_STR(KEY_LNUM); + msgpack_pack_long(spacker, entry.data.filemark.mark.lnum); + } + if (!CHECK_DEFAULT(entry, filemark.mark.col)) { + PACK_STATIC_STR(KEY_COL); + msgpack_pack_long(spacker, entry.data.filemark.mark.col); + } + assert(entry.type == kSDItemJump || entry.type == kSDItemChange ? CHECK_DEFAULT(entry, filemark.name) : true); - if (!CHECK_DEFAULT(entry, filemark.name)) { - PACK_STATIC_STR(KEY_NAME_CHAR); - msgpack_pack_uint8(spacker, (uint8_t) entry.data.filemark.name); - } - DUMP_ADDITIONAL_DATA(entry.data.filemark.additional_data, - "mark (change, jump, global or local) item"); - break; + if (!CHECK_DEFAULT(entry, filemark.name)) { + PACK_STATIC_STR(KEY_NAME_CHAR); + msgpack_pack_uint8(spacker, (uint8_t)entry.data.filemark.name); } - case kSDItemRegister: { - const size_t map_size = (size_t) ( - 2 // Register contents and name - + ONE_IF_NOT_DEFAULT(entry, reg.type) - + ONE_IF_NOT_DEFAULT(entry, reg.width) - + ONE_IF_NOT_DEFAULT(entry, reg.is_unnamed) - // Additional entries, if any: - + (size_t) (entry.data.reg.additional_data == NULL + DUMP_ADDITIONAL_DATA(entry.data.filemark.additional_data, + "mark (change, jump, global or local) item"); + break; + } + case kSDItemRegister: { + const size_t map_size = (size_t)( + 2 // Register contents and name + + ONE_IF_NOT_DEFAULT(entry, reg.type) + + ONE_IF_NOT_DEFAULT(entry, reg.width) + + ONE_IF_NOT_DEFAULT(entry, reg.is_unnamed) + // Additional entries, if any: + + (size_t)(entry.data.reg.additional_data == NULL ? 0 : entry.data.reg.additional_data->dv_hashtab.ht_used)); - msgpack_pack_map(spacker, map_size); - PACK_STATIC_STR(REG_KEY_CONTENTS); - msgpack_pack_array(spacker, entry.data.reg.contents_size); - for (size_t i = 0; i < entry.data.reg.contents_size; i++) { - PACK_BIN(cstr_as_string(entry.data.reg.contents[i])); - } - PACK_STATIC_STR(KEY_NAME_CHAR); - msgpack_pack_char(spacker, entry.data.reg.name); - if (!CHECK_DEFAULT(entry, reg.type)) { - PACK_STATIC_STR(REG_KEY_TYPE); - msgpack_pack_uint8(spacker, (uint8_t)entry.data.reg.type); - } - if (!CHECK_DEFAULT(entry, reg.width)) { - PACK_STATIC_STR(REG_KEY_WIDTH); - msgpack_pack_uint64(spacker, (uint64_t) entry.data.reg.width); - } - if (!CHECK_DEFAULT(entry, reg.is_unnamed)) { - PACK_STATIC_STR(REG_KEY_UNNAMED); - if (entry.data.reg.is_unnamed) { - msgpack_pack_true(spacker); - } else { - msgpack_pack_false(spacker); - } + msgpack_pack_map(spacker, map_size); + PACK_STATIC_STR(REG_KEY_CONTENTS); + msgpack_pack_array(spacker, entry.data.reg.contents_size); + for (size_t i = 0; i < entry.data.reg.contents_size; i++) { + PACK_BIN(cstr_as_string(entry.data.reg.contents[i])); + } + PACK_STATIC_STR(KEY_NAME_CHAR); + msgpack_pack_char(spacker, entry.data.reg.name); + if (!CHECK_DEFAULT(entry, reg.type)) { + PACK_STATIC_STR(REG_KEY_TYPE); + msgpack_pack_uint8(spacker, (uint8_t)entry.data.reg.type); + } + if (!CHECK_DEFAULT(entry, reg.width)) { + PACK_STATIC_STR(REG_KEY_WIDTH); + msgpack_pack_uint64(spacker, (uint64_t)entry.data.reg.width); + } + if (!CHECK_DEFAULT(entry, reg.is_unnamed)) { + PACK_STATIC_STR(REG_KEY_UNNAMED); + if (entry.data.reg.is_unnamed) { + msgpack_pack_true(spacker); + } else { + msgpack_pack_false(spacker); } - DUMP_ADDITIONAL_DATA(entry.data.reg.additional_data, "register item"); - break; } - case kSDItemBufferList: { - msgpack_pack_array(spacker, entry.data.buffer_list.size); - for (size_t i = 0; i < entry.data.buffer_list.size; i++) { - const size_t map_size = (size_t) ( - 1 // Buffer name - + (size_t) (entry.data.buffer_list.buffers[i].pos.lnum - != default_pos.lnum) - + (size_t) (entry.data.buffer_list.buffers[i].pos.col - != default_pos.col) - // Additional entries, if any: - + (size_t) ( - entry.data.buffer_list.buffers[i].additional_data == NULL + DUMP_ADDITIONAL_DATA(entry.data.reg.additional_data, "register item"); + break; + } + case kSDItemBufferList: + msgpack_pack_array(spacker, entry.data.buffer_list.size); + for (size_t i = 0; i < entry.data.buffer_list.size; i++) { + const size_t map_size = (size_t)( + 1 // Buffer name + + (size_t)(entry.data.buffer_list.buffers[i].pos.lnum + != default_pos.lnum) + + (size_t)(entry.data.buffer_list.buffers[i].pos.col + != default_pos.col) + // Additional entries, if any: + + (size_t)( + entry.data.buffer_list.buffers[i].additional_data + == NULL ? 0 : (entry.data.buffer_list.buffers[i].additional_data ->dv_hashtab.ht_used))); - msgpack_pack_map(spacker, map_size); - PACK_STATIC_STR(KEY_FILE); - PACK_BIN(cstr_as_string(entry.data.buffer_list.buffers[i].fname)); - if (entry.data.buffer_list.buffers[i].pos.lnum != 1) { - PACK_STATIC_STR(KEY_LNUM); - msgpack_pack_uint64( - spacker, (uint64_t) entry.data.buffer_list.buffers[i].pos.lnum); - } - if (entry.data.buffer_list.buffers[i].pos.col != 0) { - PACK_STATIC_STR(KEY_COL); - msgpack_pack_uint64( - spacker, (uint64_t) entry.data.buffer_list.buffers[i].pos.col); - } - DUMP_ADDITIONAL_DATA(entry.data.buffer_list.buffers[i].additional_data, - "buffer list subitem"); + msgpack_pack_map(spacker, map_size); + PACK_STATIC_STR(KEY_FILE); + PACK_BIN(cstr_as_string(entry.data.buffer_list.buffers[i].fname)); + if (entry.data.buffer_list.buffers[i].pos.lnum != 1) { + PACK_STATIC_STR(KEY_LNUM); + msgpack_pack_uint64(spacker, (uint64_t)entry.data.buffer_list.buffers[i].pos.lnum); } - break; + if (entry.data.buffer_list.buffers[i].pos.col != 0) { + PACK_STATIC_STR(KEY_COL); + msgpack_pack_uint64(spacker, (uint64_t)entry.data.buffer_list.buffers[i].pos.col); + } + DUMP_ADDITIONAL_DATA(entry.data.buffer_list.buffers[i].additional_data, + "buffer list subitem"); } - case kSDItemHeader: { - msgpack_pack_map(spacker, entry.data.header.size); - for (size_t i = 0; i < entry.data.header.size; i++) { - PACK_STRING(entry.data.header.items[i].key); - const Object obj = entry.data.header.items[i].value; - switch (obj.type) { - case kObjectTypeString: { - PACK_BIN(obj.data.string); - break; - } - case kObjectTypeInteger: { - msgpack_pack_int64(spacker, (int64_t) obj.data.integer); - break; - } - default: { - abort(); - } - } + break; + case kSDItemHeader: + msgpack_pack_map(spacker, entry.data.header.size); + for (size_t i = 0; i < entry.data.header.size; i++) { + const String s = entry.data.header.items[i].key; + msgpack_pack_str(spacker, s.size); + if (s.size) { + msgpack_pack_str_body(spacker, s.data, s.size); + } + const Object obj = entry.data.header.items[i].value; + switch (obj.type) { + case kObjectTypeString: + PACK_BIN(obj.data.string); + break; + case kObjectTypeInteger: + msgpack_pack_int64(spacker, (int64_t)obj.data.integer); + break; + default: + abort(); } - break; } + break; } #undef CHECK_DEFAULT #undef ONE_IF_NOT_DEFAULT @@ -1872,17 +1798,17 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer, goto shada_pack_entry_error; } } else { - if (msgpack_pack_uint64(packer, (uint64_t) entry.type) == -1) { + if (msgpack_pack_uint64(packer, (uint64_t)entry.type) == -1) { goto shada_pack_entry_error; } } - if (msgpack_pack_uint64(packer, (uint64_t) entry.timestamp) == -1) { + if (msgpack_pack_uint64(packer, (uint64_t)entry.timestamp) == -1) { goto shada_pack_entry_error; } if (sbuf.size > 0) { - if ((msgpack_pack_uint64(packer, (uint64_t) sbuf.size) == -1) + if ((msgpack_pack_uint64(packer, (uint64_t)sbuf.size) == -1) || (packer->callback(packer->data, sbuf.data, - (unsigned) sbuf.size) == -1)) { + (unsigned)sbuf.size) == -1)) { goto shada_pack_entry_error; } } @@ -1895,7 +1821,6 @@ shada_pack_entry_error: msgpack_sbuffer_destroy(&sbuf); return ret; } -#undef PACK_STRING /// Write single ShaDa entry and free it afterwards /// @@ -1905,9 +1830,9 @@ shada_pack_entry_error: /// @param[in] entry Entry written. /// @param[in] max_kbyte Maximum size of an item in KiB. Zero means no /// restrictions. -static inline ShaDaWriteResult shada_pack_pfreed_entry( - msgpack_packer *const packer, PossiblyFreedShadaEntry entry, - const size_t max_kbyte) +static inline ShaDaWriteResult shada_pack_pfreed_entry(msgpack_packer *const packer, + PossiblyFreedShadaEntry entry, + const size_t max_kbyte) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE { ShaDaWriteResult ret = kSDWriteSuccessfull; @@ -1945,9 +1870,10 @@ static int compare_file_marks(const void *a, const void *b) /// /// @return kSDReadStatusNotShaDa, kSDReadStatusReadError or /// kSDReadStatusSuccess. -static inline ShaDaReadResult shada_parse_msgpack( - ShaDaReadDef *const sd_reader, const size_t length, - msgpack_unpacked *ret_unpacked, char **const ret_buf) +static inline ShaDaReadResult shada_parse_msgpack(ShaDaReadDef *const sd_reader, + const size_t length, + msgpack_unpacked *ret_unpacked, + char **const ret_buf) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1) { const uintmax_t initial_fpos = sd_reader->fpos; @@ -1964,47 +1890,42 @@ shada_parse_msgpack_read_next: {} msgpack_unpacked unpacked; msgpack_unpacked_init(&unpacked); const msgpack_unpack_return result = - msgpack_unpack_next(&unpacked, buf, length, &off); + msgpack_unpack_next(&unpacked, buf, length, &off); ShaDaReadResult ret = kSDReadStatusSuccess; switch (result) { - case MSGPACK_UNPACK_SUCCESS: { - if (off < length) { - goto shada_parse_msgpack_extra_bytes; - } - break; + case MSGPACK_UNPACK_SUCCESS: + if (off < length) { + goto shada_parse_msgpack_extra_bytes; } - case MSGPACK_UNPACK_PARSE_ERROR: { - emsgf(_(RCERR "Failed to parse ShaDa file due to a msgpack parser error " - "at position %" PRIu64), - (uint64_t) initial_fpos); - ret = kSDReadStatusNotShaDa; - break; + break; + case MSGPACK_UNPACK_PARSE_ERROR: + emsgf(_(RCERR "Failed to parse ShaDa file due to a msgpack parser error " + "at position %" PRIu64), + (uint64_t)initial_fpos); + ret = kSDReadStatusNotShaDa; + break; + case MSGPACK_UNPACK_NOMEM_ERROR: + if (!did_try_to_free) { + did_try_to_free = true; + try_to_free_memory(); + goto shada_parse_msgpack_read_next; } - case MSGPACK_UNPACK_NOMEM_ERROR: { - if (!did_try_to_free) { - did_try_to_free = true; - try_to_free_memory(); - goto shada_parse_msgpack_read_next; - } - EMSG(_(e_outofmem)); - ret = kSDReadStatusReadError; - break; - } - case MSGPACK_UNPACK_CONTINUE: { - emsgf(_(RCERR "Failed to parse ShaDa file: incomplete msgpack string " - "at position %" PRIu64), - (uint64_t) initial_fpos); - ret = kSDReadStatusNotShaDa; - break; - } - case MSGPACK_UNPACK_EXTRA_BYTES: { + EMSG(_(e_outofmem)); + ret = kSDReadStatusReadError; + break; + case MSGPACK_UNPACK_CONTINUE: + emsgf(_(RCERR "Failed to parse ShaDa file: incomplete msgpack string " + "at position %" PRIu64), + (uint64_t)initial_fpos); + ret = kSDReadStatusNotShaDa; + break; + case MSGPACK_UNPACK_EXTRA_BYTES: shada_parse_msgpack_extra_bytes: - emsgf(_(RCERR "Failed to parse ShaDa file: extra bytes in msgpack string " - "at position %" PRIu64), - (uint64_t) initial_fpos); - ret = kSDReadStatusNotShaDa; - break; - } + emsgf(_(RCERR "Failed to parse ShaDa file: extra bytes in msgpack string " + "at position %" PRIu64), + (uint64_t)initial_fpos); + ret = kSDReadStatusNotShaDa; + break; } if (ret_buf != NULL && ret == kSDReadStatusSuccess) { if (ret_unpacked == NULL) { @@ -2034,81 +1955,67 @@ static const char *shada_format_entry(const ShadaEntry entry) vim_snprintf(S_LEN(ret), "%s", "[ ] ts=%" PRIu64 " "); // ^ Space for `can_free_entry` switch (entry.type) { - case kSDItemMissing: { - vim_snprintf_add(S_LEN(ret), "Missing"); - break; - } - case kSDItemHeader: { - vim_snprintf_add(S_LEN(ret), "Header { TODO }"); - break; - } - case kSDItemBufferList: { - vim_snprintf_add(S_LEN(ret), "BufferList { TODO }"); - break; - } - case kSDItemUnknown: { - vim_snprintf_add(S_LEN(ret), "Unknown { TODO }"); - break; - } - case kSDItemSearchPattern: { - vim_snprintf_add(S_LEN(ret), "SearchPattern { TODO }"); - break; - } - case kSDItemSubString: { - vim_snprintf_add(S_LEN(ret), "SubString { TODO }"); - break; - } - case kSDItemHistoryEntry: { - vim_snprintf_add(S_LEN(ret), "HistoryEntry { TODO }"); - break; - } - case kSDItemRegister: { - vim_snprintf_add(S_LEN(ret), "Register { TODO }"); - break; - } - case kSDItemVariable: { - vim_snprintf_add(S_LEN(ret), "Variable { TODO }"); - break; - } + case kSDItemMissing: + vim_snprintf_add(S_LEN(ret), "Missing"); + break; + case kSDItemHeader: + vim_snprintf_add(S_LEN(ret), "Header { TODO }"); + break; + case kSDItemBufferList: + vim_snprintf_add(S_LEN(ret), "BufferList { TODO }"); + break; + case kSDItemUnknown: + vim_snprintf_add(S_LEN(ret), "Unknown { TODO }"); + break; + case kSDItemSearchPattern: + vim_snprintf_add(S_LEN(ret), "SearchPattern { TODO }"); + break; + case kSDItemSubString: + vim_snprintf_add(S_LEN(ret), "SubString { TODO }"); + break; + case kSDItemHistoryEntry: + vim_snprintf_add(S_LEN(ret), "HistoryEntry { TODO }"); + break; + case kSDItemRegister: + vim_snprintf_add(S_LEN(ret), "Register { TODO }"); + break; + case kSDItemVariable: + vim_snprintf_add(S_LEN(ret), "Variable { TODO }"); + break; #define FORMAT_MARK_ENTRY(entry_name, name_fmt, name_fmt_arg) \ - do { \ - typval_T ad_tv = { \ - .v_type = VAR_DICT, \ - .vval.v_dict = entry.data.filemark.additional_data \ - }; \ - size_t ad_len; \ - char *const ad = encode_tv2string(&ad_tv, &ad_len); \ - vim_snprintf_add( \ - S_LEN(ret), \ - entry_name " {" name_fmt " file=[%zu]\"%.512s\", " \ - "pos={l=%" PRIdLINENR ",c=%" PRIdCOLNR ",a=%" PRIdCOLNR "}, " \ - "ad={%p:[%zu]%.64s} }", \ - name_fmt_arg, \ - strlen(entry.data.filemark.fname), \ - entry.data.filemark.fname, \ - entry.data.filemark.mark.lnum, \ - entry.data.filemark.mark.col, \ - entry.data.filemark.mark.coladd, \ - (void *)entry.data.filemark.additional_data, \ - ad_len, \ - ad); \ - } while (0) - case kSDItemGlobalMark: { - FORMAT_MARK_ENTRY("GlobalMark", " name='%c',", entry.data.filemark.name); - break; - } - case kSDItemChange: { - FORMAT_MARK_ENTRY("Change", "%s", ""); - break; - } - case kSDItemLocalMark: { - FORMAT_MARK_ENTRY("LocalMark", " name='%c',", entry.data.filemark.name); - break; - } - case kSDItemJump: { - FORMAT_MARK_ENTRY("Jump", "%s", ""); - break; - } + do { \ + typval_T ad_tv = { \ + .v_type = VAR_DICT, \ + .vval.v_dict = entry.data.filemark.additional_data \ + }; \ + size_t ad_len; \ + char *const ad = encode_tv2string(&ad_tv, &ad_len); \ + vim_snprintf_add(S_LEN(ret), \ + entry_name " {" name_fmt " file=[%zu]\"%.512s\", " \ + "pos={l=%" PRIdLINENR ",c=%" PRIdCOLNR ",a=%" PRIdCOLNR "}, " \ + "ad={%p:[%zu]%.64s} }", \ + name_fmt_arg, \ + strlen(entry.data.filemark.fname), \ + entry.data.filemark.fname, \ + entry.data.filemark.mark.lnum, \ + entry.data.filemark.mark.col, \ + entry.data.filemark.mark.coladd, \ + (void *)entry.data.filemark.additional_data, \ + ad_len, \ + ad); \ + } while (0) + case kSDItemGlobalMark: + FORMAT_MARK_ENTRY("GlobalMark", " name='%c',", entry.data.filemark.name); + break; + case kSDItemChange: + FORMAT_MARK_ENTRY("Change", "%s", ""); + break; + case kSDItemLocalMark: + FORMAT_MARK_ENTRY("LocalMark", " name='%c',", entry.data.filemark.name); + break; + case kSDItemJump: + FORMAT_MARK_ENTRY("Jump", "%s", ""); + break; #undef FORMAT_MARK_ENTRY } return ret; @@ -2119,8 +2026,7 @@ static const char *shada_format_entry(const ShadaEntry entry) /// @param[in] entry ShaDa entry to format. /// /// @return string representing ShaDa entry in a static buffer. -static const char *shada_format_pfreed_entry( - const PossiblyFreedShadaEntry pfs_entry) +static const char *shada_format_pfreed_entry(const PossiblyFreedShadaEntry pfs_entry) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_UNUSED FUNC_ATTR_NONNULL_RET { char *ret = (char *)shada_format_entry(pfs_entry.data); @@ -2136,10 +2042,11 @@ static const char *shada_format_pfreed_entry( /// @param[in,out] ret_wms Location where results are saved. /// @param[out] packer MessagePack packer for entries which are not /// merged. -static inline ShaDaWriteResult shada_read_when_writing( - ShaDaReadDef *const sd_reader, const unsigned srni_flags, - const size_t max_kbyte, WriteMergerState *const wms, - msgpack_packer *const packer) +static inline ShaDaWriteResult shada_read_when_writing(ShaDaReadDef *const sd_reader, + const unsigned srni_flags, + const size_t max_kbyte, + WriteMergerState *const wms, + msgpack_packer *const packer) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { ShaDaWriteResult ret = kSDWriteSuccessfull; @@ -2149,217 +2056,202 @@ static inline ShaDaWriteResult shada_read_when_writing( max_kbyte)) != kSDReadStatusFinished) { switch (srni_ret) { - case kSDReadStatusSuccess: { - break; - } - case kSDReadStatusFinished: { - // Should be handled by the while condition. - abort(); - } - case kSDReadStatusNotShaDa: { - ret = kSDWriteReadNotShada; - FALLTHROUGH; - } - case kSDReadStatusReadError: { - return ret; - } - case kSDReadStatusMalformed: { - continue; - } + case kSDReadStatusSuccess: + break; + case kSDReadStatusFinished: + // Should be handled by the while condition. + abort(); + case kSDReadStatusNotShaDa: + ret = kSDWriteReadNotShada; + FALLTHROUGH; + case kSDReadStatusReadError: + return ret; + case kSDReadStatusMalformed: + continue; } #define COMPARE_WITH_ENTRY(wms_entry_, entry) \ - do { \ - PossiblyFreedShadaEntry *const wms_entry = (wms_entry_); \ - if (wms_entry->data.type != kSDItemMissing) { \ - if (wms_entry->data.timestamp >= (entry).timestamp) { \ - shada_free_shada_entry(&(entry)); \ - break; \ - } \ - if (wms_entry->can_free_entry) { \ - shada_free_shada_entry(&wms_entry->data); \ - } \ + do { \ + PossiblyFreedShadaEntry *const wms_entry = (wms_entry_); \ + if (wms_entry->data.type != kSDItemMissing) { \ + if (wms_entry->data.timestamp >= (entry).timestamp) { \ + shada_free_shada_entry(&(entry)); \ + break; \ + } \ + if (wms_entry->can_free_entry) { \ + shada_free_shada_entry(&wms_entry->data); \ } \ - *wms_entry = pfs_entry; \ - } while (0) + } \ + *wms_entry = pfs_entry; \ + } while (0) const PossiblyFreedShadaEntry pfs_entry = { .can_free_entry = true, .data = entry, }; switch (entry.type) { - case kSDItemMissing: { + case kSDItemMissing: + break; + case kSDItemHeader: + case kSDItemBufferList: + abort(); + case kSDItemUnknown: + ret = shada_pack_entry(packer, entry, 0); + shada_free_shada_entry(&entry); + break; + case kSDItemSearchPattern: + COMPARE_WITH_ENTRY((entry.data.search_pattern.is_substitute_pattern + ? &wms->sub_search_pattern + : &wms->search_pattern), entry); + break; + case kSDItemSubString: + COMPARE_WITH_ENTRY(&wms->replacement, entry); + break; + case kSDItemHistoryEntry: + if (entry.data.history_item.histtype >= HIST_COUNT) { + ret = shada_pack_entry(packer, entry, 0); + shada_free_shada_entry(&entry); break; } - case kSDItemHeader: - case kSDItemBufferList: { - abort(); + if (wms->hms[entry.data.history_item.histtype].hmll.size != 0) { + hms_insert(&wms->hms[entry.data.history_item.histtype], entry, true, + true); + } else { + shada_free_shada_entry(&entry); } - case kSDItemUnknown: { + break; + case kSDItemRegister: { + const int idx = op_reg_index(entry.data.reg.name); + if (idx < 0) { ret = shada_pack_entry(packer, entry, 0); shada_free_shada_entry(&entry); break; } - case kSDItemSearchPattern: { - COMPARE_WITH_ENTRY((entry.data.search_pattern.is_substitute_pattern - ? &wms->sub_search_pattern - : &wms->search_pattern), entry); - break; - } - case kSDItemSubString: { - COMPARE_WITH_ENTRY(&wms->replacement, entry); - break; + COMPARE_WITH_ENTRY(&wms->registers[idx], entry); + break; + } + case kSDItemVariable: + if (!in_strset(&wms->dumped_variables, entry.data.global_var.name)) { + ret = shada_pack_entry(packer, entry, 0); } - case kSDItemHistoryEntry: { - if (entry.data.history_item.histtype >= HIST_COUNT) { - ret = shada_pack_entry(packer, entry, 0); - shada_free_shada_entry(&entry); - break; + shada_free_shada_entry(&entry); + break; + case kSDItemGlobalMark: + if (ascii_isdigit(entry.data.filemark.name)) { + bool processed_mark = false; + // Completely ignore numbered mark names, make a list sorted by + // timestamp. + for (size_t i = ARRAY_SIZE(wms->numbered_marks); i > 0; i--) { + ShadaEntry wms_entry = wms->numbered_marks[i - 1].data; + if (wms_entry.type != kSDItemGlobalMark) { + continue; + } + // Ignore duplicates. + if (wms_entry.timestamp == entry.timestamp + && (wms_entry.data.filemark.additional_data == NULL + && entry.data.filemark.additional_data == NULL) + && marks_equal(wms_entry.data.filemark.mark, + entry.data.filemark.mark) + && strcmp(wms_entry.data.filemark.fname, + entry.data.filemark.fname) == 0) { + shada_free_shada_entry(&entry); + processed_mark = true; + break; + } + if (wms_entry.timestamp >= entry.timestamp) { + processed_mark = true; + if (i < ARRAY_SIZE(wms->numbered_marks)) { + replace_numbered_mark(wms, i, pfs_entry); + } else { + shada_free_shada_entry(&entry); + } + break; + } } - if (wms->hms[entry.data.history_item.histtype].hmll.size != 0) { - hms_insert(&wms->hms[entry.data.history_item.histtype], entry, true, - true); - } else { - shada_free_shada_entry(&entry); + if (!processed_mark) { + replace_numbered_mark(wms, 0, pfs_entry); } - break; - } - case kSDItemRegister: { - const int idx = op_reg_index(entry.data.reg.name); + } else { + const int idx = mark_global_index(entry.data.filemark.name); if (idx < 0) { ret = shada_pack_entry(packer, entry, 0); shada_free_shada_entry(&entry); break; } - COMPARE_WITH_ENTRY(&wms->registers[idx], entry); - break; + COMPARE_WITH_ENTRY(&wms->global_marks[idx], entry); } - case kSDItemVariable: { - if (!in_strset(&wms->dumped_variables, entry.data.global_var.name)) { - ret = shada_pack_entry(packer, entry, 0); - } + break; + case kSDItemChange: + case kSDItemLocalMark: { + if (shada_removable(entry.data.filemark.fname)) { shada_free_shada_entry(&entry); break; } - case kSDItemGlobalMark: { - if (ascii_isdigit(entry.data.filemark.name)) { - bool processed_mark = false; - // Completely ignore numbered mark names, make a list sorted by - // timestamp. - for (size_t i = ARRAY_SIZE(wms->numbered_marks); i > 0; i--) { - ShadaEntry wms_entry = wms->numbered_marks[i - 1].data; - if (wms_entry.type != kSDItemGlobalMark) { - continue; - } - // Ignore duplicates. - if (wms_entry.timestamp == entry.timestamp - && (wms_entry.data.filemark.additional_data == NULL - && entry.data.filemark.additional_data == NULL) - && marks_equal(wms_entry.data.filemark.mark, - entry.data.filemark.mark) - && strcmp(wms_entry.data.filemark.fname, - entry.data.filemark.fname) == 0) { + const char *const fname = (const char *)entry.data.filemark.fname; + khiter_t k; + int kh_ret; + k = kh_put(file_marks, &wms->file_marks, fname, &kh_ret); + FileMarks *const filemarks = &kh_val(&wms->file_marks, k); + if (kh_ret > 0) { + memset(filemarks, 0, sizeof(*filemarks)); + } + if (entry.timestamp > filemarks->greatest_timestamp) { + filemarks->greatest_timestamp = entry.timestamp; + } + if (entry.type == kSDItemLocalMark) { + const int idx = mark_local_index(entry.data.filemark.name); + if (idx < 0) { + filemarks->additional_marks = xrealloc(filemarks->additional_marks, + (++filemarks->additional_marks_size + * sizeof(filemarks->additional_marks[0]))); + filemarks->additional_marks[filemarks->additional_marks_size - 1] = + entry; + } else { + PossiblyFreedShadaEntry *const wms_entry = &filemarks->marks[idx]; + if (wms_entry->data.type != kSDItemMissing) { + if (wms_entry->data.timestamp >= entry.timestamp) { shada_free_shada_entry(&entry); - processed_mark = true; break; } - if (wms_entry.timestamp >= entry.timestamp) { - processed_mark = true; - if (i < ARRAY_SIZE(wms->numbered_marks)) { - replace_numbered_mark(wms, i, pfs_entry); - } else { - shada_free_shada_entry(&entry); + if (wms_entry->can_free_entry) { + if (kh_key(&wms->file_marks, k) + == wms_entry->data.data.filemark.fname) { + kh_key(&wms->file_marks, k) = entry.data.filemark.fname; } - break; + shada_free_shada_entry(&wms_entry->data); } } - if (!processed_mark) { - replace_numbered_mark(wms, 0, pfs_entry); - } - } else { - const int idx = mark_global_index(entry.data.filemark.name); - if (idx < 0) { - ret = shada_pack_entry(packer, entry, 0); - shada_free_shada_entry(&entry); - break; - } - COMPARE_WITH_ENTRY(&wms->global_marks[idx], entry); - } - break; - } - case kSDItemChange: - case kSDItemLocalMark: { - if (shada_removable(entry.data.filemark.fname)) { - shada_free_shada_entry(&entry); - break; + *wms_entry = pfs_entry; } - const char *const fname = (const char *) entry.data.filemark.fname; - khiter_t k; - int kh_ret; - k = kh_put(file_marks, &wms->file_marks, fname, &kh_ret); - FileMarks *const filemarks = &kh_val(&wms->file_marks, k); - if (kh_ret > 0) { - memset(filemarks, 0, sizeof(*filemarks)); - } - if (entry.timestamp > filemarks->greatest_timestamp) { - filemarks->greatest_timestamp = entry.timestamp; - } - if (entry.type == kSDItemLocalMark) { - const int idx = mark_local_index(entry.data.filemark.name); - if (idx < 0) { - filemarks->additional_marks = xrealloc( - filemarks->additional_marks, - (++filemarks->additional_marks_size - * sizeof(filemarks->additional_marks[0]))); - filemarks->additional_marks[filemarks->additional_marks_size - 1] = - entry; - } else { - PossiblyFreedShadaEntry *const wms_entry = &filemarks->marks[idx]; - if (wms_entry->data.type != kSDItemMissing) { - if (wms_entry->data.timestamp >= entry.timestamp) { - shada_free_shada_entry(&entry); - break; - } - if (wms_entry->can_free_entry) { - if (kh_key(&wms->file_marks, k) - == wms_entry->data.data.filemark.fname) { - kh_key(&wms->file_marks, k) = entry.data.filemark.fname; - } - shada_free_shada_entry(&wms_entry->data); - } - } - *wms_entry = pfs_entry; - } - } else { + } else { #define FREE_POSSIBLY_FREED_SHADA_ENTRY(entry) \ - do { \ - if (entry.can_free_entry) { \ - shada_free_shada_entry(&entry.data); \ - } \ - } while (0) + do { \ + if (entry.can_free_entry) { \ + shada_free_shada_entry(&entry.data); \ + } \ + } while (0) #define SDE_TO_PFSDE(entry) \ - ((PossiblyFreedShadaEntry) { .can_free_entry = true, .data = entry }) + ((PossiblyFreedShadaEntry) { .can_free_entry = true, .data = entry }) #define AFTERFREE_DUMMY(entry) #define DUMMY_IDX_ADJ(i) - MERGE_JUMPS(filemarks->changes_size, filemarks->changes, - PossiblyFreedShadaEntry, data.timestamp, - data.data.filemark.mark, entry, true, - FREE_POSSIBLY_FREED_SHADA_ENTRY, SDE_TO_PFSDE, - DUMMY_IDX_ADJ, AFTERFREE_DUMMY); - } - break; - } - case kSDItemJump: { - MERGE_JUMPS(wms->jumps_size, wms->jumps, PossiblyFreedShadaEntry, - data.timestamp, data.data.filemark.mark, entry, - strcmp(jl_entry.data.data.filemark.fname, - entry.data.filemark.fname) == 0, + MERGE_JUMPS(filemarks->changes_size, filemarks->changes, + PossiblyFreedShadaEntry, data.timestamp, + data.data.filemark.mark, entry, true, FREE_POSSIBLY_FREED_SHADA_ENTRY, SDE_TO_PFSDE, DUMMY_IDX_ADJ, AFTERFREE_DUMMY); + } + break; + } + case kSDItemJump: + MERGE_JUMPS(wms->jumps_size, wms->jumps, PossiblyFreedShadaEntry, + data.timestamp, data.data.filemark.mark, entry, + strcmp(jl_entry.data.data.filemark.fname, + entry.data.filemark.fname) == 0, + FREE_POSSIBLY_FREED_SHADA_ENTRY, SDE_TO_PFSDE, + DUMMY_IDX_ADJ, AFTERFREE_DUMMY); #undef FREE_POSSIBLY_FREED_SHADA_ENTRY #undef SDE_TO_PFSDE #undef DUMMY_IDX_ADJ #undef AFTERFREE_DUMMY - break; - } + break; } } #undef COMPARE_WITH_ENTRY @@ -2372,8 +2264,7 @@ static inline ShaDaWriteResult shada_read_when_writing( /// @param[in] removable_bufs Cache of buffers ignored due to their location. /// /// @return true or false. -static inline bool ignore_buf(const buf_T *const buf, - khash_t(bufset) *const removable_bufs) +static inline bool ignore_buf(const buf_T *const buf, khash_t(bufset) *const removable_bufs) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE { return (buf->b_ffname == NULL || !buf->b_p_bl || bt_quickfix(buf) \ @@ -2385,8 +2276,7 @@ static inline bool ignore_buf(const buf_T *const buf, /// @param[in] removable_bufs Buffers which are ignored /// /// @return ShadaEntry List of buffers to save, kSDItemBufferList entry. -static inline ShadaEntry shada_get_buflist( - khash_t(bufset) *const removable_bufs) +static inline ShadaEntry shada_get_buflist(khash_t(bufset) *const removable_bufs) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE { int max_bufs = get_shada_parameter('%'); @@ -2400,14 +2290,14 @@ static inline ShadaEntry shada_get_buflist( ShadaEntry buflist_entry = (ShadaEntry) { .type = kSDItemBufferList, - .timestamp = os_time(), - .data = { - .buffer_list = { - .size = buf_count, - .buffers = xmalloc(buf_count - * sizeof(*buflist_entry.data.buffer_list.buffers)), - }, + .timestamp = os_time(), + .data = { + .buffer_list = { + .size = buf_count, + .buffers = xmalloc(buf_count + * sizeof(*buflist_entry.data.buffer_list.buffers)), }, + }, }; size_t i = 0; FOR_ALL_BUFFERS(buf) { @@ -2419,8 +2309,8 @@ static inline ShadaEntry shada_get_buflist( } buflist_entry.data.buffer_list.buffers[i] = (struct buffer_list_buffer) { .pos = buf->b_last_cursor.mark, - .fname = (char *)buf->b_ffname, - .additional_data = buf->additional_data, + .fname = (char *)buf->b_ffname, + .additional_data = buf->additional_data, }; i++; } @@ -2442,8 +2332,7 @@ static inline ShadaEntry shada_get_buflist( /// saved. static inline void add_search_pattern(PossiblyFreedShadaEntry *const ret_pse, const SearchPatternGetter get_pattern, - const bool is_substitute_pattern, - const bool search_last_used, + const bool is_substitute_pattern, const bool search_last_used, const bool search_highlighted) FUNC_ATTR_ALWAYS_INLINE { @@ -2464,7 +2353,7 @@ static inline void add_search_pattern(PossiblyFreedShadaEntry *const ret_pse, ? defaults.data.search_pattern.has_line_offset : pat.off.line), .place_cursor_at_end = ( - is_substitute_pattern + is_substitute_pattern ? defaults.data.search_pattern.place_cursor_at_end : pat.off.end), .offset = (is_substitute_pattern @@ -2488,8 +2377,7 @@ static inline void add_search_pattern(PossiblyFreedShadaEntry *const ret_pse, /// /// @param[in] wms The WriteMergerState used when writing. /// @param[in] max_reg_lines The maximum number of register lines. -static inline void shada_initialize_registers(WriteMergerState *const wms, - int max_reg_lines) +static inline void shada_initialize_registers(WriteMergerState *const wms, int max_reg_lines) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE { const void *reg_iter = NULL; @@ -2513,7 +2401,7 @@ static inline void shada_initialize_registers(WriteMergerState *const wms, .data = { .reg = { .contents = (char **)reg.y_array, - .contents_size = (size_t)reg.y_size, + .contents_size = reg.y_size, .type = reg.y_type, .width = (size_t)(reg.y_type == kMTBlockWise ? reg.y_width : 0), .additional_data = reg.additional_data, @@ -2534,8 +2422,7 @@ static inline void shada_initialize_registers(WriteMergerState *const wms, /// @param[out] wms Merger state to adjust. /// @param[in] idx Index at which new mark should be placed. /// @param[in] entry New mark. -static inline void replace_numbered_mark(WriteMergerState *const wms, - const size_t idx, +static inline void replace_numbered_mark(WriteMergerState *const wms, const size_t idx, const PossiblyFreedShadaEntry entry) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE { @@ -2573,8 +2460,7 @@ static inline void find_removable_bufs(khash_t(bufset) *removable_bufs) /// @param[in] sd_reader Structure containing file reader definition. If it is /// not NULL then contents of this file will be merged /// with current Neovim runtime. -static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, - ShaDaReadDef *const sd_reader) +static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef *const sd_reader) FUNC_ATTR_NONNULL_ARG(1) { ShaDaWriteResult ret = kSDWriteSuccessfull; @@ -2595,8 +2481,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, } const bool dump_registers = (max_reg_lines != 0); khash_t(bufset) removable_bufs = KHASH_EMPTY_TABLE(bufset); - const size_t max_kbyte = (size_t) max_kbyte_i; - const size_t num_marked_files = (size_t) get_shada_parameter('\''); + const size_t max_kbyte = (size_t)max_kbyte_i; + const size_t num_marked_files = (size_t)get_shada_parameter('\''); const bool dump_global_marks = get_shada_parameter('f') != 0; bool dump_history = false; @@ -2609,20 +2495,21 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, if (num_saved > 0) { dump_history = true; dump_one_history[i] = true; - hms_init(&wms->hms[i], i, (size_t) num_saved, sd_reader != NULL, false); + hms_init(&wms->hms[i], i, (size_t)num_saved, sd_reader != NULL, false); } else { dump_one_history[i] = false; } } - const unsigned srni_flags = (unsigned) ( - kSDReadUndisableableData - | kSDReadUnknown - | (dump_history ? kSDReadHistory : 0) - | (dump_registers ? kSDReadRegisters : 0) - | (dump_global_vars ? kSDReadVariables : 0) - | (dump_global_marks ? kSDReadGlobalMarks : 0) - | (num_marked_files ? kSDReadLocalMarks | kSDReadChanges : 0)); + const unsigned srni_flags = (unsigned)( + kSDReadUndisableableData + | kSDReadUnknown + | (dump_history ? kSDReadHistory : 0) + | (dump_registers ? kSDReadRegisters : 0) + | (dump_global_vars ? kSDReadVariables : 0) + | (dump_global_marks ? kSDReadGlobalMarks : 0) + | (num_marked_files ? kSDReadLocalMarks | + kSDReadChanges : 0)); msgpack_packer *const packer = msgpack_packer_new(sd_writer, &msgpack_sd_writer_write); @@ -2652,11 +2539,11 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, { STATIC_CSTR_AS_STRING("version"), STRING_OBJ(cstr_as_string(longVersion)) }, { STATIC_CSTR_AS_STRING("max_kbyte"), - INTEGER_OBJ((Integer) max_kbyte) }, + INTEGER_OBJ((Integer)max_kbyte) }, { STATIC_CSTR_AS_STRING("pid"), - INTEGER_OBJ((Integer) os_get_pid()) }, + INTEGER_OBJ((Integer)os_get_pid()) }, { STATIC_CSTR_AS_STRING("encoding"), - STRING_OBJ(cstr_as_string((char *) p_enc)) }, + STRING_OBJ(cstr_as_string((char *)p_enc)) }, }), } } @@ -2688,34 +2575,32 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, break; } switch (vartv.v_type) { - case VAR_FUNC: - case VAR_PARTIAL: + case VAR_FUNC: + case VAR_PARTIAL: + tv_clear(&vartv); + continue; + case VAR_DICT: { + dict_T *di = vartv.vval.v_dict; + int copyID = get_copyID(); + if (!set_ref_in_ht(&di->dv_hashtab, copyID, NULL) + && copyID == di->dv_copyID) { tv_clear(&vartv); continue; - case VAR_DICT: - { - dict_T *di = vartv.vval.v_dict; - int copyID = get_copyID(); - if (!set_ref_in_ht(&di->dv_hashtab, copyID, NULL) - && copyID == di->dv_copyID) { - tv_clear(&vartv); - continue; - } - break; - } - case VAR_LIST: - { - list_T *l = vartv.vval.v_list; - int copyID = get_copyID(); - if (!set_ref_in_list(l, copyID, NULL) - && copyID == l->lv_copyID) { - tv_clear(&vartv); - continue; - } - break; - } - default: - break; + } + break; + } + case VAR_LIST: { + list_T *l = vartv.vval.v_list; + int copyID = get_copyID(); + if (!set_ref_in_list(l, copyID, NULL) + && copyID == l->lv_copyID) { + tv_clear(&vartv); + continue; + } + break; + } + default: + break; } typval_T tgttv; tv_copy(&vartv, &tgttv); @@ -2725,7 +2610,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, .timestamp = cur_timestamp, .data = { .global_var = { - .name = (char *) name, + .name = (char *)name, .value = tgttv, .additional_elements = NULL, } @@ -2740,7 +2625,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, tv_clear(&tgttv); if (spe_ret == kSDWriteSuccessfull) { int kh_ret; - (void) kh_put(strset, &wms->dumped_variables, name, &kh_ret); + (void)kh_put(strset, &wms->dumped_variables, name, &kh_ret); } } while (var_iter != NULL); } @@ -2773,7 +2658,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, .timestamp = sub.timestamp, .data = { .sub_string = { - .sub = (char *) sub.sub, + .sub = sub.sub, .additional_elements = sub.additional_elements, } } @@ -2795,17 +2680,17 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, const char *fname; if (fm.fmark.fnum == 0) { assert(fm.fname != NULL); - if (shada_removable((const char *) fm.fname)) { + if (shada_removable((const char *)fm.fname)) { continue; } - fname = (const char *) fm.fname; + fname = (const char *)fm.fname; } else { const buf_T *const buf = buflist_findnr(fm.fmark.fnum); if (buf == NULL || buf->b_ffname == NULL || in_bufset(&removable_bufs, buf)) { continue; } - fname = (const char *) buf->b_ffname; + fname = (const char *)buf->b_ffname; } const PossiblyFreedShadaEntry pf_entry = { .can_free_entry = false, @@ -2842,7 +2727,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, continue; } const void *local_marks_iter = NULL; - const char *const fname = (const char *) buf->b_ffname; + const char *const fname = (const char *)buf->b_ffname; khiter_t k; int kh_ret; k = kh_put(file_marks, &wms->file_marks, fname, &kh_ret); @@ -2866,7 +2751,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, .filemark = { .mark = fm.mark, .name = name, - .fname = (char *) fname, + .fname = (char *)fname, .additional_data = fm.additional_data, } } @@ -2886,7 +2771,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, .data = { .filemark = { .mark = fm.mark, - .fname = (char *) fname, + .fname = (char *)fname, .additional_data = fm.additional_data, } } @@ -2896,13 +2781,13 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, filemarks->greatest_timestamp = fm.timestamp; } } - filemarks->changes_size = (size_t) buf->b_changelistlen; + filemarks->changes_size = (size_t)buf->b_changelistlen; } } if (sd_reader != NULL) { - const ShaDaWriteResult srww_ret = shada_read_when_writing( - sd_reader, srni_flags, max_kbyte, wms, packer); + const ShaDaWriteResult srww_ret = shada_read_when_writing(sd_reader, srni_flags, max_kbyte, wms, + packer); if (srww_ret != kSDWriteSuccessfull) { ret = srww_ret; } @@ -2968,7 +2853,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, const size_t file_markss_size = kh_size(&wms->file_marks); FileMarks **const all_file_markss = - xmalloc(file_markss_size * sizeof(*all_file_markss)); + xmalloc(file_markss_size * sizeof(*all_file_markss)); FileMarks **cur_file_marks = all_file_markss; for (khint_t i = kh_begin(&wms->file_marks); i != kh_end(&wms->file_marks); i++) { @@ -2976,7 +2861,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, *cur_file_marks++ = &kh_val(&wms->file_marks, i); } } - qsort((void *) all_file_markss, file_markss_size, sizeof(*all_file_markss), + qsort((void *)all_file_markss, file_markss_size, sizeof(*all_file_markss), &compare_file_marks); const size_t file_markss_to_dump = MIN(num_marked_files, file_markss_size); for (size_t i = 0; i < file_markss_to_dump; i++) { @@ -3007,11 +2892,10 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, if (dump_one_history[i]) { hms_insert_whole_neovim_history(&wms->hms[i]); HMS_ITER(&wms->hms[i], cur_entry, { - if (shada_pack_pfreed_entry( - packer, (PossiblyFreedShadaEntry) { - .data = cur_entry->data, - .can_free_entry = cur_entry->can_free_entry, - }, max_kbyte) == kSDWriteFailed) { + if (shada_pack_pfreed_entry(packer, (PossiblyFreedShadaEntry) { + .data = cur_entry->data, + .can_free_entry = cur_entry->can_free_entry, + }, max_kbyte) == kSDWriteFailed) { ret = kSDWriteFailed; break; } @@ -3037,7 +2921,6 @@ shada_write_exit: return ret; } -#undef IGNORE_BUF #undef PACK_STATIC_STR /// Write ShaDa file to a given location @@ -3082,7 +2965,7 @@ int shada_write_file(const char *const file, bool nomerge) } // Save permissions from the original file, with modifications: - int perm = (int) os_getperm(fname); + int perm = (int)os_getperm(fname); perm = (perm >= 0) ? ((perm & 0777) | 0600) : 0600; // ^3 ^1 ^2 ^2,3 // 1: Strip SUID bit if any. @@ -3090,8 +2973,7 @@ int shada_write_file(const char *const file, bool nomerge) // 3: If somebody happened to delete the file after it was opened for // reading use u=rw permissions. shada_write_file_open: {} - sd_writer.cookie = file_open_new( - &error, tempname, kFileCreateOnly|kFileNoSymlink, perm); + sd_writer.cookie = file_open_new(&error, tempname, kFileCreateOnly|kFileNoSymlink, perm); if (sd_writer.cookie == NULL) { if (error == UV_EEXIST || error == UV_ELOOP) { // File already exists, try another name @@ -3118,11 +3000,11 @@ shada_write_file_open: {} } if (nomerge) { shada_write_file_nomerge: {} - char *const tail = path_tail_with_sep(fname); + char *const tail = (char *)path_tail_with_sep((char_u *)fname); if (tail != fname) { const char tail_save = *tail; *tail = NUL; - if (!os_isdir(fname)) { + if (!os_isdir((char_u *)fname)) { int ret; char *failed_dir; if ((ret = os_mkdir_recurse(fname, 0700, &failed_dir)) != 0) { @@ -3173,7 +3055,7 @@ shada_write_file_nomerge: {} // overwrite a user’s viminfo file after a "su root", with a // viminfo file that the user can't read. FileInfo old_info; - if (os_fileinfo((char *)fname, &old_info)) { + if (os_fileinfo(fname, &old_info)) { if (getuid() == ROOT_UID) { if (old_info.stat.st_uid != ROOT_UID || old_info.stat.st_gid != getgid()) { @@ -3197,7 +3079,7 @@ shada_write_file_nomerge: {} } } #endif - if (vim_rename(tempname, fname) == -1) { + if (vim_rename((char_u *)tempname, (char_u *)fname) == -1) { EMSG3(_(RNERR "Can't rename ShaDa file from %s to %s!"), tempname, fname); } else { @@ -3244,8 +3126,7 @@ int shada_read_marks(void) /// @param[in] missing_ok If true, do not error out when file is missing. /// /// @return OK in case of success, FAIL otherwise. -int shada_read_everything(const char *const fname, const bool forceit, - const bool missing_ok) +int shada_read_everything(const char *const fname, const bool forceit, const bool missing_ok) { return shada_read_file(fname, kShaDaWantInfo|kShaDaWantMarks|kShaDaGetOldfiles @@ -3259,81 +3140,71 @@ static void shada_free_shada_entry(ShadaEntry *const entry) return; } switch (entry->type) { - case kSDItemMissing: { - break; + case kSDItemMissing: + break; + case kSDItemUnknown: + xfree(entry->data.unknown_item.contents); + break; + case kSDItemHeader: + api_free_dictionary(entry->data.header); + break; + case kSDItemChange: + case kSDItemJump: + case kSDItemGlobalMark: + case kSDItemLocalMark: + tv_dict_unref(entry->data.filemark.additional_data); + xfree(entry->data.filemark.fname); + break; + case kSDItemSearchPattern: + tv_dict_unref(entry->data.search_pattern.additional_data); + xfree(entry->data.search_pattern.pat); + break; + case kSDItemRegister: + tv_dict_unref(entry->data.reg.additional_data); + for (size_t i = 0; i < entry->data.reg.contents_size; i++) { + xfree(entry->data.reg.contents[i]); } - case kSDItemUnknown: { - xfree(entry->data.unknown_item.contents); - break; - } - case kSDItemHeader: { - api_free_dictionary(entry->data.header); - break; - } - case kSDItemChange: - case kSDItemJump: - case kSDItemGlobalMark: - case kSDItemLocalMark: { - tv_dict_unref(entry->data.filemark.additional_data); - xfree(entry->data.filemark.fname); - break; - } - case kSDItemSearchPattern: { - tv_dict_unref(entry->data.search_pattern.additional_data); - xfree(entry->data.search_pattern.pat); - break; - } - case kSDItemRegister: { - tv_dict_unref(entry->data.reg.additional_data); - for (size_t i = 0; i < entry->data.reg.contents_size; i++) { - xfree(entry->data.reg.contents[i]); - } - xfree(entry->data.reg.contents); - break; - } - case kSDItemHistoryEntry: { - tv_list_unref(entry->data.history_item.additional_elements); - xfree(entry->data.history_item.string); - break; - } - case kSDItemVariable: { - tv_list_unref(entry->data.global_var.additional_elements); - xfree(entry->data.global_var.name); - tv_clear(&entry->data.global_var.value); - break; - } - case kSDItemSubString: { - tv_list_unref(entry->data.sub_string.additional_elements); - xfree(entry->data.sub_string.sub); - break; - } - case kSDItemBufferList: { - for (size_t i = 0; i < entry->data.buffer_list.size; i++) { - xfree(entry->data.buffer_list.buffers[i].fname); - tv_dict_unref(entry->data.buffer_list.buffers[i].additional_data); - } - xfree(entry->data.buffer_list.buffers); - break; + xfree(entry->data.reg.contents); + break; + case kSDItemHistoryEntry: + tv_list_unref(entry->data.history_item.additional_elements); + xfree(entry->data.history_item.string); + break; + case kSDItemVariable: + tv_list_unref(entry->data.global_var.additional_elements); + xfree(entry->data.global_var.name); + tv_clear(&entry->data.global_var.value); + break; + case kSDItemSubString: + tv_list_unref(entry->data.sub_string.additional_elements); + xfree(entry->data.sub_string.sub); + break; + case kSDItemBufferList: + for (size_t i = 0; i < entry->data.buffer_list.size; i++) { + xfree(entry->data.buffer_list.buffers[i].fname); + tv_dict_unref(entry->data.buffer_list.buffers[i].additional_data); } + xfree(entry->data.buffer_list.buffers); + break; } } #ifndef HAVE_BE64TOH static inline uint64_t be64toh(uint64_t big_endian_64_bits) { -#ifdef ORDER_BIG_ENDIAN +# ifdef ORDER_BIG_ENDIAN return big_endian_64_bits; -#else +# else // It may appear that when !defined(ORDER_BIG_ENDIAN) actual order is big // endian. This variant is suboptimal, but it works regardless of actual // order. - uint8_t *buf = (uint8_t *) &big_endian_64_bits; + uint8_t *buf = (uint8_t *)&big_endian_64_bits; uint64_t ret = 0; for (size_t i = 8; i; i--) { - ret |= ((uint64_t) buf[i - 1]) << ((8 - i) * 8); + ret |= ((uint64_t)buf[i - 1]) << ((8 - i) * 8); } return ret; -#endif +# endif } #endif @@ -3346,8 +3217,7 @@ static inline uint64_t be64toh(uint64_t big_endian_64_bits) /// @return kSDReadStatusSuccess if everything was OK, kSDReadStatusNotShaDa if /// there were not enough bytes to read or kSDReadStatusReadError if /// there was some error while reading. -static ShaDaReadResult fread_len(ShaDaReadDef *const sd_reader, - char *const buffer, +static ShaDaReadResult fread_len(ShaDaReadDef *const sd_reader, char *const buffer, const size_t length) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { @@ -3385,8 +3255,7 @@ static ShaDaReadResult fread_len(ShaDaReadDef *const sd_reader, /// @return kSDReadStatusSuccess if reading was successful, /// kSDReadStatusNotShaDa if there were not enough bytes to read or /// kSDReadStatusReadError if reading failed for whatever reason. -static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, - const int first_char, +static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, const int first_char, uint64_t *const result) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { @@ -3401,42 +3270,37 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, emsgf(_(RCERR "Error while reading ShaDa file: " "expected positive integer at position %" PRIu64 ", but got nothing"), - (uint64_t) fpos); + (uint64_t)fpos); return kSDReadStatusNotShaDa; } } if (~first_char & 0x80) { // Positive fixnum - *result = (uint64_t) ((uint8_t) first_char); + *result = (uint64_t)((uint8_t)first_char); } else { size_t length = 0; switch (first_char) { - case 0xCC: { // uint8 - length = 1; - break; - } - case 0xCD: { // uint16 - length = 2; - break; - } - case 0xCE: { // uint32 - length = 4; - break; - } - case 0xCF: { // uint64 - length = 8; - break; - } - default: { - emsgf(_(RCERR "Error while reading ShaDa file: " - "expected positive integer at position %" PRIu64), - (uint64_t) fpos); - return kSDReadStatusNotShaDa; - } + case 0xCC: // uint8 + length = 1; + break; + case 0xCD: // uint16 + length = 2; + break; + case 0xCE: // uint32 + length = 4; + break; + case 0xCF: // uint64 + length = 8; + break; + default: + emsgf(_(RCERR "Error while reading ShaDa file: " + "expected positive integer at position %" PRIu64), + (uint64_t)fpos); + return kSDReadStatusNotShaDa; } uint64_t buf = 0; - char *buf_u8 = (char *) &buf; + char *buf_u8 = (char *)&buf; ShaDaReadResult fl_ret; if ((fl_ret = fread_len(sd_reader, &(buf_u8[sizeof(buf)-length]), length)) != kSDReadStatusSuccess) { @@ -3448,24 +3312,24 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, } #define READERR(entry_name, error_desc) \ - RERR "Error while reading ShaDa file: " \ - entry_name " entry at position %" PRIu64 " " \ - error_desc + RERR "Error while reading ShaDa file: " \ + entry_name " entry at position %" PRIu64 " " \ + error_desc #define CHECK_KEY(key, expected) ( \ - key.via.str.size == sizeof(expected) - 1 \ - && STRNCMP(key.via.str.ptr, expected, sizeof(expected) - 1) == 0) + key.via.str.size == sizeof(expected) - 1 \ + && STRNCMP(key.via.str.ptr, expected, sizeof(expected) - 1) == 0) #define CLEAR_GA_AND_ERROR_OUT(ga) \ - do { \ - ga_clear(&ga); \ - goto shada_read_next_item_error; \ - } while (0) + do { \ + ga_clear(&ga); \ + goto shada_read_next_item_error; \ + } while (0) #define ID(s) s #define BINDUP(b) xmemdupz(b.ptr, b.size) -#define TOINT(s) ((int) (s)) -#define TOLONG(s) ((long) (s)) -#define TOCHAR(s) ((char) (s)) -#define TOU8(s) ((uint8_t) (s)) -#define TOSIZE(s) ((size_t) (s)) +#define TOINT(s) ((int)(s)) +#define TOLONG(s) ((long)(s)) +#define TOCHAR(s) ((char)(s)) +#define TOU8(s) ((uint8_t)(s)) +#define TOSIZE(s) ((size_t)(s)) #define CHECKED_ENTRY(condition, error_desc, entry_name, obj, tgt, attr, \ proc) \ do { \ @@ -3486,18 +3350,16 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, } #define CHECKED_KEY(un, entry_name, name, error_desc, tgt, condition, attr, \ proc) \ - else if (CHECK_KEY( /* NOLINT(readability/braces) */ \ - un.data.via.map.ptr[i].key, name)) { \ - CHECKED_ENTRY( \ - condition, "has " name " key value " error_desc, \ - entry_name, un.data.via.map.ptr[i].val, \ - tgt, attr, proc); \ + else if (CHECK_KEY( /* NOLINT(readability/braces) */ \ + un.data.via.map.ptr[i].key, name)) { \ + CHECKED_ENTRY(condition, "has " name " key value " error_desc, \ + entry_name, un.data.via.map.ptr[i].val, \ + tgt, attr, proc); \ } #define TYPED_KEY(un, entry_name, name, type_name, tgt, objtype, attr, proc) \ - CHECKED_KEY( \ - un, entry_name, name, "which is not " type_name, tgt, \ - un.data.via.map.ptr[i].val.type == MSGPACK_OBJECT_##objtype, \ - attr, proc) + CHECKED_KEY(un, entry_name, name, "which is not " type_name, tgt, \ + un.data.via.map.ptr[i].val.type == MSGPACK_OBJECT_##objtype, \ + attr, proc) #define BOOLEAN_KEY(un, entry_name, name, tgt) \ TYPED_KEY(un, entry_name, name, "a boolean", tgt, BOOLEAN, boolean, ID) #define STRING_KEY(un, entry_name, name, tgt) \ @@ -3506,19 +3368,18 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, TYPED_KEY(un, entry_name, name, "a binary", tgt, BIN, bin, \ BIN_CONVERTED) #define INT_KEY(un, entry_name, name, tgt, proc) \ - CHECKED_KEY( \ - un, entry_name, name, "which is not an integer", tgt, \ - ((un.data.via.map.ptr[i].val.type \ - == MSGPACK_OBJECT_POSITIVE_INTEGER) \ - || (un.data.via.map.ptr[i].val.type \ - == MSGPACK_OBJECT_NEGATIVE_INTEGER)), \ - i64, proc) + CHECKED_KEY(un, entry_name, name, "which is not an integer", tgt, \ + ((un.data.via.map.ptr[i].val.type \ + == MSGPACK_OBJECT_POSITIVE_INTEGER) \ + || (un.data.via.map.ptr[i].val.type \ + == MSGPACK_OBJECT_NEGATIVE_INTEGER)), \ + i64, proc) #define INTEGER_KEY(un, entry_name, name, tgt) \ INT_KEY(un, entry_name, name, tgt, TOINT) #define LONG_KEY(un, entry_name, name, tgt) \ INT_KEY(un, entry_name, name, tgt, TOLONG) #define ADDITIONAL_KEY(un) \ - else { /* NOLINT(readability/braces) */ \ + else { /* NOLINT(readability/braces) */ \ ga_grow(&ad_ga, 1); \ memcpy(((char *)ad_ga.ga_data) + ((size_t)ad_ga.ga_len \ * sizeof(*un.data.via.map.ptr)), \ @@ -3526,57 +3387,56 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, sizeof(*un.data.via.map.ptr)); \ ad_ga.ga_len++; \ } -#define CONVERTED(str, len) (xmemdupz((str), (len))) -#define BIN_CONVERTED(b) CONVERTED(b.ptr, b.size) +#define BIN_CONVERTED(b) (xmemdupz((b.ptr), (b.size))) #define SET_ADDITIONAL_DATA(tgt, name) \ - do { \ - if (ad_ga.ga_len) { \ - msgpack_object obj = { \ - .type = MSGPACK_OBJECT_MAP, \ - .via = { \ - .map = { \ - .size = (uint32_t) ad_ga.ga_len, \ - .ptr = ad_ga.ga_data, \ - } \ - } \ - }; \ - typval_T adtv; \ - if (msgpack_to_vim(obj, &adtv) == FAIL \ - || adtv.v_type != VAR_DICT) { \ - emsgf(_(READERR(name, \ - "cannot be converted to a VimL dictionary")), \ - initial_fpos); \ - ga_clear(&ad_ga); \ - tv_clear(&adtv); \ - goto shada_read_next_item_error; \ + do { \ + if (ad_ga.ga_len) { \ + msgpack_object obj = { \ + .type = MSGPACK_OBJECT_MAP, \ + .via = { \ + .map = { \ + .size = (uint32_t)ad_ga.ga_len, \ + .ptr = ad_ga.ga_data, \ } \ - tgt = adtv.vval.v_dict; \ } \ + }; \ + typval_T adtv; \ + if (msgpack_to_vim(obj, &adtv) == FAIL \ + || adtv.v_type != VAR_DICT) { \ + emsgf(_(READERR(name, \ + "cannot be converted to a VimL dictionary")), \ + initial_fpos); \ ga_clear(&ad_ga); \ - } while (0) + tv_clear(&adtv); \ + goto shada_read_next_item_error; \ + } \ + tgt = adtv.vval.v_dict; \ + } \ + ga_clear(&ad_ga); \ + } while (0) #define SET_ADDITIONAL_ELEMENTS(src, src_maxsize, tgt, name) \ - do { \ - if ((src).size > (size_t) (src_maxsize)) { \ - msgpack_object obj = { \ - .type = MSGPACK_OBJECT_ARRAY, \ - .via = { \ - .array = { \ - .size = ((src).size - (uint32_t) (src_maxsize)), \ - .ptr = (src).ptr + (src_maxsize), \ - } \ - } \ - }; \ - typval_T aetv; \ - if (msgpack_to_vim(obj, &aetv) == FAIL) { \ - emsgf(_(READERR(name, "cannot be converted to a VimL list")), \ - initial_fpos); \ - tv_clear(&aetv); \ - goto shada_read_next_item_error; \ + do { \ + if ((src).size > (size_t)(src_maxsize)) { \ + msgpack_object obj = { \ + .type = MSGPACK_OBJECT_ARRAY, \ + .via = { \ + .array = { \ + .size = ((src).size - (uint32_t)(src_maxsize)), \ + .ptr = (src).ptr + (src_maxsize), \ } \ - assert(aetv.v_type == VAR_LIST); \ - (tgt) = aetv.vval.v_list; \ } \ - } while (0) + }; \ + typval_T aetv; \ + if (msgpack_to_vim(obj, &aetv) == FAIL) { \ + emsgf(_(READERR(name, "cannot be converted to a VimL list")), \ + initial_fpos); \ + tv_clear(&aetv); \ + goto shada_read_next_item_error; \ + } \ + assert(aetv.v_type == VAR_LIST); \ + (tgt) = aetv.vval.v_list; \ + } \ + } while (0) /// Iterate over shada file contents /// @@ -3588,10 +3448,8 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, /// greater then given. /// /// @return Any value from ShaDaReadResult enum. -static ShaDaReadResult shada_read_next_item(ShaDaReadDef *const sd_reader, - ShadaEntry *const entry, - const unsigned flags, - const size_t max_kbyte) +static ShaDaReadResult shada_read_next_item(ShaDaReadDef *const sd_reader, ShadaEntry *const entry, + const unsigned flags, const size_t max_kbyte) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { ShaDaReadResult ret = kSDReadStatusMalformed; @@ -3607,11 +3465,11 @@ shada_read_next_item_start: // First: manually unpack type, timestamp and length. // This is needed to avoid both seeking and having to maintain a buffer. - uint64_t type_u64 = (uint64_t) kSDItemMissing; + uint64_t type_u64 = (uint64_t)kSDItemMissing; uint64_t timestamp_u64; uint64_t length_u64; - const uint64_t initial_fpos = (uint64_t) sd_reader->fpos; + const uint64_t initial_fpos = (uint64_t)sd_reader->fpos; const int first_char = read_char(sd_reader); if (first_char == EOF && sd_reader->eof) { return kSDReadStatusFinished; @@ -3654,7 +3512,7 @@ shada_read_next_item_start: if ((type_u64 > SHADA_LAST_ENTRY ? !(flags & kSDReadUnknown) - : !((unsigned) (1 << type_u64) & flags)) + : !((unsigned)(1 << type_u64) & flags)) || (max_kbyte && length > max_kbyte * 1024)) { // First entry is unknown or equal to "\n" (10)? Most likely this means that // current file is not a ShaDa file because first item should normally be @@ -3682,16 +3540,16 @@ shada_read_next_item_start: entry->data.unknown_item.size = length; entry->data.unknown_item.type = type_u64; if (initial_fpos == 0) { - const ShaDaReadResult spm_ret = shada_parse_msgpack( - sd_reader, length, NULL, &entry->data.unknown_item.contents); + const ShaDaReadResult spm_ret = shada_parse_msgpack(sd_reader, length, NULL, + &entry->data.unknown_item.contents); if (spm_ret != kSDReadStatusSuccess) { entry->type = kSDItemMissing; } return spm_ret; } else { entry->data.unknown_item.contents = xmalloc(length); - const ShaDaReadResult fl_ret = fread_len( - sd_reader, entry->data.unknown_item.contents, length); + const ShaDaReadResult fl_ret = + fread_len(sd_reader, entry->data.unknown_item.contents, length); if (fl_ret != kSDReadStatusSuccess) { shada_free_shada_entry(entry); entry->type = kSDItemMissing; @@ -3711,373 +3569,367 @@ shada_read_next_item_start: } ret = kSDReadStatusMalformed; entry->data = sd_default_values[type_u64].data; - switch ((ShadaEntryType) type_u64) { - case kSDItemHeader: { - if (!msgpack_rpc_to_dictionary(&(unpacked.data), &(entry->data.header))) { - emsgf(_(READERR("header", "is not a dictionary")), initial_fpos); - goto shada_read_next_item_error; - } - break; + switch ((ShadaEntryType)type_u64) { + case kSDItemHeader: + if (!msgpack_rpc_to_dictionary(&(unpacked.data), &(entry->data.header))) { + emsgf(_(READERR("header", "is not a dictionary")), initial_fpos); + goto shada_read_next_item_error; } - case kSDItemSearchPattern: { - if (unpacked.data.type != MSGPACK_OBJECT_MAP) { - emsgf(_(READERR("search pattern", "is not a dictionary")), - initial_fpos); - goto shada_read_next_item_error; - } - garray_T ad_ga; - ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1); - for (size_t i = 0; i < unpacked.data.via.map.size; i++) { - CHECK_KEY_IS_STR(unpacked, "search pattern") - BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_MAGIC, - entry->data.search_pattern.magic) - BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_SMARTCASE, - entry->data.search_pattern.smartcase) - BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_HAS_LINE_OFFSET, - entry->data.search_pattern.has_line_offset) - BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_PLACE_CURSOR_AT_END, - entry->data.search_pattern.place_cursor_at_end) - BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_IS_LAST_USED, - entry->data.search_pattern.is_last_used) - BOOLEAN_KEY(unpacked, "search pattern", - SEARCH_KEY_IS_SUBSTITUTE_PATTERN, - entry->data.search_pattern.is_substitute_pattern) - BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_HIGHLIGHTED, - entry->data.search_pattern.highlighted) - BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_BACKWARD, - entry->data.search_pattern.search_backward) - INTEGER_KEY(unpacked, "search pattern", SEARCH_KEY_OFFSET, - entry->data.search_pattern.offset) - CONVERTED_STRING_KEY(unpacked, "search pattern", SEARCH_KEY_PAT, - entry->data.search_pattern.pat) - ADDITIONAL_KEY(unpacked) - } - if (entry->data.search_pattern.pat == NULL) { - emsgf(_(READERR("search pattern", "has no pattern")), initial_fpos); - CLEAR_GA_AND_ERROR_OUT(ad_ga); - } - SET_ADDITIONAL_DATA(entry->data.search_pattern.additional_data, - "search pattern"); - break; + break; + case kSDItemSearchPattern: { + if (unpacked.data.type != MSGPACK_OBJECT_MAP) { + emsgf(_(READERR("search pattern", "is not a dictionary")), + initial_fpos); + goto shada_read_next_item_error; } - case kSDItemChange: - case kSDItemJump: - case kSDItemGlobalMark: - case kSDItemLocalMark: { - if (unpacked.data.type != MSGPACK_OBJECT_MAP) { - emsgf(_(READERR("mark", "is not a dictionary")), initial_fpos); - goto shada_read_next_item_error; - } - garray_T ad_ga; - ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1); - for (size_t i = 0; i < unpacked.data.via.map.size; i++) { - CHECK_KEY_IS_STR(unpacked, "mark") - if (CHECK_KEY(unpacked.data.via.map.ptr[i].key, KEY_NAME_CHAR)) { - if (type_u64 == kSDItemJump || type_u64 == kSDItemChange) { - emsgf(_(READERR("mark", "has n key which is only valid for " - "local and global mark entries")), initial_fpos); - CLEAR_GA_AND_ERROR_OUT(ad_ga); - } - CHECKED_ENTRY( - (unpacked.data.via.map.ptr[i].val.type - == MSGPACK_OBJECT_POSITIVE_INTEGER), - "has n key value which is not an unsigned integer", - "mark", unpacked.data.via.map.ptr[i].val, - entry->data.filemark.name, u64, TOCHAR); + garray_T ad_ga; + ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1); + for (size_t i = 0; i < unpacked.data.via.map.size; i++) { + CHECK_KEY_IS_STR(unpacked, "search pattern") + BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_MAGIC, + entry->data.search_pattern.magic) + BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_SMARTCASE, + entry->data.search_pattern.smartcase) + BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_HAS_LINE_OFFSET, + entry->data.search_pattern.has_line_offset) + BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_PLACE_CURSOR_AT_END, + entry->data.search_pattern.place_cursor_at_end) + BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_IS_LAST_USED, + entry->data.search_pattern.is_last_used) + BOOLEAN_KEY(unpacked, "search pattern", + SEARCH_KEY_IS_SUBSTITUTE_PATTERN, + entry->data.search_pattern.is_substitute_pattern) + BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_HIGHLIGHTED, + entry->data.search_pattern.highlighted) + BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_BACKWARD, + entry->data.search_pattern.search_backward) + INTEGER_KEY(unpacked, "search pattern", SEARCH_KEY_OFFSET, + entry->data.search_pattern.offset) + CONVERTED_STRING_KEY(unpacked, "search pattern", SEARCH_KEY_PAT, + entry->data.search_pattern.pat) + ADDITIONAL_KEY(unpacked) + } + if (entry->data.search_pattern.pat == NULL) { + emsgf(_(READERR("search pattern", "has no pattern")), initial_fpos); + CLEAR_GA_AND_ERROR_OUT(ad_ga); + } + SET_ADDITIONAL_DATA(entry->data.search_pattern.additional_data, + "search pattern"); + break; + } + case kSDItemChange: + case kSDItemJump: + case kSDItemGlobalMark: + case kSDItemLocalMark: { + if (unpacked.data.type != MSGPACK_OBJECT_MAP) { + emsgf(_(READERR("mark", "is not a dictionary")), initial_fpos); + goto shada_read_next_item_error; + } + garray_T ad_ga; + ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1); + for (size_t i = 0; i < unpacked.data.via.map.size; i++) { + CHECK_KEY_IS_STR(unpacked, "mark") + if (CHECK_KEY(unpacked.data.via.map.ptr[i].key, KEY_NAME_CHAR)) { + if (type_u64 == kSDItemJump || type_u64 == kSDItemChange) { + emsgf(_(READERR("mark", "has n key which is only valid for " + "local and global mark entries")), initial_fpos); + CLEAR_GA_AND_ERROR_OUT(ad_ga); } - LONG_KEY(unpacked, "mark", KEY_LNUM, entry->data.filemark.mark.lnum) - INTEGER_KEY(unpacked, "mark", KEY_COL, entry->data.filemark.mark.col) - STRING_KEY(unpacked, "mark", KEY_FILE, entry->data.filemark.fname) - ADDITIONAL_KEY(unpacked) - } - if (entry->data.filemark.fname == NULL) { - emsgf(_(READERR("mark", "is missing file name")), initial_fpos); - CLEAR_GA_AND_ERROR_OUT(ad_ga); - } - if (entry->data.filemark.mark.lnum <= 0) { - emsgf(_(READERR("mark", "has invalid line number")), initial_fpos); - CLEAR_GA_AND_ERROR_OUT(ad_ga); + CHECKED_ENTRY((unpacked.data.via.map.ptr[i].val.type + == MSGPACK_OBJECT_POSITIVE_INTEGER), + "has n key value which is not an unsigned integer", + "mark", unpacked.data.via.map.ptr[i].val, + entry->data.filemark.name, u64, TOCHAR); } - if (entry->data.filemark.mark.col < 0) { - emsgf(_(READERR("mark", "has invalid column number")), initial_fpos); - CLEAR_GA_AND_ERROR_OUT(ad_ga); - } - SET_ADDITIONAL_DATA(entry->data.filemark.additional_data, "mark"); - break; + LONG_KEY(unpacked, "mark", KEY_LNUM, entry->data.filemark.mark.lnum) + INTEGER_KEY(unpacked, "mark", KEY_COL, entry->data.filemark.mark.col) + STRING_KEY(unpacked, "mark", KEY_FILE, entry->data.filemark.fname) + ADDITIONAL_KEY(unpacked) } - case kSDItemRegister: { - if (unpacked.data.type != MSGPACK_OBJECT_MAP) { - emsgf(_(READERR("register", "is not a dictionary")), initial_fpos); - goto shada_read_next_item_error; - } - garray_T ad_ga; - ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1); - for (size_t i = 0; i < unpacked.data.via.map.size; i++) { - CHECK_KEY_IS_STR(unpacked, "register") - if (CHECK_KEY(unpacked.data.via.map.ptr[i].key, - REG_KEY_CONTENTS)) { - if (unpacked.data.via.map.ptr[i].val.type != MSGPACK_OBJECT_ARRAY) { - emsgf(_(READERR("register", - "has " REG_KEY_CONTENTS - " key with non-array value")), - initial_fpos); - CLEAR_GA_AND_ERROR_OUT(ad_ga); - } - if (unpacked.data.via.map.ptr[i].val.via.array.size == 0) { - emsgf(_(READERR("register", - "has " REG_KEY_CONTENTS " key with empty array")), - initial_fpos); + if (entry->data.filemark.fname == NULL) { + emsgf(_(READERR("mark", "is missing file name")), initial_fpos); + CLEAR_GA_AND_ERROR_OUT(ad_ga); + } + if (entry->data.filemark.mark.lnum <= 0) { + emsgf(_(READERR("mark", "has invalid line number")), initial_fpos); + CLEAR_GA_AND_ERROR_OUT(ad_ga); + } + if (entry->data.filemark.mark.col < 0) { + emsgf(_(READERR("mark", "has invalid column number")), initial_fpos); + CLEAR_GA_AND_ERROR_OUT(ad_ga); + } + SET_ADDITIONAL_DATA(entry->data.filemark.additional_data, "mark"); + break; + } + case kSDItemRegister: { + if (unpacked.data.type != MSGPACK_OBJECT_MAP) { + emsgf(_(READERR("register", "is not a dictionary")), initial_fpos); + goto shada_read_next_item_error; + } + garray_T ad_ga; + ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1); + for (size_t i = 0; i < unpacked.data.via.map.size; i++) { + CHECK_KEY_IS_STR(unpacked, "register") + if (CHECK_KEY(unpacked.data.via.map.ptr[i].key, + REG_KEY_CONTENTS)) { + if (unpacked.data.via.map.ptr[i].val.type != MSGPACK_OBJECT_ARRAY) { + emsgf(_(READERR("register", + "has " REG_KEY_CONTENTS + " key with non-array value")), + initial_fpos); + CLEAR_GA_AND_ERROR_OUT(ad_ga); + } + if (unpacked.data.via.map.ptr[i].val.via.array.size == 0) { + emsgf(_(READERR("register", + "has " REG_KEY_CONTENTS " key with empty array")), + initial_fpos); + CLEAR_GA_AND_ERROR_OUT(ad_ga); + } + const msgpack_object_array arr = + unpacked.data.via.map.ptr[i].val.via.array; + for (size_t j = 0; j < arr.size; j++) { + if (arr.ptr[j].type != MSGPACK_OBJECT_BIN) { + emsgf(_(READERR("register", "has " REG_KEY_CONTENTS " array " + "with non-binary value")), initial_fpos); CLEAR_GA_AND_ERROR_OUT(ad_ga); } - const msgpack_object_array arr = - unpacked.data.via.map.ptr[i].val.via.array; - for (size_t j = 0; j < arr.size; j++) { - if (arr.ptr[j].type != MSGPACK_OBJECT_BIN) { - emsgf(_(READERR("register", "has " REG_KEY_CONTENTS " array " - "with non-binary value")), initial_fpos); - CLEAR_GA_AND_ERROR_OUT(ad_ga); - } - } - entry->data.reg.contents_size = arr.size; - entry->data.reg.contents = xmalloc(arr.size * sizeof(char *)); - for (size_t j = 0; j < arr.size; j++) { - entry->data.reg.contents[j] = BIN_CONVERTED(arr.ptr[j].via.bin); - } } - BOOLEAN_KEY(unpacked, "register", REG_KEY_UNNAMED, - entry->data.reg.is_unnamed) - TYPED_KEY(unpacked, "register", REG_KEY_TYPE, "an unsigned integer", - entry->data.reg.type, POSITIVE_INTEGER, u64, TOU8) - TYPED_KEY(unpacked, "register", KEY_NAME_CHAR, "an unsigned integer", - entry->data.reg.name, POSITIVE_INTEGER, u64, TOCHAR) - TYPED_KEY(unpacked, "register", REG_KEY_WIDTH, "an unsigned integer", - entry->data.reg.width, POSITIVE_INTEGER, u64, TOSIZE) - ADDITIONAL_KEY(unpacked) - } - if (entry->data.reg.contents == NULL) { - emsgf(_(READERR("register", "has missing " REG_KEY_CONTENTS " array")), - initial_fpos); - CLEAR_GA_AND_ERROR_OUT(ad_ga); + entry->data.reg.contents_size = arr.size; + entry->data.reg.contents = xmalloc(arr.size * sizeof(char *)); + for (size_t j = 0; j < arr.size; j++) { + entry->data.reg.contents[j] = BIN_CONVERTED(arr.ptr[j].via.bin); + } } - SET_ADDITIONAL_DATA(entry->data.reg.additional_data, "register"); - break; + BOOLEAN_KEY(unpacked, "register", REG_KEY_UNNAMED, + entry->data.reg.is_unnamed) + TYPED_KEY(unpacked, "register", REG_KEY_TYPE, "an unsigned integer", + entry->data.reg.type, POSITIVE_INTEGER, u64, TOU8) + TYPED_KEY(unpacked, "register", KEY_NAME_CHAR, "an unsigned integer", + entry->data.reg.name, POSITIVE_INTEGER, u64, TOCHAR) + TYPED_KEY(unpacked, "register", REG_KEY_WIDTH, "an unsigned integer", + entry->data.reg.width, POSITIVE_INTEGER, u64, TOSIZE) + ADDITIONAL_KEY(unpacked) } - case kSDItemHistoryEntry: { - if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) { - emsgf(_(READERR("history", "is not an array")), initial_fpos); - goto shada_read_next_item_error; - } - if (unpacked.data.via.array.size < 2) { - emsgf(_(READERR("history", "does not have enough elements")), - initial_fpos); + if (entry->data.reg.contents == NULL) { + emsgf(_(READERR("register", "has missing " REG_KEY_CONTENTS " array")), + initial_fpos); + CLEAR_GA_AND_ERROR_OUT(ad_ga); + } + SET_ADDITIONAL_DATA(entry->data.reg.additional_data, "register"); + break; + } + case kSDItemHistoryEntry: { + if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) { + emsgf(_(READERR("history", "is not an array")), initial_fpos); + goto shada_read_next_item_error; + } + if (unpacked.data.via.array.size < 2) { + emsgf(_(READERR("history", "does not have enough elements")), + initial_fpos); + goto shada_read_next_item_error; + } + if (unpacked.data.via.array.ptr[0].type + != MSGPACK_OBJECT_POSITIVE_INTEGER) { + emsgf(_(READERR("history", "has wrong history type type")), + initial_fpos); + goto shada_read_next_item_error; + } + if (unpacked.data.via.array.ptr[1].type + != MSGPACK_OBJECT_BIN) { + emsgf(_(READERR("history", "has wrong history string type")), + initial_fpos); + goto shada_read_next_item_error; + } + if (memchr(unpacked.data.via.array.ptr[1].via.bin.ptr, 0, + unpacked.data.via.array.ptr[1].via.bin.size) != NULL) { + emsgf(_(READERR("history", "contains string with zero byte inside")), + initial_fpos); + goto shada_read_next_item_error; + } + entry->data.history_item.histtype = + (uint8_t)unpacked.data.via.array.ptr[0].via.u64; + const bool is_hist_search = + entry->data.history_item.histtype == HIST_SEARCH; + if (is_hist_search) { + if (unpacked.data.via.array.size < 3) { + emsgf(_(READERR("search history", + "does not have separator character")), initial_fpos); goto shada_read_next_item_error; } - if (unpacked.data.via.array.ptr[0].type + if (unpacked.data.via.array.ptr[2].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { - emsgf(_(READERR("history", "has wrong history type type")), - initial_fpos); - goto shada_read_next_item_error; - } - if (unpacked.data.via.array.ptr[1].type - != MSGPACK_OBJECT_BIN) { - emsgf(_(READERR("history", "has wrong history string type")), - initial_fpos); + emsgf(_(READERR("search history", + "has wrong history separator type")), initial_fpos); goto shada_read_next_item_error; } - if (memchr(unpacked.data.via.array.ptr[1].via.bin.ptr, 0, - unpacked.data.via.array.ptr[1].via.bin.size) != NULL) { - emsgf(_(READERR("history", "contains string with zero byte inside")), - initial_fpos); - goto shada_read_next_item_error; - } - entry->data.history_item.histtype = - (uint8_t) unpacked.data.via.array.ptr[0].via.u64; - const bool is_hist_search = - entry->data.history_item.histtype == HIST_SEARCH; - if (is_hist_search) { - if (unpacked.data.via.array.size < 3) { - emsgf(_(READERR("search history", - "does not have separator character")), initial_fpos); - goto shada_read_next_item_error; - } - if (unpacked.data.via.array.ptr[2].type - != MSGPACK_OBJECT_POSITIVE_INTEGER) { - emsgf(_(READERR("search history", - "has wrong history separator type")), initial_fpos); + entry->data.history_item.sep = + (char)unpacked.data.via.array.ptr[2].via.u64; + } + size_t strsize; + strsize = ( + unpacked.data.via.array.ptr[1].via.bin.size + + 1 // Zero byte + + 1); // Separator character + entry->data.history_item.string = xmalloc(strsize); + memcpy(entry->data.history_item.string, + unpacked.data.via.array.ptr[1].via.bin.ptr, + unpacked.data.via.array.ptr[1].via.bin.size); + entry->data.history_item.string[strsize - 2] = 0; + entry->data.history_item.string[strsize - 1] = + entry->data.history_item.sep; + SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, (2 + is_hist_search), + entry->data.history_item.additional_elements, + "history"); + break; + } + case kSDItemVariable: { + if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) { + emsgf(_(READERR("variable", "is not an array")), initial_fpos); + goto shada_read_next_item_error; + } + if (unpacked.data.via.array.size < 2) { + emsgf(_(READERR("variable", "does not have enough elements")), + initial_fpos); + goto shada_read_next_item_error; + } + if (unpacked.data.via.array.ptr[0].type != MSGPACK_OBJECT_BIN) { + emsgf(_(READERR("variable", "has wrong variable name type")), + initial_fpos); + goto shada_read_next_item_error; + } + entry->data.global_var.name = + xmemdupz(unpacked.data.via.array.ptr[0].via.bin.ptr, + unpacked.data.via.array.ptr[0].via.bin.size); + SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2, + entry->data.global_var.additional_elements, + "variable"); + bool is_blob = false; + // A msgpack BIN could be a String or Blob; an additional VAR_TYPE_BLOB + // element is stored with Blobs which can be used to differentiate them + if (unpacked.data.via.array.ptr[1].type == MSGPACK_OBJECT_BIN) { + const listitem_T *type_item + = tv_list_first(entry->data.global_var.additional_elements); + if (type_item != NULL) { + const typval_T *type_tv = TV_LIST_ITEM_TV(type_item); + if (type_tv->v_type != VAR_NUMBER + || type_tv->vval.v_number != VAR_TYPE_BLOB) { + emsgf(_(READERR("variable", "has wrong variable type")), + initial_fpos); goto shada_read_next_item_error; } - entry->data.history_item.sep = - (char) unpacked.data.via.array.ptr[2].via.u64; + is_blob = true; } - size_t strsize; - strsize = ( - unpacked.data.via.array.ptr[1].via.bin.size - + 1 // Zero byte - + 1); // Separator character - entry->data.history_item.string = xmalloc(strsize); - memcpy(entry->data.history_item.string, - unpacked.data.via.array.ptr[1].via.bin.ptr, - unpacked.data.via.array.ptr[1].via.bin.size); - entry->data.history_item.string[strsize - 2] = 0; - entry->data.history_item.string[strsize - 1] = - entry->data.history_item.sep; - SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, (2 + is_hist_search), - entry->data.history_item.additional_elements, - "history"); - break; } - case kSDItemVariable: { - if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) { - emsgf(_(READERR("variable", "is not an array")), initial_fpos); - goto shada_read_next_item_error; - } - if (unpacked.data.via.array.size < 2) { - emsgf(_(READERR("variable", "does not have enough elements")), - initial_fpos); - goto shada_read_next_item_error; - } - if (unpacked.data.via.array.ptr[0].type != MSGPACK_OBJECT_BIN) { - emsgf(_(READERR("variable", "has wrong variable name type")), - initial_fpos); - goto shada_read_next_item_error; - } - entry->data.global_var.name = - xmemdupz(unpacked.data.via.array.ptr[0].via.bin.ptr, - unpacked.data.via.array.ptr[0].via.bin.size); - SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2, - entry->data.global_var.additional_elements, - "variable"); - bool is_blob = false; - // A msgpack BIN could be a String or Blob; an additional VAR_TYPE_BLOB - // element is stored with Blobs which can be used to differentiate them - if (unpacked.data.via.array.ptr[1].type == MSGPACK_OBJECT_BIN) { - const listitem_T *type_item - = tv_list_first(entry->data.global_var.additional_elements); - if (type_item != NULL) { - const typval_T *type_tv = TV_LIST_ITEM_TV(type_item); - if (type_tv->v_type != VAR_NUMBER - || type_tv->vval.v_number != VAR_TYPE_BLOB) { - emsgf(_(READERR("variable", "has wrong variable type")), - initial_fpos); - goto shada_read_next_item_error; - } - is_blob = true; - } - } - if (is_blob) { - const msgpack_object_bin *const bin - = &unpacked.data.via.array.ptr[1].via.bin; - blob_T *const blob = tv_blob_alloc(); - ga_concat_len(&blob->bv_ga, bin->ptr, (size_t)bin->size); - tv_blob_set_ret(&entry->data.global_var.value, blob); - } else if (msgpack_to_vim(unpacked.data.via.array.ptr[1], - &(entry->data.global_var.value)) == FAIL) { - emsgf(_(READERR("variable", "has value that cannot " - "be converted to the VimL value")), initial_fpos); - goto shada_read_next_item_error; - } - break; + if (is_blob) { + const msgpack_object_bin *const bin + = &unpacked.data.via.array.ptr[1].via.bin; + blob_T *const blob = tv_blob_alloc(); + ga_concat_len(&blob->bv_ga, bin->ptr, (size_t)bin->size); + tv_blob_set_ret(&entry->data.global_var.value, blob); + } else if (msgpack_to_vim(unpacked.data.via.array.ptr[1], + &(entry->data.global_var.value)) == FAIL) { + emsgf(_(READERR("variable", "has value that cannot " + "be converted to the VimL value")), initial_fpos); + goto shada_read_next_item_error; } - case kSDItemSubString: { - if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) { - emsgf(_(READERR("sub string", "is not an array")), initial_fpos); - goto shada_read_next_item_error; - } - if (unpacked.data.via.array.size < 1) { - emsgf(_(READERR("sub string", "does not have enough elements")), - initial_fpos); - goto shada_read_next_item_error; - } - if (unpacked.data.via.array.ptr[0].type != MSGPACK_OBJECT_BIN) { - emsgf(_(READERR("sub string", "has wrong sub string type")), - initial_fpos); - goto shada_read_next_item_error; - } - entry->data.sub_string.sub = - BIN_CONVERTED(unpacked.data.via.array.ptr[0].via.bin); - SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 1, - entry->data.sub_string.additional_elements, - "sub string"); + break; + } + case kSDItemSubString: + if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) { + emsgf(_(READERR("sub string", "is not an array")), initial_fpos); + goto shada_read_next_item_error; + } + if (unpacked.data.via.array.size < 1) { + emsgf(_(READERR("sub string", "does not have enough elements")), + initial_fpos); + goto shada_read_next_item_error; + } + if (unpacked.data.via.array.ptr[0].type != MSGPACK_OBJECT_BIN) { + emsgf(_(READERR("sub string", "has wrong sub string type")), + initial_fpos); + goto shada_read_next_item_error; + } + entry->data.sub_string.sub = + BIN_CONVERTED(unpacked.data.via.array.ptr[0].via.bin); + SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 1, + entry->data.sub_string.additional_elements, + "sub string"); + break; + case kSDItemBufferList: + if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) { + emsgf(_(READERR("buffer list", "is not an array")), initial_fpos); + goto shada_read_next_item_error; + } + if (unpacked.data.via.array.size == 0) { break; } - case kSDItemBufferList: { - if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) { - emsgf(_(READERR("buffer list", "is not an array")), initial_fpos); - goto shada_read_next_item_error; - } - if (unpacked.data.via.array.size == 0) { - break; - } - entry->data.buffer_list.buffers = - xcalloc(unpacked.data.via.array.size, - sizeof(*entry->data.buffer_list.buffers)); - for (size_t i = 0; i < unpacked.data.via.array.size; i++) { - entry->data.buffer_list.size++; - msgpack_unpacked unpacked_2 = (msgpack_unpacked) { - .data = unpacked.data.via.array.ptr[i], - }; + entry->data.buffer_list.buffers = + xcalloc(unpacked.data.via.array.size, + sizeof(*entry->data.buffer_list.buffers)); + for (size_t i = 0; i < unpacked.data.via.array.size; i++) { + entry->data.buffer_list.size++; + msgpack_unpacked unpacked_2 = (msgpack_unpacked) { + .data = unpacked.data.via.array.ptr[i], + }; + { + if (unpacked_2.data.type != MSGPACK_OBJECT_MAP) { + emsgf(_(RERR "Error while reading ShaDa file: " + "buffer list at position %" PRIu64 " " + "contains entry that is not a dictionary"), + initial_fpos); + goto shada_read_next_item_error; + } + entry->data.buffer_list.buffers[i].pos = default_pos; + garray_T ad_ga; + ga_init(&ad_ga, sizeof(*(unpacked_2.data.via.map.ptr)), 1); { - if (unpacked_2.data.type != MSGPACK_OBJECT_MAP) { - emsgf(_(RERR "Error while reading ShaDa file: " - "buffer list at position %" PRIu64 " " - "contains entry that is not a dictionary"), - initial_fpos); - goto shada_read_next_item_error; - } - entry->data.buffer_list.buffers[i].pos = default_pos; - garray_T ad_ga; - ga_init(&ad_ga, sizeof(*(unpacked_2.data.via.map.ptr)), 1); + // XXX: Temporarily reassign `i` because the macros depend on it. + const size_t j = i; { - // XXX: Temporarily reassign `i` because the macros depend on it. - const size_t j = i; - { - for (i = 0; i < unpacked_2.data.via.map.size; i++) { // -V535 - CHECK_KEY_IS_STR(unpacked_2, "buffer list entry") - LONG_KEY(unpacked_2, "buffer list entry", KEY_LNUM, - entry->data.buffer_list.buffers[j].pos.lnum) - INTEGER_KEY(unpacked_2, "buffer list entry", KEY_COL, - entry->data.buffer_list.buffers[j].pos.col) - STRING_KEY(unpacked_2, "buffer list entry", KEY_FILE, - entry->data.buffer_list.buffers[j].fname) - ADDITIONAL_KEY(unpacked_2) - } + for (i = 0; i < unpacked_2.data.via.map.size; i++) { // -V535 + CHECK_KEY_IS_STR(unpacked_2, "buffer list entry") + LONG_KEY(unpacked_2, "buffer list entry", KEY_LNUM, + entry->data.buffer_list.buffers[j].pos.lnum) + INTEGER_KEY(unpacked_2, "buffer list entry", KEY_COL, + entry->data.buffer_list.buffers[j].pos.col) + STRING_KEY(unpacked_2, "buffer list entry", KEY_FILE, + entry->data.buffer_list.buffers[j].fname) + ADDITIONAL_KEY(unpacked_2) } - i = j; // XXX: Restore `i`. } - if (entry->data.buffer_list.buffers[i].pos.lnum <= 0) { - emsgf(_(RERR "Error while reading ShaDa file: " - "buffer list at position %" PRIu64 " " - "contains entry with invalid line number"), - initial_fpos); - CLEAR_GA_AND_ERROR_OUT(ad_ga); - } - if (entry->data.buffer_list.buffers[i].pos.col < 0) { - emsgf(_(RERR "Error while reading ShaDa file: " - "buffer list at position %" PRIu64 " " - "contains entry with invalid column number"), - initial_fpos); - CLEAR_GA_AND_ERROR_OUT(ad_ga); - } - if (entry->data.buffer_list.buffers[i].fname == NULL) { - emsgf(_(RERR "Error while reading ShaDa file: " - "buffer list at position %" PRIu64 " " - "contains entry that does not have a file name"), - initial_fpos); - CLEAR_GA_AND_ERROR_OUT(ad_ga); - } - SET_ADDITIONAL_DATA( - entry->data.buffer_list.buffers[i].additional_data, - "buffer list entry"); + i = j; // XXX: Restore `i`. + } + if (entry->data.buffer_list.buffers[i].pos.lnum <= 0) { + emsgf(_(RERR "Error while reading ShaDa file: " + "buffer list at position %" PRIu64 " " + "contains entry with invalid line number"), + initial_fpos); + CLEAR_GA_AND_ERROR_OUT(ad_ga); + } + if (entry->data.buffer_list.buffers[i].pos.col < 0) { + emsgf(_(RERR "Error while reading ShaDa file: " + "buffer list at position %" PRIu64 " " + "contains entry with invalid column number"), + initial_fpos); + CLEAR_GA_AND_ERROR_OUT(ad_ga); } + if (entry->data.buffer_list.buffers[i].fname == NULL) { + emsgf(_(RERR "Error while reading ShaDa file: " + "buffer list at position %" PRIu64 " " + "contains entry that does not have a file name"), + initial_fpos); + CLEAR_GA_AND_ERROR_OUT(ad_ga); + } + SET_ADDITIONAL_DATA(entry->data.buffer_list.buffers[i].additional_data, + "buffer list entry"); } - break; - } - case kSDItemMissing: - case kSDItemUnknown: { - abort(); } + break; + case kSDItemMissing: + case kSDItemUnknown: + abort(); } - entry->type = (ShadaEntryType) type_u64; + entry->type = (ShadaEntryType)type_u64; ret = kSDReadStatusSuccess; shada_read_next_item_end: if (buf != NULL) { @@ -4086,13 +3938,12 @@ shada_read_next_item_end: } return ret; shada_read_next_item_error: - entry->type = (ShadaEntryType) type_u64; + entry->type = (ShadaEntryType)type_u64; shada_free_shada_entry(entry); entry->type = kSDItemMissing; goto shada_read_next_item_end; } #undef BIN_CONVERTED -#undef CONVERTED #undef CHECK_KEY #undef BOOLEAN_KEY #undef CONVERTED_STRING_KEY @@ -4121,17 +3972,17 @@ shada_read_next_item_error: static bool shada_removable(const char *name) FUNC_ATTR_WARN_UNUSED_RESULT { - char *p; + char *p; char part[MAXPATHL + 1]; bool retval = false; - char *new_name = home_replace_save(NULL, name); - for (p = (char *) p_shada; *p; ) { - (void) copy_option_part(&p, part, ARRAY_SIZE(part), ", "); + char *new_name = (char *)home_replace_save(NULL, (char_u *)name); + for (p = (char *)p_shada; *p; ) { + (void)copy_option_part((char_u **)&p, (char_u *)part, ARRAY_SIZE(part), ", "); if (part[0] == 'r') { - home_replace(NULL, part + 1, NameBuff, MAXPATHL, true); + home_replace(NULL, (char_u *)(part + 1), (char_u *)NameBuff, MAXPATHL, true); size_t n = STRLEN(NameBuff); - if (mb_strnicmp(NameBuff, new_name, n) == 0) { + if (mb_strnicmp((char_u *)NameBuff, (char_u *)new_name, n) == 0) { retval = true; break; } @@ -4148,8 +3999,8 @@ static bool shada_removable(const char *name) /// location. /// /// @return number of jumplist entries -static inline size_t shada_init_jumps( - PossiblyFreedShadaEntry *jumps, khash_t(bufset) *const removable_bufs) +static inline size_t shada_init_jumps(PossiblyFreedShadaEntry *jumps, + khash_t(bufset) *const removable_bufs) { if (!curwin->w_jumplistlen) { return 0; @@ -4176,9 +4027,9 @@ static inline size_t shada_init_jumps( : fm.fmark.fnum != 0) { continue; } - const char *const fname = (char *) (fm.fmark.fnum == 0 + const char *const fname = (char *)(fm.fmark.fnum == 0 ? (fm.fname == NULL ? NULL : fm.fname) - : buf ? buf->b_ffname : NULL); + : buf ? buf->b_ffname : NULL); if (fname == NULL) { continue; } @@ -4191,7 +4042,7 @@ static inline size_t shada_init_jumps( .filemark = { .name = NUL, .mark = fm.fmark.mark, - .fname = (char *) fname, + .fname = (char *)fname, .additional_data = fm.fmark.additional_data, } } @@ -4272,9 +4123,8 @@ void shada_encode_gvars(msgpack_sbuffer *const sbuf) do { typval_T vartv; const char *name = NULL; - var_iter = var_shada_iter( - var_iter, &name, &vartv, - VAR_FLAVOUR_DEFAULT | VAR_FLAVOUR_SESSION | VAR_FLAVOUR_SHADA); + var_iter = var_shada_iter(var_iter, &name, &vartv, + VAR_FLAVOUR_DEFAULT | VAR_FLAVOUR_SESSION | VAR_FLAVOUR_SHADA); if (name == NULL) { break; } @@ -4304,8 +4154,7 @@ void shada_encode_gvars(msgpack_sbuffer *const sbuf) /// Wrapper for reading from msgpack_sbuffer. /// /// @return number of bytes read. -static ptrdiff_t read_sbuf(ShaDaReadDef *const sd_reader, void *const dest, - const size_t size) +static ptrdiff_t read_sbuf(ShaDaReadDef *const sd_reader, void *const dest, const size_t size) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { msgpack_sbuffer *sbuf = (msgpack_sbuffer *)sd_reader->cookie; @@ -4327,8 +4176,7 @@ static ptrdiff_t read_sbuf(ShaDaReadDef *const sd_reader, void *const dest, /// /// @return FAIL in case of failure, OK in case of success. May set /// sd_reader->eof. -static int sd_sbuf_reader_skip_read(ShaDaReadDef *const sd_reader, - const size_t offset) +static int sd_sbuf_reader_skip_read(ShaDaReadDef *const sd_reader, const size_t offset) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { msgpack_sbuffer *sbuf = (msgpack_sbuffer *)sd_reader->cookie; @@ -4346,8 +4194,7 @@ static int sd_sbuf_reader_skip_read(ShaDaReadDef *const sd_reader, /// /// @param[in] sbuf msgpack_sbuffer to read from. /// @param[out] sd_reader Location where reader structure will be saved. -static void open_shada_sbuf_for_reading(const msgpack_sbuffer *const sbuf, - ShaDaReadDef *sd_reader) +static void open_shada_sbuf_for_reading(const msgpack_sbuffer *const sbuf, ShaDaReadDef *sd_reader) FUNC_ATTR_NONNULL_ALL { *sd_reader = (ShaDaReadDef) { diff --git a/src/nvim/sign.c b/src/nvim/sign.c index c6f59b42b8..1b100161bf 100644 --- a/src/nvim/sign.c +++ b/src/nvim/sign.c @@ -6,33 +6,33 @@ // -#include "nvim/vim.h" -#include "nvim/sign.h" #include "nvim/ascii.h" #include "nvim/buffer.h" #include "nvim/charset.h" #include "nvim/cursor.h" -#include "nvim/ex_docmd.h" #include "nvim/edit.h" +#include "nvim/ex_docmd.h" #include "nvim/fold.h" #include "nvim/move.h" +#include "nvim/option.h" #include "nvim/screen.h" +#include "nvim/sign.h" #include "nvim/syntax.h" -#include "nvim/option.h" +#include "nvim/vim.h" /// Struct to hold the sign properties. typedef struct sign sign_T; struct sign { - sign_T *sn_next; // next sign in list - int sn_typenr; // type number of sign - char_u *sn_name; // name of sign - char_u *sn_icon; // name of pixmap - char_u *sn_text; // text used instead of pixmap - int sn_line_hl; // highlight ID for line - int sn_text_hl; // highlight ID for text - int sn_num_hl; // highlight ID for line number + sign_T *sn_next; // next sign in list + int sn_typenr; // type number of sign + char_u *sn_name; // name of sign + char_u *sn_icon; // name of pixmap + char_u *sn_text; // text used instead of pixmap + int sn_line_hl; // highlight ID for line + int sn_text_hl; // highlight ID for text + int sn_num_hl; // highlight ID for line number }; static sign_T *first_sign = NULL; @@ -42,19 +42,19 @@ static void sign_list_defined(sign_T *sp); static void sign_undefine(sign_T *sp, sign_T *sp_prev); static char *cmds[] = { - "define", + "define", #define SIGNCMD_DEFINE 0 - "undefine", + "undefine", #define SIGNCMD_UNDEFINE 1 - "list", + "list", #define SIGNCMD_LIST 2 - "place", + "place", #define SIGNCMD_PLACE 3 - "unplace", + "unplace", #define SIGNCMD_UNPLACE 4 - "jump", + "jump", #define SIGNCMD_JUMP 5 - NULL + NULL #define SIGNCMD_LAST 6 }; @@ -65,17 +65,17 @@ static int next_sign_id = 1; // next sign id in the global group /// Initialize data needed for managing signs void init_signs(void) { - hash_init(&sg_table); // sign group hash table + hash_init(&sg_table); // sign group hash table } /// A new sign in group 'groupname' is added. If the group is not present, /// create it. Otherwise reference the group. /// -static signgroup_T * sign_group_ref(const char_u *groupname) +static signgroup_T *sign_group_ref(const char_u *groupname) { - hash_T hash; - hashitem_T *hi; - signgroup_T *group; + hash_T hash; + hashitem_T *hi; + signgroup_T *group; hash = hash_hash(groupname); hi = hash_lookup(&sg_table, (char *)groupname, STRLEN(groupname), hash); @@ -100,7 +100,7 @@ static signgroup_T * sign_group_ref(const char_u *groupname) /// removed, then remove the group. static void sign_group_unref(char_u *groupname) { - hashitem_T *hi; + hashitem_T *hi; signgroup_T *group; hi = hash_find(&sg_table, groupname); @@ -120,10 +120,10 @@ static void sign_group_unref(char_u *groupname) /// or in a named group. If 'group' is '*', then the sign is part of the group. bool sign_in_group(sign_entry_T *sign, const char_u *group) { - return ((group != NULL && STRCMP(group, "*") == 0) - || (group == NULL && sign->se_group == NULL) - || (group != NULL && sign->se_group != NULL - && STRCMP(group, sign->se_group->sg_name) == 0)); + return ((group != NULL && STRCMP(group, "*") == 0) + || (group == NULL && sign->se_group == NULL) + || (group != NULL && sign->se_group != NULL + && STRCMP(group, sign->se_group->sg_name) == 0)); } /// Get the next free sign identifier in the specified group @@ -166,17 +166,19 @@ int sign_group_get_next_signid(buf_T *buf, const char_u *groupname) /// Insert a new sign into the signlist for buffer 'buf' between the 'prev' and /// 'next' signs. -static void insert_sign( - buf_T *buf, // buffer to store sign in - sign_entry_T *prev, // previous sign entry - sign_entry_T *next, // next sign entry - int id, // sign ID - const char_u *group, // sign group; NULL for global group - int prio, // sign priority - linenr_T lnum, // line number which gets the mark - int typenr, // typenr of sign we are adding - bool has_text_or_icon // sign has text or icon -) +/// +/// @param buf buffer to store sign in +/// @param prev previous sign entry +/// @param next next sign entry +/// @param id sign ID +/// @param group sign group; NULL for global group +/// @param prio sign priority +/// @param lnum line number which gets the mark +/// @param typenr typenr of sign we are adding +/// @param has_text_or_icon sign has text or icon +static void insert_sign(buf_T *buf, sign_entry_T *prev, sign_entry_T *next, int id, + const char_u *group, int prio, linenr_T lnum, int typenr, + bool has_text_or_icon) { sign_entry_T *newsign = xmalloc(sizeof(sign_entry_T)); newsign->se_id = id; @@ -212,18 +214,19 @@ static void insert_sign( } /// Insert a new sign sorted by line number and sign priority. -static void insert_sign_by_lnum_prio( - buf_T *buf, // buffer to store sign in - sign_entry_T *prev, // previous sign entry - int id, // sign ID - const char_u *group, // sign group; NULL for global group - int prio, // sign priority - linenr_T lnum, // line number which gets the mark - int typenr, // typenr of sign we are adding - bool has_text_or_icon // sign has text or icon -) +/// +/// @param buf buffer to store sign in +/// @param prev previous sign entry +/// @param id sign ID +/// @param group sign group; NULL for global group +/// @param prio sign priority +/// @param lnum line number which gets the mark +/// @param typenr typenr of sign we are adding +/// @param has_text_or_icon sign has text or icon +static void insert_sign_by_lnum_prio(buf_T *buf, sign_entry_T *prev, int id, const char_u *group, + int prio, linenr_T lnum, int typenr, bool has_text_or_icon) { - sign_entry_T *sign; + sign_entry_T *sign; // keep signs sorted by lnum, priority and id: insert new sign at // the proper position in the list for this lnum. @@ -242,9 +245,9 @@ static void insert_sign_by_lnum_prio( } /// Get the name of a sign by its typenr. -char_u * sign_typenr2name(int typenr) +char_u *sign_typenr2name(int typenr) { - sign_T *sp; + sign_T *sp; for (sp = first_sign; sp != NULL; sp = sp->sn_next) { if (sp->sn_typenr == typenr) { @@ -255,9 +258,9 @@ char_u * sign_typenr2name(int typenr) } /// Return information about a sign in a Dict -dict_T * sign_get_info(sign_entry_T *sign) +dict_T *sign_get_info(sign_entry_T *sign) { - dict_T *d = tv_dict_alloc(); + dict_T *d = tv_dict_alloc(); tv_dict_add_nr(d, S_LEN("id"), sign->se_id); tv_dict_add_str(d, S_LEN("group"), ((sign->se_group == NULL) ? (char *)"" @@ -345,15 +348,16 @@ static void sign_sort_by_prio_on_line(buf_T *buf, sign_entry_T *sign) /// Add the sign into the signlist. Find the right spot to do it though. -void buf_addsign( - buf_T *buf, // buffer to store sign in - int id, // sign ID - const char_u *groupname, // sign group - int prio, // sign priority - linenr_T lnum, // line number which gets the mark - int typenr, // typenr of sign we are adding - bool has_text_or_icon // sign has text or icon -) +/// +/// @param buf buffer to store sign in +/// @param id sign ID +/// @param groupname sign group +/// @param prio sign priority +/// @param lnum line number which gets the mark +/// @param typenr typenr of sign we are adding +/// @param has_text_or_icon sign has text or icon +void buf_addsign(buf_T *buf, int id, const char_u *groupname, int prio, linenr_T lnum, int typenr, + bool has_text_or_icon) { sign_entry_T *sign; // a sign in the signlist sign_entry_T *prev; // the previous sign @@ -368,53 +372,51 @@ void buf_addsign( sign_sort_by_prio_on_line(buf, sign); return; } else if (lnum < sign->se_lnum) { - insert_sign_by_lnum_prio( - buf, - prev, - id, - groupname, - prio, - lnum, - typenr, - has_text_or_icon); + insert_sign_by_lnum_prio(buf, + prev, + id, + groupname, + prio, + lnum, + typenr, + has_text_or_icon); return; } prev = sign; } - insert_sign_by_lnum_prio( - buf, - prev, - id, - groupname, - prio, - lnum, - typenr, - has_text_or_icon); + insert_sign_by_lnum_prio(buf, + prev, + id, + groupname, + prio, + lnum, + typenr, + has_text_or_icon); } -// For an existing, placed sign "markId" change the type to "typenr". -// Returns the line number of the sign, or zero if the sign is not found. -linenr_T buf_change_sign_type( - buf_T *buf, // buffer to store sign in - int markId, // sign ID - const char_u *group, // sign group - int typenr, // typenr of sign we are adding - int prio // sign priority -) +/// For an existing, placed sign "markId" change the type to "typenr". +/// Returns the line number of the sign, or zero if the sign is not found. +/// +/// @param buf buffer to store sign in +/// @param markId sign ID +/// @param group sign group +/// @param typenr typenr of sign we are adding +/// @param prio sign priority +linenr_T buf_change_sign_type(buf_T *buf, int markId, const char_u *group, int typenr, int prio) { - sign_entry_T *sign; // a sign in the signlist + sign_entry_T *sign; // a sign in the signlist - FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (sign->se_id == markId && sign_in_group(sign, group)) { - sign->se_typenr = typenr; - sign->se_priority = prio; - sign_sort_by_prio_on_line(buf, sign); - return sign->se_lnum; - } + FOR_ALL_SIGNS_IN_BUF(buf, sign) { + if (sign->se_id == markId && sign_in_group(sign, group)) { + sign->se_typenr = typenr; + sign->se_priority = prio; + sign_sort_by_prio_on_line(buf, sign); + return sign->se_lnum; } + } - return (linenr_T)0; + return (linenr_T)0; } /// Return the sign attrs which has the attribute specified by 'type'. Returns @@ -426,44 +428,43 @@ linenr_T buf_change_sign_type( /// @param max_signs the number of signs, with priority for the ones /// with the highest Ids. /// @return Attrs of the matching sign, or NULL -sign_attrs_T * sign_get_attr(SignType type, sign_attrs_T sattrs[], - int idx, int max_signs) +sign_attrs_T *sign_get_attr(SignType type, sign_attrs_T sattrs[], int idx, int max_signs) { - sign_attrs_T *matches[SIGN_SHOW_MAX]; - int nr_matches = 0; - - for (int i = 0; i < SIGN_SHOW_MAX; i++) { - if ( (type == SIGN_TEXT && sattrs[i].sat_text != NULL) - || (type == SIGN_LINEHL && sattrs[i].sat_linehl != 0) - || (type == SIGN_NUMHL && sattrs[i].sat_numhl != 0)) { - matches[nr_matches] = &sattrs[i]; - nr_matches++; - // attr list is sorted with most important (priority, id), thus we - // may stop as soon as we have max_signs matches - if (nr_matches >= max_signs) { - break; - } - } + sign_attrs_T *matches[SIGN_SHOW_MAX]; + int nr_matches = 0; + + for (int i = 0; i < SIGN_SHOW_MAX; i++) { + if ( (type == SIGN_TEXT && sattrs[i].sat_text != NULL) + || (type == SIGN_LINEHL && sattrs[i].sat_linehl != 0) + || (type == SIGN_NUMHL && sattrs[i].sat_numhl != 0)) { + matches[nr_matches] = &sattrs[i]; + nr_matches++; + // attr list is sorted with most important (priority, id), thus we + // may stop as soon as we have max_signs matches + if (nr_matches >= max_signs) { + break; + } } + } - if (nr_matches > idx) { - return matches[nr_matches - idx - 1]; - } + if (nr_matches > idx) { + return matches[nr_matches - idx - 1]; + } - return NULL; + return NULL; } /// Lookup a sign by typenr. Returns NULL if sign is not found. -static sign_T * find_sign_by_typenr(int typenr) +static sign_T *find_sign_by_typenr(int typenr) { - sign_T *sp; + sign_T *sp; - for (sp = first_sign; sp != NULL; sp = sp->sn_next) { - if (sp->sn_typenr == typenr) { - return sp; - } + for (sp = first_sign; sp != NULL; sp = sp->sn_next) { + if (sp->sn_typenr == typenr) { + return sp; } - return NULL; + } + return NULL; } /// Return the attributes of all the signs placed on line 'lnum' in buffer @@ -474,44 +475,44 @@ static sign_T * find_sign_by_typenr(int typenr) /// @return Number of signs of which attrs were found int buf_get_signattrs(buf_T *buf, linenr_T lnum, sign_attrs_T sattrs[]) { - sign_entry_T *sign; - sign_T *sp; + sign_entry_T *sign; + sign_T *sp; - int nr_matches = 0; + int nr_matches = 0; - FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (sign->se_lnum > lnum) { - // Signs are sorted by line number in the buffer. No need to check - // for signs after the specified line number 'lnum'. - break; - } + FOR_ALL_SIGNS_IN_BUF(buf, sign) { + if (sign->se_lnum > lnum) { + // Signs are sorted by line number in the buffer. No need to check + // for signs after the specified line number 'lnum'. + break; + } - if (sign->se_lnum == lnum) { - sign_attrs_T sattr; - memset(&sattr, 0, sizeof(sattr)); - sattr.sat_typenr = sign->se_typenr; - sp = find_sign_by_typenr(sign->se_typenr); - if (sp != NULL) { - sattr.sat_text = sp->sn_text; - if (sattr.sat_text != NULL && sp->sn_text_hl != 0) { - sattr.sat_texthl = syn_id2attr(sp->sn_text_hl); - } - if (sp->sn_line_hl != 0) { - sattr.sat_linehl = syn_id2attr(sp->sn_line_hl); - } - if (sp->sn_num_hl != 0) { - sattr.sat_numhl = syn_id2attr(sp->sn_num_hl); - } - } - - sattrs[nr_matches] = sattr; - nr_matches++; - if (nr_matches == SIGN_SHOW_MAX) { - break; - } + if (sign->se_lnum == lnum) { + sign_attrs_T sattr; + memset(&sattr, 0, sizeof(sattr)); + sattr.sat_typenr = sign->se_typenr; + sp = find_sign_by_typenr(sign->se_typenr); + if (sp != NULL) { + sattr.sat_text = sp->sn_text; + if (sattr.sat_text != NULL && sp->sn_text_hl != 0) { + sattr.sat_texthl = syn_id2attr(sp->sn_text_hl); + } + if (sp->sn_line_hl != 0) { + sattr.sat_linehl = syn_id2attr(sp->sn_line_hl); + } + if (sp->sn_num_hl != 0) { + sattr.sat_numhl = syn_id2attr(sp->sn_num_hl); } + } + + sattrs[nr_matches] = sattr; + nr_matches++; + if (nr_matches == SIGN_SHOW_MAX) { + break; + } } - return nr_matches; + } + return nr_matches; } /// Delete sign 'id' in group 'group' from buffer 'buf'. @@ -520,14 +521,15 @@ int buf_get_signattrs(buf_T *buf, linenr_T lnum, sign_attrs_T sattrs[]) /// If 'group' is '*', then delete the sign in all the groups. If 'group' is /// NULL, then delete the sign in the global group. Otherwise delete the sign in /// the specified group. -/// Returns the line number of the deleted sign. If multiple signs are deleted, +/// +/// @param buf buffer sign is stored in +/// @param atlnum sign at this line, 0 - at any line +/// @param id sign id +/// @param group sign group +/// +/// @return the line number of the deleted sign. If multiple signs are deleted, /// then returns the line number of the last sign deleted. -linenr_T buf_delsign( - buf_T *buf, // buffer sign is stored in - linenr_T atlnum, // sign at this line, 0 - at any line - int id, // sign id - char_u *group // sign group -) +linenr_T buf_delsign(buf_T *buf, linenr_T atlnum, int id, char_u *group) { sign_entry_T **lastp; // pointer to pointer to current sign sign_entry_T *sign; // a sign in a b_signlist @@ -580,30 +582,30 @@ linenr_T buf_delsign( /// Find the line number of the sign with the requested id in group 'group'. If /// the sign does not exist, return 0 as the line number. This will still let /// the correct file get loaded. -int buf_findsign( - buf_T *buf, // buffer to store sign in - int id, // sign ID - char_u *group // sign group -) +/// +/// @param buf buffer to store sign in +/// @param id sign ID +/// @param group sign group +int buf_findsign(buf_T *buf, int id, char_u *group) { - sign_entry_T *sign; // a sign in the signlist + sign_entry_T *sign; // a sign in the signlist - FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (sign->se_id == id && sign_in_group(sign, group)) { - return (int)sign->se_lnum; - } + FOR_ALL_SIGNS_IN_BUF(buf, sign) { + if (sign->se_id == id && sign_in_group(sign, group)) { + return (int)sign->se_lnum; } + } - return 0; + return 0; } /// Return the sign at line 'lnum' in buffer 'buf'. Returns NULL if a sign is /// not found at the line. If 'groupname' is NULL, searches in the global group. -static sign_entry_T * buf_getsign_at_line( - buf_T *buf, // buffer whose sign we are searching for - linenr_T lnum, // line number of sign - char_u *groupname // sign group name -) +/// +/// @param buf buffer whose sign we are searching for +/// @param lnum line number of sign +/// @param groupname sign group name +static sign_entry_T *buf_getsign_at_line(buf_T *buf, linenr_T lnum, char_u *groupname) { sign_entry_T *sign; // a sign in the signlist @@ -623,61 +625,61 @@ static sign_entry_T * buf_getsign_at_line( } /// Return the identifier of the sign at line number 'lnum' in buffer 'buf'. -int buf_findsign_id( - buf_T *buf, // buffer whose sign we are searching for - linenr_T lnum, // line number of sign - char_u *groupname // sign group name -) +/// +/// @param buf buffer whose sign we are searching for +/// @param lnum line number of sign +/// @param groupname sign group name +int buf_findsign_id(buf_T *buf, linenr_T lnum, char_u *groupname) { - sign_entry_T *sign; // a sign in the signlist + sign_entry_T *sign; // a sign in the signlist - sign = buf_getsign_at_line(buf, lnum, groupname); - if (sign != NULL) { - return sign->se_id; - } + sign = buf_getsign_at_line(buf, lnum, groupname); + if (sign != NULL) { + return sign->se_id; + } - return 0; + return 0; } /// Delete signs in buffer "buf". void buf_delete_signs(buf_T *buf, char_u *group) { - sign_entry_T *sign; - sign_entry_T **lastp; // pointer to pointer to current sign - sign_entry_T *next; + sign_entry_T *sign; + sign_entry_T **lastp; // pointer to pointer to current sign + sign_entry_T *next; - // When deleting the last sign need to redraw the windows to remove the - // sign column. Not when curwin is NULL (this means we're exiting). - if (buf->b_signlist != NULL && curwin != NULL) { - changed_line_abv_curs(); - } + // When deleting the last sign need to redraw the windows to remove the + // sign column. Not when curwin is NULL (this means we're exiting). + if (buf->b_signlist != NULL && curwin != NULL) { + changed_line_abv_curs(); + } - lastp = &buf->b_signlist; - for (sign = buf->b_signlist; sign != NULL; sign = next) { - next = sign->se_next; - if (sign_in_group(sign, group)) { - *lastp = next; - if (next != NULL) { - next->se_prev = sign->se_prev; - } - if (sign->se_group != NULL) { - sign_group_unref(sign->se_group->sg_name); - } - xfree(sign); - } else { - lastp = &sign->se_next; + lastp = &buf->b_signlist; + for (sign = buf->b_signlist; sign != NULL; sign = next) { + next = sign->se_next; + if (sign_in_group(sign, group)) { + *lastp = next; + if (next != NULL) { + next->se_prev = sign->se_prev; + } + if (sign->se_group != NULL) { + sign_group_unref(sign->se_group->sg_name); } + xfree(sign); + } else { + lastp = &sign->se_next; } - buf->b_signcols_valid = false; + } + buf->b_signcols_valid = false; } /// List placed signs for "rbuf". If "rbuf" is NULL do it for all buffers. void sign_list_placed(buf_T *rbuf, char_u *sign_group) { buf_T *buf; - sign_entry_T *sign; - char lbuf[MSG_BUF_LEN]; - char group[MSG_BUF_LEN]; + sign_entry_T *sign; + char lbuf[MSG_BUF_LEN]; + char group[MSG_BUF_LEN]; MSG_PUTS_TITLE(_("\n--- Signs ---")); msg_putchar('\n'); @@ -720,12 +722,7 @@ void sign_list_placed(buf_T *rbuf, char_u *sign_group) } /// Adjust a placed sign for inserted/deleted lines. -void sign_mark_adjust( - linenr_T line1, - linenr_T line2, - long amount, - long amount_after -) +void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) { sign_entry_T *sign; // a sign in a b_signlist sign_entry_T *next; // the next sign in a b_signlist @@ -769,26 +766,26 @@ void sign_mark_adjust( /// Find index of a ":sign" subcmd from its name. /// "*end_cmd" must be writable. -static int sign_cmd_idx( - char_u *begin_cmd, // begin of sign subcmd - char_u *end_cmd // just after sign subcmd -) +/// +/// @param begin_cmd begin of sign subcmd +/// @param end_cmd just after sign subcmd +static int sign_cmd_idx(char_u *begin_cmd, char_u *end_cmd) { - int idx; - char_u save = *end_cmd; + int idx; + char_u save = *end_cmd; - *end_cmd = (char_u)NUL; - for (idx = 0; ; idx++) { - if (cmds[idx] == NULL || STRCMP(begin_cmd, cmds[idx]) == 0) { - break; - } + *end_cmd = (char_u)NUL; + for (idx = 0; ; idx++) { + if (cmds[idx] == NULL || STRCMP(begin_cmd, cmds[idx]) == 0) { + break; } - *end_cmd = save; - return idx; + } + *end_cmd = save; + return idx; } /// Find a sign by name. Also returns pointer to the previous sign. -static sign_T * sign_find(const char_u *name, sign_T **sp_prev) +static sign_T *sign_find(const char_u *name, sign_T **sp_prev) { sign_T *sp; @@ -808,10 +805,10 @@ static sign_T * sign_find(const char_u *name, sign_T **sp_prev) } /// Allocate a new sign -static sign_T * alloc_new_sign(char_u *name) +static sign_T *alloc_new_sign(char_u *name) { - sign_T *sp; - sign_T *lp; + sign_T *sp; + sign_T *lp; int start = next_sign_typenr; // Allocate a new sign. @@ -858,8 +855,8 @@ static void sign_define_init_icon(sign_T *sp, char_u *icon) /// Initialize the text for a new sign static int sign_define_init_text(sign_T *sp, char_u *text) { - char_u *s; - char_u *endp; + char_u *s; + char_u *endp; int cells; size_t len; @@ -904,17 +901,11 @@ static int sign_define_init_text(sign_T *sp, char_u *text) } /// Define a new sign or update an existing sign -int sign_define_by_name( - char_u *name, - char_u *icon, - char_u *linehl, - char_u *text, - char_u *texthl, - char_u *numhl -) +int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl, + char *numhl) { - sign_T *sp_prev; - sign_T *sp; + sign_T *sp_prev; + sign_T *sp; sp = sign_find(name, &sp_prev); if (sp == NULL) { @@ -949,11 +940,11 @@ int sign_define_by_name( } if (linehl != NULL) { - sp->sn_line_hl = syn_check_group(linehl, (int)STRLEN(linehl)); + sp->sn_line_hl = syn_check_group((char *)linehl, (int)STRLEN(linehl)); } if (texthl != NULL) { - sp->sn_text_hl = syn_check_group(texthl, (int)STRLEN(texthl)); + sp->sn_text_hl = syn_check_group((char *)texthl, (int)STRLEN(texthl)); } if (numhl != NULL) { @@ -966,8 +957,8 @@ int sign_define_by_name( /// Free the sign specified by 'name'. int sign_undefine_by_name(const char_u *name) { - sign_T *sp_prev; - sign_T *sp; + sign_T *sp_prev; + sign_T *sp; sp = sign_find(name, &sp_prev); if (sp == NULL) { @@ -982,18 +973,18 @@ int sign_undefine_by_name(const char_u *name) static void may_force_numberwidth_recompute(buf_T *buf, int unplace) { FOR_ALL_TAB_WINDOWS(tp, wp) - if (wp->w_buffer == buf - && (wp->w_p_nu || wp->w_p_rnu) - && (unplace || wp->w_nrwidth_width < 2) - && (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u')) { - wp->w_nrwidth_line_count = 0; - } + if (wp->w_buffer == buf + && (wp->w_p_nu || wp->w_p_rnu) + && (unplace || wp->w_nrwidth_width < 2) + && (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u')) { + wp->w_nrwidth_line_count = 0; + } } /// List the signs matching 'name' static void sign_list_by_name(char_u *name) { - sign_T *sp; + sign_T *sp; sp = sign_find(name, NULL); if (sp != NULL) { @@ -1005,14 +996,8 @@ static void sign_list_by_name(char_u *name) /// Place a sign at the specified file location or update a sign. -int sign_place( - int *sign_id, - const char_u *sign_group, - const char_u *sign_name, - buf_T *buf, - linenr_T lnum, - int prio -) +int sign_place(int *sign_id, const char_u *sign_group, const char_u *sign_name, buf_T *buf, + linenr_T lnum, int prio) { sign_T *sp; @@ -1038,14 +1023,13 @@ int sign_place( // ":sign place {id} line={lnum} name={name} file={fname}": // place a sign bool has_text_or_icon = sp->sn_text != NULL || sp->sn_icon != NULL; - buf_addsign( - buf, - *sign_id, - sign_group, - prio, - lnum, - sp->sn_typenr, - has_text_or_icon); + buf_addsign(buf, + *sign_id, + sign_group, + prio, + lnum, + sp->sn_typenr, + has_text_or_icon); } else { // ":sign place {id} file={fname}": change sign type and/or priority lnum = buf_change_sign_type(buf, *sign_id, sign_group, sp->sn_typenr, prio); @@ -1075,7 +1059,7 @@ int sign_unplace(int sign_id, char_u *sign_group, buf_T *buf, linenr_T atlnum) redraw_buf_later(buf, NOT_VALID); buf_delete_signs(buf, sign_group); } else { - linenr_T lnum; + linenr_T lnum; // Delete only the specified signs lnum = buf_delsign(buf, atlnum, sign_id, sign_group); @@ -1098,7 +1082,7 @@ int sign_unplace(int sign_id, char_u *sign_group, buf_T *buf, linenr_T atlnum) /// Unplace the sign at the current cursor line. static void sign_unplace_at_cursor(char_u *groupname) { - int id = -1; + int id = -1; id = buf_findsign_id(curwin->w_buffer, curwin->w_cursor.lnum, groupname); if (id > 0) { @@ -1144,13 +1128,13 @@ linenr_T sign_jump(int sign_id, char_u *sign_group, buf_T *buf) /// ":sign define {name} ..." command static void sign_define_cmd(char_u *sign_name, char_u *cmdline) { - char_u *arg; - char_u *p = cmdline; - char_u *icon = NULL; - char_u *text = NULL; - char_u *linehl = NULL; - char_u *texthl = NULL; - char_u *numhl = NULL; + char_u *arg; + char_u *p = cmdline; + char_u *icon = NULL; + char_u *text = NULL; + char_u *linehl = NULL; + char_u *texthl = NULL; + char_u *numhl = NULL; int failed = false; // set values for a defined sign. @@ -1183,7 +1167,7 @@ static void sign_define_cmd(char_u *sign_name, char_u *cmdline) } if (!failed) { - sign_define_by_name(sign_name, icon, linehl, text, texthl, numhl); + sign_define_by_name(sign_name, icon, linehl, text, texthl, (char *)numhl); } xfree(icon); @@ -1194,14 +1178,8 @@ static void sign_define_cmd(char_u *sign_name, char_u *cmdline) } /// ":sign place" command -static void sign_place_cmd( - buf_T *buf, - linenr_T lnum, - char_u *sign_name, - int id, - char_u *group, - int prio -) +static void sign_place_cmd(buf_T *buf, linenr_T lnum, char_u *sign_name, int id, char_u *group, + int prio) { if (id <= 0) { // List signs placed in a file/buffer @@ -1233,62 +1211,56 @@ static void sign_place_cmd( } /// ":sign unplace" command -static void sign_unplace_cmd( - buf_T *buf, - linenr_T lnum, - char_u *sign_name, - int id, - char_u *group -) +static void sign_unplace_cmd(buf_T *buf, linenr_T lnum, char_u *sign_name, int id, char_u *group) { - if (lnum >= 0 || sign_name != NULL || (group != NULL && *group == '\0')) { - EMSG(_(e_invarg)); - return; - } + if (lnum >= 0 || sign_name != NULL || (group != NULL && *group == '\0')) { + EMSG(_(e_invarg)); + return; + } - if (id == -2) { - if (buf != NULL) { - // :sign unplace * file={fname} - // :sign unplace * group={group} file={fname} - // :sign unplace * group=* file={fname} - // :sign unplace * buffer={nr} - // :sign unplace * group={group} buffer={nr} - // :sign unplace * group=* buffer={nr} - sign_unplace(0, group, buf, 0); - } else { - // :sign unplace * - // :sign unplace * group={group} - // :sign unplace * group=* - FOR_ALL_BUFFERS(cbuf) { - if (cbuf->b_signlist != NULL) { - buf_delete_signs(cbuf, group); - } + if (id == -2) { + if (buf != NULL) { + // :sign unplace * file={fname} + // :sign unplace * group={group} file={fname} + // :sign unplace * group=* file={fname} + // :sign unplace * buffer={nr} + // :sign unplace * group={group} buffer={nr} + // :sign unplace * group=* buffer={nr} + sign_unplace(0, group, buf, 0); + } else { + // :sign unplace * + // :sign unplace * group={group} + // :sign unplace * group=* + FOR_ALL_BUFFERS(cbuf) { + if (cbuf->b_signlist != NULL) { + buf_delete_signs(cbuf, group); } } + } + } else { + if (buf != NULL) { + // :sign unplace {id} file={fname} + // :sign unplace {id} group={group} file={fname} + // :sign unplace {id} group=* file={fname} + // :sign unplace {id} buffer={nr} + // :sign unplace {id} group={group} buffer={nr} + // :sign unplace {id} group=* buffer={nr} + sign_unplace(id, group, buf, 0); } else { - if (buf != NULL) { - // :sign unplace {id} file={fname} - // :sign unplace {id} group={group} file={fname} - // :sign unplace {id} group=* file={fname} - // :sign unplace {id} buffer={nr} - // :sign unplace {id} group={group} buffer={nr} - // :sign unplace {id} group=* buffer={nr} - sign_unplace(id, group, buf, 0); + if (id == -1) { + // :sign unplace group={group} + // :sign unplace group=* + sign_unplace_at_cursor(group); } else { - if (id == -1) { - // :sign unplace group={group} - // :sign unplace group=* - sign_unplace_at_cursor(group); - } else { - // :sign unplace {id} - // :sign unplace {id} group={group} - // :sign unplace {id} group=* - FOR_ALL_BUFFERS(cbuf) { - sign_unplace(id, group, cbuf, 0); - } + // :sign unplace {id} + // :sign unplace {id} group={group} + // :sign unplace {id} group=* + FOR_ALL_BUFFERS(cbuf) { + sign_unplace(id, group, cbuf, 0); } } } + } } /// Jump to a placed sign commands: @@ -1296,13 +1268,7 @@ static void sign_unplace_cmd( /// :sign jump {id} buffer={nr} /// :sign jump {id} group={group} file={fname} /// :sign jump {id} group={group} buffer={nr} -static void sign_jump_cmd( - buf_T *buf, - linenr_T lnum, - char_u *sign_name, - int id, - char_u *group -) +static void sign_jump_cmd(buf_T *buf, linenr_T lnum, char_u *sign_name, int id, char_u *group) { if (sign_name == NULL && group == NULL && id == -1) { EMSG(_(e_argreq)); @@ -1324,21 +1290,13 @@ static void sign_jump_cmd( /// ":sign jump" commands. /// The supported arguments are: line={lnum} name={name} group={group} /// priority={prio} and file={fname} or buffer={nr}. -static int parse_sign_cmd_args( - int cmd, - char_u *arg, - char_u **sign_name, - int *signid, - char_u **group, - int *prio, - buf_T **buf, - linenr_T *lnum -) +static int parse_sign_cmd_args(int cmd, char_u *arg, char_u **sign_name, int *signid, + char_u **group, int *prio, buf_T **buf, linenr_T *lnum) { - char_u *arg1; - char_u *name; - char_u *filename = NULL; - int lnum_arg = false; + char_u *arg1; + char_u *name; + char_u *filename = NULL; + int lnum_arg = false; // first arg could be placed sign id arg1 = arg; @@ -1448,7 +1406,7 @@ void ex_sign(exarg_T *eap) } else if (*arg == NUL) { EMSG(_("E156: Missing sign name")); } else { - char_u *name; + char_u *name; // Isolate the sign name. If it's a number skip leading zeroes, // so that "099" and "99" are the same sign. But keep "0". @@ -1574,12 +1532,8 @@ list_T *get_buffer_signs(buf_T *buf) } /// Return information about all the signs placed in a buffer -static void sign_get_placed_in_buf( - buf_T *buf, - linenr_T lnum, - int sign_id, - const char_u *sign_group, - list_T *retlist) +static void sign_get_placed_in_buf(buf_T *buf, linenr_T lnum, int sign_id, const char_u *sign_group, + list_T *retlist) { dict_T *d; list_T *l; @@ -1609,13 +1563,8 @@ static void sign_get_placed_in_buf( /// Get a list of signs placed in buffer 'buf'. If 'num' is non-zero, return the /// sign placed at the line number. If 'lnum' is zero, return all the signs /// placed in 'buf'. If 'buf' is NULL, return signs placed in all the buffers. -void sign_get_placed( - buf_T *buf, - linenr_T lnum, - int sign_id, - const char_u *sign_group, - list_T *retlist -) +void sign_get_placed(buf_T *buf, linenr_T lnum, int sign_id, const char_u *sign_group, + list_T *retlist) { if (buf != NULL) { sign_get_placed_in_buf(buf, lnum, sign_id, sign_group, retlist); @@ -1697,13 +1646,13 @@ void free_signs(void) static enum { - EXP_SUBCMD, // expand :sign sub-commands - EXP_DEFINE, // expand :sign define {name} args - EXP_PLACE, // expand :sign place {id} args - EXP_LIST, // expand :sign place args - EXP_UNPLACE, // expand :sign unplace" - EXP_SIGN_NAMES, // expand with name of placed signs - EXP_SIGN_GROUPS, // expand with name of placed sign groups + EXP_SUBCMD, // expand :sign sub-commands + EXP_DEFINE, // expand :sign define {name} args + EXP_PLACE, // expand :sign place {id} args + EXP_LIST, // expand :sign place args + EXP_UNPLACE, // expand :sign unplace" + EXP_SIGN_NAMES, // expand with name of placed signs + EXP_SIGN_GROUPS, // expand with name of placed sign groups } expand_what; // Return the n'th sign name (used for command line completion) @@ -1740,45 +1689,45 @@ static char_u *get_nth_sign_group_name(int idx) /// Function given to ExpandGeneric() to obtain the sign command /// expansion. -char_u * get_sign_name(expand_T *xp, int idx) +char_u *get_sign_name(expand_T *xp, int idx) { switch (expand_what) { - case EXP_SUBCMD: - return (char_u *)cmds[idx]; - case EXP_DEFINE: { - char *define_arg[] = { "icon=", "linehl=", "text=", "texthl=", "numhl=", - NULL }; - return (char_u *)define_arg[idx]; - } - case EXP_PLACE: { - char *place_arg[] = { "line=", "name=", "group=", "priority=", "file=", - "buffer=", NULL }; - return (char_u *)place_arg[idx]; - } - case EXP_LIST: { - char *list_arg[] = { "group=", "file=", "buffer=", NULL }; - return (char_u *)list_arg[idx]; - } - case EXP_UNPLACE: { - char *unplace_arg[] = { "group=", "file=", "buffer=", NULL }; - return (char_u *)unplace_arg[idx]; - } - case EXP_SIGN_NAMES: - return get_nth_sign_name(idx); - case EXP_SIGN_GROUPS: - return get_nth_sign_group_name(idx); - default: - return NULL; + case EXP_SUBCMD: + return (char_u *)cmds[idx]; + case EXP_DEFINE: { + char *define_arg[] = { "icon=", "linehl=", "text=", "texthl=", "numhl=", + NULL }; + return (char_u *)define_arg[idx]; + } + case EXP_PLACE: { + char *place_arg[] = { "line=", "name=", "group=", "priority=", "file=", + "buffer=", NULL }; + return (char_u *)place_arg[idx]; + } + case EXP_LIST: { + char *list_arg[] = { "group=", "file=", "buffer=", NULL }; + return (char_u *)list_arg[idx]; + } + case EXP_UNPLACE: { + char *unplace_arg[] = { "group=", "file=", "buffer=", NULL }; + return (char_u *)unplace_arg[idx]; + } + case EXP_SIGN_NAMES: + return get_nth_sign_name(idx); + case EXP_SIGN_GROUPS: + return get_nth_sign_group_name(idx); + default: + return NULL; } } /// Handle command line completion for :sign command. void set_context_in_sign_cmd(expand_T *xp, char_u *arg) { - char_u *end_subcmd; - char_u *last; - int cmd_idx; - char_u *begin_subcmd_args; + char_u *end_subcmd; + char_u *last; + int cmd_idx; + char_u *begin_subcmd_args; // Default: expand subcommands. xp->xp_context = EXPAND_SIGN; @@ -1822,70 +1771,70 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg) // Expand last argument name (before equal sign). xp->xp_pattern = last; switch (cmd_idx) { - case SIGNCMD_DEFINE: - expand_what = EXP_DEFINE; - break; - case SIGNCMD_PLACE: - // List placed signs - if (ascii_isdigit(*begin_subcmd_args)) { - // :sign place {id} {args}... - expand_what = EXP_PLACE; - } else { - // :sign place {args}... - expand_what = EXP_LIST; - } - break; - case SIGNCMD_LIST: - case SIGNCMD_UNDEFINE: - // :sign list <CTRL-D> - // :sign undefine <CTRL-D> - expand_what = EXP_SIGN_NAMES; - break; - case SIGNCMD_JUMP: - case SIGNCMD_UNPLACE: - expand_what = EXP_UNPLACE; - break; - default: - xp->xp_context = EXPAND_NOTHING; + case SIGNCMD_DEFINE: + expand_what = EXP_DEFINE; + break; + case SIGNCMD_PLACE: + // List placed signs + if (ascii_isdigit(*begin_subcmd_args)) { + // :sign place {id} {args}... + expand_what = EXP_PLACE; + } else { + // :sign place {args}... + expand_what = EXP_LIST; + } + break; + case SIGNCMD_LIST: + case SIGNCMD_UNDEFINE: + // :sign list <CTRL-D> + // :sign undefine <CTRL-D> + expand_what = EXP_SIGN_NAMES; + break; + case SIGNCMD_JUMP: + case SIGNCMD_UNPLACE: + expand_what = EXP_UNPLACE; + break; + default: + xp->xp_context = EXPAND_NOTHING; } } else { - // Expand last argument value (after equal sign). + // Expand last argument value (after equal sign). xp->xp_pattern = p + 1; switch (cmd_idx) { - case SIGNCMD_DEFINE: - if (STRNCMP(last, "texthl", 6) == 0 - || STRNCMP(last, "linehl", 6) == 0 - || STRNCMP(last, "numhl", 5) == 0) { - xp->xp_context = EXPAND_HIGHLIGHT; - } else if (STRNCMP(last, "icon", 4) == 0) { - xp->xp_context = EXPAND_FILES; - } else { - xp->xp_context = EXPAND_NOTHING; - } - break; - case SIGNCMD_PLACE: - if (STRNCMP(last, "name", 4) == 0) { - expand_what = EXP_SIGN_NAMES; - } else if (STRNCMP(last, "group", 5) == 0) { - expand_what = EXP_SIGN_GROUPS; - } else if (STRNCMP(last, "file", 4) == 0) { - xp->xp_context = EXPAND_BUFFERS; - } else { - xp->xp_context = EXPAND_NOTHING; - } - break; - case SIGNCMD_UNPLACE: - case SIGNCMD_JUMP: - if (STRNCMP(last, "group", 5) == 0) { - expand_what = EXP_SIGN_GROUPS; - } else if (STRNCMP(last, "file", 4) == 0) { - xp->xp_context = EXPAND_BUFFERS; - } else { - xp->xp_context = EXPAND_NOTHING; - } - break; - default: + case SIGNCMD_DEFINE: + if (STRNCMP(last, "texthl", 6) == 0 + || STRNCMP(last, "linehl", 6) == 0 + || STRNCMP(last, "numhl", 5) == 0) { + xp->xp_context = EXPAND_HIGHLIGHT; + } else if (STRNCMP(last, "icon", 4) == 0) { + xp->xp_context = EXPAND_FILES; + } else { xp->xp_context = EXPAND_NOTHING; + } + break; + case SIGNCMD_PLACE: + if (STRNCMP(last, "name", 4) == 0) { + expand_what = EXP_SIGN_NAMES; + } else if (STRNCMP(last, "group", 5) == 0) { + expand_what = EXP_SIGN_GROUPS; + } else if (STRNCMP(last, "file", 4) == 0) { + xp->xp_context = EXPAND_BUFFERS; + } else { + xp->xp_context = EXPAND_NOTHING; + } + break; + case SIGNCMD_UNPLACE: + case SIGNCMD_JUMP: + if (STRNCMP(last, "group", 5) == 0) { + expand_what = EXP_SIGN_GROUPS; + } else if (STRNCMP(last, "file", 4) == 0) { + xp->xp_context = EXPAND_BUFFERS; + } else { + xp->xp_context = EXPAND_NOTHING; + } + break; + default: + xp->xp_context = EXPAND_NOTHING; } } } @@ -1914,15 +1863,15 @@ int sign_define_from_dict(const char *name_arg, dict_T *dict) goto cleanup; } if (dict != NULL) { - icon = tv_dict_get_string(dict, "icon" , true); + icon = tv_dict_get_string(dict, "icon", true); linehl = tv_dict_get_string(dict, "linehl", true); - text = tv_dict_get_string(dict, "text" , true); + text = tv_dict_get_string(dict, "text", true); texthl = tv_dict_get_string(dict, "texthl", true); - numhl = tv_dict_get_string(dict, "numhl" , true); + numhl = tv_dict_get_string(dict, "numhl", true); } if (sign_define_by_name((char_u *)name, (char_u *)icon, (char_u *)linehl, - (char_u *)text, (char_u *)texthl, (char_u *)numhl) + (char_u *)text, (char_u *)texthl, numhl) == OK) { retval = 0; } @@ -1942,27 +1891,23 @@ cleanup: /// values in 'retlist'. void sign_define_multiple(list_T *l, list_T *retlist) { - int retval; + int retval; - TV_LIST_ITER_CONST(l, li, { - retval = -1; - if (TV_LIST_ITEM_TV(li)->v_type == VAR_DICT) { - retval = sign_define_from_dict(NULL, TV_LIST_ITEM_TV(li)->vval.v_dict); - } else { - EMSG(_(e_dictreq)); - } - tv_list_append_number(retlist, retval); - }); + TV_LIST_ITER_CONST(l, li, { + retval = -1; + if (TV_LIST_ITEM_TV(li)->v_type == VAR_DICT) { + retval = sign_define_from_dict(NULL, TV_LIST_ITEM_TV(li)->vval.v_dict); + } else { + EMSG(_(e_dictreq)); + } + tv_list_append_number(retlist, retval); + }); } /// Place a new sign using the values specified in dict 'dict'. Returns the sign /// identifier if successfully placed, otherwise returns 0. -int sign_place_from_dict( - typval_T *id_tv, - typval_T *group_tv, - typval_T *name_tv, - typval_T *buf_tv, - dict_T *dict) +int sign_place_from_dict(typval_T *id_tv, typval_T *group_tv, typval_T *name_tv, typval_T *buf_tv, + dict_T *dict) { int sign_id = 0; char_u *group = NULL; diff --git a/src/nvim/sign.h b/src/nvim/sign.h index e3a5a27c74..9044c2d0bb 100644 --- a/src/nvim/sign.h +++ b/src/nvim/sign.h @@ -2,6 +2,7 @@ #define NVIM_SIGN_H #include <stdbool.h> + #include "nvim/buffer_defs.h" #include "nvim/ex_cmds_defs.h" #include "nvim/sign_defs.h" diff --git a/src/nvim/sign_defs.h b/src/nvim/sign_defs.h index 721b2db25b..f3ec2c45f6 100644 --- a/src/nvim/sign_defs.h +++ b/src/nvim/sign_defs.h @@ -2,6 +2,7 @@ #define NVIM_SIGN_DEFS_H #include <stdbool.h> + #include "nvim/pos.h" #include "nvim/types.h" @@ -10,9 +11,9 @@ // Sign group typedef struct signgroup_S { - uint16_t sg_refcount; // number of signs in this group - int sg_next_sign_id; // next sign id for this group - char_u sg_name[1]; // sign group name + uint16_t sg_refcount; // number of signs in this group + int sg_next_sign_id; // next sign id for this group + char_u sg_name[1]; // sign group name } signgroup_T; // Macros to get the sign group structure from the group name @@ -22,23 +23,23 @@ typedef struct signgroup_S typedef struct sign_entry sign_entry_T; struct sign_entry { - int se_id; // unique identifier for each placed sign - int se_typenr; // typenr of sign - int se_priority; // priority for highlighting - bool se_has_text_or_icon; // has text or icon - linenr_T se_lnum; // line number which has this sign - signgroup_T *se_group; // sign group - sign_entry_T *se_next; // next entry in a list of signs - sign_entry_T *se_prev; // previous entry -- for easy reordering + int se_id; // unique identifier for each placed sign + int se_typenr; // typenr of sign + int se_priority; // priority for highlighting + bool se_has_text_or_icon; // has text or icon + linenr_T se_lnum; // line number which has this sign + signgroup_T *se_group; // sign group + sign_entry_T *se_next; // next entry in a list of signs + sign_entry_T *se_prev; // previous entry -- for easy reordering }; /// Sign attributes. Used by the screen refresh routines. typedef struct sign_attrs_S { - int sat_typenr; - char_u *sat_text; - int sat_texthl; - int sat_linehl; - int sat_numhl; + int sat_typenr; + char_u *sat_text; + int sat_texthl; + int sat_linehl; + int sat_numhl; } sign_attrs_T; #define SIGN_SHOW_MAX 9 diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 610a359141..9ed421c8a0 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -72,15 +72,14 @@ #include <inttypes.h> #include <limits.h> #include <stdbool.h> -#include <string.h> #include <stdlib.h> +#include <string.h> #include <wctype.h> -/* for offsetof() */ +// for offsetof() #include <stddef.h> #include "nvim/ascii.h" -#include "nvim/spell.h" #include "nvim/buffer.h" #include "nvim/change.h" #include "nvim/charset.h" @@ -92,6 +91,7 @@ #include "nvim/ex_docmd.h" #include "nvim/fileio.h" #include "nvim/func_attr.h" +#include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/hashtab.h" #include "nvim/mark.h" @@ -100,21 +100,21 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/garray.h" #include "nvim/normal.h" #include "nvim/option.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" #include "nvim/os_unix.h" #include "nvim/path.h" #include "nvim/regexp.h" #include "nvim/screen.h" #include "nvim/search.h" +#include "nvim/spell.h" #include "nvim/spellfile.h" #include "nvim/strings.h" #include "nvim/syntax.h" -#include "nvim/undo.h" #include "nvim/ui.h" -#include "nvim/os/os.h" -#include "nvim/os/input.h" +#include "nvim/undo.h" // only used for su_badflags #define WF_MIXCAP 0x20 // mix of upper and lower case: macaRONI @@ -151,26 +151,26 @@ typedef struct suginfo_S { int su_maxscore; // maximum score for adding to su_ga int su_sfmaxscore; // idem, for when doing soundfold words garray_T su_sga; // like su_ga, sound-folded scoring - char_u *su_badptr; // start of bad word in line + char_u *su_badptr; // start of bad word in line int su_badlen; // length of detected bad word in line int su_badflags; // caps flags for bad word char_u su_badword[MAXWLEN]; // bad word truncated at su_badlen char_u su_fbadword[MAXWLEN]; // su_badword case-folded char_u su_sal_badword[MAXWLEN]; // su_badword soundfolded hashtab_T su_banned; // table with banned words - slang_T *su_sallang; // default language for sound folding + slang_T *su_sallang; // default language for sound folding } suginfo_T; // One word suggestion. Used in "si_ga". typedef struct { - char_u *st_word; // suggested word, allocated string + char_u *st_word; // suggested word, allocated string int st_wordlen; // STRLEN(st_word) int st_orglen; // length of replaced text int st_score; // lower is better int st_altscore; // used when st_score compares equal bool st_salscore; // st_score is for soundalike bool st_had_bonus; // bonus already included in score - slang_T *st_slang; // language used for sound folding + slang_T *st_slang; // language used for sound folding } suggest_T; #define SUG(ga, i) (((suggest_T *)(ga).ga_data)[i]) @@ -235,14 +235,14 @@ typedef struct { // Structure to store info for word matching. typedef struct matchinf_S { - langp_T *mi_lp; // info for language and region + langp_T *mi_lp; // info for language and region // pointers to original text to be checked - char_u *mi_word; // start of word being checked - char_u *mi_end; // end of matching word so far - char_u *mi_fend; // next char to be added to mi_fword - char_u *mi_cend; // char after what was used for - // mi_capflags + char_u *mi_word; // start of word being checked + char_u *mi_end; // end of matching word so far + char_u *mi_fend; // next char to be added to mi_fword + char_u *mi_cend; // char after what was used for + // mi_capflags // case-folded text char_u mi_fword[MAXWLEN + 1]; // mi_word case-folded @@ -265,11 +265,11 @@ typedef struct matchinf_S { // others int mi_result; // result so far: SP_BAD, SP_OK, etc. int mi_capflags; // WF_ONECAP WF_ALLCAP WF_KEEPCAP - win_T *mi_win; // buffer being checked + win_T *mi_win; // buffer being checked // for NOBREAK int mi_result2; // "mi_resul" without following word - char_u *mi_end2; // "mi_end" without following word + char_u *mi_end2; // "mi_end" without following word } matchinf_T; // Structure used for the cookie argument of do_in_runtimepath(). @@ -334,26 +334,24 @@ char *e_format = N_("E759: Format error in spell file"); static char_u *repl_from = NULL; static char_u *repl_to = NULL; -// Main spell-checking function. -// "ptr" points to a character that could be the start of a word. -// "*attrp" is set to the highlight index for a badly spelled word. For a -// non-word or when it's OK it remains unchanged. -// This must only be called when 'spelllang' is not empty. -// -// "capcol" is used to check for a Capitalised word after the end of a -// sentence. If it's zero then perform the check. Return the column where to -// check next, or -1 when no sentence end was found. If it's NULL then don't -// worry. -// -// Returns the length of the word in bytes, also when it's OK, so that the -// caller can skip over the word. -size_t spell_check( - win_T *wp, // current window - char_u *ptr, - hlf_T *attrp, - int *capcol, // column to check for Capital - bool docount // count good words -) +/// Main spell-checking function. +/// "ptr" points to a character that could be the start of a word. +/// "*attrp" is set to the highlight index for a badly spelled word. For a +/// non-word or when it's OK it remains unchanged. +/// This must only be called when 'spelllang' is not empty. +/// +/// "capcol" is used to check for a Capitalised word after the end of a +/// sentence. If it's zero then perform the check. Return the column where to +/// check next, or -1 when no sentence end was found. If it's NULL then don't +/// worry. +/// +/// @param wp current window +/// @param capcol column to check for Capital +/// @param docount count good words +/// +/// @return the length of the word in bytes, also when it's OK, so that the +/// caller can skip over the word. +size_t spell_check(win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol, bool docount) { matchinf_T mi; // Most things are put in "mi" so that it can // be passed to functions quickly. @@ -383,7 +381,7 @@ size_t spell_check( // julifeest". if (*ptr >= '0' && *ptr <= '9') { if (*ptr == '0' && (ptr[1] == 'b' || ptr[1] == 'B')) { - mi.mi_end = (char_u*) skipbin((char*) ptr + 2); + mi.mi_end = (char_u *)skipbin((char *)ptr + 2); } else if (*ptr == '0' && (ptr[1] == 'x' || ptr[1] == 'X')) { mi.mi_end = skiphex(ptr + 2); } else { @@ -486,7 +484,7 @@ size_t spell_check( // Count the word in the first language where it's found to be OK. if (count_word && mi.mi_result == SP_OK) { count_common_word(mi.mi_lp->lp_slang, ptr, - (int)(mi.mi_end - ptr), 1); + (int)(mi.mi_end - ptr), 1); count_word = false; } } @@ -499,8 +497,8 @@ size_t spell_check( return nrlen; } } else if (!spell_iswordp_nmw(ptr, wp)) { - // When we are at a non-word character there is no error, just - // skip over the character (try looking for a word after it). + // When we are at a non-word character there is no error, just + // skip over the character (try looking for a word after it). if (capcol != NULL && wp->w_s->b_cap_prog != NULL) { regmatch_T regmatch; @@ -521,7 +519,7 @@ size_t spell_check( MB_PTR_ADV(mi.mi_end); } else if (mi.mi_result == SP_BAD && LANGP_ENTRY(wp->w_s->b_langp, 0)->lp_slang->sl_nobreak) { - char_u *p, *fp; + char_u *p, *fp; int save_result = mi.mi_result; // First language in 'spelllang' is NOBREAK. Find first position @@ -576,10 +574,10 @@ static void find_word(matchinf_T *mip, int mode) { int wlen = 0; int flen; - char_u *ptr; - slang_T *slang = mip->mi_lp->lp_slang; - char_u *byts; - idx_T *idxs; + char_u *ptr; + slang_T *slang = mip->mi_lp->lp_slang; + char_u *byts; + idx_T *idxs; if (mode == FIND_KEEPWORD || mode == FIND_KEEPCOMPOUND) { // Check for word with matching case in keep-case tree. @@ -588,9 +586,10 @@ static void find_word(matchinf_T *mip, int mode) byts = slang->sl_kbyts; idxs = slang->sl_kidxs; - if (mode == FIND_KEEPCOMPOUND) + if (mode == FIND_KEEPCOMPOUND) { // Skip over the previously found word(s). wlen += mip->mi_compoff; + } } else { // Check for case-folded in case-folded tree. ptr = mip->mi_fword; @@ -607,12 +606,11 @@ static void find_word(matchinf_T *mip, int mode) wlen = mip->mi_compoff; flen -= mip->mi_compoff; } - } - if (byts == NULL) + if (byts == NULL) { return; // array is empty - + } idx_T arridx = 0; int endlen[MAXWLEN]; // length at possible word endings idx_T endidx[MAXWLEN]; // possible word endings @@ -625,8 +623,9 @@ static void find_word(matchinf_T *mip, int mode) // - we reach the end of the tree, // - or we reach the end of the line. for (;; ) { - if (flen <= 0 && *mip->mi_fend != NUL) + if (flen <= 0 && *mip->mi_fend != NUL) { flen = fold_more(mip); + } len = byts[arridx++]; @@ -648,35 +647,39 @@ static void find_word(matchinf_T *mip, int mode) ++arridx; --len; } - if (len == 0) + if (len == 0) { break; // no children, word must end here + } } // Stop looking at end of the line. - if (ptr[wlen] == NUL) + if (ptr[wlen] == NUL) { break; + } // Perform a binary search in the list of accepted bytes. c = ptr[wlen]; - if (c == TAB) // <Tab> is handled like <Space> + if (c == TAB) { // <Tab> is handled like <Space> c = ' '; + } idx_T lo = arridx; idx_T hi = arridx + len - 1; while (lo < hi) { idx_T m = (lo + hi) / 2; - if (byts[m] > c) + if (byts[m] > c) { hi = m - 1; - else if (byts[m] < c) + } else if (byts[m] < c) { lo = m + 1; - else { + } else { lo = hi = m; break; } } // Stop if there is no matching byte. - if (hi < lo || byts[lo] != c) + if (hi < lo || byts[lo] != c) { break; + } // Continue at the child (if there is one). arridx = idxs[lo]; @@ -687,10 +690,12 @@ static void find_word(matchinf_T *mip, int mode) // checked word. if (c == ' ') { for (;; ) { - if (flen <= 0 && *mip->mi_fend != NUL) + if (flen <= 0 && *mip->mi_fend != NUL) { flen = fold_more(mip); - if (ptr[wlen] != ' ' && ptr[wlen] != TAB) + } + if (ptr[wlen] != ' ' && ptr[wlen] != TAB) { break; + } ++wlen; --flen; } @@ -711,11 +716,13 @@ static void find_word(matchinf_T *mip, int mode) continue; // not at first byte of character } if (spell_iswordp(ptr + wlen, mip->mi_win)) { - if (slang->sl_compprog == NULL && !slang->sl_nobreak) + if (slang->sl_compprog == NULL && !slang->sl_nobreak) { continue; // next char is a word character + } word_ends = false; - } else + } else { word_ends = true; + } // The prefix flag is before compound flags. Once a valid prefix flag // has been found we try compound flags. bool prefix_found = false; @@ -754,23 +761,26 @@ static void find_word(matchinf_T *mip, int mode) } if (mip->mi_capflags == WF_KEEPCAP - || !spell_valid_case(mip->mi_capflags, flags)) + || !spell_valid_case(mip->mi_capflags, flags)) { continue; + } } // When mode is FIND_PREFIX the word must support the prefix: // check the prefix ID and the condition. Do that for the list at // mip->mi_prefarridx that find_prefix() filled. else if (mode == FIND_PREFIX && !prefix_found) { c = valid_word_prefix(mip->mi_prefcnt, mip->mi_prefarridx, - flags, - mip->mi_word + mip->mi_cprefixlen, slang, - false); - if (c == 0) + flags, + mip->mi_word + mip->mi_cprefixlen, slang, + false); + if (c == 0) { continue; + } // Use the WF_RARE flag for a rare prefix. - if (c & WF_RAREPFX) + if (c & WF_RAREPFX) { flags |= WF_RARE; + } prefix_found = true; } @@ -790,8 +800,9 @@ static void find_word(matchinf_T *mip, int mode) // that's too short... Myspell compatibility requires this // anyway. if (((unsigned)flags >> 24) == 0 - || wlen - mip->mi_compoff < slang->sl_compminlen) + || wlen - mip->mi_compoff < slang->sl_compminlen) { continue; + } // For multi-byte chars check character length against // COMPOUNDMIN. if (slang->sl_compminlen > 0 @@ -804,27 +815,32 @@ static void find_word(matchinf_T *mip, int mode) // maximum for syllables is specified. if (!word_ends && mip->mi_complen + mip->mi_compextra + 2 > slang->sl_compmax - && slang->sl_compsylmax == MAXWLEN) + && slang->sl_compsylmax == MAXWLEN) { continue; + } // Don't allow compounding on a side where an affix was added, // unless COMPOUNDPERMITFLAG was used. - if (mip->mi_complen > 0 && (flags & WF_NOCOMPBEF)) + if (mip->mi_complen > 0 && (flags & WF_NOCOMPBEF)) { continue; - if (!word_ends && (flags & WF_NOCOMPAFT)) + } + if (!word_ends && (flags & WF_NOCOMPAFT)) { continue; + } // Quickly check if compounding is possible with this flag. if (!byte_in_str(mip->mi_complen == 0 ? slang->sl_compstartflags : slang->sl_compallflags, - ((unsigned)flags >> 24))) + ((unsigned)flags >> 24))) { continue; + } // If there is a match with a CHECKCOMPOUNDPATTERN rule // discard the compound word. - if (match_checkcompoundpattern(ptr, wlen, &slang->sl_comppat)) + if (match_checkcompoundpattern(ptr, wlen, &slang->sl_comppat)) { continue; + } if (mode == FIND_COMPOUND) { int capflags; @@ -842,8 +858,9 @@ static void find_word(matchinf_T *mip, int mode) } capflags = captype(p, mip->mi_word + wlen); if (capflags == WF_KEEPCAP || (capflags == WF_ALLCAP - && (flags & WF_FIXCAP) != 0)) + && (flags & WF_FIXCAP) != 0)) { continue; + } if (capflags != WF_ALLCAP) { // When the character before the word is a word @@ -876,23 +893,26 @@ static void find_word(matchinf_T *mip, int mode) STRLCPY(fword, ptr, endlen[endidxcnt] + 1); } } - if (!can_compound(slang, fword, mip->mi_compflags)) + if (!can_compound(slang, fword, mip->mi_compflags)) { continue; + } } else if (slang->sl_comprules != NULL - && !match_compoundrule(slang, mip->mi_compflags)) + && !match_compoundrule(slang, mip->mi_compflags)) { // The compound flags collected so far do not match any // COMPOUNDRULE, discard the compounded word. continue; + } } // Check NEEDCOMPOUND: can't use word without compounding. - else if (flags & WF_NEEDCOMP) + else if (flags & WF_NEEDCOMP) { continue; + } int nobreak_result = SP_OK; if (!word_ends) { int save_result = mip->mi_result; - char_u *save_end = mip->mi_end; + char_u *save_end = mip->mi_end; langp_T *save_lp = mip->mi_lp; // Check that a valid word follows. If there is one and we @@ -900,8 +920,9 @@ static void find_word(matchinf_T *mip, int mode) // always finished here. For NOBREAK we only check that a // valid word follows. // Recursive! - if (slang->sl_nobreak) + if (slang->sl_nobreak) { mip->mi_result = SP_BAD; + } // Find following word in case-folded tree. mip->mi_compoff = endlen[endidxcnt]; @@ -922,8 +943,9 @@ static void find_word(matchinf_T *mip, int mode) c = mip->mi_compoff; #endif ++mip->mi_complen; - if (flags & WF_COMPROOT) + if (flags & WF_COMPROOT) { ++mip->mi_compextra; + } // For NOBREAK we need to try all NOBREAK languages, at least // to find the ".add" file(s). @@ -931,8 +953,9 @@ static void find_word(matchinf_T *mip, int mode) if (slang->sl_nobreak) { mip->mi_lp = LANGP_ENTRY(mip->mi_win->w_s->b_langp, lpi); if (mip->mi_lp->lp_slang->sl_fidxs == NULL - || !mip->mi_lp->lp_slang->sl_nobreak) + || !mip->mi_lp->lp_slang->sl_nobreak) { continue; + } } find_word(mip, FIND_COMPOUND); @@ -956,12 +979,14 @@ static void find_word(matchinf_T *mip, int mode) #endif } - if (!slang->sl_nobreak) + if (!slang->sl_nobreak) { break; + } } --mip->mi_complen; - if (flags & WF_COMPROOT) + if (flags & WF_COMPROOT) { --mip->mi_compextra; + } mip->mi_lp = save_lp; if (slang->sl_nobreak) { @@ -969,25 +994,28 @@ static void find_word(matchinf_T *mip, int mode) mip->mi_result = save_result; mip->mi_end = save_end; } else { - if (mip->mi_result == SP_OK) + if (mip->mi_result == SP_OK) { break; + } continue; } } int res = SP_BAD; - if (flags & WF_BANNED) + if (flags & WF_BANNED) { res = SP_BANNED; - else if (flags & WF_REGION) { + } else if (flags & WF_REGION) { // Check region. - if ((mip->mi_lp->lp_region & (flags >> 16)) != 0) + if ((mip->mi_lp->lp_region & (flags >> 16)) != 0) { res = SP_OK; - else + } else { res = SP_LOCAL; - } else if (flags & WF_RARE) + } + } else if (flags & WF_RARE) { res = SP_RARE; - else + } else { res = SP_OK; + } // Always use the longest match and the best result. For NOBREAK // we separately keep the longest match without a following good @@ -997,36 +1025,37 @@ static void find_word(matchinf_T *mip, int mode) mip->mi_result2 = res; mip->mi_end2 = mip->mi_word + wlen; } else if (mip->mi_result2 == res - && mip->mi_end2 < mip->mi_word + wlen) + && mip->mi_end2 < mip->mi_word + wlen) { mip->mi_end2 = mip->mi_word + wlen; + } } else if (mip->mi_result > res) { mip->mi_result = res; mip->mi_end = mip->mi_word + wlen; - } else if (mip->mi_result == res && mip->mi_end < mip->mi_word + wlen) + } else if (mip->mi_result == res && mip->mi_end < mip->mi_word + wlen) { mip->mi_end = mip->mi_word + wlen; + } - if (mip->mi_result == SP_OK) + if (mip->mi_result == SP_OK) { break; + } } - if (mip->mi_result == SP_OK) + if (mip->mi_result == SP_OK) { break; + } } } -// Returns true if there is a match between the word ptr[wlen] and -// CHECKCOMPOUNDPATTERN rules, assuming that we will concatenate with another -// word. -// A match means that the first part of CHECKCOMPOUNDPATTERN matches at the -// end of ptr[wlen] and the second part matches after it. -static bool -match_checkcompoundpattern ( - char_u *ptr, - int wlen, - garray_T *gap // &sl_comppat -) +/// Returns true if there is a match between the word ptr[wlen] and +/// CHECKCOMPOUNDPATTERN rules, assuming that we will concatenate with another +/// word. +/// A match means that the first part of CHECKCOMPOUNDPATTERN matches at the +/// end of ptr[wlen] and the second part matches after it. +/// +/// @param gap &sl_comppat +static bool match_checkcompoundpattern(char_u *ptr, int wlen, garray_T *gap) { - char_u *p; + char_u *p; int len; for (int i = 0; i + 1 < gap->ga_len; i += 2) { @@ -1036,8 +1065,9 @@ match_checkcompoundpattern ( // check if first part matches at end of previous word. p = ((char_u **)gap->ga_data)[i]; len = (int)STRLEN(p); - if (len <= wlen && STRNCMP(ptr + wlen - len, p, len) == 0) + if (len <= wlen && STRNCMP(ptr + wlen - len, p, len) == 0) { return true; + } } } return false; @@ -1045,8 +1075,7 @@ match_checkcompoundpattern ( // Returns true if "flags" is a valid sequence of compound flags and "word" // does not have too many syllables. -static bool can_compound(slang_T *slang, const char_u *word, - const char_u *flags) +static bool can_compound(slang_T *slang, const char_u *word, const char_u *flags) FUNC_ATTR_NONNULL_ALL { char_u uflags[MAXWLEN * 2] = { 0 }; @@ -1069,8 +1098,9 @@ static bool can_compound(slang_T *slang, const char_u *word, // are too many syllables AND the number of compound words is above // COMPOUNDWORDMAX then compounding is not allowed. if (slang->sl_compsylmax < MAXWLEN - && count_syllables(slang, word) > slang->sl_compsylmax) + && count_syllables(slang, word) > slang->sl_compsylmax) { return (int)STRLEN(flags) < slang->sl_compmax; + } return true; } @@ -1082,8 +1112,9 @@ static bool can_be_compound(trystate_T *sp, slang_T *slang, char_u *compflags, i // If the flag doesn't appear in sl_compstartflags or sl_compallflags // then it can't possibly compound. if (!byte_in_str(sp->ts_complen == sp->ts_compsplit - ? slang->sl_compstartflags : slang->sl_compallflags, flag)) + ? slang->sl_compstartflags : slang->sl_compallflags, flag)) { return false; + } // If there are no wildcards, we can check if the flags collected so far // possibly can form a match with COMPOUNDRULE patterns. This only @@ -1105,7 +1136,7 @@ static bool can_be_compound(trystate_T *sp, slang_T *slang, char_u *compflags, i // Caller must check that slang->sl_comprules is not NULL. static bool match_compoundrule(slang_T *slang, char_u *compflags) { - char_u *p; + char_u *p; int i; int c; @@ -1115,30 +1146,37 @@ static bool match_compoundrule(slang_T *slang, char_u *compflags) // them against the current rule entry for (i = 0;; ++i) { c = compflags[i]; - if (c == NUL) + if (c == NUL) { // found a rule that matches for the flags we have so far return true; - if (*p == '/' || *p == NUL) + } + if (*p == '/' || *p == NUL) { break; // end of rule, it's too short + } if (*p == '[') { bool match = false; // compare against all the flags in [] ++p; - while (*p != ']' && *p != NUL) - if (*p++ == c) + while (*p != ']' && *p != NUL) { + if (*p++ == c) { match = true; - if (!match) + } + } + if (!match) { break; // none matches - } else if (*p != c) + } + } else if (*p != c) { break; // flag of word doesn't match flag in pattern + } ++p; } // Skip to the next "/", where the next pattern starts. p = vim_strchr(p, '/'); - if (p == NULL) + if (p == NULL) { break; + } } // Checked all the rules and none of them match the flags, so there @@ -1146,18 +1184,15 @@ static bool match_compoundrule(slang_T *slang, char_u *compflags) return false; } -// Return non-zero if the prefix indicated by "arridx" matches with the prefix -// ID in "flags" for the word "word". -// The WF_RAREPFX flag is included in the return value for a rare prefix. -static int -valid_word_prefix ( - int totprefcnt, // nr of prefix IDs - int arridx, // idx in sl_pidxs[] - int flags, - char_u *word, - slang_T *slang, - bool cond_req // only use prefixes with a condition -) +/// Return non-zero if the prefix indicated by "arridx" matches with the prefix +/// ID in "flags" for the word "word". +/// The WF_RAREPFX flag is included in the return value for a rare prefix. +/// +/// @param totprefcnt nr of prefix IDs +/// @param arridx idx in sl_pidxs[] +/// @param cond_req only use prefixes with a condition +static int valid_word_prefix(int totprefcnt, int arridx, int flags, char_u *word, slang_T *slang, + bool cond_req) { int prefcnt; int pidx; @@ -1168,13 +1203,15 @@ valid_word_prefix ( pidx = slang->sl_pidxs[arridx + prefcnt]; // Check the prefix ID. - if (prefid != (pidx & 0xff)) + if (prefid != (pidx & 0xff)) { continue; + } // Check if the prefix doesn't combine and the word already has a // suffix. - if ((flags & WF_HAS_AFF) && (pidx & WF_PFX_NC)) + if ((flags & WF_HAS_AFF) && (pidx & WF_PFX_NC)) { continue; + } // Check the condition, if there is one. The condition index is // stored in the two bytes above the prefix ID byte. @@ -1183,8 +1220,9 @@ valid_word_prefix ( if (!vim_regexec_prog(rp, false, word, 0)) { continue; } - } else if (cond_req) + } else if (cond_req) { continue; + } // It's a match! Return the WF_ flags. return pidx; @@ -1206,16 +1244,16 @@ static void find_prefix(matchinf_T *mip, int mode) int wlen = 0; int flen; int c; - char_u *ptr; + char_u *ptr; idx_T lo, hi, m; - slang_T *slang = mip->mi_lp->lp_slang; - char_u *byts; - idx_T *idxs; + slang_T *slang = mip->mi_lp->lp_slang; + char_u *byts; + idx_T *idxs; byts = slang->sl_pbyts; - if (byts == NULL) + if (byts == NULL) { return; // array is empty - + } // We use the case-folded word here, since prefixes are always // case-folded. ptr = mip->mi_fword; @@ -1232,8 +1270,9 @@ static void find_prefix(matchinf_T *mip, int mode) // - we reach the end of the tree, // - or we reach the end of the line. for (;; ) { - if (flen == 0 && *mip->mi_fend != NUL) + if (flen == 0 && *mip->mi_fend != NUL) { flen = fold_more(mip); + } len = byts[arridx++]; @@ -1254,9 +1293,10 @@ static void find_prefix(matchinf_T *mip, int mode) // Find the word that comes after the prefix. mip->mi_prefixlen = wlen; - if (mode == FIND_COMPOUND) + if (mode == FIND_COMPOUND) { // Skip over the previously found word(s). mip->mi_prefixlen += mip->mi_compoff; + } // Case-folded length may differ from original length. mip->mi_cprefixlen = nofold_len(mip->mi_fword, mip->mi_prefixlen, @@ -1264,13 +1304,15 @@ static void find_prefix(matchinf_T *mip, int mode) find_word(mip, FIND_PREFIX); - if (len == 0) + if (len == 0) { break; // no children, word must end here + } } // Stop looking at end of the line. - if (ptr[wlen] == NUL) + if (ptr[wlen] == NUL) { break; + } // Perform a binary search in the list of accepted bytes. c = ptr[wlen]; @@ -1278,19 +1320,20 @@ static void find_prefix(matchinf_T *mip, int mode) hi = arridx + len - 1; while (lo < hi) { m = (lo + hi) / 2; - if (byts[m] > c) + if (byts[m] > c) { hi = m - 1; - else if (byts[m] < c) + } else if (byts[m] < c) { lo = m + 1; - else { + } else { lo = hi = m; break; } } // Stop if there is no matching byte. - if (hi < lo || byts[lo] != c) + if (hi < lo || byts[lo] != c) { break; + } // Continue at the child (if there is one). arridx = idxs[lo]; @@ -1305,7 +1348,7 @@ static void find_prefix(matchinf_T *mip, int mode) static int fold_more(matchinf_T *mip) { int flen; - char_u *p; + char_u *p; p = mip->mi_fend; do { @@ -1349,42 +1392,40 @@ static bool no_spell_checking(win_T *wp) return false; } -// Moves to the next spell error. -// "curline" is false for "[s", "]s", "[S" and "]S". -// "curline" is true to find word under/after cursor in the same line. -// For Insert mode completion "dir" is BACKWARD and "curline" is true: move -// to after badly spelled word before the cursor. -// Return 0 if not found, length of the badly spelled word otherwise. -size_t -spell_move_to ( - win_T *wp, - int dir, // FORWARD or BACKWARD - bool allwords, // true for "[s"/"]s", false for "[S"/"]S" - bool curline, - hlf_T *attrp // return: attributes of bad word or NULL - // (only when "dir" is FORWARD) -) +/// Moves to the next spell error. +/// "curline" is false for "[s", "]s", "[S" and "]S". +/// "curline" is true to find word under/after cursor in the same line. +/// For Insert mode completion "dir" is BACKWARD and "curline" is true: move +/// to after badly spelled word before the cursor. +/// +/// @param dir FORWARD or BACKWARD +/// @param allwords true for "[s"/"]s", false for "[S"/"]S" +/// @param attrp return: attributes of bad word or NULL (only when "dir" is FORWARD) +/// +/// @return 0 if not found, length of the badly spelled word otherwise. +size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *attrp) { linenr_T lnum; pos_T found_pos; size_t found_len = 0; - char_u *line; - char_u *p; - char_u *endp; + char_u *line; + char_u *p; + char_u *endp; hlf_T attr = HLF_COUNT; size_t len; int has_syntax = syntax_present(wp); int col; bool can_spell; - char_u *buf = NULL; + char_u *buf = NULL; size_t buflen = 0; int skip = 0; int capcol = -1; bool found_one = false; bool wrapped = false; - if (no_spell_checking(wp)) + if (no_spell_checking(wp)) { return 0; + } // Start looking for bad word at the start of the line, because we can't // start halfway through a word, we don't know where it starts or ends. @@ -1410,8 +1451,9 @@ spell_move_to ( assert(buf && buflen >= len + MAXWLEN + 2); // In first line check first word for Capital. - if (lnum == 1) + if (lnum == 1) { capcol = 0; + } // For checking first word with a capital skip white space. if (capcol == 0) { @@ -1431,10 +1473,11 @@ spell_move_to ( // Copy the line into "buf" and append the start of the next line if // possible. STRCPY(buf, line); - if (lnum < wp->w_buffer->b_ml.ml_line_count) + if (lnum < wp->w_buffer->b_ml.ml_line_count) { spell_cat_line(buf + STRLEN(buf), ml_get_buf(wp->w_buffer, lnum + 1, false), MAXWLEN); + } p = buf + skip; endp = buf + len; while (p < endp) { @@ -1443,8 +1486,9 @@ spell_move_to ( if (dir == BACKWARD && lnum == wp->w_cursor.lnum && !wrapped - && (colnr_T)(p - buf) >= wp->w_cursor.col) + && (colnr_T)(p - buf) >= wp->w_cursor.col) { break; + } // start of word attr = HLF_COUNT; @@ -1464,11 +1508,13 @@ spell_move_to ( if (has_syntax) { col = (int)(p - buf); (void)syn_get_id(wp, lnum, (colnr_T)col, - FALSE, &can_spell, FALSE); - if (!can_spell) + FALSE, &can_spell, FALSE); + if (!can_spell) { attr = HLF_COUNT; - } else + } + } else { can_spell = true; + } if (can_spell) { found_one = true; @@ -1479,8 +1525,9 @@ spell_move_to ( // No need to search further. wp->w_cursor = found_pos; xfree(buf); - if (attrp != NULL) + if (attrp != NULL) { *attrp = attr; + } return len; } else if (curline) { // Insert mode completion: put cursor after @@ -1490,8 +1537,9 @@ spell_move_to ( } found_len = len; } - } else + } else { found_one = true; + } } } @@ -1529,22 +1577,24 @@ spell_move_to ( // starting line again and accept the last match. lnum = wp->w_buffer->b_ml.ml_line_count; wrapped = true; - if (!shortmess(SHM_SEARCH)) + if (!shortmess(SHM_SEARCH)) { give_warning((char_u *)_(top_bot_msg), true); + } } capcol = -1; } else { - if (lnum < wp->w_buffer->b_ml.ml_line_count) + if (lnum < wp->w_buffer->b_ml.ml_line_count) { ++lnum; - else if (!p_ws) + } else if (!p_ws) { break; // at first line and 'nowrapscan' - else { + } else { // Wrap around to the start of the buffer. May search the // starting line again and accept the first match. lnum = 1; wrapped = true; - if (!shortmess(SHM_SEARCH)) + if (!shortmess(SHM_SEARCH)) { give_warning((char_u *)_(bot_top_msg), true); + } } // If we are back at the starting line and there is no match then @@ -1555,17 +1605,19 @@ spell_move_to ( // Skip the characters at the start of the next line that were // included in a match crossing line boundaries. - if (attr == HLF_COUNT) + if (attr == HLF_COUNT) { skip = (int)(p - endp); - else + } else { skip = 0; + } // Capcol skips over the inserted space. --capcol; // But after empty line check first word in next line - if (*skipwhite(line) == NUL) + if (*skipwhite(line) == NUL) { capcol = 0; + } } line_breakcheck(); @@ -1581,12 +1633,13 @@ spell_move_to ( // to skip those bytes if the word was OK. void spell_cat_line(char_u *buf, char_u *line, int maxlen) { - char_u *p; + char_u *p; int n; p = skipwhite(line); - while (vim_strchr((char_u *)"*#/\"\t", *p) != NULL) + while (vim_strchr((char_u *)"*#/\"\t", *p) != NULL) { p = skipwhite(p + 1); + } if (*p != NUL) { // Only worth concatenating if there is something else than spaces to @@ -1630,8 +1683,9 @@ static void spell_load_lang(char_u *lang) if (r == FAIL && *sl.sl_lang != NUL && round == 1 && apply_autocmds(EVENT_SPELLFILEMISSING, lang, - curbuf->b_fname, FALSE, curbuf)) + curbuf->b_fname, FALSE, curbuf)) { continue; + } break; } break; @@ -1647,9 +1701,8 @@ static void spell_load_lang(char_u *lang) lang); do_cmdline_cmd(autocmd_buf); } else { - smsg( - _("Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""), - lang, spell_enc(), lang); + smsg(_("Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""), + lang, spell_enc(), lang); } } else if (sl.sl_slang != NULL) { // At least one file was loaded, now load ALL the additions. @@ -1662,9 +1715,9 @@ static void spell_load_lang(char_u *lang) // use "latin1" for "latin9". And limit to 60 characters (just in case). char_u *spell_enc(void) { - - if (STRLEN(p_enc) < 60 && STRCMP(p_enc, "iso-8859-15") != 0) + if (STRLEN(p_enc) < 60 && STRCMP(p_enc, "iso-8859-15") != 0) { return p_enc; + } return (char_u *)"latin1"; } @@ -1673,7 +1726,7 @@ char_u *spell_enc(void) static void int_wordlist_spl(char_u *fname) { vim_snprintf((char *)fname, MAXPATHL, SPL_FNAME_TMPL, - int_wordlist, spell_enc()); + int_wordlist, spell_enc()); } // Allocate a new slang_T for language "lang". "lang" can be NULL. @@ -1683,8 +1736,9 @@ slang_T *slang_alloc(char_u *lang) { slang_T *lp = xcalloc(1, sizeof(slang_T)); - if (lang != NULL) + if (lang != NULL) { lp->sl_name = vim_strsave(lang); + } ga_init(&lp->sl_rep, sizeof(fromto_T), 10); ga_init(&lp->sl_repsal, sizeof(fromto_T), 10); lp->sl_compmax = MAXWLEN; @@ -1722,7 +1776,7 @@ static void free_fromto(fromto_T *ftp) { // Clear an slang_T so that the file can be reloaded. void slang_clear(slang_T *lp) { - garray_T *gap; + garray_T *gap; XFREE_CLEAR(lp->sl_fbyts); XFREE_CLEAR(lp->sl_kbyts); @@ -1792,17 +1846,18 @@ void slang_clear_sug(slang_T *lp) // Invoked through do_in_runtimepath(). static void spell_load_cb(char_u *fname, void *cookie) { - spelload_T *slp = (spelload_T *)cookie; - slang_T *slang; + spelload_T *slp = (spelload_T *)cookie; + slang_T *slang; slang = spell_load_file(fname, slp->sl_lang, NULL, false); if (slang != NULL) { // When a previously loaded file has NOBREAK also use it for the // ".add" files. - if (slp->sl_nobreak && slang->sl_add) + if (slp->sl_nobreak && slang->sl_add) { slang->sl_nobreak = true; - else if (slang->sl_nobreak) + } else if (slang->sl_nobreak) { slp->sl_nobreak = true; + } slp->sl_slang = slang; } @@ -1818,10 +1873,10 @@ static void spell_load_cb(char_u *fname, void *cookie) void count_common_word(slang_T *lp, char_u *word, int len, int count) { hash_T hash; - hashitem_T *hi; + hashitem_T *hi; wordcount_T *wc; char_u buf[MAXWLEN]; - char_u *p; + char_u *p; if (len == -1) { p = word; @@ -1842,21 +1897,18 @@ void count_common_word(slang_T *lp, char_u *word, int len, int count) hash_add_item(&lp->sl_wordcount, hi, wc->wc_word, hash); } else { wc = HI2WC(hi); - if ((wc->wc_count += count) < (unsigned)count) // check for overflow + if ((wc->wc_count += count) < (unsigned)count) { // check for overflow wc->wc_count = MAXWORDCOUNT; + } } } -// Adjust the score of common words. -static int -score_wordcount_adj ( - slang_T *slang, - int score, - char_u *word, - bool split // word was split, less bonus -) +/// Adjust the score of common words. +/// +/// @param split word was split, less bonus +static int score_wordcount_adj(slang_T *slang, int score, char_u *word, bool split) { - hashitem_T *hi; + hashitem_T *hi; wordcount_T *wc; int bonus; int newscore; @@ -1864,18 +1916,21 @@ score_wordcount_adj ( hi = hash_find(&slang->sl_wordcount, word); if (!HASHITEM_EMPTY(hi)) { wc = HI2WC(hi); - if (wc->wc_count < SCORE_THRES2) + if (wc->wc_count < SCORE_THRES2) { bonus = SCORE_COMMON1; - else if (wc->wc_count < SCORE_THRES3) + } else if (wc->wc_count < SCORE_THRES3) { bonus = SCORE_COMMON2; - else + } else { bonus = SCORE_COMMON3; - if (split) + } + if (split) { newscore = score - bonus / 2; - else + } else { newscore = score - bonus; - if (newscore < 0) + } + if (newscore < 0) { return 0; + } return newscore; } return score; @@ -1885,11 +1940,13 @@ score_wordcount_adj ( // Like strchr() but independent of locale. bool byte_in_str(char_u *str, int n) { - char_u *p; + char_u *p; - for (p = str; *p != NUL; ++p) - if (*p == n) + for (p = str; *p != NUL; ++p) { + if (*p == n) { return true; + } + } return false; } @@ -1897,24 +1954,27 @@ bool byte_in_str(char_u *str, int n) // in "slang->sl_syl_items". int init_syl_tab(slang_T *slang) { - char_u *p; - char_u *s; + char_u *p; + char_u *s; int l; ga_init(&slang->sl_syl_items, sizeof(syl_item_T), 4); p = vim_strchr(slang->sl_syllable, '/'); while (p != NULL) { *p++ = NUL; - if (*p == NUL) // trailing slash + if (*p == NUL) { // trailing slash break; + } s = p; p = vim_strchr(p, '/'); - if (p == NULL) + if (p == NULL) { l = (int)STRLEN(s); - else + } else { l = (int)(p - s); - if (l >= SY_MAXLEN) + } + if (l >= SY_MAXLEN) { return SP_FORMERROR; + } syl_item_T *syl = GA_APPEND_VIA_PTR(syl_item_T, &slang->sl_syl_items); STRLCPY(syl->sy_chars, s, l + 1); @@ -1932,11 +1992,12 @@ static int count_syllables(slang_T *slang, const char_u *word) int cnt = 0; bool skip = false; int len; - syl_item_T *syl; + syl_item_T *syl; int c; - if (slang->sl_syllable == NULL) + if (slang->sl_syllable == NULL) { return 0; + } for (const char_u *p = word; *p != NUL; p += len) { // When running into a space reset counter. @@ -1951,8 +2012,9 @@ static int count_syllables(slang_T *slang, const char_u *word) for (int i = 0; i < slang->sl_syl_items.ga_len; ++i) { syl = ((syl_item_T *)slang->sl_syl_items.ga_data) + i; if (syl->sy_len > len - && STRNCMP(p, syl->sy_chars, syl->sy_len) == 0) + && STRNCMP(p, syl->sy_chars, syl->sy_len) == 0) { len = syl->sy_len; + } } if (len != 0) { // found a match, count syllable ++cnt; @@ -1961,9 +2023,9 @@ static int count_syllables(slang_T *slang, const char_u *word) // No recognized syllable item, at least a syllable char then? c = utf_ptr2char(p); len = (*mb_ptr2len)(p); - if (vim_strchr(slang->sl_syllable, c) == NULL) + if (vim_strchr(slang->sl_syllable, c) == NULL) { skip = false; // No, search for next syllable - else if (!skip) { + } else if (!skip) { ++cnt; // Yes, count it skip = true; // don't count following syllable chars } @@ -1977,26 +2039,26 @@ static int count_syllables(slang_T *slang, const char_u *word) char_u *did_set_spelllang(win_T *wp) { garray_T ga; - char_u *splp; - char_u *region; + char_u *splp; + char_u *region; char_u region_cp[3]; bool filename; int region_mask; - slang_T *slang; + slang_T *slang; int c; char_u lang[MAXWLEN + 1]; char_u spf_name[MAXPATHL]; int len; - char_u *p; + char_u *p; int round; - char_u *spf; - char_u *use_region = NULL; + char_u *spf; + char_u *use_region = NULL; bool dont_use_region = false; bool nobreak = false; - langp_T *lp, *lp2; + langp_T *lp, *lp2; static bool recursive = false; - char_u *ret_msg = NULL; - char_u *spl_copy; + char_u *ret_msg = NULL; + char_u *spl_copy; bufref_T bufref; set_bufref(&bufref, wp->w_buffer); @@ -2004,8 +2066,9 @@ char_u *did_set_spelllang(win_T *wp) // We don't want to do this recursively. May happen when a language is // not available and the SpellFileMissing autocommand opens a new buffer // in which 'spell' is set. - if (recursive) + if (recursive) { return NULL; + } recursive = true; ga_init(&ga, sizeof(langp_T), 2); @@ -2046,8 +2109,9 @@ char_u *did_set_spelllang(win_T *wp) STRLCPY(region_cp, p + 1, 3); memmove(p, p + 3, len - (p - lang) - 2); region = region_cp; - } else + } else { dont_use_region = true; + } // Check if we loaded this language before. for (slang = first_lang; slang != NULL; slang = slang->sl_next) { @@ -2061,28 +2125,32 @@ char_u *did_set_spelllang(win_T *wp) if (len > 3 && lang[len - 3] == '_') { region = lang + len - 2; lang[len - 3] = NUL; - } else + } else { dont_use_region = true; + } // Check if we loaded this language before. - for (slang = first_lang; slang != NULL; slang = slang->sl_next) - if (STRICMP(lang, slang->sl_name) == 0) + for (slang = first_lang; slang != NULL; slang = slang->sl_next) { + if (STRICMP(lang, slang->sl_name) == 0) { break; + } + } } if (region != NULL) { // If the region differs from what was used before then don't // use it for 'spellfile'. - if (use_region != NULL && STRCMP(region, use_region) != 0) + if (use_region != NULL && STRCMP(region, use_region) != 0) { dont_use_region = true; + } use_region = region; } // If not found try loading the language now. if (slang == NULL) { - if (filename) + if (filename) { (void)spell_load_file(lang, lang, NULL, false); - else { + } else { spell_load_lang(lang); // SpellFileMissing autocommands may do anything, including // destroying the buffer we are using... @@ -2105,16 +2173,19 @@ char_u *did_set_spelllang(win_T *wp) c = find_region(slang->sl_regions, region); if (c == REGION_ALL) { if (slang->sl_add) { - if (*slang->sl_regions != NUL) + if (*slang->sl_regions != NUL) { // This addition file is for other regions. region_mask = 0; - } else + } + } else { // This is probably an error. Give a warning and // accept the words anyway. smsg(_("Warning: region %s not supported"), region); - } else + } + } else { region_mask = 1 << c; + } } if (region_mask != 0) { @@ -2123,8 +2194,9 @@ char_u *did_set_spelllang(win_T *wp) p_->lp_region = region_mask; use_midword(slang, wp); - if (slang->sl_nobreak) + if (slang->sl_nobreak) { nobreak = true; + } } } } @@ -2138,8 +2210,9 @@ char_u *did_set_spelllang(win_T *wp) for (round = 0; round == 0 || *spf != NUL; ++round) { if (round == 0) { // Internal wordlist, if there is one. - if (int_wordlist == NULL) + if (int_wordlist == NULL) { continue; + } int_wordlist_spl(spf_name); } else { // One entry in 'spellfile'. @@ -2154,8 +2227,9 @@ char_u *did_set_spelllang(win_T *wp) break; } } - if (c < ga.ga_len) + if (c < ga.ga_len) { continue; + } } // Check if it was loaded already. @@ -2169,31 +2243,34 @@ char_u *did_set_spelllang(win_T *wp) // Not loaded, try loading it now. The language name includes the // region name, the region is ignored otherwise. for int_wordlist // use an arbitrary name. - if (round == 0) + if (round == 0) { STRCPY(lang, "internal wordlist"); - else { + } else { STRLCPY(lang, path_tail(spf_name), MAXWLEN + 1); p = vim_strchr(lang, '.'); - if (p != NULL) + if (p != NULL) { *p = NUL; // truncate at ".encoding.add" + } } slang = spell_load_file(spf_name, lang, NULL, true); // If one of the languages has NOBREAK we assume the addition // files also have this. - if (slang != NULL && nobreak) + if (slang != NULL && nobreak) { slang->sl_nobreak = true; + } } if (slang != NULL) { region_mask = REGION_ALL; if (use_region != NULL && !dont_use_region) { // find region in sl_regions c = find_region(slang->sl_regions, use_region); - if (c != REGION_ALL) + if (c != REGION_ALL) { region_mask = 1 << c; - else if (*slang->sl_regions != NUL) + } else if (*slang->sl_regions != NUL) { // This spell file is for other regions. region_mask = 0; + } } if (region_mask != 0) { @@ -2219,36 +2296,38 @@ char_u *did_set_spelllang(win_T *wp) lp = LANGP_ENTRY(ga, i); // sound folding - if (!GA_EMPTY(&lp->lp_slang->sl_sal)) + if (!GA_EMPTY(&lp->lp_slang->sl_sal)) { // language does sound folding itself lp->lp_sallang = lp->lp_slang; - else + } else { // find first similar language that does sound folding for (int j = 0; j < ga.ga_len; ++j) { lp2 = LANGP_ENTRY(ga, j); if (!GA_EMPTY(&lp2->lp_slang->sl_sal) && STRNCMP(lp->lp_slang->sl_name, - lp2->lp_slang->sl_name, 2) == 0) { + lp2->lp_slang->sl_name, 2) == 0) { lp->lp_sallang = lp2->lp_slang; break; } } + } // REP items - if (!GA_EMPTY(&lp->lp_slang->sl_rep)) + if (!GA_EMPTY(&lp->lp_slang->sl_rep)) { // language has REP items itself lp->lp_replang = lp->lp_slang; - else + } else { // find first similar language that has REP items for (int j = 0; j < ga.ga_len; ++j) { lp2 = LANGP_ENTRY(ga, j); if (!GA_EMPTY(&lp2->lp_slang->sl_rep) && STRNCMP(lp->lp_slang->sl_name, - lp2->lp_slang->sl_name, 2) == 0) { + lp2->lp_slang->sl_name, 2) == 0) { lp->lp_replang = lp2->lp_slang; break; } } + } } theend: @@ -2302,10 +2381,12 @@ static int find_region(char_u *rp, char_u *region) int i; for (i = 0;; i += 2) { - if (rp[i] == NUL) + if (rp[i] == NUL) { return REGION_ALL; - if (rp[i] == region[0] && rp[i + 1] == region[1]) + } + if (rp[i] == region[0] && rp[i + 1] == region[1]) { break; + } } return i / 2; } @@ -2323,7 +2404,7 @@ static int find_region(char_u *rp, char_u *region) int captype(char_u *word, char_u *end) FUNC_ATTR_NONNULL_ARG(1) { - char_u *p; + char_u *p; int firstcap; bool allcap; bool past_second = false; // past second word char @@ -2356,10 +2437,12 @@ int captype(char_u *word, char_u *end) } } - if (allcap) + if (allcap) { return WF_ALLCAP; - if (firstcap) + } + if (firstcap) { return WF_ONECAP; + } return 0; } @@ -2373,7 +2456,7 @@ static int badword_captype(char_u *word, char_u *end) int c; int l, u; bool first; - char_u *p; + char_u *p; if (flags & WF_KEEPCAP) { // Count the number of UPPER and lower case letters. @@ -2383,23 +2466,27 @@ static int badword_captype(char_u *word, char_u *end) c = PTR2CHAR(p); if (SPELL_ISUPPER(c)) { ++u; - if (p == word) + if (p == word) { first = true; - } else + } + } else { ++l; + } } // If there are more UPPER than lower case letters suggest an // ALLCAP word. Otherwise, if the first letter is UPPER then // suggest ONECAP. Exception: "ALl" most likely should be "All", // require three upper case letters. - if (u > l && u > 2) + if (u > l && u > 2) { flags |= WF_ALLCAP; - else if (first) + } else if (first) { flags |= WF_ONECAP; + } - if (u >= 2 && l >= 2) // maCARONI maCAroni + if (u >= 2 && l >= 2) { // maCARONI maCAroni flags |= WF_MIXCAP; + } } return flags; } @@ -2407,7 +2494,7 @@ static int badword_captype(char_u *word, char_u *end) // Delete the internal wordlist and its .spl file. void spell_delete_wordlist(void) { - char_u fname[MAXPATHL] = {0}; + char_u fname[MAXPATHL] = { 0 }; if (int_wordlist != NULL) { os_remove((char *)int_wordlist); @@ -2420,7 +2507,7 @@ void spell_delete_wordlist(void) // Free all languages. void spell_free_all(void) { - slang_T *slang; + slang_T *slang; // Go through all buffers and handle 'spelllang'. <VN> FOR_ALL_BUFFERS(buf) { @@ -2475,10 +2562,10 @@ static int bytes2offset(char_u **pp) c = *p++; if ((c & 0x80) == 0x00) { // 1 byte nr = c - 1; - } else if ((c & 0xc0) == 0x80) { // 2 bytes + } else if ((c & 0xc0) == 0x80) { // 2 bytes nr = (c & 0x3f) - 1; nr = nr * 255 + (*p++ - 1); - } else if ((c & 0xe0) == 0xc0) { // 3 bytes + } else if ((c & 0xe0) == 0xc0) { // 3 bytes nr = (c & 0x1f) - 1; nr = nr * 255 + (*p++ - 1); nr = nr * 255 + (*p++ - 1); @@ -2537,8 +2624,9 @@ void clear_spell_chartab(spelltab_T *sp) // We include digits. A word shouldn't start with a digit, but handling // that is done separately. - for (i = '0'; i <= '9'; ++i) + for (i = '0'; i <= '9'; ++i) { sp->st_isw[i] = true; + } for (i = 'A'; i <= 'Z'; ++i) { sp->st_isw[i] = true; sp->st_isu[i] = true; @@ -2627,9 +2715,10 @@ bool spell_iswordp_nmw(const char_u *p, win_T *wp) static bool spell_mb_isword_class(int cl, const win_T *wp) FUNC_ATTR_PURE FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { - if (wp->w_s->b_cjk) + if (wp->w_s->b_cjk) { // East Asian characters are not considered word characters. return cl == 2 || cl == 0x2800; + } return cl >= 2 && cl != 0x2070 && cl != 0x2080 && cl != 3; } @@ -2641,11 +2730,12 @@ static bool spell_iswordp_w(const int *p, const win_T *wp) const int *s; if (*p < 256 ? wp->w_s->b_spell_ismw[*p] - : (wp->w_s->b_spell_ismw_mb != NULL - && vim_strchr(wp->w_s->b_spell_ismw_mb, *p) != NULL)) + : (wp->w_s->b_spell_ismw_mb != NULL + && vim_strchr(wp->w_s->b_spell_ismw_mb, *p) != NULL)) { s = p + 1; - else + } else { s = p; + } if (*s > 255) { return spell_mb_isword_class(utf_class(*s), wp); @@ -2657,8 +2747,7 @@ static bool spell_iswordp_w(const int *p, const win_T *wp) // Uses the character definitions from the .spl file. // When using a multi-byte 'encoding' the length may change! // Returns FAIL when something wrong. -int spell_casefold(const win_T *wp, char_u *str, int len, char_u *buf, - int buflen) +int spell_casefold(const win_T *wp, char_u *str, int len, char_u *buf, int buflen) FUNC_ATTR_NONNULL_ALL { if (len >= buflen) { @@ -2708,8 +2797,8 @@ static int sps_limit = 9999; // max nr of suggestions given // Sets "sps_flags" and "sps_limit". int spell_check_sps(void) { - char_u *p; - char_u *s; + char_u *p; + char_u *s; char_u buf[MAXPATHL]; int f; @@ -2742,12 +2831,14 @@ int spell_check_sps(void) sps_limit = 9999; return FAIL; } - if (f != 0) + if (f != 0) { sps_flags = f; + } } - if (sps_flags == 0) + if (sps_flags == 0) { sps_flags = SPS_BEST; + } return OK; } @@ -2758,13 +2849,13 @@ int spell_check_sps(void) // When "count" is non-zero use that suggestion. void spell_suggest(int count) { - char_u *line; + char_u *line; pos_T prev_cursor = curwin->w_cursor; char_u wcopy[MAXWLEN + 2]; - char_u *p; + char_u *p; int c; suginfo_T sug; - suggest_T *stp; + suggest_T *stp; int mouse_used; int need_cap; int limit; @@ -2833,36 +2924,39 @@ void spell_suggest(int count) // Get the list of suggestions. Limit to 'lines' - 2 or the number in // 'spellsuggest', whatever is smaller. - if (sps_limit > (int)Rows - 2) - limit = (int)Rows - 2; - else + if (sps_limit > Rows - 2) { + limit = Rows - 2; + } else { limit = sps_limit; + } spell_find_suggest(line + curwin->w_cursor.col, badlen, &sug, limit, - true, need_cap, true); + true, need_cap, true); - if (GA_EMPTY(&sug.su_ga)) + if (GA_EMPTY(&sug.su_ga)) { MSG(_("Sorry, no suggestions")); - else if (count > 0) { - if (count > sug.su_ga.ga_len) + } else if (count > 0) { + if (count > sug.su_ga.ga_len) { smsg(_("Sorry, only %" PRId64 " suggestions"), (int64_t)sug.su_ga.ga_len); + } } else { // When 'rightleft' is set the list is drawn right-left. cmdmsg_rl = curwin->w_p_rl; - if (cmdmsg_rl) + if (cmdmsg_rl) { msg_col = Columns - 1; + } // List the suggestions. msg_start(); msg_row = Rows - 1; // for when 'cmdheight' > 1 lines_left = Rows; // avoid more prompt vim_snprintf((char *)IObuff, IOSIZE, _("Change \"%.*s\" to:"), - sug.su_badlen, sug.su_badptr); + sug.su_badlen, sug.su_badptr); if (cmdmsg_rl && STRNCMP(IObuff, "Change", 6) == 0) { // And now the rabbit from the high hat: Avoid showing the // untranslated message rightleft. vim_snprintf((char *)IObuff, IOSIZE, ":ot \"%.*s\" egnahC", - sug.su_badlen, sug.su_badptr); + sug.su_badlen, sug.su_badptr); } msg_puts((const char *)IObuff); msg_clr_eos(); @@ -2875,10 +2969,11 @@ void spell_suggest(int count) // The suggested word may replace only part of the bad word, add // the not replaced part. STRLCPY(wcopy, stp->st_word, MAXWLEN + 1); - if (sug.su_badlen > stp->st_orglen) + if (sug.su_badlen > stp->st_orglen) { STRLCPY(wcopy + stp->st_wordlen, - sug.su_badptr + stp->st_orglen, - sug.su_badlen - stp->st_orglen + 1); + sug.su_badptr + stp->st_orglen, + sug.su_badlen - stp->st_orglen + 1); + } vim_snprintf((char *)IObuff, IOSIZE, "%2d", i + 1); if (cmdmsg_rl) { rl_mirror(IObuff); @@ -2897,16 +2992,18 @@ void spell_suggest(int count) if (p_verbose > 0) { // Add the score. - if (sps_flags & (SPS_DOUBLE | SPS_BEST)) + if (sps_flags & (SPS_DOUBLE | SPS_BEST)) { vim_snprintf((char *)IObuff, IOSIZE, " (%s%d - %d)", - stp->st_salscore ? "s " : "", - stp->st_score, stp->st_altscore); - else + stp->st_salscore ? "s " : "", + stp->st_score, stp->st_altscore); + } else { vim_snprintf((char *)IObuff, IOSIZE, " (%d)", - stp->st_score); - if (cmdmsg_rl) + stp->st_score); + } + if (cmdmsg_rl) { // Mirror the numbers, but keep the leading space. rl_mirror(IObuff + 1); + } msg_advance(30); msg_puts((const char *)IObuff); } @@ -2941,8 +3038,8 @@ void spell_suggest(int count) // repl_to. repl_from = vim_strnsave(sug.su_badptr, sug.su_badlen); vim_snprintf((char *)IObuff, IOSIZE, "%s%.*s", stp->st_word, - sug.su_badlen - stp->st_orglen, - sug.su_badptr + stp->st_orglen); + sug.su_badlen - stp->st_orglen, + sug.su_badptr + stp->st_orglen); repl_to = vim_strsave(IObuff); } else { // Replacing su_badlen or more, use the whole word. @@ -2961,7 +3058,7 @@ void spell_suggest(int count) ResetRedobuff(); AppendToRedobuff("ciw"); AppendToRedobuffLit(p + c, - stp->st_wordlen + sug.su_badlen - stp->st_orglen); + stp->st_wordlen + sug.su_badlen - stp->st_orglen); AppendCharToRedobuff(ESC); // "p" may be freed here @@ -2969,8 +3066,9 @@ void spell_suggest(int count) curwin->w_cursor.col = c; changed_bytes(curwin->w_cursor.lnum, c); - } else + } else { curwin->w_cursor = prev_cursor; + } spell_find_cleanup(&sug); xfree(line); @@ -2982,27 +3080,28 @@ void spell_suggest(int count) static bool check_need_cap(linenr_T lnum, colnr_T col) { bool need_cap = false; - char_u *line; - char_u *line_copy = NULL; - char_u *p; + char_u *line; + char_u *line_copy = NULL; + char_u *p; colnr_T endcol; regmatch_T regmatch; - if (curwin->w_s->b_cap_prog == NULL) + if (curwin->w_s->b_cap_prog == NULL) { return false; + } line = get_cursor_line_ptr(); endcol = 0; if (getwhitecols(line) >= (int)col) { // At start of line, check if previous line is empty or sentence // ends there. - if (lnum == 1) + if (lnum == 1) { need_cap = true; - else { + } else { line = ml_get(lnum - 1); - if (*skipwhite(line) == NUL) + if (*skipwhite(line) == NUL) { need_cap = true; - else { + } else { // Append a space in place of the line break. line_copy = concat_str(line, (char_u *)" "); line = line_copy; @@ -3042,10 +3141,10 @@ static bool check_need_cap(linenr_T lnum, colnr_T col) void ex_spellrepall(exarg_T *eap) { pos_T pos = curwin->w_cursor; - char_u *frompat; + char_u *frompat; int addlen; - char_u *line; - char_u *p; + char_u *line; + char_u *p; bool save_ws = p_ws; linenr_T prev_lnum = 0; @@ -3072,7 +3171,7 @@ void ex_spellrepall(exarg_T *eap) // when changing "etc" to "etc.". line = get_cursor_line_ptr(); if (addlen <= 0 || STRNCMP(line + curwin->w_cursor.col, - repl_to, STRLEN(repl_to)) != 0) { + repl_to, STRLEN(repl_to)) != 0) { p = xmalloc(STRLEN(line) + addlen + 1); memmove(p, line, curwin->w_cursor.col); STRCPY(p + curwin->w_cursor.col, repl_to); @@ -3093,26 +3192,23 @@ void ex_spellrepall(exarg_T *eap) curwin->w_cursor = pos; xfree(frompat); - if (sub_nsubs == 0) + if (sub_nsubs == 0) { EMSG2(_("E753: Not found: %s"), repl_from); - else + } else { do_sub_msg(false); + } } -// Find spell suggestions for "word". Return them in the growarray "*gap" as -// a list of allocated strings. -void -spell_suggest_list ( - garray_T *gap, - char_u *word, - int maxcount, // maximum nr of suggestions - bool need_cap, // 'spellcapcheck' matched - bool interactive -) +/// Find spell suggestions for "word". Return them in the growarray "*gap" as +/// a list of allocated strings. +/// +/// @param maxcount maximum nr of suggestions +/// @param need_cap 'spellcapcheck' matched +void spell_suggest_list(garray_T *gap, char_u *word, int maxcount, bool need_cap, bool interactive) { suginfo_T sug; - suggest_T *stp; - char_u *wcopy; + suggest_T *stp; + char_u *wcopy; spell_find_suggest(word, 0, &sug, maxcount, false, need_cap, interactive); @@ -3134,44 +3230,41 @@ spell_suggest_list ( spell_find_cleanup(&sug); } -// Find spell suggestions for the word at the start of "badptr". -// Return the suggestions in "su->su_ga". -// The maximum number of suggestions is "maxcount". -// Note: does use info for the current window. -// This is based on the mechanisms of Aspell, but completely reimplemented. -static void -spell_find_suggest ( - char_u *badptr, - int badlen, // length of bad word or 0 if unknown - suginfo_T *su, - int maxcount, - bool banbadword, // don't include badword in suggestions - bool need_cap, // word should start with capital - bool interactive -) +/// Find spell suggestions for the word at the start of "badptr". +/// Return the suggestions in "su->su_ga". +/// The maximum number of suggestions is "maxcount". +/// Note: does use info for the current window. +/// This is based on the mechanisms of Aspell, but completely reimplemented. +/// +/// @param badlen length of bad word or 0 if unknown +/// @param banbadword don't include badword in suggestions +/// @param need_cap word should start with capital +static void spell_find_suggest(char_u *badptr, int badlen, suginfo_T *su, int maxcount, + bool banbadword, bool need_cap, bool interactive) { hlf_T attr = HLF_COUNT; char_u buf[MAXPATHL]; - char_u *p; + char_u *p; bool do_combine = false; - char_u *sps_copy; + char_u *sps_copy; static bool expr_busy = false; int c; - langp_T *lp; + langp_T *lp; bool did_intern = false; // Set the info in "*su". memset(su, 0, sizeof(suginfo_T)); ga_init(&su->su_ga, (int)sizeof(suggest_T), 10); ga_init(&su->su_sga, (int)sizeof(suggest_T), 10); - if (*badptr == NUL) + if (*badptr == NUL) { return; + } hash_init(&su->su_banned); su->su_badptr = badptr; - if (badlen != 0) + if (badlen != 0) { su->su_badlen = badlen; - else { + } else { size_t tmplen = spell_check(curwin, su->su_badptr, &attr, NULL, false); assert(tmplen <= INT_MAX); su->su_badlen = (int)tmplen; @@ -3179,8 +3272,9 @@ spell_find_suggest ( su->su_maxcount = maxcount; su->su_maxscore = SCORE_MAXINIT; - if (su->su_badlen >= MAXWLEN) + if (su->su_badlen >= MAXWLEN) { su->su_badlen = MAXWLEN - 1; // just in case + } STRLCPY(su->su_badword, su->su_badptr, su->su_badlen + 1); (void)spell_casefold(curwin, su->su_badptr, su->su_badlen, su->su_fbadword, MAXWLEN); @@ -3192,9 +3286,10 @@ spell_find_suggest ( // get caps flags for bad word su->su_badflags = badword_captype(su->su_badptr, - su->su_badptr + su->su_badlen); - if (need_cap) + su->su_badptr + su->su_badlen); + if (need_cap) { su->su_badflags |= WF_ONECAP; + } // Find the default language for sound folding. We simply use the first // one in 'spelllang' that supports sound folding. That's good for when @@ -3210,9 +3305,10 @@ spell_find_suggest ( // Soundfold the bad word with the default sound folding, so that we don't // have to do this many times. - if (su->su_sallang != NULL) + if (su->su_sallang != NULL) { spell_soundfold(su->su_sallang, su->su_fbadword, true, - su->su_sal_badword); + su->su_sal_badword); + } // If the word is not capitalised and spell_check() doesn't consider the // word to be bad then it might need to be capitalised. Add a suggestion @@ -3221,12 +3317,13 @@ spell_find_suggest ( if (!SPELL_ISUPPER(c) && attr == HLF_COUNT) { make_case_word(su->su_badword, buf, WF_ONECAP); add_suggestion(su, &su->su_ga, buf, su->su_badlen, SCORE_ICASE, - 0, true, su->su_sallang, false); + 0, true, su->su_sallang, false); } // Ban the bad word itself. It may appear in another region. - if (banbadword) + if (banbadword) { add_banned(su, su->su_badword); + } // Make a copy of 'spellsuggest', because the expression may change it. sps_copy = vim_strsave(p_sps); @@ -3258,10 +3355,11 @@ spell_find_suggest ( xfree(sps_copy); - if (do_combine) + if (do_combine) { // Combine the two list of suggestions. This must be done last, // because sorting changes the order again. score_combine(su); + } } // Find suggestions by evaluating expression "expr". @@ -3297,9 +3395,9 @@ static void spell_suggest_expr(suginfo_T *su, char_u *expr) // Find suggestions in file "fname". Used for "file:" in 'spellsuggest'. static void spell_suggest_file(suginfo_T *su, char_u *fname) { - FILE *fd; + FILE *fd; char_u line[MAXWLEN * 2]; - char_u *p; + char_u *p; int len; char_u cword[MAXWLEN]; @@ -3315,13 +3413,15 @@ static void spell_suggest_file(suginfo_T *su, char_u *fname) line_breakcheck(); p = vim_strchr(line, '/'); - if (p == NULL) + if (p == NULL) { continue; // No Tab found, just skip the line. + } *p++ = NUL; if (STRICMP(su->su_badword, line) == 0) { // Match! Isolate the good word, until CR or NL. - for (len = 0; p[len] >= ' '; ++len) + for (len = 0; p[len] >= ' '; ++len) { ; + } p[len] = NUL; // If the suggestion doesn't have specific case duplicate the case @@ -3332,7 +3432,7 @@ static void spell_suggest_file(suginfo_T *su, char_u *fname) } add_suggestion(su, &su->su_ga, p, su->su_badlen, - SCORE_FILE, 0, true, su->su_sallang, false); + SCORE_FILE, 0, true, su->su_sallang, false); } } @@ -3360,15 +3460,17 @@ static void spell_suggest_intern(suginfo_T *su, bool interactive) suggest_try_change(su); // For the resulting top-scorers compute the sound-a-like score. - if (sps_flags & SPS_DOUBLE) + if (sps_flags & SPS_DOUBLE) { score_comp_sal(su); + } // 3. Try finding sound-a-like words. if ((sps_flags & SPS_FAST) == 0) { - if (sps_flags & SPS_BEST) + if (sps_flags & SPS_BEST) { // Adjust the word score for the suggestions found so far for how // they sounds like. rescore_suggestions(su); + } // While going through the soundfold tree "su_maxscore" is the score // for the soundfold word, limits the changes that are being tried, @@ -3407,9 +3509,10 @@ static void spell_suggest_intern(suginfo_T *su, bool interactive) } if ((sps_flags & SPS_DOUBLE) == 0 && su->su_ga.ga_len != 0) { - if (sps_flags & SPS_BEST) + if (sps_flags & SPS_BEST) { // Adjust the word score for how it sounds like. rescore_suggestions(su); + } // Remove bogus suggestions, sort and truncate at "maxcount". check_suggestions(su, &su->su_ga); @@ -3420,7 +3523,7 @@ static void spell_suggest_intern(suginfo_T *su, bool interactive) // Free the info put in "*su" by spell_find_suggest(). static void spell_find_cleanup(suginfo_T *su) { -# define FREE_SUG_WORD(sug) xfree(sug->st_word) +#define FREE_SUG_WORD(sug) xfree(sug->st_word) // Free the suggestions. GA_DEEP_CLEAR(&su->su_ga, suggest_T, FREE_SUG_WORD); GA_DEEP_CLEAR(&su->su_sga, suggest_T, FREE_SUG_WORD); @@ -3459,11 +3562,13 @@ static void allcap_copy(char_u *word, char_u *wcopy) if (c == 0xdf) { c = 'S'; - if (d - wcopy >= MAXWLEN - 1) + if (d - wcopy >= MAXWLEN - 1) { break; + } *d++ = c; - } else + } else { c = SPELL_TOUPPER(c); + } if (d - wcopy >= MAXWLEN - MB_MAXBYTES) { break; @@ -3476,7 +3581,7 @@ static void allcap_copy(char_u *word, char_u *wcopy) // Try finding suggestions by recognizing specific situations. static void suggest_try_special(suginfo_T *su) { - char_u *p; + char_u *p; size_t len; int c; char_u word[MAXWLEN]; @@ -3496,7 +3601,7 @@ static void suggest_try_special(suginfo_T *su) // Give a soundalike score of 0, compute the score as if deleting one // character. add_suggestion(su, &su->su_ga, word, su->su_badlen, - RESCORE(SCORE_REP, 0), 0, true, su->su_sallang, false); + RESCORE(SCORE_REP, 0), 0, true, su->su_sallang, false); } } @@ -3509,8 +3614,7 @@ proftime_T total; proftime_T times[STATE_FINAL + 1]; long counts[STATE_FINAL + 1]; - static void -prof_init(void) +static void prof_init(void) { for (int i = 0; i <= STATE_FINAL; i++) { profile_zero(×[i]); @@ -3521,8 +3625,7 @@ prof_init(void) } // call before changing state - static void -prof_store(state_T state) +static void prof_store(state_T state) { profile_end(¤t); profile_add(×[state], ¤t); @@ -3531,8 +3634,7 @@ prof_store(state_T state) } # define PROF_STORE(state) prof_store(state); - static void -prof_report(char *name) +static void prof_report(char *name) { FILE *fd = fopen("suggestprof", "a"); @@ -3554,8 +3656,8 @@ static void suggest_try_change(suginfo_T *su) { char_u fword[MAXWLEN]; // copy of the bad word, case-folded int n; - char_u *p; - langp_T *lp; + char_u *p; + langp_T *lp; // We make a copy of the case-folded bad word, so that we can modify it // to find matches (esp. REP items). Append some more text, changing @@ -3570,8 +3672,9 @@ static void suggest_try_change(suginfo_T *su) // If reloading a spell file fails it's still in the list but // everything has been cleared. - if (lp->lp_slang->sl_fbyts == NULL) + if (lp->lp_slang->sl_fbyts == NULL) { continue; + } // Try it for this language. Will add possible suggestions. // @@ -3623,28 +3726,28 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so char_u tword[MAXWLEN]; // good word collected so far trystate_T stack[MAXWLEN]; char_u preword[MAXWLEN * 3] = { 0 }; // word found with proper case; - // concatenation of prefix compound - // words and split word. NUL terminated - // when going deeper but not when coming - // back. + // concatenation of prefix compound + // words and split word. NUL terminated + // when going deeper but not when coming + // back. char_u compflags[MAXWLEN]; // compound flags, one for each word - trystate_T *sp; + trystate_T *sp; int newscore; int score; - char_u *byts, *fbyts, *pbyts; - idx_T *idxs, *fidxs, *pidxs; + char_u *byts, *fbyts, *pbyts; + idx_T *idxs, *fidxs, *pidxs; int depth; int c, c2, c3; int n = 0; int flags; - garray_T *gap; + garray_T *gap; idx_T arridx; int len; - char_u *p; - fromto_T *ftp; + char_u *p; + fromto_T *ftp; int fl = 0, tl; int repextra = 0; // extra bytes in fword[] from REP item - slang_T *slang = lp->lp_slang; + slang_T *slang = lp->lp_slang; int fword_ends; bool goodword_ends; #ifdef DEBUG_TRIEWALK @@ -3709,8 +3812,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so if (sp->ts_prefixdepth == PFD_PREFIXTREE) { // Skip over the NUL bytes, we use them later. - for (n = 0; n < len && byts[arridx + n] == 0; ++n) + for (n = 0; n < len && byts[arridx + n] == 0; ++n) { ; + } sp->ts_curi += n; // Always past NUL bytes now. @@ -3727,7 +3831,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so n = nofold_len(fword, sp->ts_fidx, su->su_badptr); flags = badword_captype(su->su_badptr, su->su_badptr + n); su->su_badflags = badword_captype(su->su_badptr + n, - su->su_badptr + su->su_badlen); + su->su_badptr + su->su_badlen); #ifdef DEBUG_TRIEWALK sprintf(changename[depth], "prefix"); #endif @@ -3743,7 +3847,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // and make find_keepcap_word() works. tword[sp->ts_twordlen] = NUL; make_case_word(tword + sp->ts_splitoff, - preword + sp->ts_prewordlen, flags); + preword + sp->ts_prewordlen, flags); sp->ts_prewordlen = (char_u)STRLEN(preword); sp->ts_splitoff = sp->ts_twordlen; } @@ -3764,8 +3868,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so flags = (int)idxs[arridx]; // Skip words with the NOSUGGEST flag. - if (flags & WF_NOSUGGEST) + if (flags & WF_NOSUGGEST) { break; + } fword_ends = (fword[sp->ts_fidx] == NUL || (soundfold @@ -3782,17 +3887,20 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // none this must be the first try without a prefix. n = stack[sp->ts_prefixdepth].ts_arridx; len = pbyts[n++]; - for (c = 0; c < len && pbyts[n + c] == 0; ++c) + for (c = 0; c < len && pbyts[n + c] == 0; ++c) { ; + } if (c > 0) { c = valid_word_prefix(c, n, flags, - tword + sp->ts_splitoff, slang, false); - if (c == 0) + tword + sp->ts_splitoff, slang, false); + if (c == 0) { break; + } // Use the WF_RARE flag for a rare prefix. - if (c & WF_RAREPFX) + if (c & WF_RAREPFX) { flags |= WF_RARE; + } // Tricky: when checking for both prefix and compounding // we run into the prefix flag first. @@ -3805,10 +3913,11 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // Check NEEDCOMPOUND: can't use word without compounding. Do try // appending another compound word below. if (sp->ts_complen == sp->ts_compsplit && fword_ends - && (flags & WF_NEEDCOMP)) + && (flags & WF_NEEDCOMP)) { goodword_ends = false; - else + } else { goodword_ends = true; + } p = NULL; compound_ok = true; @@ -3821,18 +3930,19 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so if (sp->ts_fidx - sp->ts_splitfidx == sp->ts_twordlen - sp->ts_splitoff && STRNCMP(fword + sp->ts_splitfidx, - tword + sp->ts_splitoff, - sp->ts_fidx - sp->ts_splitfidx) == 0) { + tword + sp->ts_splitoff, + sp->ts_fidx - sp->ts_splitfidx) == 0) { preword[sp->ts_prewordlen] = NUL; newscore = score_wordcount_adj(slang, sp->ts_score, - preword + sp->ts_prewordlen, - sp->ts_prewordlen > 0); + preword + sp->ts_prewordlen, + sp->ts_prewordlen > 0); // Add the suggestion if the score isn't too bad. - if (newscore <= su->su_maxscore) + if (newscore <= su->su_maxscore) { add_suggestion(su, &su->su_ga, preword, - sp->ts_splitfidx - repextra, - newscore, 0, false, - lp->lp_sallang, false); + sp->ts_splitfidx - repextra, + newscore, 0, false, + lp->lp_sallang, false); + } break; } } else { @@ -3856,23 +3966,26 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so compflags[sp->ts_complen] = ((unsigned)flags >> 24); compflags[sp->ts_complen + 1] = NUL; STRLCPY(preword + sp->ts_prewordlen, - tword + sp->ts_splitoff, - sp->ts_twordlen - sp->ts_splitoff + 1); + tword + sp->ts_splitoff, + sp->ts_twordlen - sp->ts_splitoff + 1); // Verify CHECKCOMPOUNDPATTERN rules. if (match_checkcompoundpattern(preword, sp->ts_prewordlen, - &slang->sl_comppat)) + &slang->sl_comppat)) { compound_ok = false; + } if (compound_ok) { p = preword; - while (*skiptowhite(p) != NUL) + while (*skiptowhite(p) != NUL) { p = skipwhite(skiptowhite(p)); + } if (fword_ends && !can_compound(slang, p, - compflags + sp->ts_compsplit)) + compflags + sp->ts_compsplit)) { // Compound is not allowed. But it may still be // possible if we add another (short) word. compound_ok = false; + } } // Get pointer to last char of previous word. @@ -3884,29 +3997,31 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // Form the word with proper case in preword. // If there is a word from a previous split, append. // For the soundfold tree don't change the case, simply append. - if (soundfold) + if (soundfold) { STRCPY(preword + sp->ts_prewordlen, tword + sp->ts_splitoff); - else if (flags & WF_KEEPCAP) + } else if (flags & WF_KEEPCAP) { // Must find the word in the keep-case tree. find_keepcap_word(slang, tword + sp->ts_splitoff, - preword + sp->ts_prewordlen); - else { + preword + sp->ts_prewordlen); + } else { // Include badflags: If the badword is onecap or allcap // use that for the goodword too. But if the badword is // allcap and it's only one char long use onecap. c = su->su_badflags; if ((c & WF_ALLCAP) - && su->su_badlen == (*mb_ptr2len)(su->su_badptr) - ) + && su->su_badlen == + (*mb_ptr2len)(su->su_badptr)) { c = WF_ONECAP; + } c |= flags; // When appending a compound word after a word character don't // use Onecap. - if (p != NULL && spell_iswordp_nmw(p, curwin)) + if (p != NULL && spell_iswordp_nmw(p, curwin)) { c &= ~WF_ONECAP; + } make_case_word(tword + sp->ts_splitoff, - preword + sp->ts_prewordlen, c); + preword + sp->ts_prewordlen, c); } if (!soundfold) { @@ -3919,8 +4034,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so if ((sp->ts_complen == sp->ts_compsplit && WAS_BANNED(su, preword + sp->ts_prewordlen)) || WAS_BANNED(su, preword)) { - if (slang->sl_compprog == NULL) + if (slang->sl_compprog == NULL) { break; + } // the word so far was banned but we may try compounding goodword_ends = false; } @@ -3929,14 +4045,17 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so newscore = 0; if (!soundfold) { // soundfold words don't have flags if ((flags & WF_REGION) - && (((unsigned)flags >> 16) & lp->lp_region) == 0) + && (((unsigned)flags >> 16) & lp->lp_region) == 0) { newscore += SCORE_REGION; - if (flags & WF_RARE) + } + if (flags & WF_RARE) { newscore += SCORE_RARE; + } if (!spell_valid_case(su->su_badflags, - captype(preword + sp->ts_prewordlen, NULL))) + captype(preword + sp->ts_prewordlen, NULL))) { newscore += SCORE_ICASE; + } } // TODO: how about splitting in the soundfold tree? @@ -3951,15 +4070,16 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // print the stack of changes that brought us here smsg("------ %s -------", fword); - for (j = 0; j < depth; ++j) + for (j = 0; j < depth; ++j) { smsg("%s", changename[j]); + } } #endif if (soundfold) { // For soundfolded words we need to find the original // words, the edit distance and then add them. add_sound_suggest(su, preword, sp->ts_score, lp); - } else if (sp->ts_fidx > 0) { + } else if (sp->ts_fidx > 0) { // Give a penalty when changing non-word char to word // char, e.g., "thes," -> "these". p = fword + sp->ts_fidx; @@ -3974,15 +4094,15 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // Give a bonus to words seen before. score = score_wordcount_adj(slang, - sp->ts_score + newscore, - preword + sp->ts_prewordlen, - sp->ts_prewordlen > 0); + sp->ts_score + newscore, + preword + sp->ts_prewordlen, + sp->ts_prewordlen > 0); // Add the suggestion if the score isn't too bad. if (score <= su->su_maxscore) { add_suggestion(su, &su->su_ga, preword, - sp->ts_fidx - repextra, - score, 0, false, lp->lp_sallang, false); + sp->ts_fidx - repextra, + score, 0, false, lp->lp_sallang, false); if (su->su_badflags & WF_MIXCAP) { // We really don't know if the word should be @@ -3990,13 +4110,13 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so c = captype(preword, NULL); if (c == 0 || c == WF_ALLCAP) { make_case_word(tword + sp->ts_splitoff, - preword + sp->ts_prewordlen, - c == 0 ? WF_ALLCAP : 0); + preword + sp->ts_prewordlen, + c == 0 ? WF_ALLCAP : 0); add_suggestion(su, &su->su_ga, preword, - sp->ts_fidx - repextra, - score + SCORE_ICASE, 0, false, - lp->lp_sallang, false); + sp->ts_fidx - repextra, + score + SCORE_ICASE, 0, false, + lp->lp_sallang, false); } } } @@ -4006,8 +4126,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // Try word split and/or compounding. if ((sp->ts_fidx >= sp->ts_fidxtry || fword_ends) // Don't split in the middle of a character - && (sp->ts_tcharlen == 0) - ) { + && (sp->ts_tcharlen == 0)) { bool try_compound; int try_split; @@ -4045,7 +4164,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so || sp->ts_complen + 1 - sp->ts_compsplit < slang->sl_compmax) && (can_be_compound(sp, slang, - compflags, ((unsigned)flags >> 24)))) { + compflags, ((unsigned)flags >> 24)))) { try_compound = true; compflags[sp->ts_complen] = ((unsigned)flags >> 24); compflags[sp->ts_complen + 1] = NUL; @@ -4076,35 +4195,40 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // is only one word it must not have the NEEDCOMPOUND // flag. if (sp->ts_complen == sp->ts_compsplit - && (flags & WF_NEEDCOMP)) + && (flags & WF_NEEDCOMP)) { break; + } p = preword; - while (*skiptowhite(p) != NUL) + while (*skiptowhite(p) != NUL) { p = skipwhite(skiptowhite(p)); + } if (sp->ts_complen > sp->ts_compsplit && !can_compound(slang, p, - compflags + sp->ts_compsplit)) + compflags + sp->ts_compsplit)) { break; + } - if (slang->sl_nosplitsugs) + if (slang->sl_nosplitsugs) { newscore += SCORE_SPLIT_NO; - else + } else { newscore += SCORE_SPLIT; + } // Give a bonus to words seen before. newscore = score_wordcount_adj(slang, newscore, - preword + sp->ts_prewordlen, true); + preword + sp->ts_prewordlen, true); } if (TRY_DEEPER(su, stack, depth, newscore)) { go_deeper(stack, depth, newscore); #ifdef DEBUG_TRIEWALK - if (!try_compound && !fword_ends) + if (!try_compound && !fword_ends) { sprintf(changename[depth], "%.*s-%s: split", - sp->ts_twordlen, tword, fword + sp->ts_fidx); - else + sp->ts_twordlen, tword, fword + sp->ts_fidx); + } else { sprintf(changename[depth], "%.*s-%s: compound", - sp->ts_twordlen, tword, fword + sp->ts_fidx); + sp->ts_twordlen, tword, fword + sp->ts_fidx); + } #endif // Save things to be restored at STATE_SPLITUNDO. sp->ts_save_badflags = su->su_badflags; @@ -4115,8 +4239,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so sp = &stack[depth]; // Append a space to preword when splitting. - if (!try_compound && !fword_ends) + if (!try_compound && !fword_ends) { STRCAT(preword, " "); + } sp->ts_prewordlen = (char_u)STRLEN(preword); sp->ts_splitoff = sp->ts_twordlen; sp->ts_splitfidx = sp->ts_fidx; @@ -4127,8 +4252,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // character when the word ends. But only when the // good word can end. if (((!try_compound && !spell_iswordp_nmw(fword - + sp->ts_fidx, - curwin)) + + sp->ts_fidx, + curwin)) || fword_ends) && fword[sp->ts_fidx] != NUL && goodword_ends) { @@ -4138,28 +4263,30 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so if (fword_ends) { // Copy the skipped character to preword. memmove(preword + sp->ts_prewordlen, - fword + sp->ts_fidx, l); + fword + sp->ts_fidx, l); sp->ts_prewordlen += l; preword[sp->ts_prewordlen] = NUL; - } else + } else { sp->ts_score -= SCORE_SPLIT - SCORE_SUBST; + } sp->ts_fidx += l; } // When compounding include compound flag in // compflags[] (already set above). When splitting we // may start compounding over again. - if (try_compound) + if (try_compound) { ++sp->ts_complen; - else + } else { sp->ts_compsplit = sp->ts_complen; + } sp->ts_prefixdepth = PFD_NOPREFIX; // set su->su_badflags to the caps type at this // position n = nofold_len(fword, sp->ts_fidx, su->su_badptr); su->su_badflags = badword_captype(su->su_badptr + n, - su->su_badptr + su->su_badlen); + su->su_badptr + su->su_badlen); // Restart at top of the tree. sp->ts_arridx = 0; @@ -4194,8 +4321,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // Past the NUL bytes in the node. su->su_badflags = sp->ts_save_badflags; if (fword[sp->ts_fidx] == NUL - && sp->ts_tcharlen == 0 - ) { + && sp->ts_tcharlen == 0) { // The badword ends, can't use STATE_PLAIN. PROF_STORE(sp->ts_state) sp->ts_state = STATE_DEL; @@ -4228,11 +4354,12 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // just deleted this byte, accepting it is always cheaper than // delete + substitute. if (c == fword[sp->ts_fidx] - || (sp->ts_tcharlen > 0 && sp->ts_isdiff != DIFF_NONE) - ) + || (sp->ts_tcharlen > 0 && + sp->ts_isdiff != DIFF_NONE)) { newscore = 0; - else + } else { newscore = SCORE_SUBST; + } if ((newscore == 0 || (sp->ts_fidx >= sp->ts_fidxtry && ((sp->ts_flags & TSF_DIDDEL) == 0 @@ -4240,14 +4367,15 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so && TRY_DEEPER(su, stack, depth, newscore)) { go_deeper(stack, depth, newscore); #ifdef DEBUG_TRIEWALK - if (newscore > 0) + if (newscore > 0) { sprintf(changename[depth], "%.*s-%s: subst %c to %c", - sp->ts_twordlen, tword, fword + sp->ts_fidx, - fword[sp->ts_fidx], c); - else + sp->ts_twordlen, tword, fword + sp->ts_fidx, + fword[sp->ts_fidx], c); + } else { sprintf(changename[depth], "%.*s-%s: accept %c", - sp->ts_twordlen, tword, fword + sp->ts_fidx, - fword[sp->ts_fidx]); + sp->ts_twordlen, tword, fword + sp->ts_fidx, + fword[sp->ts_fidx]); + } #endif ++depth; sp = &stack[depth]; @@ -4289,12 +4417,11 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so + sp->ts_fcharstart))) { sp->ts_score -= SCORE_SUBST - SCORE_SUBCOMP; } else if ( - !soundfold - && slang->sl_has_map - && similar_chars( - slang, - utf_ptr2char(tword + sp->ts_twordlen - sp->ts_tcharlen), - utf_ptr2char(fword + sp->ts_fcharstart))) { + !soundfold + && slang->sl_has_map + && similar_chars(slang, + utf_ptr2char(tword + sp->ts_twordlen - sp->ts_tcharlen), + utf_ptr2char(fword + sp->ts_fcharstart))) { // For a similar character adjust score from // SCORE_SUBST to SCORE_SIMILAR. sp->ts_score -= SCORE_SUBST - SCORE_SIMILAR; @@ -4339,19 +4466,20 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so PROF_STORE(sp->ts_state) sp->ts_state = STATE_INS_PREP; sp->ts_curi = 1; - if (soundfold && sp->ts_fidx == 0 && fword[sp->ts_fidx] == '*') + if (soundfold && sp->ts_fidx == 0 && fword[sp->ts_fidx] == '*') { // Deleting a vowel at the start of a word counts less, see // soundalike_score(). newscore = 2 * SCORE_DEL / 3; - else + } else { newscore = SCORE_DEL; + } if (fword[sp->ts_fidx] != NUL && TRY_DEEPER(su, stack, depth, newscore)) { go_deeper(stack, depth, newscore); #ifdef DEBUG_TRIEWALK sprintf(changename[depth], "%.*s-%s: delete %c", - sp->ts_twordlen, tword, fword + sp->ts_fidx, - fword[sp->ts_fidx]); + sp->ts_twordlen, tword, fword + sp->ts_fidx, + fword[sp->ts_fidx]); #endif ++depth; @@ -4421,19 +4549,20 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // accepting that byte is always better. n += sp->ts_curi++; c = byts[n]; - if (soundfold && sp->ts_twordlen == 0 && c == '*') + if (soundfold && sp->ts_twordlen == 0 && c == '*') { // Inserting a vowel at the start of a word counts less, // see soundalike_score(). newscore = 2 * SCORE_INS / 3; - else + } else { newscore = SCORE_INS; + } if (c != fword[sp->ts_fidx] && TRY_DEEPER(su, stack, depth, newscore)) { go_deeper(stack, depth, newscore); #ifdef DEBUG_TRIEWALK sprintf(changename[depth], "%.*s-%s: insert %c", - sp->ts_twordlen, tword, fword + sp->ts_fidx, - c); + sp->ts_twordlen, tword, fword + sp->ts_fidx, + c); #endif ++depth; sp = &stack[depth]; @@ -4454,8 +4583,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // soundfold words (illogical but does give a better // score). if (sp->ts_twordlen >= 2 - && tword[sp->ts_twordlen - 2] == c) + && tword[sp->ts_twordlen - 2] == c) { sp->ts_score -= SCORE_INS - SCORE_INSDUP; + } } } break; @@ -4566,8 +4696,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so go_deeper(stack, depth, SCORE_SWAP3); #ifdef DEBUG_TRIEWALK sprintf(changename[depth], "%.*s-%s: swap3 %c and %c", - sp->ts_twordlen, tword, fword + sp->ts_fidx, - c, c3); + sp->ts_twordlen, tword, fword + sp->ts_fidx, + c, c3); #endif PROF_STORE(sp->ts_state) sp->ts_state = STATE_UNSWAP3; @@ -4611,8 +4741,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so #ifdef DEBUG_TRIEWALK p = fword + sp->ts_fidx; sprintf(changename[depth], "%.*s-%s: rotate left %c%c%c", - sp->ts_twordlen, tword, fword + sp->ts_fidx, - p[0], p[1], p[2]); + sp->ts_twordlen, tword, fword + sp->ts_fidx, + p[0], p[1], p[2]); #endif PROF_STORE(sp->ts_state) sp->ts_state = STATE_UNROT3L; @@ -4648,8 +4778,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so #ifdef DEBUG_TRIEWALK p = fword + sp->ts_fidx; sprintf(changename[depth], "%.*s-%s: rotate right %c%c%c", - sp->ts_twordlen, tword, fword + sp->ts_fidx, - p[0], p[1], p[2]); + sp->ts_twordlen, tword, fword + sp->ts_fidx, + p[0], p[1], p[2]); #endif PROF_STORE(sp->ts_state) sp->ts_state = STATE_UNROT3R; @@ -4696,10 +4826,11 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // Use the first byte to quickly find the first entry that may // match. If the index is -1 there is none. - if (soundfold) + if (soundfold) { sp->ts_curi = slang->sl_repsal_first[fword[sp->ts_fidx]]; - else + } else { sp->ts_curi = lp->lp_replang->sl_rep_first[fword[sp->ts_fidx]]; + } if (sp->ts_curi < 0) { PROF_STORE(sp->ts_state) @@ -4717,10 +4848,11 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // valid. p = fword + sp->ts_fidx; - if (soundfold) + if (soundfold) { gap = &slang->sl_repsal; - else + } else { gap = &lp->lp_replang->sl_rep; + } while (sp->ts_curi < gap->ga_len) { ftp = (fromto_T *)gap->ga_data + sp->ts_curi++; if (*ftp->ft_from != *p) { @@ -4733,8 +4865,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so go_deeper(stack, depth, SCORE_REP); #ifdef DEBUG_TRIEWALK sprintf(changename[depth], "%.*s-%s: replace %s with %s", - sp->ts_twordlen, tword, fword + sp->ts_fidx, - ftp->ft_from, ftp->ft_to); + sp->ts_twordlen, tword, fword + sp->ts_fidx, + ftp->ft_from, ftp->ft_to); #endif // Need to undo this afterwards. PROF_STORE(sp->ts_state) @@ -4755,19 +4887,21 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so } } - if (sp->ts_curi >= gap->ga_len && sp->ts_state == STATE_REP) + if (sp->ts_curi >= gap->ga_len && sp->ts_state == STATE_REP) { // No (more) matches. PROF_STORE(sp->ts_state) sp->ts_state = STATE_FINAL; + } break; case STATE_REP_UNDO: // Undo a REP replacement and continue with the next one. - if (soundfold) + if (soundfold) { gap = &slang->sl_repsal; - else + } else { gap = &lp->lp_replang->sl_rep; + } ftp = (fromto_T *)gap->ga_data + sp->ts_curi - 1; fl = (int)STRLEN(ftp->ft_from); tl = (int)STRLEN(ftp->ft_to); @@ -4815,7 +4949,7 @@ static void go_deeper(trystate_T *stack, int depth, int score_add) // fword[flen] and return the byte length of that many chars in "word". static int nofold_len(char_u *fword, int flen, char_u *word) { - char_u *p; + char_u *p; int i = 0; for (p = fword; p < fword + flen; MB_PTR_ADV(p)) { @@ -4849,9 +4983,9 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword) int len; int c; idx_T lo, hi, m; - char_u *p; - char_u *byts = slang->sl_kbyts; // array with bytes of the words - idx_T *idxs = slang->sl_kidxs; // array with indexes + char_u *p; + char_u *byts = slang->sl_kbyts; // array with bytes of the words + idx_T *idxs = slang->sl_kidxs; // array with indexes if (byts == NULL) { // array is empty: "cannot happen" @@ -4882,7 +5016,7 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword) // kword is getting too long, continue one level up --depth; - } else if (++round[depth] > 2) { + } else if (++round[depth] > 2) { // tried both fold-case and upper-case character, continue one // level up --depth; @@ -4907,19 +5041,20 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword) hi = tryidx + len - 1; while (lo < hi) { m = (lo + hi) / 2; - if (byts[m] > c) + if (byts[m] > c) { hi = m - 1; - else if (byts[m] < c) + } else if (byts[m] < c) { lo = m + 1; - else { + } else { lo = hi = m; break; } } // Stop if there is no matching byte. - if (hi < lo || byts[lo] != c) + if (hi < lo || byts[lo] != c) { break; + } // Continue at the child (if there is one). tryidx = idxs[lo]; @@ -4930,11 +5065,11 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword) // level deeper. if (round[depth] == 1) { STRNCPY(kword + kwordlen[depth], fword + fwordidx[depth], - flen); + flen); kwordlen[depth + 1] = kwordlen[depth] + flen; } else { STRNCPY(kword + kwordlen[depth], uword + uwordidx[depth], - ulen); + ulen); kwordlen[depth + 1] = kwordlen[depth] + ulen; } fwordidx[depth + 1] = fwordidx[depth] + flen; @@ -4955,11 +5090,11 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword) // su->su_sga. static void score_comp_sal(suginfo_T *su) { - langp_T *lp; + langp_T *lp; char_u badsound[MAXWLEN]; int i; - suggest_T *stp; - suggest_T *sstp; + suggest_T *stp; + suggest_T *sstp; int score; ga_grow(&su->su_sga, su->su_ga.ga_len); @@ -4998,13 +5133,13 @@ static void score_comp_sal(suginfo_T *su) static void score_combine(suginfo_T *su) { garray_T ga; - garray_T *gap; - langp_T *lp; - suggest_T *stp; - char_u *p; + garray_T *gap; + langp_T *lp; + suggest_T *stp; + char_u *p; char_u badsound[MAXWLEN]; int round; - slang_T *slang = NULL; + slang_T *slang = NULL; // Add the alternate score to su_ga. for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) { @@ -5017,11 +5152,12 @@ static void score_combine(suginfo_T *su) for (int i = 0; i < su->su_ga.ga_len; ++i) { stp = &SUG(su->su_ga, i); stp->st_altscore = stp_sal_score(stp, su, slang, badsound); - if (stp->st_altscore == SCORE_MAXMAX) + if (stp->st_altscore == SCORE_MAXMAX) { stp->st_score = (stp->st_score * 3 + SCORE_BIG) / 4; - else + } else { stp->st_score = (stp->st_score * 3 + stp->st_altscore) / 4; + } stp->st_salscore = false; } break; @@ -5030,7 +5166,7 @@ static void score_combine(suginfo_T *su) if (slang == NULL) { // Using "double" without sound folding. (void)cleanup_suggestions(&su->su_ga, su->su_maxscore, - su->su_maxcount); + su->su_maxcount); return; } @@ -5038,11 +5174,12 @@ static void score_combine(suginfo_T *su) for (int i = 0; i < su->su_sga.ga_len; ++i) { stp = &SUG(su->su_sga, i); stp->st_altscore = spell_edit_score(slang, - su->su_badword, stp->st_word); - if (stp->st_score == SCORE_MAXMAX) + su->su_badword, stp->st_word); + if (stp->st_score == SCORE_MAXMAX) { stp->st_score = (SCORE_BIG * 7 + stp->st_altscore) / 8; - else + } else { stp->st_score = (stp->st_score * 7 + stp->st_altscore) / 8; + } stp->st_salscore = true; } @@ -5066,13 +5203,16 @@ static void score_combine(suginfo_T *su) // Don't add a word if it's already there. p = SUG(*gap, i).st_word; int j; - for (j = 0; j < ga.ga_len; ++j) - if (STRCMP(stp[j].st_word, p) == 0) + for (j = 0; j < ga.ga_len; ++j) { + if (STRCMP(stp[j].st_word, p) == 0) { break; - if (j == ga.ga_len) + } + } + if (j == ga.ga_len) { stp[ga.ga_len++] = SUG(*gap, i); - else + } else { xfree(p); + } } } } @@ -5091,19 +5231,15 @@ static void score_combine(suginfo_T *su) su->su_ga = ga; } -// For the goodword in "stp" compute the soundalike score compared to the -// badword. -static int -stp_sal_score ( - suggest_T *stp, - suginfo_T *su, - slang_T *slang, - char_u *badsound // sound-folded badword -) +/// For the goodword in "stp" compute the soundalike score compared to the +/// badword. +/// +/// @param badsound sound-folded badword +static int stp_sal_score(suggest_T *stp, suginfo_T *su, slang_T *slang, char_u *badsound) { - char_u *p; - char_u *pbad; - char_u *pgood; + char_u *p; + char_u *pbad; + char_u *pgood; char_u badsound2[MAXWLEN]; char_u fword[MAXWLEN]; char_u goodsound[MAXWLEN]; @@ -5111,9 +5247,9 @@ stp_sal_score ( int lendiff; lendiff = su->su_badlen - stp->st_orglen; - if (lendiff >= 0) + if (lendiff >= 0) { pbad = badsound; - else { + } else { // soundfold the bad word with more characters following (void)spell_casefold(curwin, su->su_badptr, stp->st_orglen, fword, MAXWLEN); @@ -5122,9 +5258,11 @@ stp_sal_score ( // removing the space. Don't do it when the good word also contains a // space. if (ascii_iswhite(su->su_badptr[su->su_badlen]) - && *skiptowhite(stp->st_word) == NUL) - for (p = fword; *(p = skiptowhite(p)) != NUL; ) + && *skiptowhite(stp->st_word) == NUL) { + for (p = fword; *(p = skiptowhite(p)) != NUL; ) { STRMOVE(p, p + 1); + } + } spell_soundfold(slang, fword, true, badsound2); pbad = badsound2; @@ -5135,10 +5273,11 @@ stp_sal_score ( // what replaces the bad word. STRCPY(goodword, stp->st_word); STRLCPY(goodword + stp->st_wordlen, - su->su_badptr + su->su_badlen - lendiff, lendiff + 1); + su->su_badptr + su->su_badlen - lendiff, lendiff + 1); pgood = goodword; - } else + } else { pgood = stp->st_word; + } // Sound-fold the word and compute the score for the difference. spell_soundfold(slang, pgood, false, goodsound); @@ -5153,17 +5292,18 @@ static sftword_T dumsft; // Prepare for calling suggest_try_soundalike(). static void suggest_try_soundalike_prep(void) { - langp_T *lp; - slang_T *slang; + langp_T *lp; + slang_T *slang; // Do this for all languages that support sound folding and for which a // .sug file has been loaded. for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) { lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); slang = lp->lp_slang; - if (!GA_EMPTY(&slang->sl_sal) && slang->sl_sbyts != NULL) + if (!GA_EMPTY(&slang->sl_sal) && slang->sl_sbyts != NULL) { // prepare the hashtable used by add_sound_suggest() hash_init(&slang->sl_sounddone); + } } } @@ -5172,8 +5312,8 @@ static void suggest_try_soundalike_prep(void) static void suggest_try_soundalike(suginfo_T *su) { char_u salword[MAXWLEN]; - langp_T *lp; - slang_T *slang; + langp_T *lp; + slang_T *slang; // Do this for all languages that support sound folding and for which a // .sug file has been loaded. @@ -5201,10 +5341,10 @@ static void suggest_try_soundalike(suginfo_T *su) // Finish up after calling suggest_try_soundalike(). static void suggest_try_soundalike_finish(void) { - langp_T *lp; - slang_T *slang; + langp_T *lp; + slang_T *slang; int todo; - hashitem_T *hi; + hashitem_T *hi; // Do this for all languages that support sound folding and for which a // .sug file has been loaded. @@ -5214,11 +5354,12 @@ static void suggest_try_soundalike_finish(void) if (!GA_EMPTY(&slang->sl_sal) && slang->sl_sbyts != NULL) { // Free the info about handled words. todo = (int)slang->sl_sounddone.ht_used; - for (hi = slang->sl_sounddone.ht_array; todo > 0; ++hi) + for (hi = slang->sl_sounddone.ht_array; todo > 0; ++hi) { if (!HASHITEM_EMPTY(hi)) { xfree(HI2SFT(hi)); --todo; } + } // Clear the hashtable, it may also be used by another region. hash_clear(&slang->sl_sounddone); @@ -5227,32 +5368,28 @@ static void suggest_try_soundalike_finish(void) } } -// A match with a soundfolded word is found. Add the good word(s) that -// produce this soundfolded word. -static void -add_sound_suggest ( - suginfo_T *su, - char_u *goodword, - int score, // soundfold score - langp_T *lp -) +/// A match with a soundfolded word is found. Add the good word(s) that +/// produce this soundfolded word. +/// +/// @param score soundfold score +static void add_sound_suggest(suginfo_T *su, char_u *goodword, int score, langp_T *lp) { - slang_T *slang = lp->lp_slang; // language for sound folding + slang_T *slang = lp->lp_slang; // language for sound folding int sfwordnr; - char_u *nrline; + char_u *nrline; int orgnr; char_u theword[MAXWLEN]; int i; int wlen; - char_u *byts; - idx_T *idxs; + char_u *byts; + idx_T *idxs; int n; int wordcount; int wc; int goodscore; hash_T hash; - hashitem_T *hi; - sftword_T *sft; + hashitem_T *hi; + sftword_T *sft; int bc, gc; int limit; @@ -5271,8 +5408,9 @@ add_sound_suggest ( hash_add_item(&slang->sl_sounddone, hi, sft->sft_word, hash); } else { sft = HI2SFT(hi); - if (score >= sft->sft_score) + if (score >= sft->sft_score) { return; + } sft->sft_score = score; } @@ -5299,25 +5437,28 @@ add_sound_suggest ( wordcount = 0; for (wlen = 0; wlen < MAXWLEN - 3; ++wlen) { i = 1; - if (wordcount == orgnr && byts[n + 1] == NUL) + if (wordcount == orgnr && byts[n + 1] == NUL) { break; // found end of word - - if (byts[n + 1] == NUL) + } + if (byts[n + 1] == NUL) { ++wordcount; + } // skip over the NUL bytes - for (; byts[n + i] == NUL; ++i) + for (; byts[n + i] == NUL; ++i) { if (i > byts[n]) { // safety check STRCPY(theword + wlen, "BAD"); wlen += 3; goto badword; } + } // One of the siblings must have the word. for (; i < byts[n]; ++i) { wc = idxs[idxs[n + i]]; // nr of words under this byte - if (wordcount + wc > orgnr) + if (wordcount + wc > orgnr) { break; + } wordcount += wc; } @@ -5330,12 +5471,13 @@ badword: // Go over the possible flags and regions. for (; i <= byts[n] && byts[n + i] == NUL; ++i) { char_u cword[MAXWLEN]; - char_u *p; + char_u *p; int flags = (int)idxs[n + i]; // Skip words with the NOSUGGEST flag - if (flags & WF_NOSUGGEST) + if (flags & WF_NOSUGGEST) { continue; + } if (flags & WF_KEEPCAP) { // Must find the word in the keep-case tree. @@ -5347,23 +5489,26 @@ badword: // Need to fix case according to "flags". make_case_word(theword, cword, flags); p = cword; - } else + } else { p = theword; + } } // Add the suggestion. if (sps_flags & SPS_DOUBLE) { // Add the suggestion if the score isn't too bad. - if (score <= su->su_maxscore) + if (score <= su->su_maxscore) { add_suggestion(su, &su->su_sga, p, su->su_badlen, - score, 0, false, slang, false); + score, 0, false, slang, false); + } } else { // Add a penalty for words in another region. if ((flags & WF_REGION) - && (((unsigned)flags >> 16) & lp->lp_region) == 0) + && (((unsigned)flags >> 16) & lp->lp_region) == 0) { goodscore = SCORE_REGION; - else + } else { goodscore = 0; + } // Add a small penalty for changing the first letter from // lower to upper case. Helps for "tath" -> "Kath", which is @@ -5373,8 +5518,9 @@ badword: if (SPELL_ISUPPER(gc)) { bc = PTR2CHAR(su->su_badword); if (!SPELL_ISUPPER(bc) - && SPELL_TOFOLD(bc) != SPELL_TOFOLD(gc)) + && SPELL_TOFOLD(bc) != SPELL_TOFOLD(gc)) { goodscore += SCORE_ICASE / 2; + } } // Compute the score for the good word. This only does letter @@ -5385,11 +5531,12 @@ badword: // If the limit is very high then the iterative method is // inefficient, using an array is quicker. limit = MAXSCORE(su->su_sfmaxscore - goodscore, score); - if (limit > SCORE_LIMITMAX) + if (limit > SCORE_LIMITMAX) { goodscore += spell_edit_score(slang, su->su_badword, p); - else + } else { goodscore += spell_edit_score_limit(slang, su->su_badword, - p, limit); + p, limit); + } // When going over the limit don't bother to do the rest. if (goodscore < SCORE_MAXMAX) { @@ -5398,9 +5545,10 @@ badword: // Add the suggestion if the score isn't too bad. goodscore = RESCORE(goodscore, score); - if (goodscore <= su->su_sfmaxscore) + if (goodscore <= su->su_sfmaxscore) { add_suggestion(su, &su->su_ga, p, su->su_badlen, - goodscore, score, true, slang, true); + goodscore, score, true, slang, true); + } } } } @@ -5414,9 +5562,9 @@ static int soundfold_find(slang_T *slang, char_u *word) int len; int wlen = 0; int c; - char_u *ptr = word; - char_u *byts; - idx_T *idxs; + char_u *ptr = word; + char_u *byts; + idx_T *idxs; int wordnr = 0; byts = slang->sl_sbyts; @@ -5430,35 +5578,41 @@ static int soundfold_find(slang_T *slang, char_u *word) // If the word ends we found the word. If not skip the NUL bytes. c = ptr[wlen]; if (byts[arridx] == NUL) { - if (c == NUL) + if (c == NUL) { break; + } // Skip over the zeros, there can be several. while (len > 0 && byts[arridx] == NUL) { ++arridx; --len; } - if (len == 0) + if (len == 0) { return -1; // no children, word should have ended here + } ++wordnr; } // If the word ends we didn't find it. - if (c == NUL) + if (c == NUL) { return -1; + } // Perform a binary search in the list of accepted bytes. - if (c == TAB) // <Tab> is handled like <Space> + if (c == TAB) { // <Tab> is handled like <Space> c = ' '; + } while (byts[arridx] < c) { // The word count is in the first idxs[] entry of the child. wordnr += idxs[idxs[arridx]]; ++arridx; - if (--len == 0) // end of the bytes, didn't find it + if (--len == 0) { // end of the bytes, didn't find it return -1; + } } - if (byts[arridx] != c) // didn't find the byte + if (byts[arridx] != c) { // didn't find the byte return -1; + } // Continue at the child (if there is one). arridx = idxs[arridx]; @@ -5466,9 +5620,11 @@ static int soundfold_find(slang_T *slang, char_u *word) // One space in the good word may stand for several spaces in the // checked word. - if (c == ' ') - while (ptr[wlen] == ' ' || ptr[wlen] == TAB) + if (c == ' ') { + while (ptr[wlen] == ' ' || ptr[wlen] == TAB) { ++wlen; + } + } } return wordnr; @@ -5477,15 +5633,16 @@ static int soundfold_find(slang_T *slang, char_u *word) // Copy "fword" to "cword", fixing case according to "flags". static void make_case_word(char_u *fword, char_u *cword, int flags) { - if (flags & WF_ALLCAP) + if (flags & WF_ALLCAP) { // Make it all upper-case allcap_copy(fword, cword); - else if (flags & WF_ONECAP) + } else if (flags & WF_ONECAP) { // Make the first letter upper-case onecap_copy(fword, cword, true); - else + } else { // Use goodword as-is. STRCPY(cword, fword); + } } // Returns true if "c1" and "c2" are similar characters according to the MAP @@ -5494,7 +5651,7 @@ static bool similar_chars(slang_T *slang, int c1, int c2) { int m1, m2; char_u buf[MB_MAXBYTES + 1]; - hashitem_T *hi; + hashitem_T *hi; if (c1 >= 256) { buf[utf_char2bytes(c1, buf)] = 0; @@ -5526,25 +5683,20 @@ static bool similar_chars(slang_T *slang, int c1, int c2) return m1 == m2; } -// Adds a suggestion to the list of suggestions. -// For a suggestion that is already in the list the lowest score is remembered. -static void -add_suggestion ( - suginfo_T *su, - garray_T *gap, // either su_ga or su_sga - const char_u *goodword, - int badlenarg, // len of bad word replaced with "goodword" - int score, - int altscore, - bool had_bonus, // value for st_had_bonus - slang_T *slang, // language for sound folding - bool maxsf // su_maxscore applies to soundfold score, - // su_sfmaxscore to the total score. -) +/// Adds a suggestion to the list of suggestions. +/// For a suggestion that is already in the list the lowest score is remembered. +/// +/// @param gap either su_ga or su_sga +/// @param badlenarg len of bad word replaced with "goodword" +/// @param had_bonus value for st_had_bonus +/// @param slang language for sound folding +/// @param maxsf su_maxscore applies to soundfold score, su_sfmaxscore to the total score. +static void add_suggestion(suginfo_T *su, garray_T *gap, const char_u *goodword, int badlenarg, + int score, int altscore, bool had_bonus, slang_T *slang, bool maxsf) { int goodlen; // len of goodword changed int badlen; // len of bad word changed - suggest_T *stp; + suggest_T *stp; suggest_T new_sug; // Minimize "badlen" for consistency. Avoids that changing "the the" to @@ -5554,8 +5706,9 @@ add_suggestion ( for (;; ) { goodlen = (int)(pgood - goodword); badlen = (int)(pbad - su->su_badptr); - if (goodlen <= 0 || badlen <= 0) + if (goodlen <= 0 || badlen <= 0) { break; + } MB_PTR_BACK(goodword, pgood); MB_PTR_BACK(su->su_badptr, pbad); if (utf_ptr2char(pgood) != utf_ptr2char(pbad)) { @@ -5563,10 +5716,11 @@ add_suggestion ( } } - if (badlen == 0 && goodlen == 0) + if (badlen == 0 && goodlen == 0) { // goodword doesn't change anything; may happen for "the the" changing // the first "the" to itself. return; + } int i; if (GA_EMPTY(gap)) { @@ -5581,8 +5735,9 @@ add_suggestion ( && stp->st_orglen == badlen && STRNCMP(stp->st_word, goodword, goodlen) == 0) { // Found it. Remember the word with the lowest score. - if (stp->st_slang == NULL) + if (stp->st_slang == NULL) { stp->st_slang = slang; + } new_sug.st_score = score; new_sug.st_altscore = altscore; @@ -5595,9 +5750,9 @@ add_suggestion ( // suggest_try_change() doesn't compute the soundalike // word to keep it fast, while some special methods set // the soundalike score to zero. - if (had_bonus) + if (had_bonus) { rescore_one(su, stp); - else { + } else { new_sug.st_word = stp->st_word; new_sug.st_wordlen = stp->st_wordlen; new_sug.st_slang = stp->st_slang; @@ -5630,25 +5785,24 @@ add_suggestion ( // If we have too many suggestions now, sort the list and keep // the best suggestions. if (gap->ga_len > SUG_MAX_COUNT(su)) { - if (maxsf) + if (maxsf) { su->su_sfmaxscore = cleanup_suggestions(gap, - su->su_sfmaxscore, SUG_CLEAN_COUNT(su)); - else + su->su_sfmaxscore, SUG_CLEAN_COUNT(su)); + } else { su->su_maxscore = cleanup_suggestions(gap, - su->su_maxscore, SUG_CLEAN_COUNT(su)); + su->su_maxscore, SUG_CLEAN_COUNT(su)); + } } } } -// Suggestions may in fact be flagged as errors. Esp. for banned words and -// for split words, such as "the the". Remove these from the list here. -static void -check_suggestions ( - suginfo_T *su, - garray_T *gap // either su_ga or su_sga -) +/// Suggestions may in fact be flagged as errors. Esp. for banned words and +/// for split words, such as "the the". Remove these from the list here. +/// +/// @param gap either su_ga or su_sga +static void check_suggestions(suginfo_T *su, garray_T *gap) { - suggest_T *stp; + suggest_T *stp; char_u longword[MAXWLEN + 1]; int len; hlf_T attr; @@ -5662,16 +5816,17 @@ check_suggestions ( STRLCPY(longword, stp[i].st_word, MAXWLEN + 1); len = stp[i].st_wordlen; STRLCPY(longword + len, su->su_badptr + stp[i].st_orglen, - MAXWLEN - len + 1); + MAXWLEN - len + 1); attr = HLF_COUNT; (void)spell_check(curwin, longword, &attr, NULL, false); if (attr != HLF_COUNT) { // Remove this entry. xfree(stp[i].st_word); --gap->ga_len; - if (i < gap->ga_len) + if (i < gap->ga_len) { memmove(stp + i, stp + i + 1, - sizeof(suggest_T) * (gap->ga_len - i)); + sizeof(suggest_T) * (gap->ga_len - i)); + } } } } @@ -5680,9 +5835,9 @@ check_suggestions ( // Add a word to be banned. static void add_banned(suginfo_T *su, char_u *word) { - char_u *s; + char_u *s; hash_T hash; - hashitem_T *hi; + hashitem_T *hi; hash = hash_hash(word); const size_t word_len = STRLEN(word); @@ -5707,23 +5862,24 @@ static void rescore_suggestions(suginfo_T *su) // Recompute the score for one suggestion if sound-folding is possible. static void rescore_one(suginfo_T *su, suggest_T *stp) { - slang_T *slang = stp->st_slang; + slang_T *slang = stp->st_slang; char_u sal_badword[MAXWLEN]; - char_u *p; + char_u *p; // Only rescore suggestions that have no sal score yet and do have a // language. if (slang != NULL && !GA_EMPTY(&slang->sl_sal) && !stp->st_had_bonus) { - if (slang == su->su_sallang) + if (slang == su->su_sallang) { p = su->su_sal_badword; - else { + } else { spell_soundfold(slang, su->su_fbadword, true, sal_badword); p = sal_badword; } stp->st_altscore = stp_sal_score(stp, su, slang, p); - if (stp->st_altscore == SCORE_MAXMAX) + if (stp->st_altscore == SCORE_MAXMAX) { stp->st_altscore = SCORE_BIG; + } stp->st_score = RESCORE(stp->st_score, stp->st_altscore); stp->st_had_bonus = true; } @@ -5734,28 +5890,27 @@ static void rescore_one(suginfo_T *su, suggest_T *stp) // First on "st_score", then "st_altscore" then alphabetically. static int sug_compare(const void *s1, const void *s2) { - suggest_T *p1 = (suggest_T *)s1; - suggest_T *p2 = (suggest_T *)s2; + suggest_T *p1 = (suggest_T *)s1; + suggest_T *p2 = (suggest_T *)s2; int n = p1->st_score - p2->st_score; if (n == 0) { n = p1->st_altscore - p2->st_altscore; - if (n == 0) + if (n == 0) { n = STRICMP(p1->st_word, p2->st_word); + } } return n; } -// Cleanup the suggestions: -// - Sort on score. -// - Remove words that won't be displayed. -// Returns the maximum score in the list or "maxscore" unmodified. -static int -cleanup_suggestions ( - garray_T *gap, - int maxscore, - int keep // nr of suggestions to keep -) +/// Cleanup the suggestions: +/// - Sort on score. +/// - Remove words that won't be displayed. +/// +/// @param keep nr of suggestions to keep +/// +/// @return the maximum score in the list or "maxscore" unmodified. +static int cleanup_suggestions(garray_T *gap, int maxscore, int keep) FUNC_ATTR_NONNULL_ALL { if (gap->ga_len > 0) { @@ -5823,12 +5978,12 @@ char *eval_soundfold(const char *const word) void spell_soundfold(slang_T *slang, char_u *inword, bool folded, char_u *res) { char_u fword[MAXWLEN]; - char_u *word; + char_u *word; - if (slang->sl_sofo) + if (slang->sl_sofo) { // SOFOFROM and SOFOTO used spell_soundfold_sofo(slang, inword, res); - else { + } else { // SAL items used. Requires the word to be case-folded. if (folded) { word = inword; @@ -5892,12 +6047,12 @@ static void spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res) // Multi-byte version of spell_soundfold(). static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) { - salitem_T *smp = (salitem_T *)slang->sl_sal.ga_data; + salitem_T *smp = (salitem_T *)slang->sl_sal.ga_data; int word[MAXWLEN] = { 0 }; int wres[MAXWLEN] = { 0 }; int l; - int *ws; - int *pf; + int *ws; + int *pf; int i, j, z; int reslen; int n, k = 0; @@ -5918,7 +6073,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) wordlen = 0; for (const char_u *s = inword; *s != NUL; ) { const char_u *t = s; - c = mb_cptr2char_adv((const char_u **)&s); + c = mb_cptr2char_adv(&s); if (slang->sl_rem_accents) { if (utf_class(c) == 0) { if (did_white) { @@ -5954,27 +6109,34 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) && ws[0] != NUL; ++n) { // Quickly skip entries that don't match the word. Most // entries are less then three chars, optimize for that. - if (c != ws[0]) + if (c != ws[0]) { continue; + } k = smp[n].sm_leadlen; if (k > 1) { - if (word[i + 1] != ws[1]) + if (word[i + 1] != ws[1]) { continue; + } if (k > 2) { - for (j = 2; j < k; ++j) - if (word[i + j] != ws[j]) + for (j = 2; j < k; ++j) { + if (word[i + j] != ws[j]) { break; - if (j < k) + } + } + if (j < k) { continue; + } } } if ((pf = smp[n].sm_oneof_w) != NULL) { // Check for match with one of the chars in "sm_oneof". - while (*pf != NUL && *pf != word[i + k]) + while (*pf != NUL && *pf != word[i + k]) { ++pf; - if (*pf == NUL) + } + if (*pf == NUL) { continue; + } ++k; } char_u *s = smp[n].sm_rules; @@ -5986,15 +6148,17 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) k--; s++; } - if (*s == '<') + if (*s == '<') { s++; + } if (ascii_isdigit(*s)) { // determine priority pri = *s - '0'; s++; } - if (*s == '^' && *(s + 1) == '^') + if (*s == '^' && *(s + 1) == '^') { s++; + } if (*s == NUL || (*s == '^' @@ -6017,19 +6181,24 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) for (; ((ws = smp[n0].sm_lead_w)[0] & 0xff) == (c0 & 0xff); ++n0) { // Quickly skip entries that don't match the word. - if (c0 != ws[0]) + if (c0 != ws[0]) { continue; + } k0 = smp[n0].sm_leadlen; if (k0 > 1) { - if (word[i + k] != ws[1]) + if (word[i + k] != ws[1]) { continue; + } if (k0 > 2) { pf = word + i + k + 1; - for (j = 2; j < k0; ++j) - if (*pf++ != ws[j]) + for (j = 2; j < k0; ++j) { + if (*pf++ != ws[j]) { break; - if (j < k0) + } + } + if (j < k0) { continue; + } } } k0 += k - 1; @@ -6037,10 +6206,12 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) if ((pf = smp[n0].sm_oneof_w) != NULL) { // Check for match with one of the chars in // "sm_oneof". - while (*pf != NUL && *pf != word[i + k0]) + while (*pf != NUL && *pf != word[i + k0]) { ++pf; - if (*pf == NUL) + } + if (*pf == NUL) { continue; + } ++k0; } @@ -6051,8 +6222,9 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) // "if (k0 == k)" s++; } - if (*s == '<') + if (*s == '<') { s++; + } if (ascii_isdigit(*s)) { p0 = *s - '0'; s++; @@ -6062,22 +6234,25 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) // *s == '^' cuts || (*s == '$' && !spell_iswordp_w(word + i + k0, - curwin))) { - if (k0 == k) + curwin))) { + if (k0 == k) { // this is just a piece of the string continue; + } - if (p0 < pri) + if (p0 < pri) { // priority too low continue; + } // rule fits; stop search break; } } if (p0 >= pri && (smp[n0].sm_lead_w[0] & 0xff) - == (c0 & 0xff)) + == (c0 & 0xff)) { continue; + } } // replace string @@ -6088,20 +6263,23 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) // rule with '<' is used if (reslen > 0 && ws != NULL && *ws != NUL && (wres[reslen - 1] == c - || wres[reslen - 1] == *ws)) + || wres[reslen - 1] == *ws)) { reslen--; + } z0 = 1; z = 1; k0 = 0; - if (ws != NULL) + if (ws != NULL) { while (*ws != NUL && word[i + k0] != NUL) { word[i + k0] = *ws; k0++; ws++; } - if (k > k0) + } + if (k > k0) { memmove(word + i + k0, word + i + k, - sizeof(int) * (wordlen - (i + k) + 1)); + sizeof(int) * (wordlen - (i + k) + 1)); + } // new "actual letter" c = word[i]; @@ -6109,23 +6287,27 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) // no '<' rule used i += k - 1; z = 0; - if (ws != NULL) + if (ws != NULL) { while (*ws != NUL && ws[1] != NUL && reslen < MAXWLEN) { - if (reslen == 0 || wres[reslen - 1] != *ws) + if (reslen == 0 || wres[reslen - 1] != *ws) { wres[reslen++] = *ws; + } ws++; } + } // new "actual letter" - if (ws == NULL) + if (ws == NULL) { c = NUL; - else + } else { c = *ws; + } if (strstr((char *)s, "^^") != NULL) { - if (c != NUL) + if (c != NUL) { wres[reslen++] = c; + } memmove(word, word + i + 1, - sizeof(int) * (wordlen - (i + 1) + 1)); + sizeof(int) * (wordlen - (i + 1) + 1)); i = 0; z0 = 1; } @@ -6133,7 +6315,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) break; } } - } else if (ascii_iswhite(c)) { + } else if (ascii_iswhite(c)) { c = ' '; k = 1; } @@ -6141,9 +6323,10 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) if (z0 == 0) { if (k && !p0 && reslen < MAXWLEN && c != NUL && (!slang->sl_collapse || reslen == 0 - || wres[reslen - 1] != c)) + || wres[reslen - 1] != c)) { // condense only double letters wres[reslen++] = c; + } i++; z = 0; @@ -6162,35 +6345,36 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) res[l] = NUL; } -// Compute a score for two sound-a-like words. -// This permits up to two inserts/deletes/swaps/etc. to keep things fast. -// Instead of a generic loop we write out the code. That keeps it fast by -// avoiding checks that will not be possible. -static int -soundalike_score ( - char_u *goodstart, // sound-folded good word - char_u *badstart // sound-folded bad word -) +/// Compute a score for two sound-a-like words. +/// This permits up to two inserts/deletes/swaps/etc. to keep things fast. +/// Instead of a generic loop we write out the code. That keeps it fast by +/// avoiding checks that will not be possible. +/// +/// @param goodstart sound-folded good word +/// @param badstart sound-folded bad word +static int soundalike_score(char_u *goodstart, char_u *badstart) { - char_u *goodsound = goodstart; - char_u *badsound = badstart; + char_u *goodsound = goodstart; + char_u *badsound = badstart; int goodlen; int badlen; int n; - char_u *pl, *ps; - char_u *pl2, *ps2; + char_u *pl, *ps; + char_u *pl2, *ps2; int score = 0; // Adding/inserting "*" at the start (word starts with vowel) shouldn't be // counted so much, vowels in the middle of the word aren't counted at all. if ((*badsound == '*' || *goodsound == '*') && *badsound != *goodsound) { if ((badsound[0] == NUL && goodsound[1] == NUL) - || (goodsound[0] == NUL && badsound[1] == NUL)) + || (goodsound[0] == NUL && badsound[1] == NUL)) { // changing word with vowel to word without a sound return SCORE_DEL; - if (badsound[0] == NUL || goodsound[0] == NUL) + } + if (badsound[0] == NUL || goodsound[0] == NUL) { // more than two changes return SCORE_MAXMAX; + } if (badsound[1] == goodsound[1] || (badsound[1] != NUL @@ -6199,10 +6383,11 @@ soundalike_score ( // handle like a substitute } else { score = 2 * SCORE_DEL / 3; - if (*badsound == '*') + if (*badsound == '*') { ++badsound; - else + } else { ++goodsound; + } } } @@ -6212,8 +6397,9 @@ soundalike_score ( // Return quickly if the lengths are too different to be fixed by two // changes. n = goodlen - badlen; - if (n < -2 || n > 2) + if (n < -2 || n > 2) { return SCORE_MAXMAX; + } if (n > 0) { pl = goodsound; // goodsound is longest @@ -6239,8 +6425,9 @@ soundalike_score ( ++ps; } // strings must be equal after second delete - if (STRCMP(pl + 1, ps) == 0) + if (STRCMP(pl + 1, ps) == 0) { return score + SCORE_DEL * 2; + } // Failed to compare. break; @@ -6253,20 +6440,23 @@ soundalike_score ( pl2 = pl + 1; ps2 = ps; while (*pl2 == *ps2) { - if (*pl2 == NUL) // reached the end + if (*pl2 == NUL) { // reached the end return score + SCORE_DEL; + } ++pl2; ++ps2; } // 2: delete then swap, then rest must be equal if (pl2[0] == ps2[1] && pl2[1] == ps2[0] - && STRCMP(pl2 + 2, ps2 + 2) == 0) + && STRCMP(pl2 + 2, ps2 + 2) == 0) { return score + SCORE_DEL + SCORE_SWAP; + } // 3: delete then substitute, then the rest must be equal - if (STRCMP(pl2 + 1, ps2 + 1) == 0) + if (STRCMP(pl2 + 1, ps2 + 1) == 0) { return score + SCORE_DEL + SCORE_SUBST; + } // 4: first swap then delete if (pl[0] == ps[1] && pl[1] == ps[0]) { @@ -6277,8 +6467,9 @@ soundalike_score ( ++ps2; } // delete a char and then strings must be equal - if (STRCMP(pl2 + 1, ps2) == 0) + if (STRCMP(pl2 + 1, ps2) == 0) { return score + SCORE_SWAP + SCORE_DEL; + } } // 5: first substitute then delete @@ -6289,8 +6480,9 @@ soundalike_score ( ++ps2; } // delete a char and then strings must be equal - if (STRCMP(pl2 + 1, ps2) == 0) + if (STRCMP(pl2 + 1, ps2) == 0) { return score + SCORE_SUBST + SCORE_DEL; + } // Failed to compare. break; @@ -6299,47 +6491,54 @@ soundalike_score ( // Lengths are equal, thus changes must result in same length: An // insert is only possible in combination with a delete. // 1: check if for identical strings - if (*pl == NUL) + if (*pl == NUL) { return score; + } // 2: swap if (pl[0] == ps[1] && pl[1] == ps[0]) { pl2 = pl + 2; // swap, skip two chars ps2 = ps + 2; while (*pl2 == *ps2) { - if (*pl2 == NUL) // reached the end + if (*pl2 == NUL) { // reached the end return score + SCORE_SWAP; + } ++pl2; ++ps2; } // 3: swap and swap again if (pl2[0] == ps2[1] && pl2[1] == ps2[0] - && STRCMP(pl2 + 2, ps2 + 2) == 0) + && STRCMP(pl2 + 2, ps2 + 2) == 0) { return score + SCORE_SWAP + SCORE_SWAP; + } // 4: swap and substitute - if (STRCMP(pl2 + 1, ps2 + 1) == 0) + if (STRCMP(pl2 + 1, ps2 + 1) == 0) { return score + SCORE_SWAP + SCORE_SUBST; + } } // 5: substitute pl2 = pl + 1; ps2 = ps + 1; while (*pl2 == *ps2) { - if (*pl2 == NUL) // reached the end + if (*pl2 == NUL) { // reached the end return score + SCORE_SUBST; + } ++pl2; ++ps2; } // 6: substitute and swap if (pl2[0] == ps2[1] && pl2[1] == ps2[0] - && STRCMP(pl2 + 2, ps2 + 2) == 0) + && STRCMP(pl2 + 2, ps2 + 2) == 0) { return score + SCORE_SUBST + SCORE_SWAP; + } // 7: substitute and substitute - if (STRCMP(pl2 + 1, ps2 + 1) == 0) + if (STRCMP(pl2 + 1, ps2 + 1) == 0) { return score + SCORE_SUBST + SCORE_SUBST; + } // 8: insert then delete pl2 = pl; @@ -6348,8 +6547,9 @@ soundalike_score ( ++pl2; ++ps2; } - if (STRCMP(pl2 + 1, ps2) == 0) + if (STRCMP(pl2 + 1, ps2) == 0) { return score + SCORE_INS + SCORE_DEL; + } // 9: delete then insert pl2 = pl + 1; @@ -6358,8 +6558,9 @@ soundalike_score ( ++pl2; ++ps2; } - if (STRCMP(pl2, ps2 + 1) == 0) + if (STRCMP(pl2, ps2 + 1) == 0) { return score + SCORE_INS + SCORE_DEL; + } // Failed to compare. break; @@ -6408,8 +6609,9 @@ static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword) cnt = xmalloc(sizeof(int) * (badlen + 1) * (goodlen + 1)); CNT(0, 0) = 0; - for (j = 1; j <= goodlen; ++j) + for (j = 1; j <= goodlen; ++j) { CNT(0, j) = CNT(0, j - 1) + SCORE_INS; + } for (i = 1; i <= badlen; ++i) { CNT(i, 0) = CNT(i - 1, 0) + SCORE_DEL; @@ -6420,16 +6622,17 @@ static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword) CNT(i, j) = CNT(i - 1, j - 1); } else { // Use a better score when there is only a case difference. - if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc)) + if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc)) { CNT(i, j) = SCORE_ICASE + CNT(i - 1, j - 1); - else { + } else { // For a similar character use SCORE_SIMILAR. if (slang != NULL && slang->sl_has_map - && similar_chars(slang, gc, bc)) + && similar_chars(slang, gc, bc)) { CNT(i, j) = SCORE_SIMILAR + CNT(i - 1, j - 1); - else + } else { CNT(i, j) = SCORE_SUBST + CNT(i - 1, j - 1); + } } if (i > 1 && j > 1) { @@ -6437,16 +6640,19 @@ static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword) pgc = wgoodword[j - 2]; if (bc == pgc && pbc == gc) { t = SCORE_SWAP + CNT(i - 2, j - 2); - if (t < CNT(i, j)) + if (t < CNT(i, j)) { CNT(i, j) = t; + } } } t = SCORE_DEL + CNT(i - 1, j); - if (t < CNT(i, j)) + if (t < CNT(i, j)) { CNT(i, j) = t; + } t = SCORE_INS + CNT(i, j - 1); - if (t < CNT(i, j)) + if (t < CNT(i, j)) { CNT(i, j) = t; + } } } } @@ -6515,11 +6721,13 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo bc = wbadword[bi]; gc = wgoodword[gi]; - if (bc != gc) // stop at a char that's different + if (bc != gc) { // stop at a char that's different break; + } if (bc == NUL) { // both words end - if (score < minscore) + if (score < minscore) { minscore = score; + } goto pop; // do next alternative } ++bi; @@ -6528,14 +6736,16 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo if (gc == NUL) { // goodword ends, delete badword chars do { - if ((score += SCORE_DEL) >= minscore) + if ((score += SCORE_DEL) >= minscore) { goto pop; // do next alternative + } } while (wbadword[++bi] != NUL); minscore = score; - } else if (bc == NUL) { // badword ends, insert badword chars + } else if (bc == NUL) { // badword ends, insert badword chars do { - if ((score += SCORE_INS) >= minscore) + if ((score += SCORE_INS) >= minscore) { goto pop; // do next alternative + } } while (wgoodword[++gi] != NUL); minscore = score; } else { // both words continue @@ -6586,16 +6796,17 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo // Substitute one character for another which is the same // thing as deleting a character from both goodword and badword. // Use a better score when there is only a case difference. - if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc)) + if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc)) { score += SCORE_ICASE; - else { + } else { // For a similar character use SCORE_SIMILAR. if (slang != NULL && slang->sl_has_map - && similar_chars(slang, gc, bc)) + && similar_chars(slang, gc, bc)) { score += SCORE_SIMILAR; - else + } else { score += SCORE_SUBST; + } } if (score < minscore) { @@ -6607,8 +6818,9 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo } pop: // Get here to try the next alternative, pop it from the stack. - if (stackidx == 0) // stack is empty, finished + if (stackidx == 0) { // stack is empty, finished break; + } // pop an item from the stack --stackidx; @@ -6620,8 +6832,9 @@ pop: // When the score goes over "limit" it may actually be much higher. // Return a very large number to avoid going below the limit when giving a // bonus. - if (minscore > limit) + if (minscore > limit) { return SCORE_MAXMAX; + } return minscore; } @@ -6656,7 +6869,7 @@ void ex_spellinfo(exarg_T *eap) // ":spelldump" void ex_spelldump(exarg_T *eap) { - char_u *spl; + char_u *spl; long dummy; if (no_spell_checking(curwin)) { @@ -6685,50 +6898,49 @@ void ex_spelldump(exarg_T *eap) redraw_later(curwin, NOT_VALID); } -// Go through all possible words and: -// 1. When "pat" is NULL: dump a list of all words in the current buffer. -// "ic" and "dir" are not used. -// 2. When "pat" is not NULL: add matching words to insert mode completion. -void -spell_dump_compl ( - char_u *pat, // leading part of the word - int ic, // ignore case - Direction *dir, // direction for adding matches - int dumpflags_arg // DUMPFLAG_* -) +/// Go through all possible words and: +/// 1. When "pat" is NULL: dump a list of all words in the current buffer. +/// "ic" and "dir" are not used. +/// 2. When "pat" is not NULL: add matching words to insert mode completion. +/// +/// @param pat leading part of the word +/// @param ic ignore case +/// @param dir direction for adding matches +/// @param dumpflags_arg DUMPFLAG_* +void spell_dump_compl(char_u *pat, int ic, Direction *dir, int dumpflags_arg) { - langp_T *lp; - slang_T *slang; + langp_T *lp; + slang_T *slang; idx_T arridx[MAXWLEN]; int curi[MAXWLEN]; char_u word[MAXWLEN]; int c; - char_u *byts; - idx_T *idxs; + char_u *byts; + idx_T *idxs; linenr_T lnum = 0; int round; int depth; int n; int flags; - char_u *region_names = NULL; // region names being used + char_u *region_names = NULL; // region names being used bool do_region = true; // dump region names and numbers - char_u *p; + char_u *p; int dumpflags = dumpflags_arg; int patlen; // When ignoring case or when the pattern starts with capital pass this on // to dump_word(). if (pat != NULL) { - if (ic) + if (ic) { dumpflags |= DUMPFLAG_ICASE; - else { + } else { n = captype(pat, NULL); - if (n == WF_ONECAP) + if (n == WF_ONECAP) { dumpflags |= DUMPFLAG_ONECAP; - else if (n == WF_ALLCAP - && (int)STRLEN(pat) > mb_ptr2len(pat) - ) + } else if (n == WF_ALLCAP + && (int)STRLEN(pat) > mb_ptr2len(pat)) { dumpflags |= DUMPFLAG_ALLCAP; + } } } @@ -6738,9 +6950,9 @@ spell_dump_compl ( lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); p = lp->lp_slang->sl_regions; if (p[0] != 0) { - if (region_names == NULL) // first language with regions + if (region_names == NULL) { // first language with regions region_names = p; - else if (STRCMP(region_names, p) != 0) { + } else if (STRCMP(region_names, p) != 0) { do_region = false; // region names are different break; } @@ -6752,15 +6964,17 @@ spell_dump_compl ( vim_snprintf((char *)IObuff, IOSIZE, "/regions=%s", region_names); ml_append(lnum++, IObuff, (colnr_T)0, false); } - } else + } else { do_region = false; + } // Loop over all files loaded for the entries in 'spelllang'. for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) { lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); slang = lp->lp_slang; - if (slang->sl_fbyts == NULL) // reloading failed + if (slang->sl_fbyts == NULL) { // reloading failed continue; + } if (pat == NULL) { vim_snprintf((char *)IObuff, IOSIZE, "# file: %s", slang->sl_fname); @@ -6769,10 +6983,11 @@ spell_dump_compl ( // When matching with a pattern and there are no prefixes only use // parts of the tree that match "pat". - if (pat != NULL && slang->sl_pbyts == NULL) + if (pat != NULL && slang->sl_pbyts == NULL) { patlen = (int)STRLEN(pat); - else + } else { patlen = -1; + } // round 1: case-folded tree // round 2: keep-case tree @@ -6786,9 +7001,9 @@ spell_dump_compl ( byts = slang->sl_kbyts; idxs = slang->sl_kidxs; } - if (byts == NULL) + if (byts == NULL) { continue; // array is empty - + } depth = 0; arridx[0] = 0; curi[0] = 1; @@ -6817,23 +7032,26 @@ spell_dump_compl ( || (((unsigned)flags >> 16) & lp->lp_region) != 0)) { word[depth] = NUL; - if (!do_region) + if (!do_region) { flags &= ~WF_REGION; + } // Dump the basic word if there is no prefix or // when it's the first one. c = (unsigned)flags >> 24; if (c == 0 || curi[depth] == 2) { dump_word(slang, word, pat, dir, - dumpflags, flags, lnum); - if (pat == NULL) + dumpflags, flags, lnum); + if (pat == NULL) { ++lnum; + } } // Apply the prefix, if there is one. - if (c != 0) + if (c != 0) { lnum = dump_prefixes(slang, word, pat, dir, - dumpflags, flags, lnum); + dumpflags, flags, lnum); + } } } else { // Normal char, go one level deeper. @@ -6849,8 +7067,9 @@ spell_dump_compl ( // ignore case... assert(depth >= 0); if (depth <= patlen - && mb_strnicmp(word, pat, (size_t)depth) != 0) + && mb_strnicmp(word, pat, (size_t)depth) != 0) { --depth; + } } } } @@ -6860,22 +7079,23 @@ spell_dump_compl ( // Dumps one word: apply case modifications and append a line to the buffer. // When "lnum" is zero add insert mode completion. -static void dump_word(slang_T *slang, char_u *word, char_u *pat, - Direction *dir, int dumpflags, int wordflags, - linenr_T lnum) +static void dump_word(slang_T *slang, char_u *word, char_u *pat, Direction *dir, int dumpflags, + int wordflags, linenr_T lnum) { bool keepcap = false; - char_u *p; - char_u *tw; + char_u *p; + char_u *tw; char_u cword[MAXWLEN]; char_u badword[MAXWLEN + 10]; int i; int flags = wordflags; - if (dumpflags & DUMPFLAG_ONECAP) + if (dumpflags & DUMPFLAG_ONECAP) { flags |= WF_ONECAP; - if (dumpflags & DUMPFLAG_ALLCAP) + } + if (dumpflags & DUMPFLAG_ALLCAP) { flags |= WF_ALLCAP; + } if ((dumpflags & DUMPFLAG_KEEPCASE) == 0 && (flags & WF_CAPMASK) != 0) { // Need to fix case according to "flags". @@ -6885,8 +7105,9 @@ static void dump_word(slang_T *slang, char_u *word, char_u *pat, p = word; if ((dumpflags & DUMPFLAG_KEEPCASE) && ((captype(word, NULL) & WF_KEEPCAP) == 0 - || (flags & WF_FIXCAP) != 0)) + || (flags & WF_FIXCAP) != 0)) { keepcap = true; + } } tw = p; @@ -6917,13 +7138,13 @@ static void dump_word(slang_T *slang, char_u *word, char_u *pat, } if (dumpflags & DUMPFLAG_COUNT) { - hashitem_T *hi; + hashitem_T *hi; // Include the word count for ":spelldump!". hi = hash_find(&slang->sl_wordcount, tw); if (!HASHITEM_EMPTY(hi)) { vim_snprintf((char *)IObuff, IOSIZE, "%s\t%d", - tw, HI2WC(hi)->wc_count); + tw, HI2WC(hi)->wc_count); p = IObuff; } } @@ -6939,20 +7160,16 @@ static void dump_word(slang_T *slang, char_u *word, char_u *pat, } } -// For ":spelldump": Find matching prefixes for "word". Prepend each to -// "word" and append a line to the buffer. -// When "lnum" is zero add insert mode completion. -// Return the updated line number. -static linenr_T -dump_prefixes ( - slang_T *slang, - char_u *word, // case-folded word - char_u *pat, - Direction *dir, - int dumpflags, - int flags, // flags with prefix ID - linenr_T startlnum -) +/// For ":spelldump": Find matching prefixes for "word". Prepend each to +/// "word" and append a line to the buffer. +/// When "lnum" is zero add insert mode completion. +/// +/// @param word case-folded word +/// @param flags flags with prefix ID +/// +/// @return the updated line number. +static linenr_T dump_prefixes(slang_T *slang, char_u *word, char_u *pat, Direction *dir, + int dumpflags, int flags, linenr_T startlnum) { idx_T arridx[MAXWLEN]; int curi[MAXWLEN]; @@ -6960,8 +7177,8 @@ dump_prefixes ( char_u word_up[MAXWLEN]; bool has_word_up = false; int c; - char_u *byts; - idx_T *idxs; + char_u *byts; + idx_T *idxs; linenr_T lnum = startlnum; int depth; int n; @@ -6998,19 +7215,22 @@ dump_prefixes ( c = byts[n]; if (c == 0) { // End of prefix, find out how many IDs there are. - for (i = 1; i < len; ++i) - if (byts[n + i] != 0) + for (i = 1; i < len; ++i) { + if (byts[n + i] != 0) { break; + } + } curi[depth] += i - 1; c = valid_word_prefix(i, n, flags, word, slang, false); if (c != 0) { STRLCPY(prefix + depth, word, MAXWLEN - depth); dump_word(slang, prefix, pat, dir, dumpflags, - (c & WF_RAREPFX) ? (flags | WF_RARE) - : flags, lnum); - if (lnum != 0) + (c & WF_RAREPFX) ? (flags | WF_RARE) + : flags, lnum); + if (lnum != 0) { ++lnum; + } } // Check for prefix that matches the word when the @@ -7018,14 +7238,15 @@ dump_prefixes ( // a condition. if (has_word_up) { c = valid_word_prefix(i, n, flags, word_up, slang, - true); + true); if (c != 0) { STRLCPY(prefix + depth, word_up, MAXWLEN - depth); dump_word(slang, prefix, pat, dir, dumpflags, - (c & WF_RAREPFX) ? (flags | WF_RARE) - : flags, lnum); - if (lnum != 0) + (c & WF_RAREPFX) ? (flags | WF_RARE) + : flags, lnum); + if (lnum != 0) { ++lnum; + } } } } else { @@ -7045,7 +7266,7 @@ dump_prefixes ( // Uses the spell-checking word characters. char_u *spell_to_word_end(char_u *start, win_T *win) { - char_u *p = start; + char_u *p = start; while (*p != NUL && spell_iswordp(p, win)) { MB_PTR_ADV(p); @@ -7060,8 +7281,8 @@ char_u *spell_to_word_end(char_u *start, win_T *win) // Returns the column number of the word. int spell_word_start(int startcol) { - char_u *line; - char_u *p; + char_u *line; + char_u *p; int col = 0; if (no_spell_checking(curwin)) { diff --git a/src/nvim/spell.h b/src/nvim/spell.h index e93c82b91d..f941f0e5e7 100644 --- a/src/nvim/spell.h +++ b/src/nvim/spell.h @@ -3,9 +3,9 @@ #include <stdbool.h> -#include "nvim/spell_defs.h" #include "nvim/ex_cmds_defs.h" #include "nvim/globals.h" +#include "nvim/spell_defs.h" #include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/spell_defs.h b/src/nvim/spell_defs.h index f07f5673f9..78aa6bf199 100644 --- a/src/nvim/spell_defs.h +++ b/src/nvim/spell_defs.h @@ -20,9 +20,9 @@ // is 8 bytes we could use something smaller, but what? typedef int idx_T; -# define SPL_FNAME_TMPL "%s.%s.spl" -# define SPL_FNAME_ADD ".add." -# define SPL_FNAME_ASCII ".ascii." +#define SPL_FNAME_TMPL "%s.%s.spl" +#define SPL_FNAME_ADD ".add." +#define SPL_FNAME_ASCII ".ascii." // Flags used for a word. Only the lowest byte can be used, the region byte // comes above it. @@ -71,22 +71,22 @@ typedef int idx_T; // si_repsal, sl_rep, and si_sal. Not for sl_sal! // One replacement: from "ft_from" to "ft_to". typedef struct fromto_S { - char_u *ft_from; - char_u *ft_to; + char_u *ft_from; + char_u *ft_to; } fromto_T; // Info from "SAL" entries in ".aff" file used in sl_sal. // The info is split for quick processing by spell_soundfold(). // Note that "sm_oneof" and "sm_rules" point into sm_lead. typedef struct salitem_S { - char_u *sm_lead; // leading letters + char_u *sm_lead; // leading letters int sm_leadlen; // length of "sm_lead" - char_u *sm_oneof; // letters from () or NULL - char_u *sm_rules; // rules like ^, $, priority - char_u *sm_to; // replacement. - int *sm_lead_w; // wide character copy of "sm_lead" - int *sm_oneof_w; // wide character copy of "sm_oneof" - int *sm_to_w; // wide character copy of "sm_to" + char_u *sm_oneof; // letters from () or NULL + char_u *sm_rules; // rules like ^, $, priority + char_u *sm_to; // replacement. + int *sm_lead_w; // wide character copy of "sm_lead" + int *sm_oneof_w; // wide character copy of "sm_oneof" + int *sm_to_w; // wide character copy of "sm_to" } salitem_T; typedef int salfirst_T; @@ -113,25 +113,25 @@ typedef int salfirst_T; typedef struct slang_S slang_T; struct slang_S { - slang_T *sl_next; // next language - char_u *sl_name; // language name "en", "en.rare", "nl", etc. - char_u *sl_fname; // name of .spl file + slang_T *sl_next; // next language + char_u *sl_name; // language name "en", "en.rare", "nl", etc. + char_u *sl_fname; // name of .spl file bool sl_add; // true if it's a .add file. - char_u *sl_fbyts; // case-folded word bytes - long sl_fbyts_len; // length of sl_fbyts - idx_T *sl_fidxs; // case-folded word indexes - char_u *sl_kbyts; // keep-case word bytes - idx_T *sl_kidxs; // keep-case word indexes - char_u *sl_pbyts; // prefix tree word bytes - idx_T *sl_pidxs; // prefix tree word indexes + char_u *sl_fbyts; // case-folded word bytes + long sl_fbyts_len; // length of sl_fbyts + idx_T *sl_fidxs; // case-folded word indexes + char_u *sl_kbyts; // keep-case word bytes + idx_T *sl_kidxs; // keep-case word indexes + char_u *sl_pbyts; // prefix tree word bytes + idx_T *sl_pidxs; // prefix tree word indexes - char_u *sl_info; // infotext string or NULL + char_u *sl_info; // infotext string or NULL char_u sl_regions[MAXREGIONS * 2 + 1]; - // table with up to 8 region names plus NUL + // table with up to 8 region names plus NUL - char_u *sl_midword; // MIDWORD string or NULL + char_u *sl_midword; // MIDWORD string or NULL hashtab_T sl_wordcount; // hashtable with word count, wordcount_T @@ -140,17 +140,17 @@ struct slang_S { int sl_compsylmax; // COMPOUNDSYLMAX (default: MAXWLEN) int sl_compoptions; // COMP_* flags garray_T sl_comppat; // CHECKCOMPOUNDPATTERN items - regprog_T *sl_compprog; // COMPOUNDRULE turned into a regexp progrm - // (NULL when no compounding) - char_u *sl_comprules; // all COMPOUNDRULE concatenated (or NULL) - char_u *sl_compstartflags; // flags for first compound word - char_u *sl_compallflags; // all flags for compound words + regprog_T *sl_compprog; // COMPOUNDRULE turned into a regexp progrm + // (NULL when no compounding) + char_u *sl_comprules; // all COMPOUNDRULE concatenated (or NULL) + char_u *sl_compstartflags; // flags for first compound word + char_u *sl_compallflags; // all flags for compound words bool sl_nobreak; // When true: no spaces between words - char_u *sl_syllable; // SYLLABLE repeatable chars or NULL + char_u *sl_syllable; // SYLLABLE repeatable chars or NULL garray_T sl_syl_items; // syllable items int sl_prefixcnt; // number of items in "sl_prefprog" - regprog_T **sl_prefprog; // table with regprogs for prefixes + regprog_T **sl_prefprog; // table with regprogs for prefixes garray_T sl_rep; // list of fromto_T entries from REP lines int16_t sl_rep_first[256]; // indexes where byte first appears, -1 if @@ -171,9 +171,9 @@ struct slang_S { // Info from the .sug file. Loaded on demand. time_t sl_sugtime; // timestamp for .sug file - char_u *sl_sbyts; // soundfolded word bytes - idx_T *sl_sidxs; // soundfolded word indexes - buf_T *sl_sugbuf; // buffer with word number table + char_u *sl_sbyts; // soundfolded word bytes + idx_T *sl_sidxs; // soundfolded word indexes + buf_T *sl_sugbuf; // buffer with word number table bool sl_sugloaded; // true when .sug file was loaded or failed to // load @@ -186,9 +186,9 @@ struct slang_S { // Structure used in "b_langp", filled from 'spelllang'. typedef struct langp_S { - slang_T *lp_slang; // info for this language - slang_T *lp_sallang; // language used for sound folding or NULL - slang_T *lp_replang; // language used for REP items or NULL + slang_T *lp_slang; // info for this language + slang_T *lp_sallang; // language used for sound folding or NULL + slang_T *lp_replang; // language used for REP items or NULL int lp_region; // bitmask for region or REGION_ALL } langp_T; @@ -268,7 +268,7 @@ typedef struct trystate_S { #define SPELL_TOFOLD(c) ((c) >= 128 ? utf_fold(c) : (int)spelltab.st_fold[c]) #define SPELL_TOUPPER(c) ((c) >= 128 ? mb_toupper(c) \ - : (int)spelltab.st_upper[c]) + : (int)spelltab.st_upper[c]) #define SPELL_ISUPPER(c) ((c) >= 128 ? mb_isupper(c) : spelltab.st_isu[c]) diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 843ecec1b1..e3a6236ae4 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -226,19 +226,17 @@ // stored as an offset to the previous number in as // few bytes as possible, see offset2bytes()) -#include <stdio.h> #include <stdint.h> +#include <stdio.h> #include <wctype.h> -#include "nvim/vim.h" -#include "nvim/spell_defs.h" #include "nvim/ascii.h" #include "nvim/buffer.h" #include "nvim/charset.h" #include "nvim/ex_cmds2.h" #include "nvim/fileio.h" -#include "nvim/memory.h" #include "nvim/memline.h" +#include "nvim/memory.h" #include "nvim/misc1.h" #include "nvim/option.h" #include "nvim/os/os.h" @@ -246,9 +244,11 @@ #include "nvim/regexp.h" #include "nvim/screen.h" #include "nvim/spell.h" +#include "nvim/spell_defs.h" #include "nvim/spellfile.h" #include "nvim/ui.h" #include "nvim/undo.h" +#include "nvim/vim.h" #ifndef UNIX // it's in os/unix_defs.h for Unix # include <time.h> // for time_t @@ -310,7 +310,7 @@ static char *msg_compressing = N_("Compressing word tree..."); // and .dic file. // Main structure to store the contents of a ".aff" file. typedef struct afffile_S { - char_u *af_enc; // "SET", normalized, alloc'ed string or NULL + char_u *af_enc; // "SET", normalized, alloc'ed string or NULL int af_flagtype; // AFT_CHAR, AFT_LONG, AFT_NUM or AFT_CAPLONG unsigned af_rare; // RARE ID for rare word unsigned af_keepcase; // KEEPCASE ID for keep-case word @@ -338,17 +338,17 @@ typedef struct afffile_S { typedef struct affentry_S affentry_T; // Affix entry from ".aff" file. Used for prefixes and suffixes. struct affentry_S { - affentry_T *ae_next; // next affix with same name/number - char_u *ae_chop; // text to chop off basic word (can be NULL) - char_u *ae_add; // text to add to basic word (can be NULL) - char_u *ae_flags; // flags on the affix (can be NULL) - char_u *ae_cond; // condition (NULL for ".") - regprog_T *ae_prog; // regexp program for ae_cond or NULL + affentry_T *ae_next; // next affix with same name/number + char_u *ae_chop; // text to chop off basic word (can be NULL) + char_u *ae_add; // text to add to basic word (can be NULL) + char_u *ae_flags; // flags on the affix (can be NULL) + char_u *ae_cond; // condition (NULL for ".") + regprog_T *ae_prog; // regexp program for ae_cond or NULL char ae_compforbid; // COMPOUNDFORBIDFLAG found char ae_comppermit; // COMPOUNDPERMITFLAG found }; -# define AH_KEY_LEN 17 // 2 x 8 bytes + NUL +#define AH_KEY_LEN 17 // 2 x 8 bytes + NUL // Affix header from ".aff" file. Used for af_pref and af_suff. typedef struct affheader_S { @@ -357,7 +357,7 @@ typedef struct affheader_S { int ah_newID; // prefix ID after renumbering; 0 if not used int ah_combine; // suffix may combine with prefix int ah_follows; // another affix block should be following - affentry_T *ah_first; // first affix entry + affentry_T *ah_first; // first affix entry } affheader_T; #define HI2AH(hi) ((affheader_T *)(hi)->hi_key) @@ -381,7 +381,7 @@ typedef struct compitem_S { typedef struct sblock_S sblock_T; struct sblock_S { int sb_used; // nr of bytes already in use - sblock_T *sb_next; // next block in list + sblock_T *sb_next; // next block in list char_u sb_data[1]; // data, actually longer }; @@ -397,9 +397,9 @@ struct wordnode_S { wordnode_T *next; // next node with same hash key wordnode_T *wnode; // parent node that will write this node } wn_u2; - wordnode_T *wn_child; // child (next byte in word) - wordnode_T *wn_sibling; // next sibling (alternate byte in word, - // always sorted) + wordnode_T *wn_child; // child (next byte in word) + wordnode_T *wn_sibling; // next sibling (alternate byte in word, + // always sorted) int wn_refs; // Nr. of references to this node. Only // relevant for first node in a list of // siblings, in following siblings it is @@ -425,29 +425,29 @@ struct wordnode_S { // Info used while reading the spell files. typedef struct spellinfo_S { - wordnode_T *si_foldroot; // tree with case-folded words + wordnode_T *si_foldroot; // tree with case-folded words long si_foldwcount; // nr of words in si_foldroot - wordnode_T *si_keeproot; // tree with keep-case words + wordnode_T *si_keeproot; // tree with keep-case words long si_keepwcount; // nr of words in si_keeproot - wordnode_T *si_prefroot; // tree with postponed prefixes + wordnode_T *si_prefroot; // tree with postponed prefixes long si_sugtree; // creating the soundfolding trie - sblock_T *si_blocks; // memory blocks used + sblock_T *si_blocks; // memory blocks used long si_blocks_cnt; // memory blocks allocated int si_did_emsg; // TRUE when ran out of memory long si_compress_cnt; // words to add before lowering // compression limit - wordnode_T *si_first_free; // List of nodes that have been freed during - // compression, linked by "wn_child" field. + wordnode_T *si_first_free; // List of nodes that have been freed during + // compression, linked by "wn_child" field. long si_free_count; // number of nodes in si_first_free #ifdef SPELL_PRINTTREE int si_wordnode_nr; // sequence nr for nodes #endif - buf_T *si_spellbuf; // buffer used to store soundfold word table + buf_T *si_spellbuf; // buffer used to store soundfold word table int si_ascii; // handling only ASCII words int si_add; // addition file @@ -457,18 +457,18 @@ typedef struct spellinfo_S { int si_memtot; // runtime memory used int si_verbose; // verbose messages int si_msg_count; // number of words added since last message - char_u *si_info; // info text chars or NULL + char_u *si_info; // info text chars or NULL int si_region_count; // number of regions supported (1 when there // are no regions) char_u si_region_name[MAXREGIONS * 2 + 1]; - // region names; used only if - // si_region_count > 1) + // region names; used only if + // si_region_count > 1) garray_T si_rep; // list of fromto_T entries from REP lines garray_T si_repsal; // list of fromto_T entries from REPSAL lines garray_T si_sal; // list of fromto_T entries from SAL lines - char_u *si_sofofr; // SOFOFROM text - char_u *si_sofoto; // SOFOTO text + char_u *si_sofofr; // SOFOFROM text + char_u *si_sofoto; // SOFOTO text int si_nosugfile; // NOSUGFILE item found int si_nosplitsugs; // NOSPLITSUGS item found int si_nocompoundsugs; // NOCOMPOUNDSUGS item found @@ -478,16 +478,16 @@ typedef struct spellinfo_S { time_t si_sugtime; // timestamp for .sug file int si_rem_accents; // soundsalike: remove accents garray_T si_map; // MAP info concatenated - char_u *si_midword; // MIDWORD chars or NULL + char_u *si_midword; // MIDWORD chars or NULL int si_compmax; // max nr of words for compounding int si_compminlen; // minimal length for compounding int si_compsylmax; // max nr of syllables for compounding int si_compoptions; // COMP_ flags garray_T si_comppat; // CHECKCOMPOUNDPATTERN items, each stored as // a string - char_u *si_compflags; // flags used for compounding + char_u *si_compflags; // flags used for compounding char_u si_nobreak; // NOBREAK - char_u *si_syllable; // syllable string + char_u *si_syllable; // syllable string garray_T si_prefcond; // table with conditions for postponed // prefixes, each stored as a string int si_newprefID; // current value for ah_newID @@ -508,16 +508,16 @@ typedef struct spellinfo_S { /// @return Allows to proceed if everything is OK, returns SP_TRUNCERROR if /// there are not enough bytes, returns SP_OTHERERROR if reading failed. #define SPELL_READ_BYTES(buf, n, fd, exit_code) \ - do { \ - const size_t n__SPRB = (n); \ - FILE *const fd__SPRB = (fd); \ - char *const buf__SPRB = (buf); \ - const size_t read_bytes__SPRB = fread(buf__SPRB, 1, n__SPRB, fd__SPRB); \ - if (read_bytes__SPRB != n__SPRB) { \ - exit_code; \ - return feof(fd__SPRB) ? SP_TRUNCERROR : SP_OTHERERROR; \ - } \ - } while (0) + do { \ + const size_t n__SPRB = (n); \ + FILE *const fd__SPRB = (fd); \ + char *const buf__SPRB = (buf); \ + const size_t read_bytes__SPRB = fread(buf__SPRB, 1, n__SPRB, fd__SPRB); \ + if (read_bytes__SPRB != n__SPRB) { \ + exit_code; \ + return feof(fd__SPRB) ? SP_TRUNCERROR : SP_OTHERERROR; \ + } \ + } while (0) /// Like #SPELL_READ_BYTES, but also error out if NUL byte was read /// @@ -525,16 +525,16 @@ typedef struct spellinfo_S { /// there are not enough bytes, returns SP_OTHERERROR if reading failed, /// returns SP_FORMERROR if read out a NUL byte. #define SPELL_READ_NONNUL_BYTES(buf, n, fd, exit_code) \ - do { \ - const size_t n__SPRNB = (n); \ - FILE *const fd__SPRNB = (fd); \ - char *const buf__SPRNB = (buf); \ - SPELL_READ_BYTES(buf__SPRNB, n__SPRNB, fd__SPRNB, exit_code); \ - if (memchr(buf__SPRNB, NUL, (size_t)n__SPRNB)) { \ - exit_code; \ - return SP_FORMERROR; \ - } \ - } while (0) + do { \ + const size_t n__SPRNB = (n); \ + FILE *const fd__SPRNB = (fd); \ + char *const buf__SPRNB = (buf); \ + SPELL_READ_BYTES(buf__SPRNB, n__SPRNB, fd__SPRNB, exit_code); \ + if (memchr(buf__SPRNB, NUL, (size_t)n__SPRNB)) { \ + exit_code; \ + return SP_FORMERROR; \ + } \ + } while (0) /// Check that spell file starts with a magic string /// @@ -556,40 +556,36 @@ static inline int spell_check_magic_string(FILE *const fd) return 0; } -// Load one spell file and store the info into a slang_T. -// -// This is invoked in three ways: -// - From spell_load_cb() to load a spell file for the first time. "lang" is -// the language name, "old_lp" is NULL. Will allocate an slang_T. -// - To reload a spell file that was changed. "lang" is NULL and "old_lp" -// points to the existing slang_T. -// - Just after writing a .spl file; it's read back to produce the .sug file. -// "old_lp" is NULL and "lang" is NULL. Will allocate an slang_T. -// -// Returns the slang_T the spell file was loaded into. NULL for error. -slang_T * -spell_load_file ( - char_u *fname, - char_u *lang, - slang_T *old_lp, - bool silent // no error if file doesn't exist -) +/// Load one spell file and store the info into a slang_T. +/// +/// This is invoked in three ways: +/// - From spell_load_cb() to load a spell file for the first time. "lang" is +/// the language name, "old_lp" is NULL. Will allocate an slang_T. +/// - To reload a spell file that was changed. "lang" is NULL and "old_lp" +/// points to the existing slang_T. +/// - Just after writing a .spl file; it's read back to produce the .sug file. +/// "old_lp" is NULL and "lang" is NULL. Will allocate an slang_T. +/// +/// @param silent no error if file doesn't exist +/// +/// @return the slang_T the spell file was loaded into. NULL for error. +slang_T *spell_load_file(char_u *fname, char_u *lang, slang_T *old_lp, bool silent) { - FILE *fd; - char_u *p; + FILE *fd; + char_u *p; int n; int len; - char_u *save_sourcing_name = sourcing_name; + char_u *save_sourcing_name = sourcing_name; linenr_T save_sourcing_lnum = sourcing_lnum; - slang_T *lp = NULL; + slang_T *lp = NULL; int c = 0; int res; fd = os_fopen((char *)fname, "r"); if (fd == NULL) { - if (!silent) + if (!silent) { EMSG2(_(e_notopen), fname); - else if (p_verbose > 2) { + } else if (p_verbose > 2) { verbose_enter(); smsg((char *)e_notopen, fname); verbose_leave(); @@ -610,8 +606,9 @@ spell_load_file ( // Check for .add.spl. lp->sl_add = strstr((char *)path_tail(fname), SPL_FNAME_ADD) != NULL; - } else + } else { lp = old_lp; + } // Set sourcing_name, so that error messages mention the file name. sourcing_name = fname; @@ -620,19 +617,16 @@ spell_load_file ( // <HEADER>: <fileID> const int scms_ret = spell_check_magic_string(fd); switch (scms_ret) { - case SP_FORMERROR: - case SP_TRUNCERROR: { - emsgf("%s", _("E757: This does not look like a spell file")); - goto endFAIL; - } - case SP_OTHERERROR: { - emsgf(_("E5042: Failed to read spell file %s: %s"), - fname, strerror(ferror(fd))); - goto endFAIL; - } - case 0: { - break; - } + case SP_FORMERROR: + case SP_TRUNCERROR: + emsgf("%s", _("E757: This does not look like a spell file")); + goto endFAIL; + case SP_OTHERERROR: + emsgf(_("E5042: Failed to read spell file %s: %s"), + fname, strerror(ferror(fd))); + goto endFAIL; + case 0: + break; } c = getc(fd); // <versionnr> if (c < VIMSPELLVERSION) { @@ -648,19 +642,22 @@ spell_load_file ( // <section>: <sectionID> <sectionflags> <sectionlen> (section contents) for (;; ) { n = getc(fd); // <sectionID> or <sectionend> - if (n == SN_END) + if (n == SN_END) { break; + } c = getc(fd); // <sectionflags> len = get4c(fd); // <sectionlen> - if (len < 0) + if (len < 0) { goto truncerr; + } res = 0; switch (n) { case SN_INFO: lp->sl_info = READ_STRING(fd, len); // <infotext> - if (lp->sl_info == NULL) + if (lp->sl_info == NULL) { goto endFAIL; + } break; case SN_REGION: @@ -673,8 +670,9 @@ spell_load_file ( case SN_MIDWORD: lp->sl_midword = READ_STRING(fd, len); // <midword> - if (lp->sl_midword == NULL) + if (lp->sl_midword == NULL) { goto endFAIL; + } break; case SN_PREFCOND: @@ -699,8 +697,9 @@ spell_load_file ( case SN_MAP: p = READ_STRING(fd, len); // <mapstr> - if (p == NULL) + if (p == NULL) { goto endFAIL; + } set_map_str(lp, p); xfree(p); break; @@ -731,10 +730,12 @@ spell_load_file ( case SN_SYLLABLE: lp->sl_syllable = READ_STRING(fd, len); // <syllable> - if (lp->sl_syllable == NULL) + if (lp->sl_syllable == NULL) { goto endFAIL; - if (init_syl_tab(lp) == FAIL) + } + if (init_syl_tab(lp) == FAIL) { goto endFAIL; + } break; default: @@ -744,9 +745,11 @@ spell_load_file ( EMSG(_("E770: Unsupported section in spell file")); goto endFAIL; } - while (--len >= 0) - if (getc(fd) < 0) + while (--len >= 0) { + if (getc(fd) < 0) { goto truncerr; + } + } break; } someerror: @@ -759,8 +762,9 @@ truncerr: EMSG(_(e_spell_trunc)); goto endFAIL; } - if (res == SP_OTHERERROR) + if (res == SP_OTHERERROR) { goto endFAIL; + } } // <LWORDTREE> @@ -792,16 +796,19 @@ truncerr: goto endOK; endFAIL: - if (lang != NULL) + if (lang != NULL) { // truncating the name signals the error to spell_load_lang() *lang = NUL; - if (lp != NULL && old_lp == NULL) + } + if (lp != NULL && old_lp == NULL) { slang_free(lp); + } lp = NULL; endOK: - if (fd != NULL) + if (fd != NULL) { fclose(fd); + } sourcing_name = save_sourcing_name; sourcing_lnum = save_sourcing_lnum; @@ -827,8 +834,9 @@ static void tree_count_words(char_u *byts, idx_T *idxs) if (curi[depth] > byts[arridx[depth]]) { // Done all bytes at this node, go up one level. idxs[arridx[depth]] = wordcount[depth]; - if (depth > 0) + if (depth > 0) { wordcount[depth - 1] += wordcount[depth]; + } --depth; fast_breakcheck(); @@ -862,10 +870,10 @@ static void tree_count_words(char_u *byts, idx_T *idxs) // Load the .sug files for languages that have one and weren't loaded yet. void suggest_load_files(void) { - langp_T *lp; - slang_T *slang; - char_u *dotp; - FILE *fd; + langp_T *lp; + slang_T *slang; + char_u *dotp; + FILE *fd; char_u buf[MAXWLEN]; int i; time_t timestamp; @@ -895,21 +903,22 @@ void suggest_load_files(void) } // <SUGHEADER>: <fileID> <versionnr> <timestamp> - for (i = 0; i < VIMSUGMAGICL; ++i) + for (i = 0; i < VIMSUGMAGICL; ++i) { buf[i] = getc(fd); // <fileID> + } if (STRNCMP(buf, VIMSUGMAGIC, VIMSUGMAGICL) != 0) { EMSG2(_("E778: This does not look like a .sug file: %s"), - slang->sl_fname); + slang->sl_fname); goto nextone; } c = getc(fd); // <versionnr> if (c < VIMSUGVERSION) { EMSG2(_("E779: Old .sug file, needs to be updated: %s"), - slang->sl_fname); + slang->sl_fname); goto nextone; - } else if (c > VIMSUGVERSION) { + } else if (c > VIMSUGVERSION) { EMSG2(_("E780: .sug file is for newer version of Vim: %s"), - slang->sl_fname); + slang->sl_fname); goto nextone; } @@ -918,7 +927,7 @@ void suggest_load_files(void) timestamp = get8ctime(fd); // <timestamp> if (timestamp != slang->sl_sugtime) { EMSG2(_("E781: .sug file doesn't match .spl file: %s"), - slang->sl_fname); + slang->sl_fname); goto nextone; } @@ -928,7 +937,7 @@ void suggest_load_files(void) false, 0) != 0) { someerror: EMSG2(_("E782: error while reading .sug file: %s"), - slang->sl_fname); + slang->sl_fname); slang_clear_sug(slang); goto nextone; } @@ -942,8 +951,9 @@ someerror: // <sugwcount> wcount = get4c(fd); - if (wcount < 0) + if (wcount < 0) { goto someerror; + } // Read all the wordnr lists into the buffer, one NUL terminated // list per line. @@ -956,8 +966,9 @@ someerror: goto someerror; } GA_APPEND(char_u, &ga, c); - if (c == NUL) + if (c == NUL) { break; + } } if (ml_append_buf(slang->sl_sugbuf, (linenr_T)wordnr, ga.ga_data, ga.ga_len, true) == FAIL) { @@ -972,8 +983,9 @@ someerror: tree_count_words(slang->sl_sbyts, slang->sl_sidxs); nextone: - if (fd != NULL) + if (fd != NULL) { fclose(fd); + } STRCPY(dotp, ".spl"); } } @@ -988,7 +1000,7 @@ nextone: static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp) { int cnt = 0; - char_u *str; + char_u *str; // read the length bytes, MSB first for (int i = 0; i < cnt_bytes; i++) { @@ -1001,12 +1013,13 @@ static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp) cnt = (cnt << 8) + (unsigned)c; } *cntp = cnt; - if (cnt == 0) + if (cnt == 0) { return NULL; // nothing to read, return NULL - + } str = READ_STRING(fd, cnt); - if (str == NULL) + if (str == NULL) { *cntp = SP_OTHERERROR; + } return str; } @@ -1027,14 +1040,15 @@ static int read_region_section(FILE *fd, slang_T *lp, int len) // Return SP_*ERROR flags. static int read_charflags_section(FILE *fd) { - char_u *flags; - char_u *fol; + char_u *flags; + char_u *fol; int flagslen, follen; // <charflagslen> <charflags> flags = read_cnt_string(fd, 1, &flagslen); - if (flagslen < 0) + if (flagslen < 0) { return flagslen; + } // <folcharslen> <folchars> fol = read_cnt_string(fd, 2, &follen); @@ -1044,15 +1058,17 @@ static int read_charflags_section(FILE *fd) } // Set the word-char flags and fill SPELL_ISUPPER() table. - if (flags != NULL && fol != NULL) + if (flags != NULL && fol != NULL) { set_spell_charflags(flags, flagslen, fol); + } xfree(flags); xfree(fol); // When <charflagslen> is zero then <fcharlen> must also be zero. - if ((flags == NULL) != (fol == NULL)) + if ((flags == NULL) != (fol == NULL)) { return SP_FORMERROR; + } return 0; } @@ -1094,11 +1110,12 @@ static int read_prefcond_section(FILE *fd, slang_T *lp) static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first) { int cnt; - fromto_T *ftp; + fromto_T *ftp; cnt = get2c(fd); // <repcount> - if (cnt < 0) + if (cnt < 0) { return SP_TRUNCERROR; + } ga_grow(gap, cnt); @@ -1107,15 +1124,18 @@ static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first) int c; ftp = &((fromto_T *)gap->ga_data)[gap->ga_len]; ftp->ft_from = read_cnt_string(fd, 1, &c); - if (c < 0) + if (c < 0) { return c; - if (c == 0) + } + if (c == 0) { return SP_FORMERROR; + } ftp->ft_to = read_cnt_string(fd, 1, &c); if (c <= 0) { xfree(ftp->ft_from); - if (c < 0) + if (c < 0) { return c; + } return SP_FORMERROR; } } @@ -1126,8 +1146,9 @@ static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first) } for (int i = 0; i < gap->ga_len; ++i) { ftp = &((fromto_T *)gap->ga_data)[i]; - if (first[*ftp->ft_from] == -1) + if (first[*ftp->ft_from] == -1) { first[*ftp->ft_from] = i; + } } return 0; } @@ -1137,10 +1158,10 @@ static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first) static int read_sal_section(FILE *fd, slang_T *slang) { int cnt; - garray_T *gap; - salitem_T *smp; + garray_T *gap; + salitem_T *smp; int ccnt; - char_u *p; + char_u *p; slang->sl_sofo = false; @@ -1156,8 +1177,9 @@ static int read_sal_section(FILE *fd, slang_T *slang) } cnt = get2c(fd); // <salcount> - if (cnt < 0) + if (cnt < 0) { return SP_TRUNCERROR; + } gap = &slang->sl_sal; ga_init(gap, sizeof(salitem_T), 10); @@ -1169,8 +1191,9 @@ static int read_sal_section(FILE *fd, slang_T *slang) smp = &((salitem_T *)gap->ga_data)[gap->ga_len]; ccnt = getc(fd); // <salfromlen> - if (ccnt < 0) + if (ccnt < 0) { return SP_TRUNCERROR; + } p = xmalloc(ccnt + 2); smp->sm_lead = p; @@ -1178,8 +1201,9 @@ static int read_sal_section(FILE *fd, slang_T *slang) int i = 0; for (; i < ccnt; ++i) { c = getc(fd); // <salfrom> - if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL) + if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL) { break; + } *p++ = c; } smp->sm_leadlen = (int)(p - smp->sm_lead); @@ -1190,15 +1214,18 @@ static int read_sal_section(FILE *fd, slang_T *slang) smp->sm_oneof = p; for (++i; i < ccnt; ++i) { c = getc(fd); // <salfrom> - if (c == ')') + if (c == ')') { break; + } *p++ = c; } *p++ = NUL; - if (++i < ccnt) + if (++i < ccnt) { c = getc(fd); - } else + } + } else { smp->sm_oneof = NULL; + } // Any following chars go in sm_rules. smp->sm_rules = p; @@ -1209,7 +1236,8 @@ static int read_sal_section(FILE *fd, slang_T *slang) i++; if (i < ccnt) { SPELL_READ_NONNUL_BYTES( // <salfrom> - (char *)p, (size_t)(ccnt - i), fd, xfree(smp->sm_lead)); + (char *)p, (size_t)(ccnt - i), fd, + xfree(smp->sm_lead)); p += (ccnt - i); } *p++ = NUL; @@ -1272,13 +1300,16 @@ static int read_words_section(FILE *fd, slang_T *lp, int len) // Read one word at a time. for (i = 0;; ++i) { c = getc(fd); - if (c == EOF) + if (c == EOF) { return SP_TRUNCERROR; + } word[i] = c; - if (word[i] == NUL) + if (word[i] == NUL) { break; - if (i == MAXWLEN - 1) + } + if (i == MAXWLEN - 1) { return SP_FORMERROR; + } } // Init the count to 10. @@ -1293,15 +1324,16 @@ static int read_words_section(FILE *fd, slang_T *lp, int len) static int read_sofo_section(FILE *fd, slang_T *slang) { int cnt; - char_u *from, *to; + char_u *from, *to; int res; slang->sl_sofo = true; // <sofofromlen> <sofofrom> from = read_cnt_string(fd, 2, &cnt); - if (cnt < 0) + if (cnt < 0) { return cnt; + } // <sofotolen> <sofoto> to = read_cnt_string(fd, 2, &cnt); @@ -1311,12 +1343,13 @@ static int read_sofo_section(FILE *fd, slang_T *slang) } // Store the info in slang->sl_sal and/or slang->sl_sal_first. - if (from != NULL && to != NULL) + if (from != NULL && to != NULL) { res = set_sofo(slang, from, to); - else if (from != NULL || to != NULL) + } else if (from != NULL || to != NULL) { res = SP_FORMERROR; // only one of two strings is an error - else + } else { res = 0; + } xfree(from); xfree(to); @@ -1331,39 +1364,42 @@ static int read_compound(FILE *fd, slang_T *slang, int len) int todo = len; int c; int atstart; - char_u *pat; - char_u *pp; - char_u *cp; - char_u *ap; - char_u *crp; + char_u *pat; + char_u *pp; + char_u *cp; + char_u *ap; + char_u *crp; int cnt; - garray_T *gap; + garray_T *gap; - if (todo < 2) + if (todo < 2) { return SP_FORMERROR; // need at least two bytes - + } --todo; c = getc(fd); // <compmax> - if (c < 2) + if (c < 2) { c = MAXWLEN; + } slang->sl_compmax = c; --todo; c = getc(fd); // <compminlen> - if (c < 1) + if (c < 1) { c = 0; + } slang->sl_compminlen = c; --todo; c = getc(fd); // <compsylmax> - if (c < 1) + if (c < 1) { c = MAXWLEN; + } slang->sl_compsylmax = c; c = getc(fd); // <compoptions> - if (c != 0) + if (c != 0) { ungetc(c, fd); // be backwards compatible with Vim 7.0b - else { + } else { --todo; c = getc(fd); // only use the lower byte for now --todo; @@ -1381,13 +1417,15 @@ static int read_compound(FILE *fd, slang_T *slang, int len) ((char_u **)(gap->ga_data))[gap->ga_len++] = read_cnt_string(fd, 1, &cnt); // <comppatlen> <comppattext> - if (cnt < 0) + if (cnt < 0) { return cnt; + } todo -= cnt + 1; } } - if (todo < 0) + if (todo < 0) { return SP_FORMERROR; + } // Turn the COMPOUNDRULE items into a regexp pattern: // "a[bc]/a*b+" -> "^\(a[bc]\|a*b\+\)$". @@ -1436,17 +1474,18 @@ static int read_compound(FILE *fd, slang_T *slang, int len) if (atstart != 0) { // At start of item: copy flags to "sl_compstartflags". For a // [abc] item set "atstart" to 2 and copy up to the ']'. - if (c == '[') + if (c == '[') { atstart = 2; - else if (c == ']') + } else if (c == ']') { atstart = 0; - else { + } else { if (!byte_in_str(slang->sl_compstartflags, c)) { *cp++ = c; *cp = NUL; } - if (atstart == 1) + if (atstart == 1) { atstart = 0; + } } } @@ -1455,8 +1494,9 @@ static int read_compound(FILE *fd, slang_T *slang, int len) if (c == '?' || c == '+' || c == '*') { XFREE_CLEAR(slang->sl_comprules); crp = NULL; - } else + } else { *crp++ = c; + } } if (c == '/') { // slash separates two items @@ -1476,13 +1516,15 @@ static int read_compound(FILE *fd, slang_T *slang, int len) *pp++ = '$'; *pp = NUL; - if (crp != NULL) + if (crp != NULL) { *crp = NUL; + } slang->sl_compprog = vim_regcomp(pat, RE_MAGIC + RE_STRING + RE_STRICT); xfree(pat); - if (slang->sl_compprog == NULL) + if (slang->sl_compprog == NULL) { return SP_FORMERROR; + } return 0; } @@ -1491,8 +1533,8 @@ static int read_compound(FILE *fd, slang_T *slang, int len) // Returns SP_*ERROR flags when there is something wrong. static int set_sofo(slang_T *lp, char_u *from, char_u *to) { - char_u *s; - char_u *p; + char_u *s; + char_u *p; // Use "sl_sal" as an array with 256 pointers to a list of wide // characters. The index is the low byte of the character. @@ -1554,10 +1596,10 @@ static int set_sofo(slang_T *lp, char_u *from, char_u *to) // Fill the first-index table for "lp". static void set_sal_first(slang_T *lp) { - salfirst_T *sfirst; - salitem_T *smp; + salfirst_T *sfirst; + salitem_T *smp; int c; - garray_T *gap = &lp->sl_sal; + garray_T *gap = &lp->sl_sal; sfirst = lp->sl_sal_first; for (int i = 0; i < 256; ++i) { @@ -1613,24 +1655,21 @@ static int *mb_str2wide(char_u *s) return res; } -// Reads a tree from the .spl or .sug file. -// Allocates the memory and stores pointers in "bytsp" and "idxsp". -// This is skipped when the tree has zero length. -// Returns zero when OK, SP_ value for an error. -static int -spell_read_tree ( - FILE *fd, - char_u **bytsp, - long *bytsp_len, - idx_T **idxsp, - bool prefixtree, // true for the prefix tree - int prefixcnt // when "prefixtree" is true: prefix count -) +/// Reads a tree from the .spl or .sug file. +/// Allocates the memory and stores pointers in "bytsp" and "idxsp". +/// This is skipped when the tree has zero length. +/// +/// @param prefixtree true for the prefix tree +/// @param prefixcnt when "prefixtree" is true: prefix count +/// +/// @return zero when OK, SP_ value for an error. +static int spell_read_tree(FILE *fd, char_u **bytsp, long *bytsp_len, idx_T **idxsp, + bool prefixtree, int prefixcnt) FUNC_ATTR_NONNULL_ARG(1, 2, 4) { int idx; - char_u *bp; - idx_T *ip; + char_u *bp; + idx_T *ip; // The tree size was computed when writing the file, so that we can // allocate it as one long block. <nodecount> @@ -1656,30 +1695,28 @@ spell_read_tree ( // Recursively read the tree and store it in the array. idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt); - if (idx < 0) + if (idx < 0) { return idx; + } } return 0; } -// Read one row of siblings from the spell file and store it in the byte array -// "byts" and index array "idxs". Recursively read the children. -// -// NOTE: The code here must match put_node()! -// -// Returns the index (>= 0) following the siblings. -// Returns SP_TRUNCERROR if the file is shorter than expected. -// Returns SP_FORMERROR if there is a format error. -static idx_T -read_tree_node ( - FILE *fd, - char_u *byts, - idx_T *idxs, - int maxidx, // size of arrays - idx_T startidx, // current index in "byts" and "idxs" - bool prefixtree, // true for reading PREFIXTREE - int maxprefcondnr // maximum for <prefcondnr> -) +/// Read one row of siblings from the spell file and store it in the byte array +/// "byts" and index array "idxs". Recursively read the children. +/// +/// NOTE: The code here must match put_node()! +/// +/// Returns the index (>= 0) following the siblings. +/// Returns SP_TRUNCERROR if the file is shorter than expected. +/// Returns SP_FORMERROR if there is a format error. +/// +/// @param maxidx size of arrays +/// @param startidx current index in "byts" and "idxs" +/// @param prefixtree true for reading PREFIXTREE +/// @param maxprefcondnr maximum for <prefcondnr> +static idx_T read_tree_node(FILE *fd, char_u *byts, idx_T *idxs, int maxidx, idx_T startidx, + bool prefixtree, int maxprefcondnr) { int len; int i; @@ -1690,18 +1727,21 @@ read_tree_node ( #define SHARED_MASK 0x8000000 len = getc(fd); // <siblingcount> - if (len <= 0) + if (len <= 0) { return SP_TRUNCERROR; + } - if (startidx + len >= maxidx) + if (startidx + len >= maxidx) { return SP_FORMERROR; + } byts[idx++] = len; // Read the byte values, flag/region bytes and shared indexes. for (i = 1; i <= len; ++i) { c = getc(fd); // <byte> - if (c < 0) + if (c < 0) { return SP_TRUNCERROR; + } if (c <= BY_SPECIAL) { if (c == BY_NOFLAGS && !prefixtree) { // No flags, all regions. @@ -1712,16 +1752,18 @@ read_tree_node ( // condition nr. In idxs[] store the prefix ID in the low // byte, the condition index shifted up 8 bits, the flags // shifted up 24 bits. - if (c == BY_FLAGS) + if (c == BY_FLAGS) { c = getc(fd) << 24; // <pflags> - else + } else { c = 0; + } c |= getc(fd); // <affixID> n = get2c(fd); // <prefcondnr> - if (n >= maxprefcondnr) + if (n >= maxprefcondnr) { return SP_FORMERROR; + } c |= (n << 8); } else { // c must be BY_FLAGS or BY_FLAGS2 // Read flags and optional region and prefix ID. In @@ -1729,21 +1771,25 @@ read_tree_node ( // that and prefix ID above the region. c2 = c; c = getc(fd); // <flags> - if (c2 == BY_FLAGS2) + if (c2 == BY_FLAGS2) { c = (getc(fd) << 8) + c; // <flags2> - if (c & WF_REGION) + } + if (c & WF_REGION) { c = (getc(fd) << 16) + c; // <region> - if (c & WF_AFX) + } + if (c & WF_AFX) { c = (getc(fd) << 24) + c; // <affixID> + } } idxs[idx] = c; c = 0; - } else { // c == BY_INDEX + } else { // c == BY_INDEX // <nodeidx> n = get3c(fd); - if (n < 0 || n >= maxidx) + if (n < 0 || n >= maxidx) { return SP_FORMERROR; + } idxs[idx] = n + SHARED_MASK; c = getc(fd); // <xbyte> } @@ -1754,38 +1800,39 @@ read_tree_node ( // Recursively read the children for non-shared siblings. // Skip the end-of-word ones (zero byte value) and the shared ones (and // remove SHARED_MASK) - for (i = 1; i <= len; ++i) + for (i = 1; i <= len; ++i) { if (byts[startidx + i] != 0) { - if (idxs[startidx + i] & SHARED_MASK) + if (idxs[startidx + i] & SHARED_MASK) { idxs[startidx + i] &= ~SHARED_MASK; - else { + } else { idxs[startidx + i] = idx; idx = read_tree_node(fd, byts, idxs, maxidx, idx, - prefixtree, maxprefcondnr); - if (idx < 0) + prefixtree, maxprefcondnr); + if (idx < 0) { break; + } } } + } return idx; } -// Reload the spell file "fname" if it's loaded. -static void -spell_reload_one ( - char_u *fname, - bool added_word // invoked through "zg" -) +/// Reload the spell file "fname" if it's loaded. +/// +/// @param added_word invoked through "zg" +static void spell_reload_one(char_u *fname, bool added_word) { - slang_T *slang; + slang_T *slang; bool didit = false; for (slang = first_lang; slang != NULL; slang = slang->sl_next) { if (path_full_compare(fname, slang->sl_fname, false, true) == kEqualFiles) { slang_clear(slang); - if (spell_load_file(fname, NULL, slang, false) == NULL) + if (spell_load_file(fname, NULL, slang, false) == NULL) { // reloading failed, clear the language slang_clear(slang); + } redraw_all_later(SOME_VALID); didit = true; } @@ -1793,8 +1840,9 @@ spell_reload_one ( // When "zg" was used and the file wasn't loaded yet, should redo // 'spelllang' to load it now. - if (added_word && !didit) + if (added_word && !didit) { did_set_spelllang(curwin); + } } // Functions for ":mkspell". @@ -1820,13 +1868,14 @@ static long compress_added = 500000; // word count // Sets "sps_flags". int spell_check_msm(void) { - char_u *p = p_msm; + char_u *p = p_msm; long start = 0; long incr = 0; long added = 0; - if (!ascii_isdigit(*p)) + if (!ascii_isdigit(*p)) { return FAIL; + } // block count = (value * 1024) / SBLOCKSIZE (but avoid overflow) start = (getdigits_long(&p, true, 0) * 10) / (SBLOCKSIZE / 102); if (*p != ',') { @@ -1864,11 +1913,12 @@ int spell_check_msm(void) // readable format, so that we can see what happens when adding a word and/or // compressing the tree. // Based on code from Olaf Seibert. -#define PRINTLINESIZE 1000 -#define PRINTWIDTH 6 +# define PRINTLINESIZE 1000 +# define PRINTWIDTH 6 -#define PRINTSOME(l, depth, fmt, a1, a2) vim_snprintf(l + depth * PRINTWIDTH, \ - PRINTLINESIZE - PRINTWIDTH * depth, fmt, a1, a2) +# define PRINTSOME(l, depth, fmt, a1, a2) vim_snprintf(l + depth * PRINTWIDTH, \ + PRINTLINESIZE - PRINTWIDTH * depth, fmt, a1, \ + a2) static char line1[PRINTLINESIZE]; static char line2[PRINTLINESIZE]; @@ -1876,7 +1926,7 @@ static char line3[PRINTLINESIZE]; static void spell_clear_flags(wordnode_T *node) { - wordnode_T *np; + wordnode_T *np; for (np = node; np != NULL; np = np->wn_sibling) { np->wn_u1.index = FALSE; @@ -1898,20 +1948,23 @@ static void spell_print_node(wordnode_T *node, int depth) node->wn_u1.index = TRUE; if (node->wn_byte != NUL) { - if (node->wn_child != NULL) + if (node->wn_child != NULL) { PRINTSOME(line1, depth, " %c -> ", node->wn_byte, 0); - else + } else { // Cannot happen? PRINTSOME(line1, depth, " %c ???", node->wn_byte, 0); - } else + } + } else { PRINTSOME(line1, depth, " $ ", 0, 0); + } PRINTSOME(line2, depth, "%d/%d ", node->wn_nr, node->wn_refs); - if (node->wn_sibling != NULL) + if (node->wn_sibling != NULL) { PRINTSOME(line3, depth, " | ", 0, 0); - else + } else { PRINTSOME(line3, depth, " ", 0, 0); + } if (node->wn_byte == NUL) { msg((char_u *)line1); @@ -1920,8 +1973,9 @@ static void spell_print_node(wordnode_T *node, int depth) } // do the children - if (node->wn_byte != NUL && node->wn_child != NULL) + if (node->wn_byte != NUL && node->wn_child != NULL) { spell_print_node(node->wn_child, depth + 1); + } // do the siblings if (node->wn_sibling != NULL) { @@ -1951,39 +2005,39 @@ static void spell_print_tree(wordnode_T *root) // Returns an afffile_T, NULL for complete failure. static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) { - FILE *fd; + FILE *fd; char_u rline[MAXLINELEN]; - char_u *line; - char_u *pc = NULL; + char_u *line; + char_u *pc = NULL; #define MAXITEMCNT 30 - char_u *(items[MAXITEMCNT]); + char_u *(items[MAXITEMCNT]); int itemcnt; - char_u *p; + char_u *p; int lnum = 0; affheader_T *cur_aff = NULL; bool did_postpone_prefix = false; int aff_todo = 0; - hashtab_T *tp; - char_u *low = NULL; - char_u *fol = NULL; - char_u *upp = NULL; + hashtab_T *tp; + char_u *low = NULL; + char_u *fol = NULL; + char_u *upp = NULL; int do_rep; int do_repsal; int do_sal; int do_mapline; bool found_map = false; - hashitem_T *hi; + hashitem_T *hi; int l; int compminlen = 0; // COMPOUNDMIN value int compsylmax = 0; // COMPOUNDSYLMAX value int compoptions = 0; // COMP_ flags int compmax = 0; // COMPOUNDWORDMAX value - char_u *compflags = NULL; // COMPOUNDFLAG and COMPOUNDRULE - // concatenated - char_u *midword = NULL; // MIDWORD value - char_u *syllable = NULL; // SYLLABLE value - char_u *sofofrom = NULL; // SOFOFROM value - char_u *sofoto = NULL; // SOFOTO value + char_u *compflags = NULL; // COMPOUNDFLAG and COMPOUNDRULE + // concatenated + char_u *midword = NULL; // MIDWORD value + char_u *syllable = NULL; // SYLLABLE value + char_u *sofofrom = NULL; // SOFOFROM value + char_u *sofoto = NULL; // SOFOTO value // Open the file. fd = os_fopen((char *)fname, "r"); @@ -2019,8 +2073,9 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) ++lnum; // Skip comment lines. - if (*rline == '#') + if (*rline == '#') { continue; + } // Convert from "SET" to 'encoding' when needed. xfree(pc); @@ -2041,22 +2096,29 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) // item. itemcnt = 0; for (p = line;; ) { - while (*p != NUL && *p <= ' ') // skip white space and CR/NL + while (*p != NUL && *p <= ' ') { // skip white space and CR/NL ++p; - if (*p == NUL) + } + if (*p == NUL) { break; - if (itemcnt == MAXITEMCNT) // too many items + } + if (itemcnt == MAXITEMCNT) { // too many items break; + } items[itemcnt++] = p; // A few items have arbitrary text argument, don't split them. - if (itemcnt == 2 && spell_info_item(items[0])) - while (*p >= ' ' || *p == TAB) // skip until CR/NL + if (itemcnt == 2 && spell_info_item(items[0])) { + while (*p >= ' ' || *p == TAB) { // skip until CR/NL ++p; - else - while (*p > ' ') // skip until white space or CR/NL + } + } else { + while (*p > ' ') { // skip until white space or CR/NL ++p; - if (*p == NUL) + } + } + if (*p == NUL) { break; + } *p++ = NUL; } @@ -2067,21 +2129,23 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) aff->af_enc = enc_canonize(items[1]); if (!spin->si_ascii && convert_setup(&spin->si_conv, aff->af_enc, - p_enc) == FAIL) + p_enc) == FAIL) { smsg(_("Conversion in %s not supported: from %s to %s"), fname, aff->af_enc, p_enc); + } spin->si_conv.vc_fail = true; } else if (is_aff_rule(items, itemcnt, "FLAG", 2) && aff->af_flagtype == AFT_CHAR) { - if (STRCMP(items[1], "long") == 0) + if (STRCMP(items[1], "long") == 0) { aff->af_flagtype = AFT_LONG; - else if (STRCMP(items[1], "num") == 0) + } else if (STRCMP(items[1], "num") == 0) { aff->af_flagtype = AFT_NUM; - else if (STRCMP(items[1], "caplong") == 0) + } else if (STRCMP(items[1], "caplong") == 0) { aff->af_flagtype = AFT_CAPLONG; - else + } else { smsg(_("Invalid value for FLAG in %s line %d: %s"), fname, lnum, items[1]); + } if (aff->af_rare != 0 || aff->af_keepcase != 0 || aff->af_bad != 0 @@ -2092,10 +2156,11 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) || aff->af_nosuggest != 0 || compflags != NULL || aff->af_suff.ht_used > 0 - || aff->af_pref.ht_used > 0) + || aff->af_pref.ht_used > 0) { smsg(_("FLAG after using flags in %s line %d: %s"), fname, lnum, items[1]); - } else if (spell_info_item(items[0]) && itemcnt > 1) { + } + } else if (spell_info_item(items[0]) && itemcnt > 1) { p = getroom(spin, (spin->si_info == NULL ? 0 : STRLEN(spin->si_info)) + STRLEN(items[0]) @@ -2111,7 +2176,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) } else if (is_aff_rule(items, itemcnt, "MIDWORD", 2) && midword == NULL) { midword = getroom_save(spin, items[1]); - } else if (is_aff_rule(items, itemcnt, "TRY", 2)) { + } else if (is_aff_rule(items, itemcnt, "TRY", 2)) { // ignored, we look in the tree for what chars may appear } // TODO: remove "RAR" later @@ -2119,54 +2184,56 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) || is_aff_rule(items, itemcnt, "RARE", 2)) && aff->af_rare == 0) { aff->af_rare = affitem2flag(aff->af_flagtype, items[1], - fname, lnum); + fname, lnum); } // TODO: remove "KEP" later else if ((is_aff_rule(items, itemcnt, "KEP", 2) || is_aff_rule(items, itemcnt, "KEEPCASE", 2)) && aff->af_keepcase == 0) { aff->af_keepcase = affitem2flag(aff->af_flagtype, items[1], - fname, lnum); + fname, lnum); } else if ((is_aff_rule(items, itemcnt, "BAD", 2) || is_aff_rule(items, itemcnt, "FORBIDDENWORD", 2)) && aff->af_bad == 0) { aff->af_bad = affitem2flag(aff->af_flagtype, items[1], - fname, lnum); + fname, lnum); } else if (is_aff_rule(items, itemcnt, "NEEDAFFIX", 2) && aff->af_needaffix == 0) { aff->af_needaffix = affitem2flag(aff->af_flagtype, items[1], - fname, lnum); + fname, lnum); } else if (is_aff_rule(items, itemcnt, "CIRCUMFIX", 2) && aff->af_circumfix == 0) { aff->af_circumfix = affitem2flag(aff->af_flagtype, items[1], - fname, lnum); + fname, lnum); } else if (is_aff_rule(items, itemcnt, "NOSUGGEST", 2) && aff->af_nosuggest == 0) { aff->af_nosuggest = affitem2flag(aff->af_flagtype, items[1], - fname, lnum); + fname, lnum); } else if ((is_aff_rule(items, itemcnt, "NEEDCOMPOUND", 2) || is_aff_rule(items, itemcnt, "ONLYINCOMPOUND", 2)) && aff->af_needcomp == 0) { aff->af_needcomp = affitem2flag(aff->af_flagtype, items[1], - fname, lnum); + fname, lnum); } else if (is_aff_rule(items, itemcnt, "COMPOUNDROOT", 2) && aff->af_comproot == 0) { aff->af_comproot = affitem2flag(aff->af_flagtype, items[1], - fname, lnum); + fname, lnum); } else if (is_aff_rule(items, itemcnt, "COMPOUNDFORBIDFLAG", 2) && aff->af_compforbid == 0) { aff->af_compforbid = affitem2flag(aff->af_flagtype, items[1], - fname, lnum); - if (aff->af_pref.ht_used > 0) + fname, lnum); + if (aff->af_pref.ht_used > 0) { smsg(_("Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line %d"), fname, lnum); + } } else if (is_aff_rule(items, itemcnt, "COMPOUNDPERMITFLAG", 2) && aff->af_comppermit == 0) { aff->af_comppermit = affitem2flag(aff->af_flagtype, items[1], - fname, lnum); - if (aff->af_pref.ht_used > 0) + fname, lnum); + if (aff->af_pref.ht_used > 0) { smsg(_("Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line %d"), fname, lnum); + } } else if (is_aff_rule(items, itemcnt, "COMPOUNDFLAG", 2) && compflags == NULL) { // Turn flag "c" into COMPOUNDRULE compatible string "c+", @@ -2175,20 +2242,22 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) STRCPY(p, items[1]); STRCAT(p, "+"); compflags = p; - } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) { + } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) { // We don't use the count, but do check that it's a number and // not COMPOUNDRULE mistyped. - if (atoi((char *)items[1]) == 0) + if (atoi((char *)items[1]) == 0) { smsg(_("Wrong COMPOUNDRULES value in %s line %d: %s"), fname, lnum, items[1]); - } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) { + } + } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) { // Don't use the first rule if it is a number. if (compflags != NULL || *skipdigits(items[1]) != NUL) { // Concatenate this string to previously defined ones, // using a slash to separate them. l = (int)STRLEN(items[1]) + 1; - if (compflags != NULL) + if (compflags != NULL) { l += (int)STRLEN(compflags) + 1; + } p = getroom(spin, l, false); if (compflags != NULL) { STRCPY(p, compflags); @@ -2200,43 +2269,49 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) } else if (is_aff_rule(items, itemcnt, "COMPOUNDWORDMAX", 2) && compmax == 0) { compmax = atoi((char *)items[1]); - if (compmax == 0) + if (compmax == 0) { smsg(_("Wrong COMPOUNDWORDMAX value in %s line %d: %s"), fname, lnum, items[1]); + } } else if (is_aff_rule(items, itemcnt, "COMPOUNDMIN", 2) && compminlen == 0) { compminlen = atoi((char *)items[1]); - if (compminlen == 0) + if (compminlen == 0) { smsg(_("Wrong COMPOUNDMIN value in %s line %d: %s"), fname, lnum, items[1]); + } } else if (is_aff_rule(items, itemcnt, "COMPOUNDSYLMAX", 2) && compsylmax == 0) { compsylmax = atoi((char *)items[1]); - if (compsylmax == 0) + if (compsylmax == 0) { smsg(_("Wrong COMPOUNDSYLMAX value in %s line %d: %s"), fname, lnum, items[1]); - } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDDUP", 1)) { + } + } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDDUP", 1)) { compoptions |= COMP_CHECKDUP; - } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDREP", 1)) { + } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDREP", 1)) { compoptions |= COMP_CHECKREP; - } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDCASE", 1)) { + } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDCASE", 1)) { compoptions |= COMP_CHECKCASE; - } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDTRIPLE", 1)) { + } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDTRIPLE", 1)) { compoptions |= COMP_CHECKTRIPLE; - } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 2)) { - if (atoi((char *)items[1]) == 0) + } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 2)) { + if (atoi((char *)items[1]) == 0) { smsg(_("Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"), fname, lnum, items[1]); - } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 3)) { - garray_T *gap = &spin->si_comppat; + } + } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 3)) { + garray_T *gap = &spin->si_comppat; int i; // Only add the couple if it isn't already there. - for (i = 0; i < gap->ga_len - 1; i += 2) + for (i = 0; i < gap->ga_len - 1; i += 2) { if (STRCMP(((char_u **)(gap->ga_data))[i], items[1]) == 0 && STRCMP(((char_u **)(gap->ga_data))[i + 1], - items[2]) == 0) + items[2]) == 0) { break; + } + } if (i >= gap->ga_len) { ga_grow(gap, 2); ((char_u **)(gap->ga_data))[gap->ga_len++] @@ -2247,15 +2322,15 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) } else if (is_aff_rule(items, itemcnt, "SYLLABLE", 2) && syllable == NULL) { syllable = getroom_save(spin, items[1]); - } else if (is_aff_rule(items, itemcnt, "NOBREAK", 1)) { + } else if (is_aff_rule(items, itemcnt, "NOBREAK", 1)) { spin->si_nobreak = true; - } else if (is_aff_rule(items, itemcnt, "NOSPLITSUGS", 1)) { + } else if (is_aff_rule(items, itemcnt, "NOSPLITSUGS", 1)) { spin->si_nosplitsugs = true; } else if (is_aff_rule(items, itemcnt, "NOCOMPOUNDSUGS", 1)) { spin->si_nocompoundsugs = true; - } else if (is_aff_rule(items, itemcnt, "NOSUGFILE", 1)) { + } else if (is_aff_rule(items, itemcnt, "NOSUGFILE", 1)) { spin->si_nosugfile = true; - } else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1)) { + } else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1)) { aff->af_pfxpostpone = true; } else if (is_aff_rule(items, itemcnt, "IGNOREEXTRA", 1)) { aff->af_ignoreextra = true; @@ -2266,10 +2341,11 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) int lasti = 4; char_u key[AH_KEY_LEN]; - if (*items[0] == 'P') + if (*items[0] == 'P') { tp = &aff->af_pref; - else + } else { tp = &aff->af_suff; + } // Myspell allows the same affix name to be used multiple // times. The affix files that do this have an undocumented @@ -2279,12 +2355,14 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) hi = hash_find(tp, key); if (!HASHITEM_EMPTY(hi)) { cur_aff = HI2AH(hi); - if (cur_aff->ah_combine != (*items[2] == 'Y')) + if (cur_aff->ah_combine != (*items[2] == 'Y')) { smsg(_("Different combining flag in continued affix block in %s line %d: %s"), fname, lnum, items[1]); - if (!cur_aff->ah_follows) + } + if (!cur_aff->ah_follows) { smsg(_("Duplicate affix in %s line %d: %s"), fname, lnum, items[1]); + } } else { // New affix letter. cur_aff = getroom(spin, sizeof(*cur_aff), true); @@ -2317,20 +2395,23 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) if (itemcnt > lasti && STRCMP(items[lasti], "S") == 0) { ++lasti; cur_aff->ah_follows = true; - } else + } else { cur_aff->ah_follows = false; + } // Myspell allows extra text after the item, but that might // mean mistakes go unnoticed. Require a comment-starter, // unless IGNOREEXTRA is used. Hunspell uses a "-" item. if (itemcnt > lasti && !aff->af_ignoreextra - && *items[lasti] != '#') + && *items[lasti] != '#') { smsg(_(e_afftrailing), fname, lnum, items[lasti]); + } - if (STRCMP(items[2], "Y") != 0 && STRCMP(items[2], "N") != 0) + if (STRCMP(items[2], "Y") != 0 && STRCMP(items[2], "N") != 0) { smsg(_("Expected Y or N in %s line %d: %s"), - fname, lnum, items[2]); + fname, lnum, items[2]); + } if (*items[0] == 'P' && aff->af_pfxpostpone) { if (cur_aff->ah_newID == 0) { @@ -2343,9 +2424,10 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) // postponed. We know that only after handling all // the items. did_postpone_prefix = false; - } else + } else { // Did use the ID in a previous block. did_postpone_prefix = true; + } } aff_todo = atoi((char *)items[3]); @@ -2354,7 +2436,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) && aff_todo > 0 && STRCMP(cur_aff->ah_key, items[1]) == 0 && itemcnt >= 5) { - affentry_T *aff_entry; + affentry_T *aff_entry; bool upper = false; int lasti = 5; @@ -2363,15 +2445,17 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) // Hunspell uses a "-" item. if (itemcnt > lasti && *items[lasti] != '#' && (STRCMP(items[lasti], "-") != 0 - || itemcnt != lasti + 1)) + || itemcnt != lasti + 1)) { smsg(_(e_afftrailing), fname, lnum, items[lasti]); + } // New item for an affix letter. aff_todo--; aff_entry = getroom(spin, sizeof(*aff_entry), true); - if (STRCMP(items[2], "0") != 0) + if (STRCMP(items[2], "0") != 0) { aff_entry->ae_chop = getroom_save(spin, items[2]); + } if (STRCMP(items[3], "0") != 0) { aff_entry->ae_add = getroom_save(spin, items[3]); @@ -2394,15 +2478,17 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) char_u buf[MAXLINELEN]; aff_entry->ae_cond = getroom_save(spin, items[4]); - if (*items[0] == 'P') + if (*items[0] == 'P') { sprintf((char *)buf, "^%s", items[4]); - else + } else { sprintf((char *)buf, "%s$", items[4]); + } aff_entry->ae_prog = vim_regcomp(buf, - RE_MAGIC + RE_STRING + RE_STRICT); - if (aff_entry->ae_prog == NULL) + RE_MAGIC + RE_STRING + RE_STRICT); + if (aff_entry->ae_prog == NULL) { smsg(_("Broken condition in %s line %d: %s"), fname, lnum, items[4]); + } } // For postponed prefixes we need an entry in si_prefcond @@ -2418,9 +2504,8 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) // be empty or start with the same letter. if (aff_entry->ae_chop != NULL && aff_entry->ae_add != NULL - && aff_entry->ae_chop[(*mb_ptr2len)( - aff_entry->ae_chop)] == NUL - ) { + && aff_entry->ae_chop[(*mb_ptr2len)(aff_entry->ae_chop)] == + NUL) { int c, c_up; c = PTR2CHAR(aff_entry->ae_chop); @@ -2445,10 +2530,9 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) aff_entry->ae_cond = getroom_save(spin, buf); if (aff_entry->ae_cond != NULL) { sprintf((char *)buf, "^%s", - aff_entry->ae_cond); + aff_entry->ae_cond); vim_regfree(aff_entry->ae_prog); - aff_entry->ae_prog = vim_regcomp( - buf, RE_MAGIC + RE_STRING); + aff_entry->ae_prog = vim_regcomp(buf, RE_MAGIC + RE_STRING); } } } @@ -2457,43 +2541,49 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) if (aff_entry->ae_chop == NULL) { int idx; - char_u **pp; + char_u **pp; int n; // Find a previously used condition. for (idx = spin->si_prefcond.ga_len - 1; idx >= 0; --idx) { p = ((char_u **)spin->si_prefcond.ga_data)[idx]; - if (str_equal(p, aff_entry->ae_cond)) + if (str_equal(p, aff_entry->ae_cond)) { break; + } } if (idx < 0) { // Not found, add a new condition. idx = spin->si_prefcond.ga_len; pp = GA_APPEND_VIA_PTR(char_u *, &spin->si_prefcond); *pp = (aff_entry->ae_cond == NULL) ? - NULL : getroom_save(spin, aff_entry->ae_cond); + NULL : getroom_save(spin, aff_entry->ae_cond); } // Add the prefix to the prefix tree. - if (aff_entry->ae_add == NULL) + if (aff_entry->ae_add == NULL) { p = (char_u *)""; - else + } else { p = aff_entry->ae_add; + } // PFX_FLAGS is a negative number, so that // tree_add_word() knows this is the prefix tree. n = PFX_FLAGS; - if (!cur_aff->ah_combine) + if (!cur_aff->ah_combine) { n |= WFP_NC; - if (upper) + } + if (upper) { n |= WFP_UP; - if (aff_entry->ae_comppermit) + } + if (aff_entry->ae_comppermit) { n |= WFP_COMPPERMIT; - if (aff_entry->ae_compforbid) + } + if (aff_entry->ae_compforbid) { n |= WFP_COMPFORBID; + } tree_add_word(spin, p, spin->si_prefroot, n, - idx, cur_aff->ah_newID); + idx, cur_aff->ah_newID); did_postpone_prefix = true; } @@ -2504,26 +2594,28 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) } } } - } else if (is_aff_rule(items, itemcnt, "FOL", 2) && fol == NULL) { + } else if (is_aff_rule(items, itemcnt, "FOL", 2) && fol == NULL) { fol = vim_strsave(items[1]); - } else if (is_aff_rule(items, itemcnt, "LOW", 2) && low == NULL) { + } else if (is_aff_rule(items, itemcnt, "LOW", 2) && low == NULL) { low = vim_strsave(items[1]); - } else if (is_aff_rule(items, itemcnt, "UPP", 2) && upp == NULL) { + } else if (is_aff_rule(items, itemcnt, "UPP", 2) && upp == NULL) { upp = vim_strsave(items[1]); } else if (is_aff_rule(items, itemcnt, "REP", 2) || is_aff_rule(items, itemcnt, "REPSAL", 2)) { - /* Ignore REP/REPSAL count */; - if (!isdigit(*items[1])) + // Ignore REP/REPSAL count + if (!isdigit(*items[1])) { smsg(_("Expected REP(SAL) count in %s line %d"), fname, lnum); + } } else if ((STRCMP(items[0], "REP") == 0 || STRCMP(items[0], "REPSAL") == 0) && itemcnt >= 3) { // REP/REPSAL item // Myspell ignores extra arguments, we require it starts with // # to detect mistakes. - if (itemcnt > 3 && items[3][0] != '#') + if (itemcnt > 3 && items[3][0] != '#') { smsg(_(e_afftrailing), fname, lnum, items[3]); + } if (items[0][3] == 'S' ? do_repsal : do_rep) { // Replace underscore with space (can't include a space // directly). @@ -2541,15 +2633,16 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) ? &spin->si_repsal : &spin->si_rep, items[1], items[2]); } - } else if (is_aff_rule(items, itemcnt, "MAP", 2)) { + } else if (is_aff_rule(items, itemcnt, "MAP", 2)) { // MAP item or count if (!found_map) { // First line contains the count. found_map = true; - if (!isdigit(*items[1])) + if (!isdigit(*items[1])) { smsg(_("Expected MAP count in %s line %d"), fname, lnum); - } else if (do_mapline) { + } + } else if (do_mapline) { int c; // Check that every character appears only once. @@ -2566,7 +2659,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) // We simply concatenate all the MAP strings, separated by // slashes. - ga_concat(&spin->si_map, items[1]); + ga_concat(&spin->si_map, (char *)items[1]); ga_append(&spin->si_map, '/'); } } @@ -2575,17 +2668,18 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) if (do_sal) { // SAL item (sounds-a-like) // Either one of the known keys or a from-to pair. - if (STRCMP(items[1], "followup") == 0) + if (STRCMP(items[1], "followup") == 0) { spin->si_followup = sal_to_bool(items[2]); - else if (STRCMP(items[1], "collapse_result") == 0) + } else if (STRCMP(items[1], "collapse_result") == 0) { spin->si_collapse = sal_to_bool(items[2]); - else if (STRCMP(items[1], "remove_accents") == 0) + } else if (STRCMP(items[1], "remove_accents") == 0) { spin->si_rem_accents = sal_to_bool(items[2]); - else + } else { // when "to" is "_" it means empty add_fromto(spin, &spin->si_sal, items[1], - STRCMP(items[2], "_") == 0 ? (char_u *)"" - : items[2]); + STRCMP(items[2], "_") == 0 ? (char_u *)"" + : items[2]); + } } } else if (is_aff_rule(items, itemcnt, "SOFOFROM", 2) && sofofrom == NULL) { @@ -2593,19 +2687,20 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) } else if (is_aff_rule(items, itemcnt, "SOFOTO", 2) && sofoto == NULL) { sofoto = getroom_save(spin, items[1]); - } else if (STRCMP(items[0], "COMMON") == 0) { + } else if (STRCMP(items[0], "COMMON") == 0) { int i; for (i = 1; i < itemcnt; ++i) { if (HASHITEM_EMPTY(hash_find(&spin->si_commonwords, - items[i]))) { + items[i]))) { p = vim_strsave(items[i]); hash_add(&spin->si_commonwords, p); } } - } else + } else { smsg(_("Unrecognized or duplicate item in %s line %d: %s"), fname, lnum, items[0]); + } } } @@ -2646,17 +2741,19 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) spin->si_compoptions |= compoptions; } - if (compflags != NULL) + if (compflags != NULL) { process_compflags(spin, aff, compflags); + } // Check that we didn't use too many renumbered flags. if (spin->si_newcompID < spin->si_newprefID) { - if (spin->si_newcompID == 127 || spin->si_newcompID == 255) + if (spin->si_newcompID == 127 || spin->si_newcompID == 255) { MSG(_("Too many postponed prefixes")); - else if (spin->si_newprefID == 0 || spin->si_newprefID == 127) + } else if (spin->si_newprefID == 0 || spin->si_newprefID == 127) { MSG(_("Too many compound flags")); - else + } else { MSG(_("Too many postponed prefixes and/or compound flags")); + } } if (syllable != NULL) { @@ -2665,12 +2762,12 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) } if (sofofrom != NULL || sofoto != NULL) { - if (sofofrom == NULL || sofoto == NULL) + if (sofofrom == NULL || sofoto == NULL) { smsg(_("Missing SOFO%s line in %s"), sofofrom == NULL ? "FROM" : "TO", fname); - else if (!GA_EMPTY(&spin->si_sal)) + } else if (!GA_EMPTY(&spin->si_sal)) { smsg(_("Both SAL and SOFO lines in %s"), fname); - else { + } else { aff_check_string(spin->si_sofofr, sofofrom, "SOFOFROM"); aff_check_string(spin->si_sofoto, sofoto, "SOFOTO"); spin->si_sofofr = sofofrom; @@ -2701,8 +2798,8 @@ static bool is_aff_rule(char_u **items, int itemcnt, char *rulename, int mincoun // ae_flags to ae_comppermit and ae_compforbid. static void aff_process_flags(afffile_T *affile, affentry_T *entry) { - char_u *p; - char_u *prevp; + char_u *p; + char_u *prevp; unsigned flag; if (entry->ae_flags != NULL @@ -2713,16 +2810,19 @@ static void aff_process_flags(afffile_T *affile, affentry_T *entry) if (flag == affile->af_comppermit || flag == affile->af_compforbid) { STRMOVE(prevp, p); p = prevp; - if (flag == affile->af_comppermit) + if (flag == affile->af_comppermit) { entry->ae_comppermit = true; - else + } else { entry->ae_compforbid = true; + } } - if (affile->af_flagtype == AFT_NUM && *p == ',') + if (affile->af_flagtype == AFT_NUM && *p == ',') { ++p; + } } - if (*entry->ae_flags == NUL) + if (*entry->ae_flags == NUL) { entry->ae_flags = NULL; // nothing left + } } } @@ -2742,16 +2842,17 @@ static bool spell_info_item(char_u *s) static unsigned affitem2flag(int flagtype, char_u *item, char_u *fname, int lnum) { unsigned res; - char_u *p = item; + char_u *p = item; res = get_affitem(flagtype, &p); if (res == 0) { - if (flagtype == AFT_NUM) + if (flagtype == AFT_NUM) { smsg(_("Flag is not a number in %s line %d: %s"), fname, lnum, item); - else + } else { smsg(_("Illegal flag in %s line %d: %s"), fname, lnum, item); + } } if (*p != NUL) { smsg(_(e_affname), fname, lnum, item); @@ -2781,8 +2882,9 @@ static unsigned get_affitem(int flagtype, char_u **pp) res = mb_ptr2char_adv((const char_u **)pp); if (flagtype == AFT_LONG || (flagtype == AFT_CAPLONG && res >= 'A' && res <= 'Z')) { - if (**pp == NUL) + if (**pp == NUL) { return 0; + } res = mb_ptr2char_adv((const char_u **)pp) + (res << 16); } } @@ -2795,22 +2897,23 @@ static unsigned get_affitem(int flagtype, char_u **pp) // they fit in one byte. static void process_compflags(spellinfo_T *spin, afffile_T *aff, char_u *compflags) { - char_u *p; - char_u *prevp; + char_u *p; + char_u *prevp; unsigned flag; - compitem_T *ci; + compitem_T *ci; int id; int len; - char_u *tp; + char_u *tp; char_u key[AH_KEY_LEN]; - hashitem_T *hi; + hashitem_T *hi; // Make room for the old and the new compflags, concatenated with a / in // between. Processing it makes it shorter, but we don't know by how // much, thus allocate the maximum. len = (int)STRLEN(compflags) + 1; - if (spin->si_compflags != NULL) + if (spin->si_compflags != NULL) { len += (int)STRLEN(spin->si_compflags) + 1; + } p = getroom(spin, len, false); if (spin->si_compflags != NULL) { STRCPY(p, spin->si_compflags); @@ -2820,10 +2923,10 @@ static void process_compflags(spellinfo_T *spin, afffile_T *aff, char_u *compfla tp = p + STRLEN(p); for (p = compflags; *p != NUL; ) { - if (vim_strchr((char_u *)"/?*+[]", *p) != NULL) + if (vim_strchr((char_u *)"/?*+[]", *p) != NULL) { // Copy non-flag characters directly. *tp++ = *p++; - else { + } else { // First get the flag number, also checks validity. prevp = p; flag = get_affitem(aff->af_flagtype, &p); @@ -2849,8 +2952,9 @@ static void process_compflags(spellinfo_T *spin, afffile_T *aff, char_u *compfla } *tp++ = id; } - if (aff->af_flagtype == AFT_NUM && *p == ',') + if (aff->af_flagtype == AFT_NUM && *p == ',') { ++p; + } } } @@ -2872,7 +2976,7 @@ static void check_renumber(spellinfo_T *spin) // Returns true if flag "flag" appears in affix list "afflist". static bool flag_in_afflist(int flagtype, char_u *afflist, unsigned flag) { - char_u *p; + char_u *p; unsigned n; switch (flagtype) { @@ -2916,25 +3020,28 @@ static bool flag_in_afflist(int flagtype, char_u *afflist, unsigned flag) // Give a warning when "spinval" and "affval" numbers are set and not the same. static void aff_check_number(int spinval, int affval, char *name) { - if (spinval != 0 && spinval != affval) + if (spinval != 0 && spinval != affval) { smsg(_("%s value differs from what is used in another .aff file"), name); + } } // Give a warning when "spinval" and "affval" strings are set and not the same. static void aff_check_string(char_u *spinval, char_u *affval, char *name) { - if (spinval != NULL && STRCMP(spinval, affval) != 0) + if (spinval != NULL && STRCMP(spinval, affval) != 0) { smsg(_("%s value differs from what is used in another .aff file"), name); + } } // Returns true if strings "s1" and "s2" are equal. Also consider both being // NULL as equal. static bool str_equal(char_u *s1, char_u *s2) { - if (s1 == NULL || s2 == NULL) + if (s1 == NULL || s2 == NULL) { return s1 == s2; + } return STRCMP(s1, s2) == 0; } @@ -2960,11 +3067,11 @@ static bool sal_to_bool(char_u *s) // Free the structure filled by spell_read_aff(). static void spell_free_aff(afffile_T *aff) { - hashtab_T *ht; - hashitem_T *hi; + hashtab_T *ht; + hashitem_T *hi; int todo; affheader_T *ah; - affentry_T *ae; + affentry_T *ae; xfree(aff->af_enc); @@ -2975,12 +3082,14 @@ static void spell_free_aff(afffile_T *aff) if (!HASHITEM_EMPTY(hi)) { --todo; ah = HI2AH(hi); - for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next) + for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next) { vim_regfree(ae->ae_prog); + } } } - if (ht == &aff->af_suff) + if (ht == &aff->af_suff) { break; + } } hash_clear(&aff->af_pref); @@ -2994,18 +3103,18 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile) { hashtab_T ht; char_u line[MAXLINELEN]; - char_u *p; - char_u *afflist; + char_u *p; + char_u *afflist; char_u store_afflist[MAXWLEN]; int pfxlen; bool need_affix; - char_u *dw; - char_u *pc; - char_u *w; + char_u *dw; + char_u *pc; + char_u *w; int l; hash_T hash; - hashitem_T *hi; - FILE *fd; + hashitem_T *hi; + FILE *fd; int lnum = 1; int non_ascii = 0; int retval = OK; @@ -3042,16 +3151,18 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile) while (!vim_fgets(line, MAXLINELEN, fd) && !got_int) { line_breakcheck(); ++lnum; - if (line[0] == '#' || line[0] == '/') + if (line[0] == '#' || line[0] == '/') { continue; // comment line - + } // Remove CR, LF and white space from the end. White space halfway through // the word is kept to allow multi-word terms like "et al.". l = (int)STRLEN(line); - while (l > 0 && line[l - 1] <= ' ') + while (l > 0 && line[l - 1] <= ' ') { --l; - if (l == 0) + } + if (l == 0) { continue; // empty line + } line[l] = NUL; // Convert from "SET" to 'encoding' when needed. @@ -3117,15 +3228,17 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile) hash = hash_hash(dw); hi = hash_lookup(&ht, (const char *)dw, STRLEN(dw), hash); if (!HASHITEM_EMPTY(hi)) { - if (p_verbose > 0) + if (p_verbose > 0) { smsg(_("Duplicate word in %s line %d: %s"), fname, lnum, dw); - else if (duplicate == 0) + } else if (duplicate == 0) { smsg(_("First duplicate word in %s line %d: %s"), fname, lnum, dw); + } ++duplicate; - } else + } else { hash_add_item(&ht, hi, dw, hash); + } flags = 0; store_afflist[0] = NUL; @@ -3135,48 +3248,57 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile) // Extract flags from the affix list. flags |= get_affix_flags(affile, afflist); - if (affile->af_needaffix != 0 && flag_in_afflist( - affile->af_flagtype, afflist, affile->af_needaffix)) + if (affile->af_needaffix != 0 && + flag_in_afflist(affile->af_flagtype, afflist, + affile->af_needaffix)) { need_affix = true; + } - if (affile->af_pfxpostpone) + if (affile->af_pfxpostpone) { // Need to store the list of prefix IDs with the word. pfxlen = get_pfxlist(affile, afflist, store_afflist); + } - if (spin->si_compflags != NULL) + if (spin->si_compflags != NULL) { // Need to store the list of compound flags with the word. // Concatenate them to the list of prefix IDs. get_compflags(affile, afflist, store_afflist + pfxlen); + } } // Add the word to the word tree(s). if (store_word(spin, dw, flags, spin->si_region, - store_afflist, need_affix) == FAIL) + store_afflist, need_affix) == FAIL) { retval = FAIL; + } if (afflist != NULL) { // Find all matching suffixes and add the resulting words. // Additionally do matching prefixes that combine. if (store_aff_word(spin, dw, afflist, affile, - &affile->af_suff, &affile->af_pref, - CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) + &affile->af_suff, &affile->af_pref, + CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) { retval = FAIL; + } // Find all matching prefixes and add the resulting words. if (store_aff_word(spin, dw, afflist, affile, - &affile->af_pref, NULL, - CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) + &affile->af_pref, NULL, + CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) { retval = FAIL; + } } xfree(pc); } - if (duplicate > 0) + if (duplicate > 0) { smsg(_("%d duplicate word(s) in %s"), duplicate, fname); - if (spin->si_ascii && non_ascii > 0) + } + if (spin->si_ascii && non_ascii > 0) { smsg(_("Ignored %d word(s) with non-ASCII characters in %s"), non_ascii, fname); + } hash_clear(&ht); fclose(fd); @@ -3189,24 +3311,34 @@ static int get_affix_flags(afffile_T *affile, char_u *afflist) { int flags = 0; - if (affile->af_keepcase != 0 && flag_in_afflist( - affile->af_flagtype, afflist, affile->af_keepcase)) + if (affile->af_keepcase != 0 && + flag_in_afflist(affile->af_flagtype, afflist, + affile->af_keepcase)) { flags |= WF_KEEPCAP | WF_FIXCAP; - if (affile->af_rare != 0 && flag_in_afflist( - affile->af_flagtype, afflist, affile->af_rare)) + } + if (affile->af_rare != 0 && + flag_in_afflist(affile->af_flagtype, afflist, affile->af_rare)) { flags |= WF_RARE; - if (affile->af_bad != 0 && flag_in_afflist( - affile->af_flagtype, afflist, affile->af_bad)) + } + if (affile->af_bad != 0 && + flag_in_afflist(affile->af_flagtype, afflist, affile->af_bad)) { flags |= WF_BANNED; - if (affile->af_needcomp != 0 && flag_in_afflist( - affile->af_flagtype, afflist, affile->af_needcomp)) + } + if (affile->af_needcomp != 0 && + flag_in_afflist(affile->af_flagtype, afflist, + affile->af_needcomp)) { flags |= WF_NEEDCOMP; - if (affile->af_comproot != 0 && flag_in_afflist( - affile->af_flagtype, afflist, affile->af_comproot)) + } + if (affile->af_comproot != 0 && + flag_in_afflist(affile->af_flagtype, afflist, + affile->af_comproot)) { flags |= WF_COMPROOT; - if (affile->af_nosuggest != 0 && flag_in_afflist( - affile->af_flagtype, afflist, affile->af_nosuggest)) + } + if (affile->af_nosuggest != 0 && + flag_in_afflist(affile->af_flagtype, afflist, + affile->af_nosuggest)) { flags |= WF_NOSUGGEST; + } return flags; } @@ -3216,12 +3348,12 @@ static int get_affix_flags(afffile_T *affile, char_u *afflist) // and return the number of affixes. static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist) { - char_u *p; - char_u *prevp; + char_u *p; + char_u *prevp; int cnt = 0; int id; char_u key[AH_KEY_LEN]; - hashitem_T *hi; + hashitem_T *hi; for (p = afflist; *p != NUL; ) { prevp = p; @@ -3232,12 +3364,14 @@ static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist hi = hash_find(&affile->af_pref, key); if (!HASHITEM_EMPTY(hi)) { id = HI2AH(hi)->ah_newID; - if (id != 0) + if (id != 0) { store_afflist[cnt++] = id; + } } } - if (affile->af_flagtype == AFT_NUM && *p == ',') + if (affile->af_flagtype == AFT_NUM && *p == ',') { ++p; + } } store_afflist[cnt] = NUL; @@ -3249,11 +3383,11 @@ static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist // Puts the flags in "store_afflist[]". static void get_compflags(afffile_T *affile, char_u *afflist, char_u *store_afflist) { - char_u *p; - char_u *prevp; + char_u *p; + char_u *prevp; int cnt = 0; char_u key[AH_KEY_LEN]; - hashitem_T *hi; + hashitem_T *hi; for (p = afflist; *p != NUL; ) { prevp = p; @@ -3261,48 +3395,47 @@ static void get_compflags(afffile_T *affile, char_u *afflist, char_u *store_affl // A flag is a compound flag if it appears in "af_comp". STRLCPY(key, prevp, p - prevp + 1); hi = hash_find(&affile->af_comp, key); - if (!HASHITEM_EMPTY(hi)) + if (!HASHITEM_EMPTY(hi)) { store_afflist[cnt++] = HI2CI(hi)->ci_newID; + } } - if (affile->af_flagtype == AFT_NUM && *p == ',') + if (affile->af_flagtype == AFT_NUM && *p == ',') { ++p; + } } store_afflist[cnt] = NUL; } -// Apply affixes to a word and store the resulting words. -// "ht" is the hashtable with affentry_T that need to be applied, either -// prefixes or suffixes. -// "xht", when not NULL, is the prefix hashtable, to be used additionally on -// the resulting words for combining affixes. -// -// Returns FAIL when out of memory. -static int -store_aff_word ( - spellinfo_T *spin, // spell info - char_u *word, // basic word start - char_u *afflist, // list of names of supported affixes - afffile_T *affile, - hashtab_T *ht, - hashtab_T *xht, - int condit, // CONDIT_SUF et al. - int flags, // flags for the word - char_u *pfxlist, // list of prefix IDs - int pfxlen // nr of flags in "pfxlist" for prefixes, rest - // is compound flags -) +/// Apply affixes to a word and store the resulting words. +/// "ht" is the hashtable with affentry_T that need to be applied, either +/// prefixes or suffixes. +/// "xht", when not NULL, is the prefix hashtable, to be used additionally on +/// the resulting words for combining affixes. +/// +/// @param spin spell info +/// @param word basic word start +/// @param afflist list of names of supported affixes +/// @param condit CONDIT_SUF et al. +/// @param flags flags for the word +/// @param pfxlist list of prefix IDs +/// @param pfxlen nr of flags in "pfxlist" for prefixes, rest is compound flags +/// +/// @return FAIL when out of memory. +static int store_aff_word(spellinfo_T *spin, char_u *word, char_u *afflist, afffile_T *affile, + hashtab_T *ht, hashtab_T *xht, int condit, int flags, char_u *pfxlist, + int pfxlen) { int todo; - hashitem_T *hi; + hashitem_T *hi; affheader_T *ah; - affentry_T *ae; + affentry_T *ae; char_u newword[MAXWLEN]; int retval = OK; int i, j; - char_u *p; + char_u *p; int use_flags; - char_u *use_pfxlist; + char_u *use_pfxlist; int use_pfxlen; bool need_affix; char_u store_afflist[MAXWLEN]; @@ -3320,7 +3453,7 @@ store_aff_word ( // supports this affix. if (((condit & CONDIT_COMB) == 0 || ah->ah_combine) && flag_in_afflist(affile->af_flagtype, afflist, - ah->ah_flag)) { + ah->ah_flag)) { // Loop over all affix entries with this name. for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next) { // Check the condition. It's not logical to match case @@ -3344,7 +3477,7 @@ store_aff_word ( == ((condit & CONDIT_AFF) == 0 || ae->ae_flags == NULL || !flag_in_afflist(affile->af_flagtype, - ae->ae_flags, affile->af_circumfix)))) { + ae->ae_flags, affile->af_circumfix)))) { // Match. Remove the chop and add the affix. if (xht == NULL) { // prefix: chop/add at the start of the word @@ -3374,8 +3507,9 @@ store_aff_word ( } *p = NUL; } - if (ae->ae_add != NULL) + if (ae->ae_add != NULL) { STRCAT(newword, ae->ae_add); + } } use_flags = flags; @@ -3387,57 +3521,64 @@ store_aff_word ( // Extract flags from the affix list. use_flags |= get_affix_flags(affile, ae->ae_flags); - if (affile->af_needaffix != 0 && flag_in_afflist( - affile->af_flagtype, ae->ae_flags, - affile->af_needaffix)) + if (affile->af_needaffix != 0 && flag_in_afflist(affile->af_flagtype, ae->ae_flags, + affile->af_needaffix)) { need_affix = true; + } // When there is a CIRCUMFIX flag the other affix // must also have it and we don't add the word // with one affix. - if (affile->af_circumfix != 0 && flag_in_afflist( - affile->af_flagtype, ae->ae_flags, - affile->af_circumfix)) { + if (affile->af_circumfix != 0 && flag_in_afflist(affile->af_flagtype, ae->ae_flags, + affile->af_circumfix)) { use_condit |= CONDIT_CFIX; - if ((condit & CONDIT_CFIX) == 0) + if ((condit & CONDIT_CFIX) == 0) { need_affix = true; + } } if (affile->af_pfxpostpone || spin->si_compflags != NULL) { - if (affile->af_pfxpostpone) + if (affile->af_pfxpostpone) { // Get prefix IDS from the affix list. use_pfxlen = get_pfxlist(affile, - ae->ae_flags, store_afflist); - else + ae->ae_flags, store_afflist); + } else { use_pfxlen = 0; + } use_pfxlist = store_afflist; // Combine the prefix IDs. Avoid adding the // same ID twice. for (i = 0; i < pfxlen; ++i) { - for (j = 0; j < use_pfxlen; ++j) - if (pfxlist[i] == use_pfxlist[j]) + for (j = 0; j < use_pfxlen; ++j) { + if (pfxlist[i] == use_pfxlist[j]) { break; - if (j == use_pfxlen) + } + } + if (j == use_pfxlen) { use_pfxlist[use_pfxlen++] = pfxlist[i]; + } } - if (spin->si_compflags != NULL) + if (spin->si_compflags != NULL) { // Get compound IDS from the affix list. get_compflags(affile, ae->ae_flags, - use_pfxlist + use_pfxlen); - else + use_pfxlist + use_pfxlen); + } else { use_pfxlist[use_pfxlen] = NUL; + } // Combine the list of compound flags. // Concatenate them to the prefix IDs list. // Avoid adding the same ID twice. for (i = pfxlen; pfxlist[i] != NUL; ++i) { for (j = use_pfxlen; - use_pfxlist[j] != NUL; ++j) - if (pfxlist[i] == use_pfxlist[j]) + use_pfxlist[j] != NUL; ++j) { + if (pfxlist[i] == use_pfxlist[j]) { break; + } + } if (use_pfxlist[j] == NUL) { use_pfxlist[j++] = pfxlist[i]; use_pfxlist[j] = NUL; @@ -3462,52 +3603,58 @@ store_aff_word ( // ... don't use a prefix list if combining // affixes is not allowed. But do use the // compound flags after them. - if (!ah->ah_combine && use_pfxlist != NULL) + if (!ah->ah_combine && use_pfxlist != NULL) { use_pfxlist += use_pfxlen; + } } // When compounding is supported and there is no // "COMPOUNDPERMITFLAG" then forbid compounding on the // side where the affix is applied. if (spin->si_compflags != NULL && !ae->ae_comppermit) { - if (xht != NULL) + if (xht != NULL) { use_flags |= WF_NOCOMPAFT; - else + } else { use_flags |= WF_NOCOMPBEF; + } } // Store the modified word. if (store_word(spin, newword, use_flags, - spin->si_region, use_pfxlist, - need_affix) == FAIL) + spin->si_region, use_pfxlist, + need_affix) == FAIL) { retval = FAIL; + } // When added a prefix or a first suffix and the affix // has flags may add a(nother) suffix. RECURSIVE! - if ((condit & CONDIT_SUF) && ae->ae_flags != NULL) + if ((condit & CONDIT_SUF) && ae->ae_flags != NULL) { if (store_aff_word(spin, newword, ae->ae_flags, - affile, &affile->af_suff, xht, - use_condit & (xht == NULL + affile, &affile->af_suff, xht, + use_condit & (xht == NULL ? ~0 : ~CONDIT_SUF), - use_flags, use_pfxlist, pfxlen) == FAIL) + use_flags, use_pfxlist, pfxlen) == FAIL) { retval = FAIL; + } + } // When added a suffix and combining is allowed also // try adding a prefix additionally. Both for the // word flags and for the affix flags. RECURSIVE! if (xht != NULL && ah->ah_combine) { if (store_aff_word(spin, newword, - afflist, affile, - xht, NULL, use_condit, - use_flags, use_pfxlist, - pfxlen) == FAIL + afflist, affile, + xht, NULL, use_condit, + use_flags, use_pfxlist, + pfxlen) == FAIL || (ae->ae_flags != NULL && store_aff_word(spin, newword, - ae->ae_flags, affile, - xht, NULL, use_condit, - use_flags, use_pfxlist, - pfxlen) == FAIL)) + ae->ae_flags, affile, + xht, NULL, use_condit, + use_flags, use_pfxlist, + pfxlen) == FAIL)) { retval = FAIL; + } } } } @@ -3521,12 +3668,12 @@ store_aff_word ( // Read a file with a list of words. static int spell_read_wordfile(spellinfo_T *spin, char_u *fname) { - FILE *fd; + FILE *fd; long lnum = 0; char_u rline[MAXLINELEN]; - char_u *line; - char_u *pc = NULL; - char_u *p; + char_u *line; + char_u *pc = NULL; + char_u *p; int l; int retval = OK; bool did_word = false; @@ -3550,15 +3697,18 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname) ++lnum; // Skip comment lines. - if (*rline == '#') + if (*rline == '#') { continue; + } // Remove CR, LF and white space from the end. l = (int)STRLEN(rline); - while (l > 0 && rline[l - 1] <= ' ') + while (l > 0 && rline[l - 1] <= ' ') { --l; - if (l == 0) + } + if (l == 0) { continue; // empty or blank line + } rline[l] = NUL; // Convert from "/encoding={encoding}" to 'encoding' when needed. @@ -3586,16 +3736,17 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname) smsg(_("/encoding= line after word ignored in %s line %ld: %s"), fname, lnum, line - 1); } else { - char_u *enc; + char_u *enc; // Setup for conversion to 'encoding'. line += 9; enc = enc_canonize(line); if (!spin->si_ascii && convert_setup(&spin->si_conv, enc, - p_enc) == FAIL) + p_enc) == FAIL) { smsg(_("Conversion in %s not supported: from %s to %s"), fname, line, p_enc); + } xfree(enc); spin->si_conv.vc_fail = true; } @@ -3635,15 +3786,16 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname) if (p != NULL) { *p++ = NUL; while (*p != NUL) { - if (*p == '=') // keep-case word + if (*p == '=') { // keep-case word flags |= WF_KEEPCAP | WF_FIXCAP; - else if (*p == '!') // Bad, bad, wicked word. + } else if (*p == '!') { // Bad, bad, wicked word. flags |= WF_BANNED; - else if (*p == '?') // Rare word. + } else if (*p == '?') { // Rare word. flags |= WF_RARE; - else if (ascii_isdigit(*p)) { // region number(s) - if ((flags & WF_REGION) == 0) // first one + } else if (ascii_isdigit(*p)) { // region number(s) + if ((flags & WF_REGION) == 0) { // first one regionmask = 0; + } flags |= WF_REGION; l = *p - '0'; @@ -3681,7 +3833,7 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname) if (spin->si_ascii && non_ascii > 0) { vim_snprintf((char *)IObuff, IOSIZE, - _("Ignored %d words with non-ASCII characters"), non_ascii); + _("Ignored %d words with non-ASCII characters"), non_ascii); spell_message(spin, IObuff); } @@ -3699,16 +3851,17 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname) static void *getroom(spellinfo_T *spin, size_t len, bool align) FUNC_ATTR_NONNULL_RET { - char_u *p; - sblock_T *bl = spin->si_blocks; + char_u *p; + sblock_T *bl = spin->si_blocks; assert(len <= SBLOCKSIZE); - - if (align && bl != NULL) + + if (align && bl != NULL) { // Round size up for alignment. On some systems structures need to be // aligned to the size of a pointer (e.g., SPARC). bl->sb_used = (bl->sb_used + sizeof(char *) - 1) & ~(sizeof(char *) - 1); + } if (bl == NULL || bl->sb_used + len > SBLOCKSIZE) { // Allocate a block of memory. It is not freed until much later. @@ -3737,7 +3890,7 @@ static char_u *getroom_save(spellinfo_T *spin, char_u *s) // Free the list of allocated sblock_T. static void free_blocks(sblock_T *bl) { - sblock_T *next; + sblock_T *next; while (bl != NULL) { next = bl->sb_next; @@ -3754,22 +3907,20 @@ static wordnode_T *wordtree_alloc(spellinfo_T *spin) return (wordnode_T *)getroom(spin, sizeof(wordnode_T), true); } -// Store a word in the tree(s). -// Always store it in the case-folded tree. For a keep-case word this is -// useful when the word can also be used with all caps (no WF_FIXCAP flag) and -// used to find suggestions. -// For a keep-case word also store it in the keep-case tree. -// When "pfxlist" is not NULL store the word for each postponed prefix ID and -// compound flag. -static int -store_word ( - spellinfo_T *spin, - char_u *word, - int flags, // extra flags, WF_BANNED - int region, // supported region(s) - const char_u *pfxlist, // list of prefix IDs or NULL - bool need_affix // only store word with affix ID -) +/// Store a word in the tree(s). +/// Always store it in the case-folded tree. For a keep-case word this is +/// useful when the word can also be used with all caps (no WF_FIXCAP flag) and +/// used to find suggestions. +/// For a keep-case word also store it in the keep-case tree. +/// When "pfxlist" is not NULL store the word for each postponed prefix ID and +/// compound flag. +/// +/// @param flags extra flags, wf_banned +/// @param region supported region(s) +/// @param pfxlist list of prefix ids or null +/// @param need_affix only store word with affix id +static int store_word(spellinfo_T *spin, char_u *word, int flags, int region, const char_u *pfxlist, + bool need_affix) { int len = (int)STRLEN(word); int ct = captype(word, word + len); @@ -3807,12 +3958,13 @@ store_word ( // When "flags" < 0 we are adding to the prefix tree where "flags" is used for // "rare" and "region" is the condition nr. // Returns FAIL when out of memory. -static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int flags, int region, int affixID) +static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int flags, int region, + int affixID) { - wordnode_T *node = root; - wordnode_T *np; - wordnode_T *copyp, **copyprev; - wordnode_T **prev = NULL; + wordnode_T *node = root; + wordnode_T *np; + wordnode_T *copyp, **copyprev; + wordnode_T **prev = NULL; int i; // Add each byte of the word to the tree, including the NUL at the end. @@ -3826,11 +3978,13 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int for (copyp = node; copyp != NULL; copyp = copyp->wn_sibling) { // Allocate a new node and copy the info. np = get_wordnode(spin); - if (np == NULL) + if (np == NULL) { return FAIL; + } np->wn_child = copyp->wn_child; - if (np->wn_child != NULL) + if (np->wn_child != NULL) { ++np->wn_child->wn_refs; // child gets extra ref + } np->wn_byte = copyp->wn_byte; if (np->wn_byte == NUL) { np->wn_flags = copyp->wn_flags; @@ -3840,13 +3994,15 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int // Link the new node in the list, there will be one ref. np->wn_refs = 1; - if (copyprev != NULL) + if (copyprev != NULL) { *copyprev = np; + } copyprev = &np->wn_sibling; // Let "node" point to the head of the copied list. - if (copyp == node) + if (copyp == node) { node = np; + } } } @@ -3877,22 +4033,24 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int || node->wn_affixID != affixID))) { // Allocate a new node. np = get_wordnode(spin); - if (np == NULL) + if (np == NULL) { return FAIL; + } np->wn_byte = word[i]; // If "node" is NULL this is a new child or the end of the sibling // list: ref count is one. Otherwise use ref count of sibling and // make ref count of sibling one (matters when inserting in front // of the list of siblings). - if (node == NULL) + if (node == NULL) { np->wn_refs = 1; - else { + } else { np->wn_refs = node->wn_refs; node->wn_refs = 1; } - if (prev != NULL) + if (prev != NULL) { *prev = np; + } np->wn_sibling = node; node = np; } @@ -3934,7 +4092,7 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int #ifndef SPELL_COMPRESS_ALLWAYS if (spin->si_compress_cnt == 1 // NOLINT(readability/braces) ? spin->si_free_count < MAXWLEN - : spin->si_blocks_cnt >= compress_start) + : spin->si_blocks_cnt >= compress_start) #endif { // Decrement the block counter. The effect is that we compress again @@ -3973,17 +4131,18 @@ static wordnode_T *get_wordnode(spellinfo_T *spin) { wordnode_T *n; - if (spin->si_first_free == NULL) + if (spin->si_first_free == NULL) { n = (wordnode_T *)getroom(spin, sizeof(wordnode_T), true); - else { + } else { n = spin->si_first_free; spin->si_first_free = n->wn_child; memset(n, 0, sizeof(wordnode_T)); --spin->si_free_count; } #ifdef SPELL_PRINTTREE - if (n != NULL) + if (n != NULL) { n->wn_nr = ++spin->si_wordnode_nr; + } #endif return n; } @@ -3995,13 +4154,14 @@ static wordnode_T *get_wordnode(spellinfo_T *spin) static int deref_wordnode(spellinfo_T *spin, wordnode_T *node) FUNC_ATTR_NONNULL_ALL { - wordnode_T *np; + wordnode_T *np; int cnt = 0; if (--node->wn_refs == 0) { for (np = node; np != NULL; np = np->wn_sibling) { - if (np->wn_child != NULL) + if (np->wn_child != NULL) { cnt += deref_wordnode(spin, np->wn_child); + } free_wordnode(spin, np); ++cnt; } @@ -4021,8 +4181,7 @@ static void free_wordnode(spellinfo_T *spin, wordnode_T *n) } // Compress a tree: find tails that are identical and can be shared. -static void wordtree_compress(spellinfo_T *spin, wordnode_T *root, - const char *name) +static void wordtree_compress(spellinfo_T *spin, wordnode_T *root, const char *name) FUNC_ATTR_NONNULL_ALL { hashtab_T ht; @@ -4039,12 +4198,13 @@ static void wordtree_compress(spellinfo_T *spin, wordnode_T *root, if (spin->si_verbose || p_verbose > 2) #endif { - if (tot > 1000000) + if (tot > 1000000) { perc = (tot - n) / (tot / 100); - else if (tot == 0) + } else if (tot == 0) { perc = 0; - else + } else { perc = (tot - n) * 100 / tot; + } vim_snprintf((char *)IObuff, IOSIZE, _("Compressed %s of %ld nodes; %ld (%ld%%) remaining"), name, tot, tot - n, perc); @@ -4057,22 +4217,18 @@ static void wordtree_compress(spellinfo_T *spin, wordnode_T *root, } } -// Compress a node, its siblings and its children, depth first. -// Returns the number of compressed nodes. -static long node_compress( - spellinfo_T *spin, - wordnode_T *node, - hashtab_T *ht, - long *tot // total count of nodes before compressing, - // incremented while going through the tree -) +/// Compress a node, its siblings and its children, depth first. +/// Returns the number of compressed nodes. +/// +/// @param tot total count of nodes before compressing, incremented while going through the tree +static long node_compress(spellinfo_T *spin, wordnode_T *node, hashtab_T *ht, long *tot) FUNC_ATTR_NONNULL_ALL { - wordnode_T *np; - wordnode_T *tp; - wordnode_T *child; + wordnode_T *np; + wordnode_T *tp; + wordnode_T *child; hash_T hash; - hashitem_T *hi; + hashitem_T *hi; long len = 0; unsigned nr, n; long compressed = 0; @@ -4095,7 +4251,7 @@ static long node_compress( // There are children we encountered before with a hash value // identical to the current child. Now check if there is one // that is really identical. - for (tp = HI2WN(hi); tp != NULL; tp = tp->wn_u2.next) + for (tp = HI2WN(hi); tp != NULL; tp = tp->wn_u2.next) { if (node_equal(child, tp)) { // Found one! Now use that child in place of the // current one. This means the current child and all @@ -4105,6 +4261,7 @@ static long node_compress( np->wn_child = tp; break; } + } if (tp == NULL) { // No other child with this hash value equals the child of // the node, add it to the linked list after the first @@ -4113,10 +4270,11 @@ static long node_compress( child->wn_u2.next = tp->wn_u2.next; tp->wn_u2.next = child; } - } else + } else { // No other child has this hash value, add it to the // hashtable. hash_add_item(ht, hi, child->wn_u1.hashkey, hash); + } } } *tot += len + 1; // add one for the node that stores the length @@ -4127,12 +4285,13 @@ static long node_compress( node->wn_u1.hashkey[0] = len; nr = 0; for (np = node; np != NULL; np = np->wn_sibling) { - if (np->wn_byte == NUL) + if (np->wn_byte == NUL) { // end node: use wn_flags, wn_region and wn_affixID n = np->wn_flags + (np->wn_region << 8) + (np->wn_affixID << 16); - else + } else { // byte node: use the byte value and the child pointer n = (unsigned)(np->wn_byte + ((uintptr_t)np->wn_child << 8)); + } nr = nr * 101 + n; } @@ -4156,18 +4315,20 @@ static long node_compress( // Returns true when two nodes have identical siblings and children. static bool node_equal(wordnode_T *n1, wordnode_T *n2) { - wordnode_T *p1; - wordnode_T *p2; + wordnode_T *p1; + wordnode_T *p2; for (p1 = n1, p2 = n2; p1 != NULL && p2 != NULL; - p1 = p1->wn_sibling, p2 = p2->wn_sibling) + p1 = p1->wn_sibling, p2 = p2->wn_sibling) { if (p1->wn_byte != p2->wn_byte || (p1->wn_byte == NUL ? (p1->wn_flags != p2->wn_flags || p1->wn_region != p2->wn_region || p1->wn_affixID != p2->wn_affixID) - : (p1->wn_child != p2->wn_child))) + : (p1->wn_child != p2->wn_child))) { break; + } + } return p1 == NULL && p2 == NULL; } @@ -4176,8 +4337,8 @@ static bool node_equal(wordnode_T *n1, wordnode_T *n2) // Function given to qsort() to sort the REP items on "from" string. static int rep_compare(const void *s1, const void *s2) { - fromto_T *p1 = (fromto_T *)s1; - fromto_T *p2 = (fromto_T *)s2; + fromto_T *p1 = (fromto_T *)s1; + fromto_T *p2 = (fromto_T *)s2; return STRCMP(p1->ft_from, p2->ft_from); } @@ -4198,9 +4359,10 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) // <HEADER>: <fileID> <versionnr> // <fileID> size_t fwv = fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, 1, fd); - if (fwv != (size_t)1) + if (fwv != (size_t)1) { // Catch first write error, don't try writing more. goto theend; + } putc(VIMSPELLVERSION, fd); // <versionnr> @@ -4225,8 +4387,9 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) fwv &= fwrite(spin->si_region_name, l, 1, fd); // <regionname> ... regionmask = (1 << spin->si_region_count) - 1; - } else + } else { regionmask = 0; + } // SN_CHARFLAGS: <charflagslen> <charflags> <folcharslen> <folchars> // @@ -4254,10 +4417,12 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) fputc(128, fd); // <charflagslen> for (size_t i = 128; i < 256; ++i) { flags = 0; - if (spelltab.st_isw[i]) + if (spelltab.st_isw[i]) { flags |= CF_WORD; - if (spelltab.st_isu[i]) + } + if (spelltab.st_isu[i]) { flags |= CF_UPPER; + } fputc(flags, fd); // <charflags> } @@ -4296,24 +4461,28 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) // round 3: SN_REPSAL section for (unsigned int round = 1; round <= 3; ++round) { garray_T *gap; - if (round == 1) + if (round == 1) { gap = &spin->si_rep; - else if (round == 2) { + } else if (round == 2) { // Don't write SN_SAL when using a SN_SOFO section - if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) + if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) { continue; + } gap = &spin->si_sal; - } else + } else { gap = &spin->si_repsal; + } // Don't write the section if there are no items. - if (GA_EMPTY(gap)) + if (GA_EMPTY(gap)) { continue; + } // Sort the REP/REPSAL items. - if (round != 2) + if (round != 2) { qsort(gap->ga_data, (size_t)gap->ga_len, - sizeof(fromto_T), rep_compare); + sizeof(fromto_T), rep_compare); + } int sect_id = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL); putc(sect_id, fd); // <sectionID> @@ -4329,18 +4498,22 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) l += 1 + STRLEN(ftp->ft_from); // count <*fromlen> and <*from> l += 1 + STRLEN(ftp->ft_to); // count <*tolen> and <*to> } - if (round == 2) + if (round == 2) { ++l; // count <salflags> + } put_bytes(fd, l, 4); // <sectionlen> if (round == 2) { int i = 0; - if (spin->si_followup) + if (spin->si_followup) { i |= SAL_F0LLOWUP; - if (spin->si_collapse) + } + if (spin->si_collapse) { i |= SAL_COLLAPSE; - if (spin->si_rem_accents) + } + if (spin->si_rem_accents) { i |= SAL_REM_ACCENTS; + } putc(i, fd); // <salflags> } @@ -4354,11 +4527,11 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) l = STRLEN(p); assert(l < INT_MAX); putc((int)l, fd); - if (l > 0) + if (l > 0) { fwv &= fwrite(p, l, 1, fd); + } } } - } // SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto> @@ -4389,19 +4562,22 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) for (unsigned int round = 1; round <= 2; ++round) { size_t todo; size_t len = 0; - hashitem_T *hi; + hashitem_T *hi; todo = spin->si_commonwords.ht_used; - for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi) + for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi) { if (!HASHITEM_EMPTY(hi)) { size_t l = STRLEN(hi->hi_key) + 1; len += l; - if (round == 2) // <word> + if (round == 2) { // <word> fwv &= fwrite(hi->hi_key, l, 1, fd); + } --todo; } - if (round == 1) + } + if (round == 1) { put_bytes(fd, len, 4); // <sectionlen> + } } } @@ -4509,12 +4685,13 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) spin->si_memtot = 0; for (unsigned int round = 1; round <= 3; ++round) { wordnode_T *tree; - if (round == 1) + if (round == 1) { tree = spin->si_foldroot->wn_sibling; - else if (round == 2) + } else if (round == 2) { tree = spin->si_keeproot->wn_sibling; - else + } else { tree = spin->si_prefroot->wn_sibling; + } // Clear the index and wnode fields in the tree. clear_node(tree); @@ -4534,16 +4711,20 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) } // Write another byte to check for errors (file system full). - if (putc(0, fd) == EOF) + if (putc(0, fd) == EOF) { retval = FAIL; + } theend: - if (fclose(fd) == EOF) + if (fclose(fd) == EOF) { retval = FAIL; + } - if (fwv != (size_t)1) + if (fwv != (size_t)1) { retval = FAIL; - if (retval == FAIL) + } + if (retval == FAIL) { EMSG(_(e_write)); + } return retval; } @@ -4553,54 +4734,54 @@ theend: // space. static void clear_node(wordnode_T *node) { - wordnode_T *np; + wordnode_T *np; - if (node != NULL) + if (node != NULL) { for (np = node; np != NULL; np = np->wn_sibling) { np->wn_u1.index = 0; np->wn_u2.wnode = NULL; - if (np->wn_byte != NUL) + if (np->wn_byte != NUL) { clear_node(np->wn_child); + } } + } } -// Dump a word tree at node "node". -// -// This first writes the list of possible bytes (siblings). Then for each -// byte recursively write the children. -// -// NOTE: The code here must match the code in read_tree_node(), since -// assumptions are made about the indexes (so that we don't have to write them -// in the file). -// -// Returns the number of nodes used. -static int -put_node ( - FILE *fd, // NULL when only counting - wordnode_T *node, - int idx, - int regionmask, - bool prefixtree // true for PREFIXTREE -) +/// Dump a word tree at node "node". +/// +/// This first writes the list of possible bytes (siblings). Then for each +/// byte recursively write the children. +/// +/// NOTE: The code here must match the code in read_tree_node(), since +/// assumptions are made about the indexes (so that we don't have to write them +/// in the file). +/// +/// @param fd NULL when only counting +/// @param prefixtree true for PREFIXTREE +/// +/// @return the number of nodes used. +static int put_node(FILE *fd, wordnode_T *node, int idx, int regionmask, bool prefixtree) { // If "node" is zero the tree is empty. - if (node == NULL) + if (node == NULL) { return 0; + } // Store the index where this node is written. node->wn_u1.index = idx; // Count the number of siblings. int siblingcount = 0; - for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) + for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) { ++siblingcount; + } // Write the sibling count. - if (fd != NULL) + if (fd != NULL) { putc(siblingcount, fd); // <siblingcount> - + } // Write each sibling byte and optionally extra info. for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) { if (np->wn_byte == 0) { @@ -4611,9 +4792,9 @@ put_node ( // associated condition nr (stored in wn_region). The // byte value is misused to store the "rare" and "not // combining" flags - if (np->wn_flags == (uint16_t)PFX_FLAGS) + if (np->wn_flags == (uint16_t)PFX_FLAGS) { putc(BY_NOFLAGS, fd); // <byte> - else { + } else { putc(BY_FLAGS, fd); // <byte> putc(np->wn_flags, fd); // <pflags> } @@ -4622,10 +4803,12 @@ put_node ( } else { // For word trees we write the flag/region items. int flags = np->wn_flags; - if (regionmask != 0 && np->wn_region != regionmask) + if (regionmask != 0 && np->wn_region != regionmask) { flags |= WF_REGION; - if (np->wn_affixID != 0) + } + if (np->wn_affixID != 0) { flags |= WF_AFX; + } if (flags == 0) { // word without flags or region putc(BY_NOFLAGS, fd); // <byte> @@ -4638,10 +4821,12 @@ put_node ( putc(BY_FLAGS, fd); // <byte> putc(flags, fd); // <flags> } - if (flags & WF_REGION) + if (flags & WF_REGION) { putc(np->wn_region, fd); // <region> - if (flags & WF_AFX) + } + if (flags & WF_AFX) { putc(np->wn_affixID, fd); // <affixID> + } } } } @@ -4653,15 +4838,17 @@ put_node ( putc(BY_INDEX, fd); // <byte> put_bytes(fd, (uintmax_t)np->wn_child->wn_u1.index, 3); // <nodeidx> } - } else if (np->wn_child->wn_u2.wnode == NULL) + } else if (np->wn_child->wn_u2.wnode == NULL) { // We will write the child below and give it an index. np->wn_child->wn_u2.wnode = node; + } - if (fd != NULL) + if (fd != NULL) { if (putc(np->wn_byte, fd) == EOF) { // <byte> or <xbyte> EMSG(_(e_write)); return 0; } + } } } @@ -4670,10 +4857,12 @@ put_node ( int newindex = idx + siblingcount + 1; // Recursively dump the children of each sibling. - for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) - if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node) + for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) { + if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node) { newindex = put_node(fd, np->wn_child, newindex, regionmask, - prefixtree); + prefixtree); + } + } return newindex; } @@ -4684,8 +4873,8 @@ put_node ( void ex_mkspell(exarg_T *eap) { int fcount; - char_u **fnames; - char_u *arg = eap->arg; + char_u **fnames; + char_u *arg = eap->arg; bool ascii = false; if (STRNCMP(arg, "-ascii", 6) == 0) { @@ -4705,9 +4894,9 @@ void ex_mkspell(exarg_T *eap) // Writes the file with the name "wfname", with ".spl" changed to ".sug". static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname) { - char_u *fname = NULL; + char_u *fname = NULL; int len; - slang_T *slang; + slang_T *slang; bool free_slang = false; // Read back the .spl file that was written. This fills the required @@ -4724,8 +4913,9 @@ static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname) if (slang == NULL) { spell_message(spin, (char_u *)_("Reading back spell file...")); slang = spell_load_file(wfname, NULL, NULL, false); - if (slang == NULL) + if (slang == NULL) { return; + } free_slang = true; } @@ -4740,15 +4930,17 @@ static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname) // Go through the trie of good words, soundfold each word and add it to // the soundfold trie. spell_message(spin, (char_u *)_("Performing soundfolding...")); - if (sug_filltree(spin, slang) == FAIL) + if (sug_filltree(spin, slang) == FAIL) { goto theend; + } // Create the table which links each soundfold word with a list of the // good words it may come from. Creates buffer "spin->si_spellbuf". // This also removes the wordnr from the NUL byte entries to make // compression possible. - if (sug_maketable(spin) == FAIL) + if (sug_maketable(spin) == FAIL) { goto theend; + } smsg(_("Number of words after soundfolding: %" PRId64), (int64_t)spin->si_spellbuf->b_ml.ml_line_count); @@ -4768,8 +4960,9 @@ static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname) theend: xfree(fname); - if (free_slang) + if (free_slang) { slang_free(slang); + } free_blocks(spin->si_blocks); close_spellbuf(spin->si_spellbuf); } @@ -4777,8 +4970,8 @@ theend: // Build the soundfold trie for language "slang". static int sug_filltree(spellinfo_T *spin, slang_T *slang) { - char_u *byts; - idx_T *idxs; + char_u *byts; + idx_T *idxs; int depth; idx_T arridx[MAXWLEN]; int curi[MAXWLEN]; @@ -4809,13 +5002,13 @@ static int sug_filltree(spellinfo_T *spin, slang_T *slang) if (curi[depth] > byts[arridx[depth]]) { // Done all bytes at this node, go up one level. idxs[arridx[depth]] = wordcount[depth]; - if (depth > 0) + if (depth > 0) { wordcount[depth - 1] += wordcount[depth]; + } --depth; line_breakcheck(); } else { - // Do one more byte at this node. n = arridx[depth] + curi[depth]; ++curi[depth]; @@ -4829,9 +5022,10 @@ static int sug_filltree(spellinfo_T *spin, slang_T *slang) // We use the "flags" field for the MSB of the wordnr, // "region" for the LSB of the wordnr. if (tree_add_word(spin, tsalword, spin->si_foldroot, - words_done >> 16, words_done & 0xffff, - 0) == FAIL) + words_done >> 16, words_done & 0xffff, + 0) == FAIL) { return FAIL; + } ++words_done; ++wordcount[depth]; @@ -4880,25 +5074,22 @@ static int sug_maketable(spellinfo_T *spin) ga_init(&ga, 1, 100); // recursively go through the tree - if (sug_filltable(spin, spin->si_foldroot->wn_sibling, 0, &ga) == -1) + if (sug_filltable(spin, spin->si_foldroot->wn_sibling, 0, &ga) == -1) { res = FAIL; + } ga_clear(&ga); return res; } -// Fill the table for one node and its children. -// Returns the wordnr at the start of the node. -// Returns -1 when out of memory. -static int -sug_filltable ( - spellinfo_T *spin, - wordnode_T *node, - int startwordnr, - garray_T *gap // place to store line of numbers -) +/// Fill the table for one node and its children. +/// Returns the wordnr at the start of the node. +/// Returns -1 when out of memory. +/// +/// @param gap place to store line of numbers +static int sug_filltable(spellinfo_T *spin, wordnode_T *node, int startwordnr, garray_T *gap) { - wordnode_T *p, *np; + wordnode_T *p, *np; int wordnr = startwordnr; int nr; int prev_nr; @@ -4918,7 +5109,7 @@ sug_filltable ( nr -= prev_nr; prev_nr += nr; gap->ga_len += offset2bytes(nr, - (char_u *)gap->ga_data + gap->ga_len); + (char_u *)gap->ga_data + gap->ga_len); } // add the NUL byte @@ -4932,8 +5123,9 @@ sug_filltable ( // Remove extra NUL entries, we no longer need them. We don't // bother freeing the nodes, the won't be reused anyway. - while (p->wn_sibling != NULL && p->wn_sibling->wn_byte == NUL) + while (p->wn_sibling != NULL && p->wn_sibling->wn_byte == NUL) { p->wn_sibling = p->wn_sibling->wn_sibling; + } // Clear the flags on the remaining NUL node, so that compression // works a lot better. @@ -4941,8 +5133,9 @@ sug_filltable ( p->wn_region = 0; } else { wordnr = sug_filltable(spin, p->wn_child, wordnr, gap); - if (wordnr == -1) + if (wordnr == -1) { return -1; + } } } return wordnr; @@ -5002,7 +5195,7 @@ static void sug_write(spellinfo_T *spin, char_u *fname) spell_message(spin, IObuff); // <SUGHEADER>: <fileID> <versionnr> <timestamp> - if (fwrite(VIMSUGMAGIC, VIMSUGMAGICL, (size_t)1, fd) != 1) { // <fileID> + if (fwrite(VIMSUGMAGIC, VIMSUGMAGICL, (size_t)1, fd) != 1) { // <fileID> EMSG(_(e_write)); goto theend; } @@ -5049,11 +5242,12 @@ static void sug_write(spellinfo_T *spin, char_u *fname) } // Write another byte to check for errors. - if (putc(0, fd) == EOF) + if (putc(0, fd) == EOF) { EMSG(_(e_write)); + } vim_snprintf((char *)IObuff, IOSIZE, - _("Estimated runtime memory use: %d bytes"), spin->si_memtot); + _("Estimated runtime memory use: %d bytes"), spin->si_memtot); spell_message(spin, IObuff); theend: @@ -5062,23 +5256,20 @@ theend: } -// Create a Vim spell file from one or more word lists. -// "fnames[0]" is the output file name. -// "fnames[fcount - 1]" is the last input file name. -// Exception: when "fnames[0]" ends in ".add" it's used as the input file name -// and ".spl" is appended to make the output file name. -static void -mkspell ( - int fcount, - char_u **fnames, - bool ascii, // -ascii argument given - bool over_write, // overwrite existing output file - bool added_word // invoked through "zg" -) +/// Create a Vim spell file from one or more word lists. +/// "fnames[0]" is the output file name. +/// "fnames[fcount - 1]" is the last input file name. +/// Exception: when "fnames[0]" ends in ".add" it's used as the input file name +/// and ".spl" is appended to make the output file name. +/// +/// @param ascii -ascii argument given +/// @param over_write overwrite existing output file +/// @param added_word invoked through "zg" +static void mkspell(int fcount, char_u **fnames, bool ascii, bool over_write, bool added_word) { - char_u *fname = NULL; - char_u *wfname; - char_u **innames; + char_u *fname = NULL; + char_u *wfname; + char_u **innames; int incount; afffile_T *(afile[MAXREGIONS]); int i; @@ -5114,26 +5305,29 @@ mkspell ( // "path/en.latin1.add.spl". incount = 1; vim_snprintf((char *)wfname, MAXPATHL, "%s.spl", fnames[0]); - } else if (fcount == 1) { + } else if (fcount == 1) { // For ":mkspell path/vim" output file is "path/vim.latin1.spl". incount = 1; vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL, - fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc()); - } else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0) { + fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc()); + } else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0) { // Name ends in ".spl", use as the file name. STRLCPY(wfname, fnames[0], MAXPATHL); - } else + } else { // Name should be language, make the file name from it. vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL, - fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc()); + fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc()); + } // Check for .ascii.spl. - if (strstr((char *)path_tail(wfname), SPL_FNAME_ASCII) != NULL) + if (strstr((char *)path_tail(wfname), SPL_FNAME_ASCII) != NULL) { spin.si_ascii = true; + } // Check for .add.spl. - if (strstr((char *)path_tail(wfname), SPL_FNAME_ADD) != NULL) + if (strstr((char *)path_tail(wfname), SPL_FNAME_ADD) != NULL) { spin.si_add = true; + } } if (incount <= 0) { @@ -5184,8 +5378,9 @@ mkspell ( // one in the .spl file if the .aff file doesn't define one. That's // better than guessing the contents, the table will match a // previously loaded spell file. - if (!spin.si_add) + if (!spin.si_add) { spin.si_clear_chartab = true; + } // Read all the .aff and .dic files. // Text is converted to 'encoding'. @@ -5199,28 +5394,31 @@ mkspell ( // Read the .aff file. Will init "spin->si_conv" based on the // "SET" line. afile[i] = spell_read_aff(&spin, fname); - if (afile[i] == NULL) + if (afile[i] == NULL) { error = true; - else { + } else { // Read the .dic file and store the words in the trees. vim_snprintf((char *)fname, MAXPATHL, "%s.dic", - innames[i]); - if (spell_read_dic(&spin, fname, afile[i]) == FAIL) + innames[i]); + if (spell_read_dic(&spin, fname, afile[i]) == FAIL) { error = true; + } } } else { // No .aff file, try reading the file as a word list. Store // the words in the trees. - if (spell_read_wordfile(&spin, innames[i]) == FAIL) + if (spell_read_wordfile(&spin, innames[i]) == FAIL) { error = true; + } } // Free any conversion stuff. convert_setup(&spin.si_conv, NULL, NULL); } - if (spin.si_compflags != NULL && spin.si_nobreak) + if (spin.si_compflags != NULL && spin.si_nobreak) { MSG(_("Warning: both compounding and NOBREAK specified")); + } if (!error && !got_int) { // Combine tails in the tree. @@ -5240,12 +5438,13 @@ mkspell ( spell_message(&spin, (char_u *)_("Done!")); vim_snprintf((char *)IObuff, IOSIZE, - _("Estimated runtime memory use: %d bytes"), spin.si_memtot); + _("Estimated runtime memory use: %d bytes"), spin.si_memtot); spell_message(&spin, IObuff); // If the file is loaded need to reload it. - if (!error) + if (!error) { spell_reload_one(wfname, added_word); + } } // Free the allocated memory. @@ -5258,18 +5457,20 @@ mkspell ( hash_clear_all(&spin.si_commonwords, 0); // Free the .aff file structures. - for (i = 0; i < incount; ++i) - if (afile[i] != NULL) + for (i = 0; i < incount; ++i) { + if (afile[i] != NULL) { spell_free_aff(afile[i]); + } + } // Free all the bits and pieces at once. free_blocks(spin.si_blocks); // If there is soundfolding info and no NOSUGFILE item create the // .sug file with the soundfolded word trie. - if (spin.si_sugtime != 0 && !error && !got_int) + if (spin.si_sugtime != 0 && !error && !got_int) { spell_make_sugfile(&spin, wfname); - + } } theend: @@ -5283,12 +5484,14 @@ static void spell_message(const spellinfo_T *spin, char_u *str) FUNC_ATTR_NONNULL_ALL { if (spin->si_verbose || p_verbose > 2) { - if (!spin->si_verbose) + if (!spin->si_verbose) { verbose_enter(); + } MSG(str); ui_flush(); - if (!spin->si_verbose) + if (!spin->si_verbose) { verbose_leave(); + } } } @@ -5305,32 +5508,29 @@ void ex_spell(exarg_T *eap) eap->cmdidx == CMD_spellundo); } -// Add "word[len]" to 'spellfile' as a good or bad word. -void -spell_add_word ( - char_u *word, - int len, - SpellAddType what, // SPELL_ADD_ values - int idx, // "zG" and "zW": zero, otherwise index in - // 'spellfile' - bool undo // true for "zug", "zuG", "zuw" and "zuW" -) +/// Add "word[len]" to 'spellfile' as a good or bad word. +/// +/// @param what SPELL_ADD_ values +/// @param idx "zG" and "zW": zero, otherwise index in 'spellfile' +/// @param bool // true for "zug", "zuG", "zuw" and "zuW" +void spell_add_word(char_u *word, int len, SpellAddType what, int idx, bool undo) { - FILE *fd = NULL; - buf_T *buf = NULL; + FILE *fd = NULL; + buf_T *buf = NULL; bool new_spf = false; - char_u *fname; - char_u *fnamebuf = NULL; + char_u *fname; + char_u *fnamebuf = NULL; char_u line[MAXWLEN * 2]; long fpos, fpos_next = 0; int i; - char_u *spf; + char_u *spf; if (idx == 0) { // use internal wordlist if (int_wordlist == NULL) { int_wordlist = vim_tempname(); - if (int_wordlist == NULL) + if (int_wordlist == NULL) { return; + } } fname = int_wordlist; } else { @@ -5348,8 +5548,9 @@ spell_add_word ( for (spf = curwin->w_s->b_p_spf, i = 1; *spf != NUL; ++i) { copy_option_part(&spf, fnamebuf, MAXPATHL, ","); - if (i == idx) + if (i == idx) { break; + } if (*spf == NUL) { EMSGN(_("E765: 'spellfile' does not have %" PRId64 " entries"), idx); xfree(fnamebuf); @@ -5359,8 +5560,9 @@ spell_add_word ( // Check that the user isn't editing the .add file somewhere. buf = buflist_findname_exp(fnamebuf); - if (buf != NULL && buf->b_ml.ml_mfp == NULL) + if (buf != NULL && buf->b_ml.ml_mfp == NULL) { buf = NULL; + } if (buf != NULL && bufIsChanged(buf)) { EMSG(_(e_bufloaded)); xfree(fnamebuf); @@ -5402,8 +5604,9 @@ spell_add_word ( } } } - if (fd != NULL) + if (fd != NULL) { fclose(fd); + } } } @@ -5450,8 +5653,9 @@ spell_add_word ( mkspell(1, &fname, false, true, true); // If the .add file is edited somewhere, reload it. - if (buf != NULL) + if (buf != NULL) { buf_reload(buf, buf->b_orig_mode); + } redraw_all_later(SOME_VALID); } @@ -5461,13 +5665,13 @@ spell_add_word ( // Initialize 'spellfile' for the current buffer. static void init_spellfile(void) { - char_u *buf; + char_u *buf; int l; - char_u *fname; - char_u *rtp; - char_u *lend; + char_u *fname; + char_u *rtp; + char_u *lend; bool aspath = false; - char_u *lstart = curbuf->b_s.b_p_spl; + char_u *lstart = curbuf->b_s.b_p_spl; if (*curwin->w_s->b_p_spl != NUL && !GA_EMPTY(&curwin->w_s->b_langp)) { buf = xmalloc(MAXPATHL); @@ -5475,31 +5679,33 @@ static void init_spellfile(void) // Find the end of the language name. Exclude the region. If there // is a path separator remember the start of the tail. for (lend = curwin->w_s->b_p_spl; *lend != NUL - && vim_strchr((char_u *)",._", *lend) == NULL; ++lend) + && vim_strchr((char_u *)",._", *lend) == NULL; ++lend) { if (vim_ispathsep(*lend)) { aspath = true; lstart = lend + 1; } + } // Loop over all entries in 'runtimepath'. Use the first one where we // are allowed to write. rtp = p_rtp; while (*rtp != NUL) { - if (aspath) + if (aspath) { // Use directory of an entry with path, e.g., for // "/dir/lg.utf-8.spl" use "/dir". STRLCPY(buf, curbuf->b_s.b_p_spl, - lstart - curbuf->b_s.b_p_spl); - else + lstart - curbuf->b_s.b_p_spl); + } else { // Copy the path from 'runtimepath' to buf[]. copy_option_part(&rtp, buf, MAXPATHL, ","); + } if (os_file_is_writable((char *)buf) == 2) { // Use the first language name from 'spelllang' and the // encoding used in the first loaded .spl file. - if (aspath) + if (aspath) { STRLCPY(buf, curbuf->b_s.b_p_spl, - lend - curbuf->b_s.b_p_spl + 1); - else { + lend - curbuf->b_s.b_p_spl + 1); + } else { // Create the "spell" directory if it doesn't exist yet. l = (int)STRLEN(buf); vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell"); @@ -5509,7 +5715,7 @@ static void init_spellfile(void) l = (int)STRLEN(buf); vim_snprintf((char *)buf + l, MAXPATHL - l, - "/%.*s", (int)(lend - lstart), lstart); + "/%.*s", (int)(lend - lstart), lstart); } l = (int)STRLEN(buf); fname = LANGP_ENTRY(curwin->w_s->b_langp, 0) @@ -5529,19 +5735,16 @@ static void init_spellfile(void) } } -// Set the spell character tables from strings in the .spl file. -static void -set_spell_charflags ( - char_u *flags, - int cnt, // length of "flags" - char_u *fol -) +/// Set the spell character tables from strings in the .spl file. +/// +/// @param cnt length of "flags" +static void set_spell_charflags(char_u *flags, int cnt, char_u *fol) { // We build the new tables here first, so that we can compare with the // previous one. spelltab_T new_st; int i; - char_u *p = fol; + char_u *p = fol; int c; clear_spell_chartab(&new_st); @@ -5555,8 +5758,9 @@ set_spell_charflags ( if (*p != NUL) { c = mb_ptr2char_adv((const char_u **)&p); new_st.st_fold[i + 128] = c; - if (i + 128 != c && new_st.st_isu[i + 128] && c < 256) + if (i + 128 != c && new_st.st_isu[i + 128] && c < 256) { new_st.st_upper[c] = i + 128; + } } } @@ -5593,9 +5797,9 @@ static int write_spell_prefcond(FILE *fd, garray_T *gap) { assert(gap->ga_len >= 0); - if (fd != NULL) + if (fd != NULL) { put_bytes(fd, (uintmax_t)gap->ga_len, 2); // <prefcondcnt> - + } size_t totlen = 2 + (size_t)gap->ga_len; // <prefcondcnt> and <condlen> bytes size_t x = 1; // collect return value of fwrite() for (int i = 0; i < gap->ga_len; ++i) { @@ -5609,8 +5813,9 @@ static int write_spell_prefcond(FILE *fd, garray_T *gap) x &= fwrite(p, len, 1, fd); } totlen += len; - } else if (fd != NULL) + } else if (fd != NULL) { fputc(0, fd); + } } assert(totlen <= INT_MAX); @@ -5620,7 +5825,7 @@ static int write_spell_prefcond(FILE *fd, garray_T *gap) // Use map string "map" for languages "lp". static void set_map_str(slang_T *lp, char_u *map) { - char_u *p; + char_u *p; int headc = 0; int c; int i; @@ -5632,8 +5837,9 @@ static void set_map_str(slang_T *lp, char_u *map) lp->sl_has_map = true; // Init the array and hash tables empty. - for (i = 0; i < 256; ++i) + for (i = 0; i < 256; ++i) { lp->sl_map_array[i] = 0; + } hash_init(&lp->sl_map_hash); // The similar characters are stored separated with slashes: @@ -5654,9 +5860,9 @@ static void set_map_str(slang_T *lp, char_u *map) if (c >= 256) { int cl = mb_char2len(c); int headcl = mb_char2len(headc); - char_u *b; + char_u *b; hash_T hash; - hashitem_T *hi; + hashitem_T *hi; b = xmalloc(cl + headcl + 2); utf_char2bytes(c, b); @@ -5673,8 +5879,9 @@ static void set_map_str(slang_T *lp, char_u *map) EMSG(_("E783: duplicate char in MAP entry")); xfree(b); } - } else + } else { lp->sl_map_array[c] = headc; + } } } } diff --git a/src/nvim/spellfile.h b/src/nvim/spellfile.h index 633ee014a7..235bc07f61 100644 --- a/src/nvim/spellfile.h +++ b/src/nvim/spellfile.h @@ -3,9 +3,9 @@ #include <stdbool.h> +#include "nvim/ex_cmds_defs.h" #include "nvim/spell_defs.h" #include "nvim/types.h" -#include "nvim/ex_cmds_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "spellfile.h.generated.h" diff --git a/src/nvim/state.c b/src/nvim/state.c index 02d63d8ab1..4eb0073873 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -3,19 +3,18 @@ #include <assert.h> -#include "nvim/lib/kvec.h" - #include "nvim/ascii.h" +#include "nvim/edit.h" +#include "nvim/ex_docmd.h" +#include "nvim/getchar.h" +#include "nvim/lib/kvec.h" #include "nvim/log.h" -#include "nvim/state.h" -#include "nvim/vim.h" #include "nvim/main.h" -#include "nvim/getchar.h" #include "nvim/option_defs.h" -#include "nvim/ui.h" #include "nvim/os/input.h" -#include "nvim/ex_docmd.h" -#include "nvim/edit.h" +#include "nvim/state.h" +#include "nvim/ui.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "state.c.generated.h" @@ -162,6 +161,11 @@ char *get_mode(void) if (State & VREPLACE_FLAG) { buf[0] = 'R'; buf[1] = 'v'; + if (ins_compl_active()) { + buf[2] = 'c'; + } else if (ctrl_x_mode_not_defined_yet()) { + buf[2] = 'x'; + } } else { if (State & REPLACE_FLAG) { buf[0] = 'R'; @@ -191,6 +195,8 @@ char *get_mode(void) || restart_edit == 'V') { buf[1] = 'i'; buf[2] = (char)restart_edit; + } else if (curbuf->terminal) { + buf[1] = 't'; } } diff --git a/src/nvim/state.h b/src/nvim/state.h index 8027514148..b93d57d035 100644 --- a/src/nvim/state.h +++ b/src/nvim/state.h @@ -5,8 +5,8 @@ typedef struct vim_state VimState; -typedef int(*state_check_callback)(VimState *state); -typedef int(*state_execute_callback)(VimState *state, int key); +typedef int (*state_check_callback)(VimState *state); +typedef int (*state_execute_callback)(VimState *state, int key); struct vim_state { state_check_callback check; diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 79a3db4843..11c1aa1760 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -1,28 +1,26 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +#include <assert.h> #include <inttypes.h> +#include <math.h> #include <stdarg.h> #include <stdbool.h> #include <string.h> -#include <math.h> -#include <assert.h> -#include "nvim/assert.h" -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/strings.h" -#include "nvim/file_search.h" +#include "nvim/assert.h" #include "nvim/buffer.h" #include "nvim/charset.h" #include "nvim/diff.h" #include "nvim/edit.h" #include "nvim/eval.h" +#include "nvim/eval/encode.h" #include "nvim/ex_cmds.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" +#include "nvim/file_search.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/fold.h" #include "nvim/func_attr.h" #include "nvim/getchar.h" @@ -35,8 +33,10 @@ #include "nvim/message.h" #include "nvim/misc1.h" #include "nvim/move.h" -#include "nvim/option.h" #include "nvim/ops.h" +#include "nvim/option.h" +#include "nvim/os/os.h" +#include "nvim/os/shell.h" #include "nvim/os_unix.h" #include "nvim/path.h" #include "nvim/quickfix.h" @@ -44,12 +44,11 @@ #include "nvim/screen.h" #include "nvim/search.h" #include "nvim/spell.h" +#include "nvim/strings.h" #include "nvim/syntax.h" #include "nvim/tag.h" +#include "nvim/vim.h" #include "nvim/window.h" -#include "nvim/os/os.h" -#include "nvim/os/shell.h" -#include "nvim/eval/encode.h" /// Copy "string" into newly allocated memory. char_u *vim_strsave(const char_u *string) @@ -84,8 +83,7 @@ char_u *vim_strsave_escaped(const char_u *string, const char_u *esc_chars) * characters where rem_backslash() would remove the backslash. * Escape the characters with "cc". */ -char_u *vim_strsave_escaped_ext(const char_u *string, const char_u *esc_chars, - char_u cc, bool bsl) +char_u *vim_strsave_escaped_ext(const char_u *string, const char_u *esc_chars, char_u cc, bool bsl) FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL { /* @@ -100,9 +98,10 @@ char_u *vim_strsave_escaped_ext(const char_u *string, const char_u *esc_chars, p += l - 1; continue; } - if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p))) - ++length; /* count a backslash */ - ++length; /* count an ordinary char */ + if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p))) { + ++length; // count a backslash + } + ++length; // count an ordinary char } char_u *escaped_string = xmalloc(length); @@ -112,11 +111,12 @@ char_u *vim_strsave_escaped_ext(const char_u *string, const char_u *esc_chars, if (l > 1) { memcpy(p2, p, l); p2 += l; - p += l - 1; /* skip multibyte char */ + p += l - 1; // skip multibyte char continue; } - if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p))) + if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p))) { *p2++ = cc; + } *p2++ = *p; } *p2 = NUL; @@ -182,12 +182,11 @@ char *vim_strnsave_unquoted(const char *const string, const size_t length) * When "do_newline" is false do not escape newline unless it is csh shell. * Returns the result in allocated memory. */ -char_u *vim_strsave_shellescape(const char_u *string, - bool do_special, bool do_newline) +char_u *vim_strsave_shellescape(const char_u *string, bool do_special, bool do_newline) FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL { - char_u *d; - char_u *escaped_string; + char_u *d; + char_u *escaped_string; size_t l; int csh_like; bool fish_like; @@ -202,7 +201,7 @@ char_u *vim_strsave_shellescape(const char_u *string, // itself must be escaped to get a literal '\'. fish_like = fish_like_shell(); - /* First count the number of extra bytes required. */ + // First count the number of extra bytes required. size_t length = STRLEN(string) + 3; // two quotes and a trailing NUL for (const char_u *p = string; *p != NUL; MB_PTR_ADV(p)) { #ifdef WIN32 @@ -217,12 +216,13 @@ char_u *vim_strsave_shellescape(const char_u *string, } if ((*p == '\n' && (csh_like || do_newline)) || (*p == '!' && (csh_like || do_special))) { - ++length; /* insert backslash */ - if (csh_like && do_special) - ++length; /* insert backslash */ + ++length; // insert backslash + if (csh_like && do_special) { + ++length; // insert backslash + } } if (do_special && find_cmdline_var(p, &l) >= 0) { - ++length; /* insert backslash */ + ++length; // insert backslash p += l - 1; } if (*p == '\\' && fish_like) { @@ -230,7 +230,7 @@ char_u *vim_strsave_shellescape(const char_u *string, } } - /* Allocate memory for the result and fill it. */ + // Allocate memory for the result and fill it. escaped_string = xmalloc(length); d = escaped_string; @@ -264,15 +264,17 @@ char_u *vim_strsave_shellescape(const char_u *string, if ((*p == '\n' && (csh_like || do_newline)) || (*p == '!' && (csh_like || do_special))) { *d++ = '\\'; - if (csh_like && do_special) + if (csh_like && do_special) { *d++ = '\\'; + } *d++ = *p++; continue; } if (do_special && find_cmdline_var(p, &l) >= 0) { - *d++ = '\\'; /* insert backslash */ - while (--l != SIZE_MAX) /* copy the var */ + *d++ = '\\'; // insert backslash + while (--l != SIZE_MAX) { // copy the var *d++ = *p++; + } continue; } if (*p == '\\' && fish_like) { @@ -285,11 +287,11 @@ char_u *vim_strsave_shellescape(const char_u *string, } // add terminating quote and finish with a NUL -# ifdef WIN32 +#ifdef WIN32 if (!p_ssl) { *d++ = '"'; } else -# endif +#endif *d++ = '\''; *d = NUL; @@ -384,11 +386,12 @@ char *strcase_save(const char *const orig, bool upper) void del_trailing_spaces(char_u *ptr) FUNC_ATTR_NONNULL_ALL { - char_u *q; + char_u *q; q = ptr + STRLEN(ptr); - while (--q > ptr && ascii_iswhite(q[0]) && q[-1] != '\\' && q[-1] != Ctrl_V) + while (--q > ptr && ascii_iswhite(q[0]) && q[-1] != '\\' && q[-1] != Ctrl_V) { *q = NUL; + } } #if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP)) @@ -404,14 +407,16 @@ int vim_stricmp(const char *s1, const char *s2) for (;; ) { i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2); - if (i != 0) - return i; /* this character different */ - if (*s1 == NUL) - break; /* strings match until NUL */ + if (i != 0) { + return i; // this character different + } + if (*s1 == NUL) { + break; // strings match until NUL + } ++s1; ++s2; } - return 0; /* strings match */ + return 0; // strings match } #endif @@ -428,15 +433,17 @@ int vim_strnicmp(const char *s1, const char *s2, size_t len) while (len > 0) { i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2); - if (i != 0) - return i; /* this character different */ - if (*s1 == NUL) - break; /* strings match until NUL */ + if (i != 0) { + return i; // this character different + } + if (*s1 == NUL) { + break; // strings match until NUL + } ++s1; ++s2; --len; } - return 0; /* strings match */ + return 0; // strings match } #endif @@ -490,10 +497,13 @@ bool has_non_ascii(const char_u *s) { const char_u *p; - if (s != NULL) - for (p = s; *p != NUL; ++p) - if (*p >= 128) + if (s != NULL) { + for (p = s; *p != NUL; ++p) { + if (*p >= 128) { return true; + } + } + } return false; } @@ -504,7 +514,7 @@ bool has_non_ascii_len(const char *const s, const size_t len) { if (s != NULL) { for (size_t i = 0; i < len; i++) { - if ((uint8_t) s[i] >= 128) { + if ((uint8_t)s[i] >= 128) { return true; } } @@ -527,7 +537,7 @@ char_u *concat_str(const char_u *restrict str1, const char_u *restrict str2) static const char *const e_printf = - N_("E766: Insufficient arguments for printf()"); + N_("E766: Insufficient arguments for printf()"); /// Get number argument from idxp entry in tvs /// @@ -606,15 +616,14 @@ static const void *tv_ptr(const typval_T *const tvs, int *const idxp) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { #define OFF(attr) offsetof(union typval_vval_union, attr) - STATIC_ASSERT( - OFF(v_string) == OFF(v_list) - && OFF(v_string) == OFF(v_dict) - && OFF(v_string) == OFF(v_partial) - && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_list) - && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_dict) - && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_partial), - "Strings, dictionaries, lists and partials are expected to be pointers, " - "so that all three of them can be accessed via v_string"); + STATIC_ASSERT(OFF(v_string) == OFF(v_list) + && OFF(v_string) == OFF(v_dict) + && OFF(v_string) == OFF(v_partial) + && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_list) + && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_dict) + && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_partial), + "Strings, dictionaries, lists and partials are expected to be pointers, " + "so that all three of them can be accessed via v_string"); #undef OFF const int idx = *idxp - 1; if (tvs[idx].v_type == VAR_UNKNOWN) { @@ -735,8 +744,8 @@ int vim_snprintf(char *str, size_t str_m, const char *fmt, ...) // Return the representation of infinity for printf() function: // "-inf", "inf", "+inf", " inf", "-INF", "INF", "+INF" or " INF". -static const char *infinity_str(bool positive, char fmt_spec, - int force_sign, int space_for_positive) +static const char *infinity_str(bool positive, char fmt_spec, int force_sign, + int space_for_positive) { static const char *table[] = { "-inf", "inf", "+inf", " inf", @@ -765,8 +774,7 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) /// /// @return Number of bytes excluding NUL byte that would be written to the /// string if str_m was greater or equal to the return value. -int vim_vsnprintf_typval( - char *str, size_t str_m, const char *fmt, va_list ap, typval_T *const tvs) +int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap, typval_T *const tvs) { size_t str_l = 0; bool str_avail = str_l < str_m; @@ -800,7 +808,7 @@ int vim_vsnprintf_typval( char length_modifier = '\0'; // temporary buffer for simple numeric->string conversion -# define TMP_LEN 350 // 1e308 seems reasonable as the maximum printable +#define TMP_LEN 350 // 1e308 seems reasonable as the maximum printable char tmp[TMP_LEN]; // string address in case of string argument @@ -832,15 +840,22 @@ int vim_vsnprintf_typval( // parse flags while (true) { switch (*p) { - case '0': zero_padding = 1; p++; continue; - case '-': justify_left = 1; p++; continue; - // if both '0' and '-' flags appear, '0' should be ignored - case '+': force_sign = 1; space_for_positive = 0; p++; continue; - case ' ': force_sign = 1; p++; continue; - // if both ' ' and '+' flags appear, ' ' should be ignored - case '#': alternate_form = 1; p++; continue; - case '\'': p++; continue; - default: break; + case '0': + zero_padding = 1; p++; continue; + case '-': + justify_left = 1; p++; continue; + // if both '0' and '-' flags appear, '0' should be ignored + case '+': + force_sign = 1; space_for_positive = 0; p++; continue; + case ' ': + force_sign = 1; p++; continue; + // if both ' ' and '+' flags appear, ' ' should be ignored + case '#': + alternate_form = 1; p++; continue; + case '\'': + p++; continue; + default: + break; } break; } @@ -905,444 +920,447 @@ int vim_vsnprintf_typval( // common synonyms switch (fmt_spec) { - case 'i': fmt_spec = 'd'; break; - case 'D': fmt_spec = 'd'; length_modifier = 'l'; break; - case 'U': fmt_spec = 'u'; length_modifier = 'l'; break; - case 'O': fmt_spec = 'o'; length_modifier = 'l'; break; - default: break; + case 'i': + fmt_spec = 'd'; break; + case 'D': + fmt_spec = 'd'; length_modifier = 'l'; break; + case 'U': + fmt_spec = 'u'; length_modifier = 'l'; break; + case 'O': + fmt_spec = 'o'; length_modifier = 'l'; break; + default: + break; } switch (fmt_spec) { - case 'b': case 'B': - case 'd': case 'u': case 'o': case 'x': case 'X': - if (tvs && length_modifier == '\0') { - length_modifier = '2'; - } + case 'b': + case 'B': + case 'd': + case 'u': + case 'o': + case 'x': + case 'X': + if (tvs && length_modifier == '\0') { + length_modifier = '2'; + } } // get parameter value, do initial processing switch (fmt_spec) { - // '%' and 'c' behave similar to 's' regarding flags and field widths - case '%': case 'c': case 's': case 'S': - str_arg_l = 1; - switch (fmt_spec) { - case '%': - str_arg = p; - break; - - case 'c': { - const int j = tvs ? (int)tv_nr(tvs, &arg_idx) : va_arg(ap, int); - // standard demands unsigned char - uchar_arg = (unsigned char)j; - str_arg = (char *)&uchar_arg; - break; - } + // '%' and 'c' behave similar to 's' regarding flags and field widths + case '%': + case 'c': + case 's': + case 'S': + str_arg_l = 1; + switch (fmt_spec) { + case '%': + str_arg = p; + break; - case 's': - case 'S': - str_arg = tvs ? tv_str(tvs, &arg_idx, &tofree) - : va_arg(ap, const char *); - if (!str_arg) { - str_arg = "[NULL]"; - str_arg_l = 6; - } else if (!precision_specified) { - // make sure not to address string beyond the specified - // precision - str_arg_l = strlen(str_arg); - } else if (precision == 0) { - // truncate string if necessary as requested by precision - str_arg_l = 0; - } else { - // memchr on HP does not like n > 2^31 - // TODO(elmart): check if this still holds / is relevant - str_arg_l = (size_t)((char *)xmemscan(str_arg, - NUL, - MIN(precision, - 0x7fffffff)) - - str_arg); - } - if (fmt_spec == 'S') { - if (min_field_width != 0) { - min_field_width += (strlen(str_arg) - - mb_string2cells((char_u *)str_arg)); - } - if (precision) { - char_u *p1; - size_t i = 0; - - for (p1 = (char_u *)str_arg; *p1; - p1 += mb_ptr2len(p1)) { - i += (size_t)utf_ptr2cells(p1); - if (i > precision) { - break; - } - } - str_arg_l = (size_t)(p1 - (char_u *)str_arg); + case 'c': { + const int j = tvs ? (int)tv_nr(tvs, &arg_idx) : va_arg(ap, int); + // standard demands unsigned char + uchar_arg = (unsigned char)j; + str_arg = (char *)&uchar_arg; + break; + } + + case 's': + case 'S': + str_arg = tvs ? tv_str(tvs, &arg_idx, &tofree) + : va_arg(ap, const char *); + if (!str_arg) { + str_arg = "[NULL]"; + str_arg_l = 6; + } else if (!precision_specified) { + // make sure not to address string beyond the specified + // precision + str_arg_l = strlen(str_arg); + } else if (precision == 0) { + // truncate string if necessary as requested by precision + str_arg_l = 0; + } else { + // memchr on HP does not like n > 2^31 + // TODO(elmart): check if this still holds / is relevant + str_arg_l = (size_t)((char *)xmemscan(str_arg, + NUL, + MIN(precision, + 0x7fffffff)) + - str_arg); + } + if (fmt_spec == 'S') { + if (min_field_width != 0) { + min_field_width += (strlen(str_arg) + - mb_string2cells((char_u *)str_arg)); + } + if (precision) { + char_u *p1; + size_t i = 0; + + for (p1 = (char_u *)str_arg; *p1; + p1 += mb_ptr2len(p1)) { + i += (size_t)utf_ptr2cells(p1); + if (i > precision) { + break; } } - break; - - default: - break; + str_arg_l = (size_t)(p1 - (char_u *)str_arg); + } } break; - case 'd': - case 'u': - case 'b': case 'B': - case 'o': - case 'x': case 'X': - case 'p': { - // u, b, B, o, x, X and p conversion specifiers imply - // the value is unsigned; d implies a signed value - - // 0 if numeric argument is zero (or if pointer is NULL for 'p'), - // +1 if greater than zero (or non NULL for 'p'), - // -1 if negative (unsigned argument is never negative) - int arg_sign = 0; - - intmax_t arg = 0; - uintmax_t uarg = 0; - - // only defined for p conversion - const void *ptr_arg = NULL; - - if (fmt_spec == 'p') { - ptr_arg = tvs ? tv_ptr(tvs, &arg_idx) : va_arg(ap, void *); - if (ptr_arg) { - arg_sign = 1; - } - } else if (fmt_spec == 'd') { - // signed - switch (length_modifier) { - case '\0': { - arg = (int)(tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int)); - break; - } - case 'h': { - // char and short arguments are passed as int16_t - arg = (int16_t)(tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int)); - break; - } - case 'l': { - arg = (tvs ? (long)tv_nr(tvs, &arg_idx) : va_arg(ap, long)); - break; - } - case '2': { - arg = ( - tvs + default: + break; + } + break; + + case 'd': + case 'u': + case 'b': + case 'B': + case 'o': + case 'x': + case 'X': + case 'p': { + // u, b, B, o, x, X and p conversion specifiers imply + // the value is unsigned; d implies a signed value + + // 0 if numeric argument is zero (or if pointer is NULL for 'p'), + // +1 if greater than zero (or non NULL for 'p'), + // -1 if negative (unsigned argument is never negative) + int arg_sign = 0; + + intmax_t arg = 0; + uintmax_t uarg = 0; + + // only defined for p conversion + const void *ptr_arg = NULL; + + if (fmt_spec == 'p') { + ptr_arg = tvs ? tv_ptr(tvs, &arg_idx) : va_arg(ap, void *); + if (ptr_arg) { + arg_sign = 1; + } + } else if (fmt_spec == 'd') { + // signed + switch (length_modifier) { + case '\0': + arg = (int)(tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int)); + break; + case 'h': + // char and short arguments are passed as int16_t + arg = (int16_t)(tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int)); + break; + case 'l': + arg = (tvs ? (long)tv_nr(tvs, &arg_idx) : va_arg(ap, long)); + break; + case '2': + arg = ( + tvs ? (long long)tv_nr(tvs, &arg_idx) // NOLINT (runtime/int) : va_arg(ap, long long)); // NOLINT (runtime/int) - break; - } - case 'z': { - arg = (tvs + break; + case 'z': + arg = (tvs ? (ptrdiff_t)tv_nr(tvs, &arg_idx) : va_arg(ap, ptrdiff_t)); - break; - } - } - if (arg > 0) { - arg_sign = 1; - } else if (arg < 0) { - arg_sign = -1; - } - } else { - // unsigned - switch (length_modifier) { - case '\0': { - uarg = (unsigned int)(tvs + break; + } + if (arg > 0) { + arg_sign = 1; + } else if (arg < 0) { + arg_sign = -1; + } + } else { + // unsigned + switch (length_modifier) { + case '\0': + uarg = (unsigned int)(tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, unsigned int)); - break; - } - case 'h': { - uarg = (uint16_t)(tvs + break; + case 'h': + uarg = (uint16_t)(tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, unsigned int)); - break; - } - case 'l': { - uarg = (tvs + break; + case 'l': + uarg = (tvs ? (unsigned long)tv_nr(tvs, &arg_idx) : va_arg(ap, unsigned long)); - break; - } - case '2': { - uarg = (uintmax_t)(unsigned long long)( // NOLINT (runtime/int) - tvs + break; + case '2': + uarg = (uintmax_t)(unsigned long long)( // NOLINT (runtime/int) + tvs ? ((unsigned long long) // NOLINT (runtime/int) tv_nr(tvs, &arg_idx)) : va_arg(ap, unsigned long long)); // NOLINT (runtime/int) - break; - } - case 'z': { - uarg = (tvs + break; + case 'z': + uarg = (tvs ? (size_t)tv_nr(tvs, &arg_idx) : va_arg(ap, size_t)); - break; - } - } - arg_sign = (uarg != 0); + break; } + arg_sign = (uarg != 0); + } - str_arg = tmp; - str_arg_l = 0; + str_arg = tmp; + str_arg_l = 0; - // For d, i, u, o, x, and X conversions, if precision is specified, - // '0' flag should be ignored. This is so with Solaris 2.6, Digital - // UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl. - if (precision_specified) { - zero_padding = 0; - } + // For d, i, u, o, x, and X conversions, if precision is specified, + // '0' flag should be ignored. This is so with Solaris 2.6, Digital + // UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl. + if (precision_specified) { + zero_padding = 0; + } - if (fmt_spec == 'd') { - if (force_sign && arg_sign >= 0) { - tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; - } - // leave negative numbers for snprintf to handle, to - // avoid handling tricky cases like (short int)-32768 - } else if (alternate_form) { - if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X' - || fmt_spec == 'b' || fmt_spec == 'B')) { - tmp[str_arg_l++] = '0'; - tmp[str_arg_l++] = fmt_spec; - } - // alternate form should have no effect for p * conversion, but ... + if (fmt_spec == 'd') { + if (force_sign && arg_sign >= 0) { + tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; } - - zero_padding_insertion_ind = str_arg_l; - if (!precision_specified) { - precision = 1; // default precision is 1 + // leave negative numbers for snprintf to handle, to + // avoid handling tricky cases like (short int)-32768 + } else if (alternate_form) { + if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X' + || fmt_spec == 'b' || fmt_spec == 'B')) { + tmp[str_arg_l++] = '0'; + tmp[str_arg_l++] = fmt_spec; } - if (precision == 0 && arg_sign == 0) { - // when zero value is formatted with an explicit precision 0, - // resulting formatted string is empty (d, i, u, b, B, o, x, X, p) - } else { - switch (fmt_spec) { - case 'p': { // pointer - str_arg_l += (size_t)snprintf(tmp + str_arg_l, - sizeof(tmp) - str_arg_l, - "%p", ptr_arg); - break; - } - case 'd': { // signed - str_arg_l += (size_t)snprintf(tmp + str_arg_l, - sizeof(tmp) - str_arg_l, - "%" PRIdMAX, arg); - break; - } - case 'b': case 'B': { // binary - size_t bits = 0; - for (bits = sizeof(uintmax_t) * 8; bits > 0; bits--) { - if ((uarg >> (bits - 1)) & 0x1) { - break; - } - } + // alternate form should have no effect for p * conversion, but ... + } - while (bits > 0) { - tmp[str_arg_l++] = ((uarg >> --bits) & 0x1) ? '1' : '0'; - } - break; - } - default: { // unsigned - // construct a simple format string for snprintf - char f[] = "%" PRIuMAX; - f[sizeof("%" PRIuMAX) - 1 - 1] = fmt_spec; - assert(PRIuMAX[sizeof(PRIuMAX) - 1 - 1] == 'u'); - str_arg_l += (size_t)snprintf(tmp + str_arg_l, - sizeof(tmp) - str_arg_l, - f, uarg); + zero_padding_insertion_ind = str_arg_l; + if (!precision_specified) { + precision = 1; // default precision is 1 + } + if (precision == 0 && arg_sign == 0) { + // when zero value is formatted with an explicit precision 0, + // resulting formatted string is empty (d, i, u, b, B, o, x, X, p) + } else { + switch (fmt_spec) { + case 'p': // pointer + str_arg_l += (size_t)snprintf(tmp + str_arg_l, + sizeof(tmp) - str_arg_l, + "%p", ptr_arg); + break; + case 'd': // signed + str_arg_l += (size_t)snprintf(tmp + str_arg_l, + sizeof(tmp) - str_arg_l, + "%" PRIdMAX, arg); + break; + case 'b': + case 'B': { // binary + size_t bits = 0; + for (bits = sizeof(uintmax_t) * 8; bits > 0; bits--) { + if ((uarg >> (bits - 1)) & 0x1) { break; } } - assert(str_arg_l < sizeof(tmp)); - // include the optional minus sign and possible "0x" in the region - // before the zero padding insertion point - if (zero_padding_insertion_ind < str_arg_l - && tmp[zero_padding_insertion_ind] == '-') { - zero_padding_insertion_ind++; - } - if (zero_padding_insertion_ind + 1 < str_arg_l - && tmp[zero_padding_insertion_ind] == '0' - && (tmp[zero_padding_insertion_ind + 1] == 'x' - || tmp[zero_padding_insertion_ind + 1] == 'X' - || tmp[zero_padding_insertion_ind + 1] == 'b' - || tmp[zero_padding_insertion_ind + 1] == 'B')) { - zero_padding_insertion_ind += 2; + while (bits > 0) { + tmp[str_arg_l++] = ((uarg >> --bits) & 0x1) ? '1' : '0'; } + break; + } + default: { // unsigned + // construct a simple format string for snprintf + char f[] = "%" PRIuMAX; + f[sizeof("%" PRIuMAX) - 1 - 1] = fmt_spec; + assert(PRIuMAX[sizeof(PRIuMAX) - 1 - 1] == 'u'); + str_arg_l += (size_t)snprintf(tmp + str_arg_l, + sizeof(tmp) - str_arg_l, + f, uarg); + break; + } } + assert(str_arg_l < sizeof(tmp)); - { - size_t num_of_digits = str_arg_l - zero_padding_insertion_ind; - - if (alternate_form && fmt_spec == 'o' - // unless zero is already the first character - && !(zero_padding_insertion_ind < str_arg_l - && tmp[zero_padding_insertion_ind] == '0')) { - // assure leading zero for alternate-form octal numbers - if (!precision_specified - || precision < num_of_digits + 1) { - // precision is increased to force the first character to be - // zero, except if a zero value is formatted with an explicit - // precision of zero - precision = num_of_digits + 1; - } - } - // zero padding to specified precision? - if (num_of_digits < precision) { - number_of_zeros_to_pad = precision - num_of_digits; - } + // include the optional minus sign and possible "0x" in the region + // before the zero padding insertion point + if (zero_padding_insertion_ind < str_arg_l + && tmp[zero_padding_insertion_ind] == '-') { + zero_padding_insertion_ind++; } - // zero padding to specified minimal field width? - if (!justify_left && zero_padding) { - const int n = (int)(min_field_width - (str_arg_l - + number_of_zeros_to_pad)); - if (n > 0) { - number_of_zeros_to_pad += (size_t)n; - } + if (zero_padding_insertion_ind + 1 < str_arg_l + && tmp[zero_padding_insertion_ind] == '0' + && (tmp[zero_padding_insertion_ind + 1] == 'x' + || tmp[zero_padding_insertion_ind + 1] == 'X' + || tmp[zero_padding_insertion_ind + 1] == 'b' + || tmp[zero_padding_insertion_ind + 1] == 'B')) { + zero_padding_insertion_ind += 2; } - break; } - case 'f': - case 'F': - case 'e': - case 'E': - case 'g': - case 'G': - { - // floating point - char format[40]; - int remove_trailing_zeroes = false; - - double f = tvs ? tv_float(tvs, &arg_idx) : va_arg(ap, double); - double abs_f = f < 0 ? -f : f; - - if (fmt_spec == 'g' || fmt_spec == 'G') { - // can't use %g directly, cause it prints "1.0" as "1" - if ((abs_f >= 0.001 && abs_f < 10000000.0) || abs_f == 0.0) { - fmt_spec = ASCII_ISUPPER(fmt_spec) ? 'F' : 'f'; - } else { - fmt_spec = fmt_spec == 'g' ? 'e' : 'E'; - } - remove_trailing_zeroes = true; + { + size_t num_of_digits = str_arg_l - zero_padding_insertion_ind; + + if (alternate_form && fmt_spec == 'o' + // unless zero is already the first character + && !(zero_padding_insertion_ind < str_arg_l + && tmp[zero_padding_insertion_ind] == '0')) { + // assure leading zero for alternate-form octal numbers + if (!precision_specified + || precision < num_of_digits + 1) { + // precision is increased to force the first character to be + // zero, except if a zero value is formatted with an explicit + // precision of zero + precision = num_of_digits + 1; } + } + // zero padding to specified precision? + if (num_of_digits < precision) { + number_of_zeros_to_pad = precision - num_of_digits; + } + } + // zero padding to specified minimal field width? + if (!justify_left && zero_padding) { + const int n = (int)(min_field_width - (str_arg_l + + number_of_zeros_to_pad)); + if (n > 0) { + number_of_zeros_to_pad += (size_t)n; + } + } + break; + } - if (xisinf(f) - || (strchr("fF", fmt_spec) != NULL && abs_f > 1.0e307)) { - xstrlcpy(tmp, infinity_str(f > 0.0, fmt_spec, - force_sign, space_for_positive), - sizeof(tmp)); - str_arg_l = strlen(tmp); - zero_padding = 0; - } else if (xisnan(f)) { - // Not a number: nan or NAN - memmove(tmp, ASCII_ISUPPER(fmt_spec) ? "NAN" : "nan", 4); - str_arg_l = 3; - zero_padding = 0; - } else { - // Regular float number - format[0] = '%'; - size_t l = 1; - if (force_sign) { - format[l++] = space_for_positive ? ' ' : '+'; - } - if (precision_specified) { - size_t max_prec = TMP_LEN - 10; + case 'f': + case 'F': + case 'e': + case 'E': + case 'g': + case 'G': { + // floating point + char format[40]; + int remove_trailing_zeroes = false; + + double f = tvs ? tv_float(tvs, &arg_idx) : va_arg(ap, double); + double abs_f = f < 0 ? -f : f; + + if (fmt_spec == 'g' || fmt_spec == 'G') { + // can't use %g directly, cause it prints "1.0" as "1" + if ((abs_f >= 0.001 && abs_f < 10000000.0) || abs_f == 0.0) { + fmt_spec = ASCII_ISUPPER(fmt_spec) ? 'F' : 'f'; + } else { + fmt_spec = fmt_spec == 'g' ? 'e' : 'E'; + } + remove_trailing_zeroes = true; + } - // make sure we don't get more digits than we have room for - if ((fmt_spec == 'f' || fmt_spec == 'F') && abs_f > 1.0) { - max_prec -= (size_t)log10(abs_f); - } - if (precision > max_prec) { - precision = max_prec; - } - l += (size_t)snprintf(format + l, sizeof(format) - l, ".%d", - (int)precision); - } + if (xisinf(f) + || (strchr("fF", fmt_spec) != NULL && abs_f > 1.0e307)) { + xstrlcpy(tmp, infinity_str(f > 0.0, fmt_spec, + force_sign, space_for_positive), + sizeof(tmp)); + str_arg_l = strlen(tmp); + zero_padding = 0; + } else if (xisnan(f)) { + // Not a number: nan or NAN + memmove(tmp, ASCII_ISUPPER(fmt_spec) ? "NAN" : "nan", 4); + str_arg_l = 3; + zero_padding = 0; + } else { + // Regular float number + format[0] = '%'; + size_t l = 1; + if (force_sign) { + format[l++] = space_for_positive ? ' ' : '+'; + } + if (precision_specified) { + size_t max_prec = TMP_LEN - 10; - // Cast to char to avoid a conversion warning on Ubuntu 12.04. - assert(l + 1 < sizeof(format)); - format[l] = (char)(fmt_spec == 'F' ? 'f' : fmt_spec); - format[l + 1] = NUL; + // make sure we don't get more digits than we have room for + if ((fmt_spec == 'f' || fmt_spec == 'F') && abs_f > 1.0) { + max_prec -= (size_t)log10(abs_f); + } + if (precision > max_prec) { + precision = max_prec; + } + l += (size_t)snprintf(format + l, sizeof(format) - l, ".%d", + (int)precision); + } - str_arg_l = (size_t)snprintf(tmp, sizeof(tmp), format, f); - assert(str_arg_l < sizeof(tmp)); + // Cast to char to avoid a conversion warning on Ubuntu 12.04. + assert(l + 1 < sizeof(format)); + format[l] = (char)(fmt_spec == 'F' ? 'f' : fmt_spec); + format[l + 1] = NUL; - if (remove_trailing_zeroes) { - int i; - char *tp; + str_arg_l = (size_t)snprintf(tmp, sizeof(tmp), format, f); + assert(str_arg_l < sizeof(tmp)); - // using %g or %G: remove superfluous zeroes - if (fmt_spec == 'f' || fmt_spec == 'F') { - tp = tmp + str_arg_l - 1; - } else { - tp = (char *)vim_strchr((char_u *)tmp, - fmt_spec == 'e' ? 'e' : 'E'); - if (tp) { - // remove superfluous '+' and leading zeroes from exponent - if (tp[1] == '+') { - // change "1.0e+07" to "1.0e07" - STRMOVE(tp + 1, tp + 2); - str_arg_l--; - } - i = (tp[1] == '-') ? 2 : 1; - while (tp[i] == '0') { - // change "1.0e07" to "1.0e7" - STRMOVE(tp + i, tp + i + 1); - str_arg_l--; - } - tp--; - } - } + if (remove_trailing_zeroes) { + int i; + char *tp; - if (tp != NULL && !precision_specified) { - // remove trailing zeroes, but keep the one just after a dot - while (tp > tmp + 2 && *tp == '0' && tp[-1] != '.') { - STRMOVE(tp, tp + 1); - tp--; - str_arg_l--; - } + // using %g or %G: remove superfluous zeroes + if (fmt_spec == 'f' || fmt_spec == 'F') { + tp = tmp + str_arg_l - 1; + } else { + tp = (char *)vim_strchr((char_u *)tmp, + fmt_spec == 'e' ? 'e' : 'E'); + if (tp) { + // remove superfluous '+' and leading zeroes from exponent + if (tp[1] == '+') { + // change "1.0e+07" to "1.0e07" + STRMOVE(tp + 1, tp + 2); + str_arg_l--; } - } else { - // Be consistent: some printf("%e") use 1.0e+12 and some - // 1.0e+012; remove one zero in the last case. - char *tp = (char *)vim_strchr((char_u *)tmp, - fmt_spec == 'e' ? 'e' : 'E'); - if (tp && (tp[1] == '+' || tp[1] == '-') && tp[2] == '0' - && ascii_isdigit(tp[3]) && ascii_isdigit(tp[4])) { - STRMOVE(tp + 2, tp + 3); + i = (tp[1] == '-') ? 2 : 1; + while (tp[i] == '0') { + // change "1.0e07" to "1.0e7" + STRMOVE(tp + i, tp + i + 1); str_arg_l--; } + tp--; } } - if (zero_padding && min_field_width > str_arg_l - && (tmp[0] == '-' || force_sign)) { - // Padding 0's should be inserted after the sign. - number_of_zeros_to_pad = min_field_width - str_arg_l; - zero_padding_insertion_ind = 1; + + if (tp != NULL && !precision_specified) { + // remove trailing zeroes, but keep the one just after a dot + while (tp > tmp + 2 && *tp == '0' && tp[-1] != '.') { + STRMOVE(tp, tp + 1); + tp--; + str_arg_l--; + } + } + } else { + // Be consistent: some printf("%e") use 1.0e+12 and some + // 1.0e+012; remove one zero in the last case. + char *tp = (char *)vim_strchr((char_u *)tmp, + fmt_spec == 'e' ? 'e' : 'E'); + if (tp && (tp[1] == '+' || tp[1] == '-') && tp[2] == '0' + && ascii_isdigit(tp[3]) && ascii_isdigit(tp[4])) { + STRMOVE(tp + 2, tp + 3); + str_arg_l--; } - str_arg = tmp; - break; } + } + if (zero_padding && min_field_width > str_arg_l + && (tmp[0] == '-' || force_sign)) { + // Padding 0's should be inserted after the sign. + number_of_zeros_to_pad = min_field_width - str_arg_l; + zero_padding_insertion_ind = 1; + } + str_arg = tmp; + break; + } - default: - // unrecognized conversion specifier, keep format string as-is - zero_padding = 0; // turn zero padding off for non-numeric conversion - justify_left = 1; - min_field_width = 0; // reset flags - - // discard the unrecognized conversion, just keep - // the unrecognized conversion character - str_arg = p; - str_arg_l = 0; - if (*p) { - str_arg_l++; // include invalid conversion specifier - } - // unchanged if not at end-of-string - break; + default: + // unrecognized conversion specifier, keep format string as-is + zero_padding = 0; // turn zero padding off for non-numeric conversion + justify_left = 1; + min_field_width = 0; // reset flags + + // discard the unrecognized conversion, just keep + // the unrecognized conversion character + str_arg = p; + str_arg_l = 0; + if (*p) { + str_arg_l++; // include invalid conversion specifier + } + // unchanged if not at end-of-string + break; } if (*p) { diff --git a/src/nvim/strings.h b/src/nvim/strings.h index f2876c6307..893b0ea269 100644 --- a/src/nvim/strings.h +++ b/src/nvim/strings.h @@ -1,12 +1,12 @@ #ifndef NVIM_STRINGS_H #define NVIM_STRINGS_H -#include <stdbool.h> #include <stdarg.h> +#include <stdbool.h> #include <string.h> -#include "nvim/types.h" #include "nvim/eval/typval.h" +#include "nvim/types.h" /// Append string to string and return pointer to the next byte /// diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 10cc2ea9b8..1e14f988f1 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -93,7 +93,7 @@ typedef struct hl_group { static garray_T highlight_ga = GA_EMPTY_INIT_VALUE; Map(cstr_t, int) highlight_unames = MAP_INIT; -static inline struct hl_group * HL_TABLE(void) +static inline struct hl_group *HL_TABLE(void) { return ((struct hl_group *)((highlight_ga.ga_data))); } @@ -230,11 +230,10 @@ struct name_list { static char *(spo_name_tab[SPO_COUNT]) = { "ms=", "me=", "hs=", "he=", "rs=", "re=", "lc=" }; -/* The sp_off_flags are computed like this: - * offset from the start of the matched text: (1 << SPO_XX_OFF) - * offset from the end of the matched text: (1 << (SPO_XX_OFF + SPO_COUNT)) - * When both are present, only one is used. - */ +// The sp_off_flags are computed like this: +// offset from the start of the matched text: (1 << SPO_XX_OFF) +// offset from the end of the matched text: (1 << (SPO_XX_OFF + SPO_COUNT)) +// When both are present, only one is used. #define SPTYPE_MATCH 1 // match keyword with this group ID #define SPTYPE_START 2 // match a regexp, start of item @@ -345,7 +344,7 @@ static int next_seqnr = 1; // value to use for si_seqnr */ static int next_match_col; // column for start of next match static lpos_T next_match_m_endpos; // position for end of next match -static lpos_T next_match_h_startpos; // pos. for highl. start of next match +static lpos_T next_match_h_startpos; // pos. for highl. start of next match static lpos_T next_match_h_endpos; // pos. for highl. end of next match static int next_match_idx; // index of matched item static long next_match_flags; // flags for next match @@ -383,7 +382,7 @@ static int current_line_id = 0; // unique number for current line #define CUR_STATE(idx) ((stateitem_T *)(current_state.ga_data))[idx] static bool syn_time_on = false; -# define IF_SYN_TIME(p) (p) +#define IF_SYN_TIME(p) (p) // Set the timeout used for syntax highlighting. // Use NULL to reset, no timeout. @@ -492,8 +491,8 @@ void syntax_start(win_T *wp, linenr_T lnum) // First line is always valid, no matter "minlines". first_stored = 1; } else { - /* Need to parse "minlines" lines before state can be considered - * valid to store. */ + // Need to parse "minlines" lines before state can be considered + // valid to store. first_stored = current_lnum + syn_block->b_syn_sync_minlines; } } else { @@ -514,12 +513,12 @@ void syntax_start(win_T *wp, linenr_T lnum) (void)syn_finish_line(false); current_lnum++; - /* If we parsed at least "minlines" lines or started at a valid - * state, the current state is considered valid. */ + // If we parsed at least "minlines" lines or started at a valid + // state, the current state is considered valid. if (current_lnum >= first_stored) { - /* Check if the saved state entry is for the current line and is - * equal to the current state. If so, then validate all saved - * states that depended on a change before the parsed line. */ + // Check if the saved state entry is for the current line and is + // equal to the current state. If so, then validate all saved + // states that depended on a change before the parsed line. if (prev == NULL) { prev = syn_stack_find_entry(current_lnum - 1); } @@ -548,19 +547,18 @@ void syntax_start(win_T *wp, linenr_T lnum) sp = sp->sst_next; } load_current_state(prev); - } - /* Store the state at this line when it's the first one, the line - * where we start parsing, or some distance from the previously - * saved state. But only when parsed at least 'minlines'. */ - else if (prev == NULL - || current_lnum == lnum - || current_lnum >= prev->sst_lnum + dist) { + } else if (prev == NULL + // Store the state at this line when it's the first one, the line + // where we start parsing, or some distance from the previously + // saved state. But only when parsed at least 'minlines'. + || current_lnum == lnum + || current_lnum >= prev->sst_lnum + dist) { prev = store_current_state(); } } - /* This can take a long time: break when CTRL-C pressed. The current - * state will be wrong then. */ + // This can take a long time: break when CTRL-C pressed. The current + // state will be wrong then. line_breakcheck(); if (got_int) { current_lnum = lnum; @@ -578,7 +576,7 @@ void syntax_start(win_T *wp, linenr_T lnum) static void clear_syn_state(synstate_T *p) { if (p->sst_stacksize > SST_FIX_STATES) { -# define UNREF_BUFSTATE_EXTMATCH(bs) unref_extmatch((bs)->bs_extmatch) +#define UNREF_BUFSTATE_EXTMATCH(bs) unref_extmatch((bs)->bs_extmatch) GA_DEEP_CLEAR(&(p->sst_union.sst_ga), bufstate_T, UNREF_BUFSTATE_EXTMATCH); } else { for (int i = 0; i < p->sst_stacksize; i++) { @@ -592,7 +590,7 @@ static void clear_syn_state(synstate_T *p) */ static void clear_current_state(void) { -# define UNREF_STATEITEM_EXTMATCH(si) unref_extmatch((si)->si_extmatch) +#define UNREF_STATEITEM_EXTMATCH(si) unref_extmatch((si)->si_extmatch) GA_DEEP_CLEAR(¤t_state, stateitem_T, UNREF_STATEITEM_EXTMATCH); } @@ -664,8 +662,8 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid) * 1. Search backwards for the end of a C-style comment. */ if (syn_block->b_syn_sync_flags & SF_CCOMMENT) { - /* Need to make syn_buf the current buffer for a moment, to be able to - * use find_start_comment(). */ + // Need to make syn_buf the current buffer for a moment, to be able to + // use find_start_comment(). curwin_save = curwin; curwin = wp; curbuf_save = curbuf; @@ -793,9 +791,9 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid) ++current_col; } - /* syn_current_attr() will have skipped the check for - * an item that ends here, need to do that now. Be - * careful not to go past the NUL. */ + // syn_current_attr() will have skipped the check for + // an item that ends here, need to do that now. Be + // careful not to go past the NUL. prev_current_col = current_col; if (syn_getcurline()[current_col] != NUL) { ++current_col; @@ -987,9 +985,8 @@ static void syn_update_ends(bool startofline) check_keepend(); } -/**************************************** - * Handling of the state stack cache. - */ +///////////////////////////////////////// +// Handling of the state stack cache. /* * EXPLANATION OF THE SYNTAX STATE STACK CACHE @@ -1081,8 +1078,8 @@ static void syn_stack_alloc(void) } if (syn_block->b_sst_array != NULL) { - /* When shrinking the array, cleanup the existing stack. - * Make sure that all valid entries fit in the new array. */ + // When shrinking the array, cleanup the existing stack. + // Make sure that all valid entries fit in the new array. while (syn_block->b_sst_len - syn_block->b_sst_freecount + 2 > len && syn_stack_cleanup()) { ; @@ -1165,9 +1162,9 @@ static void syn_stack_apply_changes_block(synblock_T *block, buf_T *buf) p = np; continue; } - /* This state is below the changed area. Remember the line - * that needs to be parsed before this entry can be made valid - * again. */ + // This state is below the changed area. Remember the line + // that needs to be parsed before this entry can be made valid + // again. if (p->sst_change_lnum != 0 && p->sst_change_lnum > buf->b_mod_top) { if (p->sst_change_lnum + buf->b_mod_xlines > buf->b_mod_top) { p->sst_change_lnum += buf->b_mod_xlines; @@ -1638,8 +1635,8 @@ int get_syntax_attr(const colnr_T col, bool *const can_spell, const bool keep_st int attr = 0; if (can_spell != NULL) { - /* Default: Only do spelling when there is no @Spell cluster or when - * ":syn spell toplevel" was used. */ + // Default: Only do spelling when there is no @Spell cluster or when + // ":syn spell toplevel" was used. *can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT ? (syn_block->b_spell_cluster_id == 0) : (syn_block->b_syn_spell == SYNSPL_TOP); @@ -1703,7 +1700,7 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con regmmatch_T regmatch; lpos_T pos; reg_extmatch_T *cur_extmatch = NULL; - char_u buf_chartab[32]; // chartab array for syn iskeyword + char_u buf_chartab[32]; // chartab array for syn iskeyword char_u *line; // current line. NOTE: becomes invalid after // looking for a pattern match! @@ -1901,15 +1898,15 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con syn_add_start_off(&pos, ®match, spp, SPO_MS_OFF, -1); if (pos.lnum > current_lnum) { - /* must have used end of match in a next line, - * we can't handle that */ + // must have used end of match in a next line, + // we can't handle that spp->sp_startcol = MAXCOL; continue; } startcol = pos.col; - /* remember the next column where this pattern - * matches in the current line */ + // remember the next column where this pattern + // matches in the current line spp->sp_startcol = startcol; /* @@ -1999,8 +1996,8 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con /* * keep the best match so far in next_match_* */ - /* Highlighting must start after startpos and end - * before endpos. */ + // Highlighting must start after startpos and end + // before endpos. if (hl_startpos.lnum == current_lnum && (int)hl_startpos.col < startcol) { hl_startpos.col = startcol; @@ -2029,8 +2026,8 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con if (next_match_idx >= 0 && next_match_col == (int)current_col) { synpat_T *lspp; - /* When a zero-width item matched which has a nextgroup, - * don't push the item but set nextgroup. */ + // When a zero-width item matched which has a nextgroup, + // don't push the item but set nextgroup. lspp = &(SYN_ITEMS(syn_block)[next_match_idx]); if (next_match_m_endpos.lnum == current_lnum && next_match_m_endpos.col == current_col @@ -2127,8 +2124,8 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con * done in the current item. */ if (syn_block->b_spell_cluster_id == 0) { - /* There is no @Spell cluster: Do spelling for items without - * @NoSpell cluster. */ + // There is no @Spell cluster: Do spelling for items without + // @NoSpell cluster. if (syn_block->b_nospell_cluster_id == 0 || current_trans_id == 0) { *can_spell = (syn_block->b_syn_spell != SYNSPL_NOTOP); @@ -2180,8 +2177,8 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con } } } else if (can_spell != NULL) { - /* Default: Only do spelling when there is no @Spell cluster or when - * ":syn spell toplevel" was used. */ + // Default: Only do spelling when there is no @Spell cluster or when + // ":syn spell toplevel" was used. *can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT ? (syn_block->b_spell_cluster_id == 0) : (syn_block->b_syn_spell == SYNSPL_TOP); @@ -2365,8 +2362,8 @@ static void check_state_ends(void) current_next_list = NULL; } - /* When the ended item has "extend", another item with - * "keepend" now needs to check for its end. */ + // When the ended item has "extend", another item with + // "keepend" now needs to check for its end. had_extend = (cur_si->si_flags & HL_EXTEND); pop_current_state(); @@ -2541,9 +2538,9 @@ static void update_si_end(stateitem_T *sip, int startcol, bool force) return; } - /* Don't update when it's already done. Can be a match of an end pattern - * that started in a previous line. Watch out: can also be a "keepend" - * from a containing item. */ + // Don't update when it's already done. Can be a match of an end pattern + // that started in a previous line. Watch out: can also be a "keepend" + // from a containing item. if (!force && sip->si_m_endpos.lnum >= current_lnum) { return; } @@ -2822,8 +2819,8 @@ static void find_endpos(int idx, lpos_T *startpos, lpos_T *m_endpos, lpos_T *hl_ } limit_pos(hl_endpos, m_endpos); - /* now the match ends where the highlighting ends, it is turned - * into the matchgroup for the end */ + // now the match ends where the highlighting ends, it is turned + // into the matchgroup for the end *m_endpos = *hl_endpos; } else { *end_idx = 0; @@ -4393,8 +4390,8 @@ static void syn_cmd_include(exarg_T *eap, int syncing) prev_toplvl_grp = curwin->w_s->b_syn_topgrp; curwin->w_s->b_syn_topgrp = sgl_id; if (source - ? do_source(eap->arg, false, DOSO_NONE) == FAIL - : source_runtime(eap->arg, DIP_ALL) == FAIL) { + ? do_source((char *)eap->arg, false, DOSO_NONE) == FAIL + : source_runtime((char *)eap->arg, DIP_ALL) == FAIL) { EMSG2(_(e_notopen), eap->arg); } curwin->w_s->b_syn_topgrp = prev_toplvl_grp; @@ -4423,7 +4420,7 @@ static void syn_cmd_keyword(exarg_T *eap, int syncing) if (eap->skip) { syn_id = -1; } else { - syn_id = syn_check_group(arg, (int)(group_name_end - arg)); + syn_id = syn_check_group((char *)arg, (int)(group_name_end - arg)); } if (syn_id != 0) { // Allocate a buffer, for removing backslashes in the keyword. @@ -4560,7 +4557,7 @@ static void syn_cmd_match(exarg_T *eap, int syncing) if (!ends_excmd(*rest) || eap->skip) { rest = NULL; } else { - if ((syn_id = syn_check_group(arg, (int)(group_name_end - arg))) != 0) { + if ((syn_id = syn_check_group((char *)arg, (int)(group_name_end - arg))) != 0) { syn_incl_toplevel(syn_id, &syn_opt_arg.flags); /* * Store the pattern in the syn_items list @@ -4709,7 +4706,7 @@ static void syn_cmd_region(exarg_T *eap, int syncing) if ((p - rest == 4 && STRNCMP(rest, "NONE", 4) == 0) || eap->skip) { matchgroup_id = 0; } else { - matchgroup_id = syn_check_group(rest, (int)(p - rest)); + matchgroup_id = syn_check_group((char *)rest, (int)(p - rest)); if (matchgroup_id == 0) { illegal = true; break; @@ -4768,7 +4765,7 @@ static void syn_cmd_region(exarg_T *eap, int syncing) rest = NULL; } else { ga_grow(&(curwin->w_s->b_syn_patterns), pat_count); - if ((syn_id = syn_check_group(arg, (int)(group_name_end - arg))) != 0) { + if ((syn_id = syn_check_group((char *)arg, (int)(group_name_end - arg))) != 0) { syn_incl_toplevel(syn_id, &syn_opt_arg.flags); /* * Store the start/skip/end in the syn_items list @@ -5264,8 +5261,7 @@ static void syn_cmd_sync(exarg_T *eap, int syncing) if (!ends_excmd(*next_arg)) { arg_end = skiptowhite(next_arg); if (!eap->skip) { - curwin->w_s->b_syn_sync_id = syn_check_group(next_arg, - (int)(arg_end - next_arg)); + curwin->w_s->b_syn_sync_id = syn_check_group((char *)next_arg, (int)(arg_end - next_arg)); } next_arg = skipwhite(arg_end); } else if (!eap->skip) { @@ -5447,7 +5443,7 @@ static int get_id_list(char_u **const arg, const int keylen, int16_t **const lis * Handle full group name. */ if (vim_strpbrk(name + 1, (char_u *)"\\.*^$~[") == NULL) { - id = syn_check_group(name + 1, (int)(end - p)); + id = syn_check_group((char *)(name + 1), (int)(end - p)); } else { // Handle match of regexp with group names. *name = '^'; @@ -5571,8 +5567,8 @@ static int in_id_list(stateitem_T *cur_si, int16_t *list, struct sp_syn *ssp, in // If ssp has a "containedin" list and "cur_si" is in it, return TRUE. if (cur_si != NULL && ssp->cont_in_list != NULL && !(cur_si->si_flags & HL_MATCH)) { - /* Ignore transparent items without a contains argument. Double check - * that we don't go back past the first one. */ + // Ignore transparent items without a contains argument. Double check + // that we don't go back past the first one. while ((cur_si->si_flags & HL_TRANS_CONT) && cur_si > (stateitem_T *)(current_state.ga_data)) { --cur_si; @@ -5636,8 +5632,8 @@ static int in_id_list(stateitem_T *cur_si, int16_t *list, struct sp_syn *ssp, in } if (item >= SYNID_CLUSTER) { scl_list = SYN_CLSTR(syn_block)[item - SYNID_CLUSTER].scl_list; - /* restrict recursiveness to 30 to avoid an endless loop for a - * cluster that includes itself (indirectly) */ + // restrict recursiveness to 30 to avoid an endless loop for a + // cluster that includes itself (indirectly) if (scl_list != NULL && depth < 30) { ++depth; r = in_id_list(NULL, scl_list, ssp, contained); @@ -5654,7 +5650,7 @@ static int in_id_list(stateitem_T *cur_si, int16_t *list, struct sp_syn *ssp, in struct subcommand { char *name; // subcommand name - void (*func)(exarg_T *, int); // function to call + void (*func)(exarg_T *, int); // function to call }; static struct subcommand subcommands[] = @@ -5932,8 +5928,8 @@ int syn_get_sub_char(void) int syn_get_stack_item(int i) { if (i >= current_state.ga_len) { - /* Need to invalidate the state, because we didn't properly finish it - * for the last character, "keep_state" was TRUE. */ + // Need to invalidate the state, because we didn't properly finish it + // for the last character, "keep_state" was TRUE. invalidate_current_state(); current_col = MAXCOL; return -1; @@ -6217,6 +6213,26 @@ static const char *highlight_init_both[] = { "default link Delimiter Special", "default link SpecialComment Special", "default link Debug Special", + "default DiagnosticError ctermfg=1 guifg=Red", + "default DiagnosticWarn ctermfg=3 guifg=Orange", + "default DiagnosticInfo ctermfg=4 guifg=LightBlue", + "default DiagnosticHint ctermfg=7 guifg=LightGrey", + "default DiagnosticUnderlineError cterm=underline gui=underline guisp=Red", + "default DiagnosticUnderlineWarn cterm=underline gui=underline guisp=Orange", + "default DiagnosticUnderlineInfo cterm=underline gui=underline guisp=LightBlue", + "default DiagnosticUnderlineHint cterm=underline gui=underline guisp=LightGrey", + "default link DiagnosticVirtualTextError DiagnosticError", + "default link DiagnosticVirtualTextWarn DiagnosticWarn", + "default link DiagnosticVirtualTextInfo DiagnosticInfo", + "default link DiagnosticVirtualTextHint DiagnosticHint", + "default link DiagnosticFloatingError DiagnosticError", + "default link DiagnosticFloatingWarn DiagnosticWarn", + "default link DiagnosticFloatingInfo DiagnosticInfo", + "default link DiagnosticFloatingHint DiagnosticHint", + "default link DiagnosticSignError DiagnosticError", + "default link DiagnosticSignWarn DiagnosticWarn", + "default link DiagnosticSignInfo DiagnosticInfo", + "default link DiagnosticSignHint DiagnosticHint", NULL }; @@ -6597,10 +6613,10 @@ int load_colors(char_u *name) buf = xmalloc(buflen); apply_autocmds(EVENT_COLORSCHEMEPRE, name, curbuf->b_fname, false, curbuf); snprintf((char *)buf, buflen, "colors/%s.vim", name); - retval = source_runtime(buf, DIP_START + DIP_OPT); + retval = source_runtime((char *)buf, DIP_START + DIP_OPT); if (retval == FAIL) { snprintf((char *)buf, buflen, "colors/%s.lua", name); - retval = source_runtime(buf, DIP_START + DIP_OPT); + retval = source_runtime((char *)buf, DIP_START + DIP_OPT); } xfree(buf); apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, false, curbuf); @@ -6793,13 +6809,11 @@ void do_highlight(const char *line, const bool forceit, const bool init) return; } - from_id = syn_check_group((const char_u *)from_start, - (int)(from_end - from_start)); + from_id = syn_check_group(from_start, (int)(from_end - from_start)); if (strncmp(to_start, "NONE", 4) == 0) { to_id = 0; } else { - to_id = syn_check_group((const char_u *)to_start, - (int)(to_end - to_start)); + to_id = syn_check_group(to_start, (int)(to_end - to_start)); } if (from_id > 0) { @@ -6860,7 +6874,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) } // Find the group name in the table. If it does not exist yet, add it. - id = syn_check_group((const char_u *)line, (int)(name_end - line)); + id = syn_check_group(line, (int)(name_end - line)); if (id == 0) { // Failed (out of memory). return; } @@ -7664,11 +7678,11 @@ char_u *syn_id2name(int id) /// @param len length of \p pp /// /// @return 0 for failure else the id of the group -int syn_check_group(const char_u *name, int len) +int syn_check_group(const char *name, int len) { - int id = syn_name2id_len(name, len); + int id = syn_name2id_len((char_u *)name, len); if (id == 0) { // doesn't exist yet - return syn_add_group(vim_strnsave(name, len)); + return syn_add_group(vim_strnsave((char_u *)name, len)); } return id; } @@ -7714,7 +7728,7 @@ static int syn_add_group(char_u *name) char *const name_up = (char *)vim_strsave_up(name); // Append another syntax_highlight entry. - struct hl_group * hlgp = GA_APPEND_VIA_PTR(struct hl_group, &highlight_ga); + struct hl_group *hlgp = GA_APPEND_VIA_PTR(struct hl_group, &highlight_ga); memset(hlgp, 0, sizeof(*hlgp)); hlgp->sg_name = name; hlgp->sg_rgb_bg = -1; @@ -7868,7 +7882,7 @@ void highlight_changed(void) /// Translate builtin highlight groups into attributes for quick lookup. for (int hlf = 0; hlf < HLF_COUNT; hlf++) { - id = syn_check_group((char_u *)hlf_names[hlf], STRLEN(hlf_names[hlf])); + id = syn_check_group(hlf_names[hlf], STRLEN(hlf_names[hlf])); if (id == 0) { abort(); } diff --git a/src/nvim/syntax.h b/src/nvim/syntax.h index 38f848f178..15fc084a0a 100644 --- a/src/nvim/syntax.h +++ b/src/nvim/syntax.h @@ -3,31 +3,31 @@ #include <stdbool.h> -#include "nvim/globals.h" #include "nvim/buffer_defs.h" #include "nvim/ex_cmds_defs.h" +#include "nvim/globals.h" -#define HL_CONTAINED 0x01 /* not used on toplevel */ -#define HL_TRANSP 0x02 /* has no highlighting */ -#define HL_ONELINE 0x04 /* match within one line only */ -#define HL_HAS_EOL 0x08 /* end pattern that matches with $ */ -#define HL_SYNC_HERE 0x10 /* sync point after this item (syncing only) */ -#define HL_SYNC_THERE 0x20 /* sync point at current line (syncing only) */ -#define HL_MATCH 0x40 /* use match ID instead of item ID */ -#define HL_SKIPNL 0x80 /* nextgroup can skip newlines */ -#define HL_SKIPWHITE 0x100 /* nextgroup can skip white space */ -#define HL_SKIPEMPTY 0x200 /* nextgroup can skip empty lines */ -#define HL_KEEPEND 0x400 /* end match always kept */ -#define HL_EXCLUDENL 0x800 /* exclude NL from match */ -#define HL_DISPLAY 0x1000 /* only used for displaying, not syncing */ -#define HL_FOLD 0x2000 /* define fold */ -#define HL_EXTEND 0x4000 /* ignore a keepend */ -#define HL_MATCHCONT 0x8000 /* match continued from previous line */ -#define HL_TRANS_CONT 0x10000 /* transparent item without contains arg */ -#define HL_CONCEAL 0x20000 /* can be concealed */ -#define HL_CONCEALENDS 0x40000 /* can be concealed */ - -#define SYN_GROUP_STATIC(s) syn_check_group((char_u *)S_LEN(s)) +#define HL_CONTAINED 0x01 // not used on toplevel +#define HL_TRANSP 0x02 // has no highlighting +#define HL_ONELINE 0x04 // match within one line only +#define HL_HAS_EOL 0x08 // end pattern that matches with $ +#define HL_SYNC_HERE 0x10 // sync point after this item (syncing only) +#define HL_SYNC_THERE 0x20 // sync point at current line (syncing only) +#define HL_MATCH 0x40 // use match ID instead of item ID +#define HL_SKIPNL 0x80 // nextgroup can skip newlines +#define HL_SKIPWHITE 0x100 // nextgroup can skip white space +#define HL_SKIPEMPTY 0x200 // nextgroup can skip empty lines +#define HL_KEEPEND 0x400 // end match always kept +#define HL_EXCLUDENL 0x800 // exclude NL from match +#define HL_DISPLAY 0x1000 // only used for displaying, not syncing +#define HL_FOLD 0x2000 // define fold +#define HL_EXTEND 0x4000 // ignore a keepend +#define HL_MATCHCONT 0x8000 // match continued from previous line +#define HL_TRANS_CONT 0x10000 // transparent item without contains arg +#define HL_CONCEAL 0x20000 // can be concealed +#define HL_CONCEALENDS 0x40000 // can be concealed + +#define SYN_GROUP_STATIC(s) syn_check_group(S_LEN(s)) typedef struct { char *name; diff --git a/src/nvim/syntax_defs.h b/src/nvim/syntax_defs.h index 5ee0611d58..526be905e9 100644 --- a/src/nvim/syntax_defs.h +++ b/src/nvim/syntax_defs.h @@ -3,18 +3,18 @@ #include "nvim/highlight_defs.h" -# define SST_MIN_ENTRIES 150 /* minimal size for state stack array */ -# define SST_MAX_ENTRIES 1000 /* maximal size for state stack array */ -# define SST_FIX_STATES 7 /* size of sst_stack[]. */ -# define SST_DIST 16 /* normal distance between entries */ -# define SST_INVALID (synstate_T *)-1 /* invalid syn_state pointer */ +#define SST_MIN_ENTRIES 150 // minimal size for state stack array +#define SST_MAX_ENTRIES 1000 // maximal size for state stack array +#define SST_FIX_STATES 7 // size of sst_stack[]. +#define SST_DIST 16 // normal distance between entries +#define SST_INVALID (synstate_T *)-1 // invalid syn_state pointer typedef struct syn_state synstate_T; #include "nvim/buffer_defs.h" #include "nvim/regexp_defs.h" -/* struct passed to in_id_list() */ +// struct passed to in_id_list() struct sp_syn { int inc_tag; // ":syn include" unique tag int16_t id; // highlight group ID of item @@ -27,7 +27,7 @@ struct sp_syn { typedef struct keyentry keyentry_T; struct keyentry { - keyentry_T *ke_next; // next entry with identical "keyword[]" + keyentry_T *ke_next; // next entry with identical "keyword[]" struct sp_syn k_syn; // struct passed to in_id_list() int16_t *next_list; // ID list for next match (if non-zero) int flags; @@ -39,11 +39,11 @@ struct keyentry { * Struct used to store one state of the state stack. */ typedef struct buf_state { - int bs_idx; /* index of pattern */ - int bs_flags; /* flags for pattern */ - int bs_seqnr; /* stores si_seqnr */ - int bs_cchar; /* stores si_cchar */ - reg_extmatch_T *bs_extmatch; /* external matches from start pattern */ + int bs_idx; // index of pattern + int bs_flags; // flags for pattern + int bs_seqnr; // stores si_seqnr + int bs_cchar; // stores si_cchar + reg_extmatch_T *bs_extmatch; // external matches from start pattern } bufstate_T; /* @@ -51,11 +51,11 @@ typedef struct buf_state { * Used by b_sst_array[]. */ struct syn_state { - synstate_T *sst_next; /* next entry in used or free list */ - linenr_T sst_lnum; /* line number for this state */ + synstate_T *sst_next; // next entry in used or free list + linenr_T sst_lnum; // line number for this state union { - bufstate_T sst_stack[SST_FIX_STATES]; /* short state stack */ - garray_T sst_ga; /* growarray for long state stack */ + bufstate_T sst_stack[SST_FIX_STATES]; // short state stack + garray_T sst_ga; // growarray for long state stack } sst_union; int sst_next_flags; // flags for sst_next_list int sst_stacksize; // number of states on the stack diff --git a/src/nvim/tag.c b/src/nvim/tag.c index c63cdad098..c22d344878 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -10,9 +10,7 @@ #include <stdbool.h> #include <string.h> -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/tag.h" #include "nvim/buffer.h" #include "nvim/charset.h" #include "nvim/cursor.h" @@ -22,18 +20,21 @@ #include "nvim/ex_cmds2.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" +#include "nvim/file_search.h" #include "nvim/fileio.h" #include "nvim/fold.h" +#include "nvim/garray.h" #include "nvim/if_cscope.h" #include "nvim/mark.h" #include "nvim/mbyte.h" +#include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/file_search.h" -#include "nvim/garray.h" -#include "nvim/memory.h" #include "nvim/move.h" #include "nvim/option.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" +#include "nvim/os/time.h" #include "nvim/os_unix.h" #include "nvim/path.h" #include "nvim/quickfix.h" @@ -41,30 +42,29 @@ #include "nvim/screen.h" #include "nvim/search.h" #include "nvim/strings.h" +#include "nvim/tag.h" #include "nvim/ui.h" +#include "nvim/vim.h" #include "nvim/window.h" -#include "nvim/os/os.h" -#include "nvim/os/time.h" -#include "nvim/os/input.h" /* * Structure to hold pointers to various items in a tag line. */ typedef struct tag_pointers { // filled in by parse_tag_line(): - char_u *tagname; // start of tag name (skip "file:") - char_u *tagname_end; // char after tag name - char_u *fname; // first char of file name - char_u *fname_end; // char after file name - char_u *command; // first char of command + char_u *tagname; // start of tag name (skip "file:") + char_u *tagname_end; // char after tag name + char_u *fname; // first char of file name + char_u *fname_end; // char after file name + char_u *command; // first char of command // filled in by parse_match(): - char_u *command_end; // first char after command - char_u *tag_fname; // file name of the tags file. This is used + char_u *command_end; // first char after command + char_u *tag_fname; // file name of the tags file. This is used // when 'tr' is set. - char_u *tagkind; // "kind:" value - char_u *tagkind_end; // end of tagkind - char_u *user_data; // user_data string - char_u *user_data_end; // end of user_data + char_u *tagkind; // "kind:" value + char_u *tagkind_end; // end of tagkind + char_u *user_data; // user_data string + char_u *user_data_end; // end of user_data linenr_T tagline; // "line:" value } tagptrs_T; @@ -72,11 +72,11 @@ typedef struct tag_pointers { * Structure to hold info about the tag pattern being used. */ typedef struct { - char_u *pat; /* the pattern */ - int len; /* length of pat[] */ - char_u *head; /* start of pattern head */ - int headlen; /* length of head[] */ - regmatch_T regmatch; /* regexp program, may be NULL */ + char_u *pat; // the pattern + int len; // length of pat[] + char_u *head; // start of pattern head + int headlen; // length of head[] + regmatch_T regmatch; // regexp program, may be NULL } pat_T; // The matching tags are first stored in one of the hash tables. In @@ -93,11 +93,11 @@ typedef struct { #define MT_MASK 7 // mask for printing priority #define MT_COUNT 16 -static char *mt_names[MT_COUNT/2] = -{"FSC", "F C", "F ", "FS ", " SC", " C", " ", " S "}; +static char *mt_names[MT_COUNT/2] = +{ "FSC", "F C", "F ", "FS ", " SC", " C", " ", " S " }; -#define NOTAGFILE 99 /* return value for jumpto_tag */ -static char_u *nofile_fname = NULL; /* fname for NOTAGFILE error */ +#define NOTAGFILE 99 // return value for jumpto_tag +static char_u *nofile_fname = NULL; // fname for NOTAGFILE error #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -111,7 +111,7 @@ static char_u *recurmsg static char_u *tfu_inv_ret_msg = (char_u *)N_("E987: invalid return value from tagfunc"); -static char_u *tagmatchname = NULL; /* name of last used tag */ +static char_u *tagmatchname = NULL; // name of last used tag /* * Tag for preview window is remembered separately, to avoid messing up the @@ -124,36 +124,31 @@ static int tfu_in_use = false; // disallow recursive call of tagfunc // Used instead of NUL to separate tag fields in the growarrays. #define TAG_SEP 0x02 -/* - * Jump to tag; handling of tag commands and tag stack - * - * *tag != NUL: ":tag {tag}", jump to new tag, add to tag stack - * - * type == DT_TAG: ":tag [tag]", jump to newer position or same tag again - * type == DT_HELP: like DT_TAG, but don't use regexp. - * type == DT_POP: ":pop" or CTRL-T, jump to old position - * type == DT_NEXT: jump to next match of same tag - * type == DT_PREV: jump to previous match of same tag - * type == DT_FIRST: jump to first match of same tag - * type == DT_LAST: jump to last match of same tag - * type == DT_SELECT: ":tselect [tag]", select tag from a list of all matches - * type == DT_JUMP: ":tjump [tag]", jump to tag or select tag from a list - * type == DT_CSCOPE: use cscope to find the tag - * type == DT_LTAG: use location list for displaying tag matches - * type == DT_FREE: free cached matches - * - * for cscope, returns TRUE if we jumped to tag or aborted, FALSE otherwise - */ -int -do_tag( - char_u *tag, // tag (pattern) to jump to - int type, - int count, - int forceit, // :ta with ! - int verbose // print "tag not found" message -) +/// Jump to tag; handling of tag commands and tag stack +/// +/// *tag != NUL: ":tag {tag}", jump to new tag, add to tag stack +/// +/// type == DT_TAG: ":tag [tag]", jump to newer position or same tag again +/// type == DT_HELP: like DT_TAG, but don't use regexp. +/// type == DT_POP: ":pop" or CTRL-T, jump to old position +/// type == DT_NEXT: jump to next match of same tag +/// type == DT_PREV: jump to previous match of same tag +/// type == DT_FIRST: jump to first match of same tag +/// type == DT_LAST: jump to last match of same tag +/// type == DT_SELECT: ":tselect [tag]", select tag from a list of all matches +/// type == DT_JUMP: ":tjump [tag]", jump to tag or select tag from a list +/// type == DT_CSCOPE: use cscope to find the tag +/// type == DT_LTAG: use location list for displaying tag matches +/// type == DT_FREE: free cached matches +/// +/// for cscope, returns TRUE if we jumped to tag or aborted, FALSE otherwise +/// +/// @param tag tag (pattern) to jump to +/// @param forceit :ta with ! +/// @param verbose print "tag not found" message +int do_tag(char_u *tag, int type, int count, int forceit, int verbose) { - taggy_T *tagstack = curwin->w_tagstack; + taggy_T *tagstack = curwin->w_tagstack; int tagstackidx = curwin->w_tagstackidx; int tagstacklen = curwin->w_tagstacklen; int cur_match = 0; @@ -170,16 +165,16 @@ do_tag( fmark_T saved_fmark; int jumped_to_tag = false; int new_num_matches; - char_u **new_matches; + char_u **new_matches; int use_tagstack; int skip_msg = false; char_u *buf_ffname = curbuf->b_ffname; // name for priority computation int use_tfu = 1; - /* remember the matches for the last used tag */ + // remember the matches for the last used tag static int num_matches = 0; - static int max_num_matches = 0; /* limit used for match search */ - static char_u **matches = NULL; + static int max_num_matches = 0; // limit used for match search + static char_u **matches = NULL; static int flags; if (tfu_in_use) { @@ -189,7 +184,7 @@ do_tag( #ifdef EXITFREE if (type == DT_FREE) { - /* remove the list of matches */ + // remove the list of matches FreeWild(num_matches, matches); cs_free_tags(); num_matches = 0; @@ -207,7 +202,7 @@ do_tag( free_string_option(nofile_fname); nofile_fname = NULL; - clearpos(&saved_fmark.mark); /* shutup gcc 4.0 */ + clearpos(&saved_fmark.mark); // shutup gcc 4.0 saved_fmark.fnum = 0; // Don't add a tag to the tagstack if 'tagstack' has been reset. @@ -226,7 +221,7 @@ do_tag( use_tagstack = true; } - /* new pattern, add to the tag stack */ + // new pattern, add to the tag stack if (*tag != NUL && (type == DT_TAG || type == DT_SELECT || type == DT_JUMP || type == DT_LTAG @@ -235,8 +230,8 @@ do_tag( if (g_do_tagpreview != 0) { if (ptag_entry.tagname != NULL && STRCMP(ptag_entry.tagname, tag) == 0) { - /* Jumping to same tag: keep the current match, so that - * the CursorHold autocommand example works. */ + // Jumping to same tag: keep the current match, so that + // the CursorHold autocommand example works. cur_match = ptag_entry.cur_match; cur_fnum = ptag_entry.cur_fnum; } else { @@ -252,7 +247,7 @@ do_tag( tagstack_clear_entry(&tagstack[--tagstacklen]); } - /* if the tagstack is full: remove oldest entry */ + // if the tagstack is full: remove oldest entry if (++tagstacklen > TAGSTACKSIZE) { tagstacklen = TAGSTACKSIZE; tagstack_clear_entry(&tagstack[0]); @@ -293,7 +288,7 @@ do_tag( * way to the bottom now. */ tagstackidx = 0; - } else if (tagstackidx >= tagstacklen) { // count == 0? + } else if (tagstackidx >= tagstacklen) { // count == 0? EMSG(_(topmsg)); goto end_do_tag; } @@ -321,8 +316,9 @@ do_tag( curwin->w_cursor.col = saved_fmark.mark.col; curwin->w_set_curswant = true; check_cursor(); - if ((fdo_flags & FDO_TAG) && old_KeyTyped) + if ((fdo_flags & FDO_TAG) && old_KeyTyped) { foldOpenCursor(); + } // remove the old list of matches FreeWild(num_matches, matches); @@ -333,8 +329,7 @@ do_tag( } if (type == DT_TAG - || type == DT_LTAG - ) { + || type == DT_LTAG) { if (g_do_tagpreview != 0) { cur_match = ptag_entry.cur_match; cur_fnum = ptag_entry.cur_fnum; @@ -350,7 +345,7 @@ do_tag( tagstackidx = tagstacklen - 1; EMSG(_(topmsg)); save_pos = false; - } else if (tagstackidx < 0) { // must have been count == 0 + } else if (tagstackidx < 0) { // must have been count == 0 EMSG(_(bottommsg)); tagstackidx = 0; goto end_do_tag; @@ -367,23 +362,28 @@ do_tag( cur_match = ptag_entry.cur_match; cur_fnum = ptag_entry.cur_fnum; } else { - if (--tagstackidx < 0) + if (--tagstackidx < 0) { tagstackidx = 0; + } cur_match = tagstack[tagstackidx].cur_match; cur_fnum = tagstack[tagstackidx].cur_fnum; } switch (type) { - case DT_FIRST: cur_match = count - 1; break; + case DT_FIRST: + cur_match = count - 1; break; case DT_SELECT: case DT_JUMP: case DT_CSCOPE: - case DT_LAST: cur_match = MAXCOL - 1; break; - case DT_NEXT: cur_match += count; break; - case DT_PREV: cur_match -= count; break; + case DT_LAST: + cur_match = MAXCOL - 1; break; + case DT_NEXT: + cur_match += count; break; + case DT_PREV: + cur_match -= count; break; } - if (cur_match >= MAXCOL) + if (cur_match >= MAXCOL) { cur_match = MAXCOL - 1; - else if (cur_match < 0) { + } else if (cur_match < 0) { EMSG(_("E425: Cannot go before first matching tag")); skip_msg = true; cur_match = 0; @@ -407,9 +407,9 @@ do_tag( tagstack[tagstackidx].fmark.fnum = curbuf->b_fnum; } - /* Curwin will change in the call to jumpto_tag() if ":stag" was - * used or an autocommand jumps to another window; store value of - * tagstackidx now. */ + // Curwin will change in the call to jumpto_tag() if ":stag" was + // used or an autocommand jumps to another window; store value of + // tagstackidx now. curwin->w_tagstackidx = tagstackidx; if (type != DT_SELECT && type != DT_JUMP) { curwin->w_tagstack[tagstackidx].cur_match = cur_match; @@ -418,14 +418,15 @@ do_tag( } } - /* When not using the current buffer get the name of buffer "cur_fnum". - * Makes sure that the tag order doesn't change when using a remembered - * position for "cur_match". */ + // When not using the current buffer get the name of buffer "cur_fnum". + // Makes sure that the tag order doesn't change when using a remembered + // position for "cur_match". if (cur_fnum != curbuf->b_fnum) { buf_T *buf = buflist_findnr(cur_fnum); - if (buf != NULL) + if (buf != NULL) { buf_ffname = buf->b_ffname; + } } /* @@ -433,7 +434,7 @@ do_tag( */ for (;; ) { int other_name; - char_u *name; + char_u *name; // When desired match not found yet, try to find it (and others). if (use_tagstack) { @@ -466,8 +467,9 @@ do_tag( if (!no_regexp && *name == '/') { flags = TAG_REGEXP; ++name; - } else + } else { flags = TAG_NOIC; + } if (type == DT_CSCOPE) { flags = TAG_CSCOPE; @@ -490,9 +492,9 @@ do_tag( * to the start. Avoids that the order changes when using * ":tnext" and jumping to another file. */ if (!new_tag && !other_name) { - int j, k; - int idx = 0; - tagptrs_T tagp, tagp2; + int j, k; + int idx = 0; + tagptrs_T tagp, tagp2; // Find the position of each old match in the new list. Need // to use parse_match() to find the tag line. @@ -517,8 +519,9 @@ do_tag( } if (num_matches <= 0) { - if (verbose) + if (verbose) { EMSG2(_("E426: tag not found: %s"), name); + } g_do_tagpreview = 0; } else { bool ask_for_selection = false; @@ -533,7 +536,7 @@ do_tag( } else if (type == DT_SELECT || (type == DT_JUMP && num_matches > 1)) { print_tag_list(new_tag, use_tagstack, num_matches, matches); ask_for_selection = true; - } else if (type == DT_LTAG) { + } else if (type == DT_LTAG) { if (add_llist_tags(tag, num_matches, matches) == FAIL) { goto end_do_tag; } @@ -563,16 +566,17 @@ do_tag( * There will be an EMSG("file doesn't exist") below then. */ if ((type == DT_NEXT || type == DT_FIRST) && nofile_fname == NULL) { - if (num_matches == 1) + if (num_matches == 1) { EMSG(_("E427: There is only one matching tag")); - else + } else { EMSG(_("E428: Cannot go beyond last matching tag")); + } skip_msg = true; } cur_match = num_matches - 1; } if (use_tagstack) { - tagptrs_T tagp2; + tagptrs_T tagp2; tagstack[tagstackidx].cur_match = cur_match; tagstack[tagstackidx].cur_fnum = cur_fnum; @@ -581,12 +585,12 @@ do_tag( if (use_tfu && parse_match(matches[cur_match], &tagp2) == OK && tagp2.user_data) { XFREE_CLEAR(tagstack[tagstackidx].user_data); - tagstack[tagstackidx].user_data = vim_strnsave( - tagp2.user_data, tagp2.user_data_end - tagp2.user_data); + tagstack[tagstackidx].user_data = vim_strnsave(tagp2.user_data, + tagp2.user_data_end - tagp2.user_data); } tagstackidx++; - } else if (g_do_tagpreview != 0) { + } else if (g_do_tagpreview != 0) { ptag_entry.cur_match = cur_match; ptag_entry.cur_fnum = cur_fnum; } @@ -595,8 +599,9 @@ do_tag( * Only when going to try the next match, report that the previous * file didn't exist. Otherwise an EMSG() is given below. */ - if (nofile_fname != NULL && error_cur_match != cur_match) + if (nofile_fname != NULL && error_cur_match != cur_match) { smsg(_("File \"%s\" does not exist"), nofile_fname); + } ic = (matches[cur_match][0] & MT_IC_OFF); @@ -631,7 +636,7 @@ do_tag( // Let the SwapExists event know what tag we are jumping to. vim_snprintf((char *)IObuff, IOSIZE, ":ta %s\r", name); - set_vim_var_string(VV_SWAPCOMMAND, (char *) IObuff, -1); + set_vim_var_string(VV_SWAPCOMMAND, (char *)IObuff, -1); /* * Jump to the desired match. @@ -648,11 +653,12 @@ do_tag( && (max_num_matches != MAXCOL || cur_match < num_matches - 1))) { error_cur_match = cur_match; - if (use_tagstack) + if (use_tagstack) { --tagstackidx; - if (type == DT_PREV) + } + if (type == DT_PREV) { --cur_match; - else { + } else { type = DT_NEXT; ++cur_match; } @@ -662,8 +668,9 @@ do_tag( } else { /* We may have jumped to another window, check that * tagstackidx is still valid. */ - if (use_tagstack && tagstackidx > curwin->w_tagstacklen) + if (use_tagstack && tagstackidx > curwin->w_tagstacklen) { tagstackidx = curwin->w_tagstackidx; + } jumped_to_tag = true; } } @@ -684,331 +691,322 @@ end_do_tag: // // List all the matching tags. // -static void -print_tag_list( - int new_tag, - int use_tagstack, - int num_matches, - char_u **matches) +static void print_tag_list(int new_tag, int use_tagstack, int num_matches, char_u **matches) { - taggy_T *tagstack = curwin->w_tagstack; - int tagstackidx = curwin->w_tagstackidx; - int i; - char_u *p; - char_u *command_end; - tagptrs_T tagp; - int taglen; - int attr; - - // Assume that the first match indicates how long the tags can - // be, and align the file names to that. - parse_match(matches[0], &tagp); - taglen = (int)(tagp.tagname_end - tagp.tagname + 2); - if (taglen < 18) { - taglen = 18; - } - if (taglen > Columns - 25) { - taglen = MAXCOL; - } - if (msg_col == 0) { - msg_didout = false; // overwrite previous message - } - msg_start(); - msg_puts_attr(_(" # pri kind tag"), HL_ATTR(HLF_T)); - msg_clr_eos(); + taggy_T *tagstack = curwin->w_tagstack; + int tagstackidx = curwin->w_tagstackidx; + int i; + char_u *p; + char_u *command_end; + tagptrs_T tagp; + int taglen; + int attr; + + // Assume that the first match indicates how long the tags can + // be, and align the file names to that. + parse_match(matches[0], &tagp); + taglen = (int)(tagp.tagname_end - tagp.tagname + 2); + if (taglen < 18) { + taglen = 18; + } + if (taglen > Columns - 25) { + taglen = MAXCOL; + } + if (msg_col == 0) { + msg_didout = false; // overwrite previous message + } + msg_start(); + msg_puts_attr(_(" # pri kind tag"), HL_ATTR(HLF_T)); + msg_clr_eos(); + taglen_advance(taglen); + msg_puts_attr(_("file\n"), HL_ATTR(HLF_T)); + + for (i = 0; i < num_matches && !got_int; i++) { + parse_match(matches[i], &tagp); + if (!new_tag && ( + (g_do_tagpreview != 0 + && i == ptag_entry.cur_match) + || (use_tagstack + && i == tagstack[tagstackidx].cur_match))) { + *IObuff = '>'; + } else { + *IObuff = ' '; + } + vim_snprintf((char *)IObuff + 1, IOSIZE - 1, + "%2d %s ", i + 1, + mt_names[matches[i][0] & MT_MASK]); + msg_puts((char *)IObuff); + if (tagp.tagkind != NULL) { + msg_outtrans_len(tagp.tagkind, + (int)(tagp.tagkind_end - tagp.tagkind)); + } + msg_advance(13); + msg_outtrans_len_attr(tagp.tagname, + (int)(tagp.tagname_end - tagp.tagname), + HL_ATTR(HLF_T)); + msg_putchar(' '); taglen_advance(taglen); - msg_puts_attr(_("file\n"), HL_ATTR(HLF_T)); - - for (i = 0; i < num_matches && !got_int; i++) { - parse_match(matches[i], &tagp); - if (!new_tag && ( - (g_do_tagpreview != 0 - && i == ptag_entry.cur_match) - || (use_tagstack - && i == tagstack[tagstackidx].cur_match))) { - *IObuff = '>'; - } else { - *IObuff = ' '; + + // Find out the actual file name. If it is long, truncate + // it and put "..." in the middle + p = tag_full_fname(&tagp); + if (p != NULL) { + msg_outtrans_attr(p, HL_ATTR(HLF_D)); + XFREE_CLEAR(p); + } + if (msg_col > 0) { + msg_putchar('\n'); + } + if (got_int) { + break; + } + msg_advance(15); + + // print any extra fields + command_end = tagp.command_end; + if (command_end != NULL) { + p = command_end + 3; + while (*p && *p != '\r' && *p != '\n') { + while (*p == TAB) { + p++; } - vim_snprintf((char *)IObuff + 1, IOSIZE - 1, - "%2d %s ", i + 1, - mt_names[matches[i][0] & MT_MASK]); - msg_puts((char *)IObuff); - if (tagp.tagkind != NULL) { - msg_outtrans_len(tagp.tagkind, - (int)(tagp.tagkind_end - tagp.tagkind)); + + // skip "file:" without a value (static tag) + if (STRNCMP(p, "file:", 5) == 0 && ascii_isspace(p[5])) { + p += 5; + continue; } - msg_advance(13); - msg_outtrans_len_attr(tagp.tagname, - (int)(tagp.tagname_end - tagp.tagname), - HL_ATTR(HLF_T)); - msg_putchar(' '); - taglen_advance(taglen); - - // Find out the actual file name. If it is long, truncate - // it and put "..." in the middle - p = tag_full_fname(&tagp); - if (p != NULL) { - msg_outtrans_attr(p, HL_ATTR(HLF_D)); - XFREE_CLEAR(p); + // skip "kind:<kind>" and "<kind>" + if (p == tagp.tagkind + || (p + 5 == tagp.tagkind + && STRNCMP(p, "kind:", 5) == 0)) { + p = tagp.tagkind_end; + continue; } - if (msg_col > 0) { + // print all other extra fields + attr = HL_ATTR(HLF_CM); + while (*p && *p != '\r' && *p != '\n') { + if (msg_col + ptr2cells(p) >= Columns) { msg_putchar('\n'); + if (got_int) { + break; + } + msg_advance(15); + } + p = msg_outtrans_one(p, attr); + if (*p == TAB) { + msg_puts_attr(" ", attr); + break; + } + if (*p == ':') { + attr = 0; + } } + } + if (msg_col > 15) { + msg_putchar('\n'); if (got_int) { - break; + break; } msg_advance(15); + } + } else { + for (p = tagp.command; + *p && *p != '\r' && *p != '\n'; + p++) { + } + command_end = p; + } - // print any extra fields - command_end = tagp.command_end; - if (command_end != NULL) { - p = command_end + 3; - while (*p && *p != '\r' && *p != '\n') { - while (*p == TAB) { - p++; - } - - // skip "file:" without a value (static tag) - if (STRNCMP(p, "file:", 5) == 0 && ascii_isspace(p[5])) { - p += 5; - continue; - } - // skip "kind:<kind>" and "<kind>" - if (p == tagp.tagkind - || (p + 5 == tagp.tagkind - && STRNCMP(p, "kind:", 5) == 0)) { - p = tagp.tagkind_end; - continue; - } - // print all other extra fields - attr = HL_ATTR(HLF_CM); - while (*p && *p != '\r' && *p != '\n') { - if (msg_col + ptr2cells(p) >= Columns) { - msg_putchar('\n'); - if (got_int) { - break; - } - msg_advance(15); - } - p = msg_outtrans_one(p, attr); - if (*p == TAB) { - msg_puts_attr(" ", attr); - break; - } - if (*p == ':') { - attr = 0; - } - } - } - if (msg_col > 15) { - msg_putchar('\n'); - if (got_int) { - break; - } - msg_advance(15); - } - } else { - for (p = tagp.command; - *p && *p != '\r' && *p != '\n'; - p++) { - } - command_end = p; - } - - // Put the info (in several lines) at column 15. - // Don't display "/^" and "?^". - p = tagp.command; - if (*p == '/' || *p == '?') { - p++; - if (*p == '^') { - p++; - } - } - // Remove leading whitespace from pattern - while (p != command_end && ascii_isspace(*p)) { - p++; - } + // Put the info (in several lines) at column 15. + // Don't display "/^" and "?^". + p = tagp.command; + if (*p == '/' || *p == '?') { + p++; + if (*p == '^') { + p++; + } + } + // Remove leading whitespace from pattern + while (p != command_end && ascii_isspace(*p)) { + p++; + } - while (p != command_end) { - if (msg_col + (*p == TAB ? 1 : ptr2cells(p)) > Columns) { - msg_putchar('\n'); - } - if (got_int) { - break; - } - msg_advance(15); + while (p != command_end) { + if (msg_col + (*p == TAB ? 1 : ptr2cells(p)) > Columns) { + msg_putchar('\n'); + } + if (got_int) { + break; + } + msg_advance(15); - // skip backslash used for escaping a command char or - // a backslash - if (*p == '\\' && (*(p + 1) == *tagp.command - || *(p + 1) == '\\')) { - p++; - } + // skip backslash used for escaping a command char or + // a backslash + if (*p == '\\' && (*(p + 1) == *tagp.command + || *(p + 1) == '\\')) { + p++; + } - if (*p == TAB) { - msg_putchar(' '); - p++; - } else { - p = msg_outtrans_one(p, 0); - } + if (*p == TAB) { + msg_putchar(' '); + p++; + } else { + p = msg_outtrans_one(p, 0); + } - // don't display the "$/;\"" and "$?;\"" - if (p == command_end - 2 && *p == '$' - && *(p + 1) == *tagp.command) { - break; - } - // don't display matching '/' or '?' - if (p == command_end - 1 && *p == *tagp.command - && (*p == '/' || *p == '?')) { - break; - } - } - if (msg_col) { - msg_putchar('\n'); - } - os_breakcheck(); + // don't display the "$/;\"" and "$?;\"" + if (p == command_end - 2 && *p == '$' + && *(p + 1) == *tagp.command) { + break; + } + // don't display matching '/' or '?' + if (p == command_end - 1 && *p == *tagp.command + && (*p == '/' || *p == '?')) { + break; + } } - if (got_int) { - got_int = false; // only stop the listing + if (msg_col) { + msg_putchar('\n'); } + os_breakcheck(); + } + if (got_int) { + got_int = false; // only stop the listing + } } // // Add the matching tags to the location list for the current // window. // -static int -add_llist_tags( - char_u *tag, - int num_matches, - char_u **matches) +static int add_llist_tags(char_u *tag, int num_matches, char_u **matches) { - list_T *list; - char_u tag_name[128 + 1]; - char_u *fname; - char_u *cmd; - int i; - char_u *p; - tagptrs_T tagp; - - fname = xmalloc(MAXPATHL + 1); - cmd = xmalloc(CMDBUFFSIZE + 1); - list = tv_list_alloc(0); - - for (i = 0; i < num_matches; i++) { - int len, cmd_len; - long lnum; - dict_T *dict; - - parse_match(matches[i], &tagp); - - // Save the tag name - len = (int)(tagp.tagname_end - tagp.tagname); - if (len > 128) { - len = 128; - } - xstrlcpy((char *)tag_name, (const char *)tagp.tagname, len + 1); - tag_name[len] = NUL; + list_T *list; + char_u tag_name[128 + 1]; + char_u *fname; + char_u *cmd; + int i; + char_u *p; + tagptrs_T tagp; - // Save the tag file name - p = tag_full_fname(&tagp); - if (p == NULL) { - continue; - } - xstrlcpy((char *)fname, (const char *)p, MAXPATHL); - XFREE_CLEAR(p); - - // Get the line number or the search pattern used to locate - // the tag. - lnum = 0; - if (isdigit(*tagp.command)) { - // Line number is used to locate the tag - lnum = atol((char *)tagp.command); - } else { - char_u *cmd_start, *cmd_end; + fname = xmalloc(MAXPATHL + 1); + cmd = xmalloc(CMDBUFFSIZE + 1); + list = tv_list_alloc(0); - // Search pattern is used to locate the tag + for (i = 0; i < num_matches; i++) { + int len, cmd_len; + long lnum; + dict_T *dict; - // Locate the end of the command - cmd_start = tagp.command; - cmd_end = tagp.command_end; - if (cmd_end == NULL) { - for (p = tagp.command; - *p && *p != '\r' && *p != '\n'; p++) { - } - cmd_end = p; - } + parse_match(matches[i], &tagp); - // Now, cmd_end points to the character after the - // command. Adjust it to point to the last - // character of the command. - cmd_end--; + // Save the tag name + len = (int)(tagp.tagname_end - tagp.tagname); + if (len > 128) { + len = 128; + } + STRLCPY(tag_name, tagp.tagname, len + 1); + tag_name[len] = NUL; - // Skip the '/' and '?' characters at the - // beginning and end of the search pattern. - if (*cmd_start == '/' || *cmd_start == '?') { - cmd_start++; - } + // Save the tag file name + p = tag_full_fname(&tagp); + if (p == NULL) { + continue; + } + STRLCPY(fname, p, MAXPATHL); + XFREE_CLEAR(p); + + // Get the line number or the search pattern used to locate + // the tag. + lnum = 0; + if (isdigit(*tagp.command)) { + // Line number is used to locate the tag + lnum = atol((char *)tagp.command); + } else { + char_u *cmd_start, *cmd_end; - if (*cmd_end == '/' || *cmd_end == '?') { - cmd_end--; - } + // Search pattern is used to locate the tag - len = 0; - cmd[0] = NUL; + // Locate the end of the command + cmd_start = tagp.command; + cmd_end = tagp.command_end; + if (cmd_end == NULL) { + for (p = tagp.command; + *p && *p != '\r' && *p != '\n'; p++) { + } + cmd_end = p; + } - // If "^" is present in the tag search pattern, then - // copy it first. - if (*cmd_start == '^') { - STRCPY(cmd, "^"); - cmd_start++; - len++; - } + // Now, cmd_end points to the character after the + // command. Adjust it to point to the last + // character of the command. + cmd_end--; - // Precede the tag pattern with \V to make it very - // nomagic. - STRCAT(cmd, "\\V"); - len += 2; + // Skip the '/' and '?' characters at the + // beginning and end of the search pattern. + if (*cmd_start == '/' || *cmd_start == '?') { + cmd_start++; + } - cmd_len = (int)(cmd_end - cmd_start + 1); - if (cmd_len > (CMDBUFFSIZE - 5)) { - cmd_len = CMDBUFFSIZE - 5; - } - snprintf((char *)cmd + len, CMDBUFFSIZE + 1 - len, - "%.*s", cmd_len, cmd_start); - len += cmd_len; - - if (cmd[len - 1] == '$') { - // Replace '$' at the end of the search pattern - // with '\$' - cmd[len - 1] = '\\'; - cmd[len] = '$'; - len++; - } + if (*cmd_end == '/' || *cmd_end == '?') { + cmd_end--; + } - cmd[len] = NUL; - } + len = 0; + cmd[0] = NUL; - dict = tv_dict_alloc(); - tv_list_append_dict(list, dict); + // If "^" is present in the tag search pattern, then + // copy it first. + if (*cmd_start == '^') { + STRCPY(cmd, "^"); + cmd_start++; + len++; + } - tv_dict_add_str(dict, S_LEN("text"), (const char *)tag_name); - tv_dict_add_str(dict, S_LEN("filename"), (const char *)fname); - tv_dict_add_nr(dict, S_LEN("lnum"), lnum); - if (lnum == 0) { - tv_dict_add_str(dict, S_LEN("pattern"), (const char *)cmd); - } + // Precede the tag pattern with \V to make it very + // nomagic. + STRCAT(cmd, "\\V"); + len += 2; + + cmd_len = (int)(cmd_end - cmd_start + 1); + if (cmd_len > (CMDBUFFSIZE - 5)) { + cmd_len = CMDBUFFSIZE - 5; + } + snprintf((char *)cmd + len, CMDBUFFSIZE + 1 - len, + "%.*s", cmd_len, cmd_start); + len += cmd_len; + + if (cmd[len - 1] == '$') { + // Replace '$' at the end of the search pattern + // with '\$' + cmd[len - 1] = '\\'; + cmd[len] = '$'; + len++; + } + + cmd[len] = NUL; } - vim_snprintf((char *)IObuff, IOSIZE, "ltag %s", tag); - set_errorlist(curwin, list, ' ', IObuff, NULL); + dict = tv_dict_alloc(); + tv_list_append_dict(list, dict); - tv_list_free(list); - XFREE_CLEAR(fname); - XFREE_CLEAR(cmd); + tv_dict_add_str(dict, S_LEN("text"), (const char *)tag_name); + tv_dict_add_str(dict, S_LEN("filename"), (const char *)fname); + tv_dict_add_nr(dict, S_LEN("lnum"), lnum); + if (lnum == 0) { + tv_dict_add_str(dict, S_LEN("pattern"), (const char *)cmd); + } + } - return OK; + vim_snprintf((char *)IObuff, IOSIZE, "ltag %s", tag); + set_errorlist(curwin, list, ' ', IObuff, NULL); + + tv_list_free(list); + XFREE_CLEAR(fname); + XFREE_CLEAR(cmd); + + return OK; } /* @@ -1024,8 +1022,9 @@ static void taglen_advance(int l) if (l == MAXCOL) { msg_putchar('\n'); msg_advance(24); - } else + } else { msg_advance(13 + l); + } } /* @@ -1034,18 +1033,19 @@ static void taglen_advance(int l) void do_tags(exarg_T *eap) { int i; - char_u *name; - taggy_T *tagstack = curwin->w_tagstack; + char_u *name; + taggy_T *tagstack = curwin->w_tagstack; int tagstackidx = curwin->w_tagstackidx; int tagstacklen = curwin->w_tagstacklen; - /* Highlight title */ + // Highlight title MSG_PUTS_TITLE(_("\n # TO tag FROM line in file/text")); for (i = 0; i < tagstacklen; ++i) { if (tagstack[i].tagname != NULL) { name = fm_getname(&(tagstack[i].fmark), 30); - if (name == NULL) /* file name not available */ + if (name == NULL) { // file name not available continue; + } msg_putchar('\n'); vim_snprintf((char *)IObuff, IOSIZE, "%c%2d %2d %-15s %5ld ", @@ -1059,10 +1059,11 @@ void do_tags(exarg_T *eap) ? HL_ATTR(HLF_D) : 0); xfree(name); } - ui_flush(); /* show one line at a time */ + ui_flush(); // show one line at a time } - if (tagstackidx == tagstacklen) /* idx at top of stack */ + if (tagstackidx == tagstacklen) { // idx at top of stack MSG_PUTS("\n>"); + } } @@ -1078,15 +1079,17 @@ static int tag_strnicmp(char_u *s1, char_u *s2, size_t len) while (len > 0) { i = TOUPPER_ASC(*s1) - TOUPPER_ASC(*s2); - if (i != 0) - return i; /* this character different */ - if (*s1 == NUL) - break; /* strings match until NUL */ + if (i != 0) { + return i; // this character different + } + if (*s1 == NUL) { + break; // strings match until NUL + } ++s1; ++s2; --len; } - return 0; /* strings match */ + return 0; // strings match } @@ -1098,50 +1101,56 @@ static void prepare_pats(pat_T *pats, int has_re) pats->head = pats->pat; pats->headlen = pats->len; if (has_re) { - /* When the pattern starts with '^' or "\\<", binary searching can be - * used (much faster). */ - if (pats->pat[0] == '^') + // When the pattern starts with '^' or "\\<", binary searching can be + // used (much faster). + if (pats->pat[0] == '^') { pats->head = pats->pat + 1; - else if (pats->pat[0] == '\\' && pats->pat[1] == '<') + } else if (pats->pat[0] == '\\' && pats->pat[1] == '<') { pats->head = pats->pat + 2; - if (pats->head == pats->pat) + } + if (pats->head == pats->pat) { pats->headlen = 0; - else + } else { for (pats->headlen = 0; pats->head[pats->headlen] != NUL; - ++pats->headlen) + ++pats->headlen) { if (vim_strchr((char_u *)(p_magic ? ".[~*\\$" : "\\$"), - pats->head[pats->headlen]) != NULL) + pats->head[pats->headlen]) != NULL) { break; - if (p_tl != 0 && pats->headlen > p_tl) /* adjust for 'taglength' */ + } + } + } + if (p_tl != 0 && pats->headlen > p_tl) { // adjust for 'taglength' pats->headlen = p_tl; + } } - if (has_re) + if (has_re) { pats->regmatch.regprog = vim_regcomp(pats->pat, p_magic ? RE_MAGIC : 0); - else + } else { pats->regmatch.regprog = NULL; + } } -// -// Call the user-defined function to generate a list of tags used by -// find_tags(). -// -// Return OK if at least 1 tag has been successfully found, -// NOTDONE if the function returns v:null, and FAIL otherwise. -// -static int find_tagfunc_tags( - char_u *pat, // pattern supplied to the user-defined function - garray_T *ga, // the tags will be placed here - int *match_count, // here the number of tags found will be placed - int flags, // flags from find_tags (TAG_*) - char_u *buf_ffname) // name of buffer for priority +/// Call the user-defined function to generate a list of tags used by +/// find_tags(). +/// +/// Return OK if at least 1 tag has been successfully found, +/// NOTDONE if the function returns v:null, and FAIL otherwise. +/// +/// @param pat pattern supplied to the user-defined function +/// @param ga the tags will be placed here +/// @param match_count here the number of tags found will be placed +/// @param flags flags from find_tags (TAG_*) +/// @param buf_ffname name of buffer for priority +static int find_tagfunc_tags(char_u *pat, garray_T *ga, int *match_count, int flags, + char_u *buf_ffname) { - pos_T save_pos; - list_T *taglist; - int ntags = 0; - int result = FAIL; - typval_T args[4]; - typval_T rettv; + pos_T save_pos; + list_T *taglist; + int ntags = 0; + int result = FAIL; + typval_T args[4]; + typval_T rettv; char_u flagString[4]; taggy_T *tag = &curwin->w_tagstack[curwin->w_tagstackidx]; @@ -1195,12 +1204,12 @@ static int find_tagfunc_tags( taglist = rettv.vval.v_list; TV_LIST_ITER_CONST(taglist, li, { - char_u *res_name; - char_u *res_fname; - char_u *res_cmd; - char_u *res_kind; - int has_extra = 0; - int name_only = flags & TAG_NAMES; + char_u *res_name; + char_u *res_fname; + char_u *res_cmd; + char_u *res_kind; + int has_extra = 0; + int name_only = flags & TAG_NAMES; if (TV_LIST_ITEM_TV(li)->v_type != VAR_DICT) { EMSG(_(tfu_inv_ret_msg)); @@ -1326,50 +1335,46 @@ static int find_tagfunc_tags( return result; } -/* - * find_tags() - search for tags in tags files - * - * Return FAIL if search completely failed (*num_matches will be 0, *matchesp - * will be NULL), OK otherwise. - * - * There is a priority in which type of tag is recognized. - * - * 6. A static or global tag with a full matching tag for the current file. - * 5. A global tag with a full matching tag for another file. - * 4. A static tag with a full matching tag for another file. - * 3. A static or global tag with an ignore-case matching tag for the - * current file. - * 2. A global tag with an ignore-case matching tag for another file. - * 1. A static tag with an ignore-case matching tag for another file. - * - * Tags in an emacs-style tags file are always global. - * - * flags: - * TAG_HELP only search for help tags - * TAG_NAMES only return name of tag - * TAG_REGEXP use "pat" as a regexp - * TAG_NOIC don't always ignore case - * TAG_KEEP_LANG keep language - * TAG_CSCOPE use cscope results for tags - * TAG_NO_TAGFUNC do not call the 'tagfunc' function - */ -int -find_tags( - char_u *pat, // pattern to search for - int *num_matches, // return: number of matches found - char_u ***matchesp, // return: array of matches found - int flags, - int mincount, /* MAXCOL: find all matches - other: minimal number of matches */ - char_u *buf_ffname /* name of buffer for priority */ -) +/// find_tags() - search for tags in tags files +/// +/// Return FAIL if search completely failed (*num_matches will be 0, *matchesp +/// will be NULL), OK otherwise. +/// +/// There is a priority in which type of tag is recognized. +/// +/// 6. A static or global tag with a full matching tag for the current file. +/// 5. A global tag with a full matching tag for another file. +/// 4. A static tag with a full matching tag for another file. +/// 3. A static or global tag with an ignore-case matching tag for the +/// current file. +/// 2. A global tag with an ignore-case matching tag for another file. +/// 1. A static tag with an ignore-case matching tag for another file. +/// +/// Tags in an emacs-style tags file are always global. +/// +/// flags: +/// TAG_HELP only search for help tags +/// TAG_NAMES only return name of tag +/// TAG_REGEXP use "pat" as a regexp +/// TAG_NOIC don't always ignore case +/// TAG_KEEP_LANG keep language +/// TAG_CSCOPE use cscope results for tags +/// TAG_NO_TAGFUNC do not call the 'tagfunc' function +/// +/// @param pat pattern to search for +/// @param num_matches return: number of matches found +/// @param matchesp return: array of matches found +/// @param mincount MAXCOL: find all matches other: minimal number of matches */ +/// @param buf_ffname name of buffer for priority +int find_tags(char_u *pat, int *num_matches, char_u ***matchesp, int flags, int mincount, + char_u *buf_ffname) { - FILE *fp; - char_u *lbuf; /* line buffer */ - int lbuf_size = LSIZE; /* length of lbuf */ - char_u *tag_fname; /* name of tag file */ - tagname_T tn; /* info for get_tagfname() */ - int first_file; /* trying first tag file */ + FILE *fp; + char_u *lbuf; // line buffer + int lbuf_size = LSIZE; // length of lbuf + char_u *tag_fname; // name of tag file + tagname_T tn; // info for get_tagfname() + int first_file; // trying first tag file tagptrs_T tagp; bool did_open = false; // did open a tag file bool stop_searching = false; // stop when match found or error @@ -1377,8 +1382,8 @@ find_tags( int is_static; // current tag line is static int is_current; // file name matches bool eof = false; // found end-of-file - char_u *p; - char_u *s; + char_u *p; + char_u *s; int i; int tag_file_sorted = NUL; // !_TAG_FILE_SORTED value struct tag_search_info { // Binary search file offsets @@ -1396,17 +1401,17 @@ find_tags( off_T offset; int round; enum { - TS_START, /* at start of file */ - TS_LINEAR /* linear searching forward, till EOF */ - , TS_BINARY, /* binary searching */ - TS_SKIP_BACK, /* skipping backwards */ - TS_STEP_FORWARD /* stepping forwards */ - } state; /* Current search state */ + TS_START, // at start of file + TS_LINEAR, // linear searching forward, till EOF + TS_BINARY, // binary searching + TS_SKIP_BACK, // skipping backwards + TS_STEP_FORWARD // stepping forwards + } state; // Current search state int cmplen; - int match; /* matches */ - int match_no_ic = 0; /* matches with rm_ic == FALSE */ - int match_re; /* match with regexp */ + int match; // matches + int match_no_ic = 0; // matches with rm_ic == FALSE + int match_re; // match with regexp int matchoff = 0; int save_emsg_off; @@ -1416,16 +1421,16 @@ find_tags( hashtab_T ht_match[MT_COUNT]; // stores matches by key hash_T hash = 0; int match_count = 0; // number of matches found - char_u **matches; + char_u **matches; int mtt; int help_save; int help_pri = 0; - char_u *help_lang_find = NULL; // lang to be found + char_u *help_lang_find = NULL; // lang to be found char_u help_lang[3]; // lang of current tags file - char_u *saved_pat = NULL; // copy of pat[] + char_u *saved_pat = NULL; // copy of pat[] bool is_txt = false; - pat_T orgpat; /* holds unconverted pattern info */ + pat_T orgpat; // holds unconverted pattern info vimconv_T vimconv; int findall = (mincount == MAXCOL || mincount == TAG_MANY); @@ -1447,22 +1452,22 @@ find_tags( // Change the value of 'ignorecase' according to 'tagcase' for the // duration of this function. switch (curbuf->b_tc_flags ? curbuf->b_tc_flags : tc_flags) { - case TC_FOLLOWIC: - break; - case TC_IGNORE: - p_ic = true; - break; - case TC_MATCH: - p_ic = false; - break; - case TC_FOLLOWSCS: - p_ic = ignorecase(pat); - break; - case TC_SMART: - p_ic = ignorecase_opt(pat, true, true); - break; - default: - abort(); + case TC_FOLLOWIC: + break; + case TC_IGNORE: + p_ic = true; + break; + case TC_MATCH: + p_ic = false; + break; + case TC_FOLLOWSCS: + p_ic = ignorecase(pat); + break; + case TC_SMART: + p_ic = ignorecase_opt(pat, true, true); + break; + default: + abort(); } help_save = curbuf->b_help; @@ -1480,7 +1485,7 @@ find_tags( hash_init(&ht_match[mtt]); } - STRCPY(tag_fname, "from cscope"); /* for error messages */ + STRCPY(tag_fname, "from cscope"); // for error messages /* * Initialize a few variables @@ -1495,8 +1500,8 @@ find_tags( orgpat.len = (int)STRLEN(pat); if (curbuf->b_help) { - /* When "@ab" is specified use only the "ab" language, otherwise - * search all languages. */ + // When "@ab" is specified use only the "ab" language, otherwise + // search all languages. if (orgpat.len > 3 && pat[orgpat.len - 3] == '@' && ASCII_ISALPHA(pat[orgpat.len - 2]) && ASCII_ISALPHA(pat[orgpat.len - 1])) { @@ -1506,15 +1511,17 @@ find_tags( orgpat.len -= 3; } } - if (p_tl != 0 && orgpat.len > p_tl) /* adjust for 'taglength' */ + if (p_tl != 0 && orgpat.len > p_tl) { // adjust for 'taglength' orgpat.len = p_tl; + } save_emsg_off = emsg_off; - emsg_off = TRUE; /* don't want error for invalid RE here */ + emsg_off = TRUE; // don't want error for invalid RE here prepare_pats(&orgpat, has_re); emsg_off = save_emsg_off; - if (has_re && orgpat.regmatch.regprog == NULL) + if (has_re && orgpat.regmatch.regprog == NULL) { goto findtag_end; + } // This is only to avoid a compiler warning for using search_info // uninitialised. @@ -1580,8 +1587,9 @@ find_tags( /* When searching for a specific language skip tags files * for other languages. */ if (help_lang_find != NULL - && STRICMP(help_lang, help_lang_find) != 0) + && STRICMP(help_lang, help_lang_find) != 0) { continue; + } /* For CTRL-] in a help file prefer a match with the same * language. */ @@ -1591,23 +1599,26 @@ find_tags( && (i = (int)STRLEN(curbuf->b_fname)) > 4 && curbuf->b_fname[i - 1] == 'x' && curbuf->b_fname[i - 4] == '.' - && STRNICMP(curbuf->b_fname + i - 3, help_lang, 2) == 0) + && STRNICMP(curbuf->b_fname + i - 3, help_lang, 2) == 0) { help_pri = 0; - else { + } else { help_pri = 1; for (s = p_hlg; *s != NUL; ++s) { - if (STRNICMP(s, help_lang, 2) == 0) + if (STRNICMP(s, help_lang, 2) == 0) { break; + } ++help_pri; - if ((s = vim_strchr(s, ',')) == NULL) + if ((s = vim_strchr(s, ',')) == NULL) { break; + } } if (s == NULL || *s == NUL) { - /* Language not in 'helplang': use last, prefer English, - * unless found already. */ - ++help_pri; - if (STRICMP(help_lang, "en") != 0) + // Language not in 'helplang': use last, prefer English, + // unless found already. + help_pri++; + if (STRICMP(help_lang, "en") != 0) { ++help_pri; + } } } } @@ -1624,7 +1635,7 @@ find_tags( } did_open = true; // remember that we found at least one file - state = TS_START; /* we're at the start of the file */ + state = TS_START; // we're at the start of the file /* * Read and parse the lines in the file one by one @@ -1636,31 +1647,34 @@ find_tags( } else { fast_breakcheck(); } - if ((flags & TAG_INS_COMP)) /* Double brackets for gcc */ + if ((flags & TAG_INS_COMP)) { // Double brackets for gcc ins_compl_check_keys(30, false); + } if (got_int || compl_interrupted) { stop_searching = true; break; } - /* When mincount is TAG_MANY, stop when enough matches have been - * found (for completion). */ + // When mincount is TAG_MANY, stop when enough matches have been + // found (for completion). if (mincount == TAG_MANY && match_count >= TAG_MANY) { stop_searching = true; retval = OK; break; } - if (get_it_again) + if (get_it_again) { goto line_read_in; + } /* * For binary search: compute the next offset to use. */ if (state == TS_BINARY) { offset = search_info.low_offset + ((search_info.high_offset - search_info.low_offset) / 2); - if (offset == search_info.curr_offset) - break; /* End the binary search without a match. */ - else + if (offset == search_info.curr_offset) { + break; // End the binary search without a match. + } else { search_info.curr_offset = offset; + } } else if (state == TS_SKIP_BACK) { // Skipping back (after a match during binary search). search_info.curr_offset -= lbuf_size * 2; @@ -1676,13 +1690,13 @@ find_tags( * start of the next line. */ if (state == TS_BINARY || state == TS_SKIP_BACK) { - /* Adjust the search file offset to the correct position */ + // Adjust the search file offset to the correct position search_info.curr_offset_used = search_info.curr_offset; vim_fseek(fp, search_info.curr_offset, SEEK_SET); eof = vim_fgets(lbuf, lbuf_size, fp); if (!eof && search_info.curr_offset != 0) { - /* The explicit cast is to work around a bug in gcc 3.4.2 - * (repeated below). */ + // The explicit cast is to work around a bug in gcc 3.4.2 + // (repeated below). search_info.curr_offset = vim_ftell(fp); if (search_info.curr_offset == search_info.high_offset) { // oops, gone a bit too far; try from low offset @@ -1691,13 +1705,13 @@ find_tags( } eof = vim_fgets(lbuf, lbuf_size, fp); } - /* skip empty and blank lines */ + // skip empty and blank lines while (!eof && vim_isblankline(lbuf)) { search_info.curr_offset = vim_ftell(fp); eof = vim_fgets(lbuf, lbuf_size, fp); } if (eof) { - /* Hit end of file. Skip backwards. */ + // Hit end of file. Skip backwards. state = TS_SKIP_BACK; search_info.match_offset = vim_ftell(fp); search_info.curr_offset = search_info.curr_offset_used; @@ -1708,7 +1722,7 @@ find_tags( * Not jumping around in the file: Read the next line. */ else { - /* skip empty and blank lines */ + // skip empty and blank lines do { eof = use_cscope ? cs_fgets(lbuf, lbuf_size) @@ -1716,21 +1730,21 @@ find_tags( } while (!eof && vim_isblankline(lbuf)); if (eof) { - break; /* end of file */ + break; // end of file } } line_read_in: if (vimconv.vc_type != CONV_NONE) { - char_u *conv_line; + char_u *conv_line; int len; - /* Convert every line. Converting the pattern from 'enc' to - * the tags file encoding doesn't work, because characters are - * not recognized. */ + // Convert every line. Converting the pattern from 'enc' to + // the tags file encoding doesn't work, because characters are + // not recognized. conv_line = string_convert(&vimconv, lbuf, NULL); if (conv_line != NULL) { - /* Copy or swap lbuf and conv_line. */ + // Copy or swap lbuf and conv_line. len = (int)STRLEN(conv_line) + 1; if (len > lbuf_size) { xfree(lbuf); @@ -1750,34 +1764,35 @@ line_read_in: * format, and for "not sorted" flag. */ if (state == TS_START) { - /* The header ends when the line sorts below "!_TAG_". When - * case is folded lower case letters sort before "_". */ + // The header ends when the line sorts below "!_TAG_". When + // case is folded lower case letters sort before "_". if (STRNCMP(lbuf, "!_TAG_", 6) <= 0 || (lbuf[0] == '!' && ASCII_ISLOWER(lbuf[1]))) { - if (STRNCMP(lbuf, "!_TAG_", 6) != 0) - /* Non-header item before the header, e.g. "!" itself. - */ + if (STRNCMP(lbuf, "!_TAG_", 6) != 0) { + // Non-header item before the header, e.g. "!" itself. goto parse_line; + } /* * Read header line. */ - if (STRNCMP(lbuf, "!_TAG_FILE_SORTED\t", 18) == 0) + if (STRNCMP(lbuf, "!_TAG_FILE_SORTED\t", 18) == 0) { tag_file_sorted = lbuf[18]; + } if (STRNCMP(lbuf, "!_TAG_FILE_ENCODING\t", 20) == 0) { - /* Prepare to convert every line from the specified - * encoding to 'encoding'. */ - for (p = lbuf + 20; *p > ' ' && *p < 127; ++p) - ; + // Prepare to convert every line from the specified + // encoding to 'encoding'. + for (p = lbuf + 20; *p > ' ' && *p < 127; p++) { + } *p = NUL; convert_setup(&vimconv, lbuf + 20, p_enc); } - /* Read the next line. Unrecognized flags are ignored. */ + // Read the next line. Unrecognized flags are ignored. continue; } - /* Headers ends. */ + // Headers ends. /* * When there is no tag head, or ignoring case, need to do a @@ -1788,23 +1803,24 @@ line_read_in: * flag set. * For cscope, it's always linear. */ - if (linear || use_cscope) + if (linear || use_cscope) { state = TS_LINEAR; - else if (tag_file_sorted == NUL) + } else if (tag_file_sorted == NUL) { state = TS_BINARY; - else if (tag_file_sorted == '1') + } else if (tag_file_sorted == '1') { state = TS_BINARY; - else if (tag_file_sorted == '2') { + } else if (tag_file_sorted == '2') { state = TS_BINARY; sortic = true; orgpat.regmatch.rm_ic = (p_ic || !noic); - } else + } else { state = TS_LINEAR; + } if (state == TS_BINARY && orgpat.regmatch.rm_ic && !sortic) { - /* Binary search won't work for ignoring case, use linear - * search. */ - linear = TRUE; + // Binary search won't work for ignoring case, use linear + // search. + linear = true; state = TS_LINEAR; } @@ -1865,20 +1881,23 @@ parse_line: * there is no regexp, or the tag is too short. */ cmplen = (int)(tagp.tagname_end - tagp.tagname); - if (p_tl != 0 && cmplen > p_tl) /* adjust for 'taglength' */ + if (p_tl != 0 && cmplen > p_tl) { // adjust for 'taglength' cmplen = p_tl; - if (has_re && orgpat.headlen < cmplen) + } + if (has_re && orgpat.headlen < cmplen) { cmplen = orgpat.headlen; - else if (state == TS_LINEAR && orgpat.headlen != cmplen) + } else if (state == TS_LINEAR && orgpat.headlen != cmplen) { continue; + } if (state == TS_BINARY) { /* * Simplistic check for unsorted tags file. */ i = (int)tagp.tagname[0]; - if (sortic) + if (sortic) { i = TOUPPER_ASC(tagp.tagname[0]); + } if (i < search_info.low_char || i > search_info.high_char) { sort_error = true; } @@ -1886,27 +1905,28 @@ parse_line: /* * Compare the current tag with the searched tag. */ - if (sortic) + if (sortic) { tagcmp = tag_strnicmp(tagp.tagname, orgpat.head, - (size_t)cmplen); - else + (size_t)cmplen); + } else { tagcmp = STRNCMP(tagp.tagname, orgpat.head, cmplen); + } /* * A match with a shorter tag means to search forward. * A match with a longer tag means to search backward. */ if (tagcmp == 0) { - if (cmplen < orgpat.headlen) + if (cmplen < orgpat.headlen) { tagcmp = -1; - else if (cmplen > orgpat.headlen) + } else if (cmplen > orgpat.headlen) { tagcmp = 1; + } } if (tagcmp == 0) { - /* We've located the tag, now skip back and search - * forward until the first matching tag is found. - */ + // We've located the tag, now skip back and search + // forward until the first matching tag is found. state = TS_SKIP_BACK; search_info.match_offset = search_info.curr_offset; continue; @@ -1915,37 +1935,40 @@ parse_line: search_info.curr_offset = vim_ftell(fp); if (search_info.curr_offset < search_info.high_offset) { search_info.low_offset = search_info.curr_offset; - if (sortic) + if (sortic) { search_info.low_char = TOUPPER_ASC(tagp.tagname[0]); - else + } else { search_info.low_char = tagp.tagname[0]; + } continue; } } if (tagcmp > 0 && search_info.curr_offset != search_info.high_offset) { search_info.high_offset = search_info.curr_offset; - if (sortic) + if (sortic) { search_info.high_char = TOUPPER_ASC(tagp.tagname[0]); - else + } else { search_info.high_char = tagp.tagname[0]; + } continue; } - /* No match yet and are at the end of the binary search. */ + // No match yet and are at the end of the binary search. break; - } else if (state == TS_SKIP_BACK) { + } else if (state == TS_SKIP_BACK) { assert(cmplen >= 0); - if (mb_strnicmp(tagp.tagname, orgpat.head, (size_t)cmplen) != 0) + if (mb_strnicmp(tagp.tagname, orgpat.head, (size_t)cmplen) != 0) { state = TS_STEP_FORWARD; - else - /* Have to skip back more. Restore the curr_offset - * used, otherwise we get stuck at a long line. */ + } else { + // Have to skip back more. Restore the curr_offset + // used, otherwise we get stuck at a long line. search_info.curr_offset = search_info.curr_offset_used; + } continue; - } else if (state == TS_STEP_FORWARD) { + } else if (state == TS_STEP_FORWARD) { assert(cmplen >= 0); if (mb_strnicmp(tagp.tagname, orgpat.head, (size_t)cmplen) != 0) { if ((off_T)vim_ftell(fp) > search_info.match_offset) { @@ -1954,23 +1977,27 @@ parse_line: continue; // before first match } } - } else - /* skip this match if it can't match */ - assert(cmplen >= 0); - if (mb_strnicmp(tagp.tagname, orgpat.head, (size_t)cmplen) != 0) + } else { + // skip this match if it can't match + assert(cmplen >= 0); + } + if (mb_strnicmp(tagp.tagname, orgpat.head, (size_t)cmplen) != 0) { continue; + } // Can be a matching tag, isolate the file name and command. tagp.fname = tagp.tagname_end + 1; tagp.fname_end = vim_strchr(tagp.fname, TAB); tagp.command = tagp.fname_end + 1; - if (tagp.fname_end == NULL) + if (tagp.fname_end == NULL) { i = FAIL; - else + } else { i = OK; - } else + } + } else { i = parse_tag_line(lbuf, - &tagp); + &tagp); + } if (i == FAIL) { line_error = true; break; @@ -1981,20 +2008,23 @@ parse_line: * a regexp). */ cmplen = (int)(tagp.tagname_end - tagp.tagname); - if (p_tl != 0 && cmplen > p_tl) /* adjust for 'taglength' */ + if (p_tl != 0 && cmplen > p_tl) { // adjust for 'taglength' cmplen = p_tl; - /* if tag length does not match, don't try comparing */ - if (orgpat.len != cmplen) + } + // if tag length does not match, don't try comparing + if (orgpat.len != cmplen) { match = FALSE; - else { + } else { if (orgpat.regmatch.rm_ic) { assert(cmplen >= 0); match = mb_strnicmp(tagp.tagname, orgpat.pat, (size_t)cmplen) == 0; - if (match) + if (match) { match_no_ic = (STRNCMP(tagp.tagname, orgpat.pat, - cmplen) == 0); - } else + cmplen) == 0); + } + } else { match = (STRNCMP(tagp.tagname, orgpat.pat, cmplen) == 0); + } } /* @@ -2012,7 +2042,7 @@ parse_line: if (orgpat.regmatch.rm_ic) { orgpat.regmatch.rm_ic = FALSE; match_no_ic = vim_regexec(&orgpat.regmatch, tagp.tagname, - (colnr_T)0); + (colnr_T)0); orgpat.regmatch.rm_ic = TRUE; } } @@ -2025,7 +2055,7 @@ parse_line: int len = 0; if (use_cscope) { - /* Don't change the ordering, always use the same table. */ + // Don't change the ordering, always use the same table. mtt = MT_GL_OTH; } else { // Decide in which array to store this match. @@ -2035,27 +2065,31 @@ parse_line: // Decide in which of the sixteen tables to store this match. if (is_static) { - if (is_current) + if (is_current) { mtt = MT_ST_CUR; - else + } else { mtt = MT_ST_OTH; + } } else { - if (is_current) + if (is_current) { mtt = MT_GL_CUR; - else + } else { mtt = MT_GL_OTH; + } } - if (orgpat.regmatch.rm_ic && !match_no_ic) + if (orgpat.regmatch.rm_ic && !match_no_ic) { mtt += MT_IC_OFF; - if (match_re) + } + if (match_re) { mtt += MT_RE_OFF; + } } // Add the found match in ht_match[mtt] and ga_match[mtt]. // Store the info we need later, which depends on the kind of // tags we are dealing with. if (help_only) { -# define ML_EXTRA 3 +#define ML_EXTRA 3 // Append the help-heuristic number after the tagname, for // sorting it later. The heuristic is ignored for // detecting duplicates. @@ -2074,7 +2108,7 @@ parse_line: + help_pri); *tagp.tagname_end = TAB; - } else if (name_only) { + } else if (name_only) { if (get_it_again) { char_u *temp_end = tagp.command; @@ -2148,7 +2182,7 @@ parse_line: hash_add_item(&ht_match[mtt], hi, mfp, hash); ga_grow(&ga_match[mtt], 1); ((char_u **)(ga_match[mtt].ga_data)) - [ga_match[mtt].ga_len++] = mfp; + [ga_match[mtt].ga_len++] = mfp; match_count++; } else { // duplicate tag, drop it @@ -2156,9 +2190,10 @@ parse_line: } } } - if (use_cscope && eof) + if (use_cscope && eof) { break; - } /* forever */ + } + } // forever if (line_error) { EMSG2(_("E431: Format error in tags file \"%s\""), tag_fname); @@ -2169,10 +2204,12 @@ parse_line: line_error = false; } - if (!use_cscope) + if (!use_cscope) { fclose(fp); - if (vimconv.vc_type != CONV_NONE) + } + if (vimconv.vc_type != CONV_NONE) { convert_setup(&vimconv, NULL, NULL); + } tag_file_sorted = NUL; if (sort_error) { @@ -2188,27 +2225,31 @@ parse_line: stop_searching = true; } - if (stop_searching || use_cscope) + if (stop_searching || use_cscope) { break; + } + } // end of for-each-file loop - } /* end of for-each-file loop */ - - if (!use_cscope) + if (!use_cscope) { tagname_free(&tn); + } /* stop searching when already did a linear search, or when TAG_NOIC * used, and 'ignorecase' not set or already did case-ignore search */ - if (stop_searching || linear || (!p_ic && noic) || orgpat.regmatch.rm_ic) + if (stop_searching || linear || (!p_ic && noic) || orgpat.regmatch.rm_ic) { break; - if (use_cscope) + } + if (use_cscope) { break; - orgpat.regmatch.rm_ic = TRUE; /* try another time while ignoring case */ + } + orgpat.regmatch.rm_ic = TRUE; // try another time while ignoring case } if (!stop_searching) { - if (!did_open && verbose) /* never opened any tags file */ + if (!did_open && verbose) { // never opened any tags file EMSG(_("E433: No tags file")); - retval = OK; /* It's OK even when no tag found */ + } + retval = OK; // It's OK even when no tag found } findtag_end: @@ -2220,13 +2261,15 @@ findtag_end: * Move the matches from the ga_match[] arrays into one list of * matches. When retval == FAIL, free the matches. */ - if (retval == FAIL) + if (retval == FAIL) { match_count = 0; + } - if (match_count > 0) + if (match_count > 0) { matches = xmalloc(match_count * sizeof(char_u *)); - else + } else { matches = NULL; + } match_count = 0; for (mtt = 0; mtt < MT_COUNT; mtt++) { for (i = 0; i < ga_match[mtt].ga_len; i++) { @@ -2245,7 +2288,7 @@ findtag_end: } } } - matches[match_count++] = (char_u *)mfp; + matches[match_count++] = mfp; } } @@ -2275,7 +2318,7 @@ static void found_tagfile_cb(char_u *fname, void *cookie) char_u *const tag_fname = vim_strsave(fname); #ifdef BACKSLASH_IN_FILENAME - slash_adjust(tag_fname); + slash_adjust(tag_fname); #endif simplify_filename(tag_fname); GA_APPEND(char_u *, &tag_fnames, tag_fname); @@ -2293,24 +2336,22 @@ void free_tag_stuff(void) #endif -/* - * Get the next name of a tag file from the tag file list. - * For help files, use "tags" file only. - * - * Return FAIL if no more tag file names, OK otherwise. - */ -int -get_tagfname( - tagname_T *tnp, // holds status info - int first, // TRUE when first file name is wanted - char_u *buf // pointer to buffer of MAXPATHL chars -) +/// Get the next name of a tag file from the tag file list. +/// For help files, use "tags" file only. +/// +/// @param tnp holds status info +/// @param first TRUE when first file name is wanted +/// @param buf pointer to buffer of MAXPATHL chars +/// +/// @return FAIL if no more tag file names, OK otherwise. +int get_tagfname(tagname_T *tnp, int first, char_u *buf) { - char_u *fname = NULL; - char_u *r_ptr; + char_u *fname = NULL; + char_u *r_ptr; - if (first) + if (first) { memset(tnp, 0, sizeof(tagname_T)); + } if (curbuf->b_help) { /* @@ -2328,8 +2369,9 @@ get_tagfname( if (tnp->tn_hf_idx >= tag_fnames.ga_len) { /* Not found in 'runtimepath', use 'helpfile', if it exists and * wasn't used yet, replacing "help.txt" with "tags". */ - if (tnp->tn_hf_idx > tag_fnames.ga_len || *p_hf == NUL) + if (tnp->tn_hf_idx > tag_fnames.ga_len || *p_hf == NUL) { return FAIL; + } ++tnp->tn_hf_idx; STRCPY(buf, p_hf); STRCPY(path_tail(buf), "tags"); @@ -2367,14 +2409,15 @@ get_tagfname( for (;; ) { if (tnp->tn_did_filefind_init) { fname = vim_findfile(tnp->tn_search_ctx); - if (fname != NULL) + if (fname != NULL) { break; + } tnp->tn_did_filefind_init = FALSE; } else { - char_u *filename = NULL; + char_u *filename = NULL; - /* Stop when used all parts of 'tags'. */ + // Stop when used all parts of 'tags'. if (*tnp->tn_np == NUL) { vim_findfile_cleanup(tnp->tn_search_ctx); tnp->tn_search_ctx = NULL; @@ -2395,12 +2438,13 @@ get_tagfname( *filename++ = NUL; tnp->tn_search_ctx = vim_findfile_init(buf, filename, - r_ptr, 100, - FALSE, /* don't free visited list */ - FINDFILE_FILE, /* we search for a file */ - tnp->tn_search_ctx, TRUE, curbuf->b_ffname); - if (tnp->tn_search_ctx != NULL) + r_ptr, 100, + FALSE, // don't free visited list + FINDFILE_FILE, // we search for a file + tnp->tn_search_ctx, TRUE, curbuf->b_ffname); + if (tnp->tn_search_ctx != NULL) { tnp->tn_did_filefind_init = TRUE; + } } } @@ -2420,43 +2464,44 @@ void tagname_free(tagname_T *tnp) ga_clear_strings(&tag_fnames); } -/* - * Parse one line from the tags file. Find start/end of tag name, start/end of - * file name and start of search pattern. - * - * If is_etag is TRUE, tagp->fname and tagp->fname_end are not set. - * - * Return FAIL if there is a format error in this line, OK otherwise. - */ -static int -parse_tag_line( - char_u *lbuf, // line to be parsed - tagptrs_T *tagp -) +/// Parse one line from the tags file. Find start/end of tag name, start/end of +/// file name and start of search pattern. +/// +/// If is_etag is TRUE, tagp->fname and tagp->fname_end are not set. +/// +/// @param lbuf line to be parsed +/// +/// @return FAIL if there is a format error in this line, OK otherwise. +static int parse_tag_line(char_u *lbuf, tagptrs_T *tagp) { - char_u *p; + char_u *p; - /* Isolate the tagname, from lbuf up to the first white */ + // Isolate the tagname, from lbuf up to the first white tagp->tagname = lbuf; p = vim_strchr(lbuf, TAB); - if (p == NULL) + if (p == NULL) { return FAIL; + } tagp->tagname_end = p; - /* Isolate file name, from first to second white space */ - if (*p != NUL) + // Isolate file name, from first to second white space + if (*p != NUL) { ++p; + } tagp->fname = p; p = vim_strchr(p, TAB); - if (p == NULL) + if (p == NULL) { return FAIL; + } tagp->fname_end = p; - /* find start of search command, after second white space */ - if (*p != NUL) + // find start of search command, after second white space + if (*p != NUL) { ++p; - if (*p == NUL) + } + if (*p == NUL) { return FAIL; + } tagp->command = p; return OK; @@ -2466,12 +2511,12 @@ parse_tag_line( * Check if tagname is a static tag * * Static tags produced by the older ctags program have the format: - * 'file:tag file /pattern'. + * 'file:tag file /pattern'. * This is only recognized when both occurrence of 'file' are the same, to * avoid recognizing "string::string" or ":exit". * * Static tags produced by the new ctags program have the format: - * 'tag file /pattern/;"<Tab>file:' " + * 'tag file /pattern/;"<Tab>file:' " * * Return TRUE if it is a static tag and adjust *tagname to the real tag. * Return FALSE if it is not a static tag. @@ -2484,8 +2529,9 @@ static bool test_for_static(tagptrs_T *tagp) p = tagp->command; while ((p = vim_strchr(p, '\t')) != NULL) { ++p; - if (STRNCMP(p, "file:", 5) == 0) + if (STRNCMP(p, "file:", 5) == 0) { return TRUE; + } } return FALSE; @@ -2501,32 +2547,29 @@ static size_t matching_line_len(const char_u *const lbuf) return (p - lbuf) + STRLEN(p); } -/* - * Parse a line from a matching tag. Does not change the line itself. - * - * The line that we get looks like this: - * Emacs tag: <mtt><tag_fname><NUL><ebuf><NUL><lbuf> - * other tag: <mtt><tag_fname><NUL><NUL><lbuf> - * without Emacs tags: <mtt><tag_fname><NUL><lbuf> - * - * Return OK or FAIL. - */ -static int -parse_match( - char_u *lbuf, // input: matching line - tagptrs_T *tagp // output: pointers into the line -) +/// Parse a line from a matching tag. Does not change the line itself. +/// +/// The line that we get looks like this: +/// Emacs tag: <mtt><tag_fname><NUL><ebuf><NUL><lbuf> +/// other tag: <mtt><tag_fname><NUL><NUL><lbuf> +/// without Emacs tags: <mtt><tag_fname><NUL><lbuf> +/// +/// @param lbuf input: matching line +/// @param tagp output: pointers into the line +/// +/// @return OK or FAIL. +static int parse_match(char_u *lbuf, tagptrs_T *tagp) { int retval; - char_u *p; - char_u *pc, *pt; + char_u *p; + char_u *pc, *pt; tagp->tag_fname = lbuf + 1; lbuf += STRLEN(tagp->tag_fname) + 2; - /* Find search pattern and the file name for non-etags. */ + // Find search pattern and the file name for non-etags. retval = parse_tag_line(lbuf, - tagp); + tagp); tagp->tagkind = NULL; tagp->user_data = NULL; @@ -2534,7 +2577,7 @@ parse_match( tagp->command_end = NULL; if (retval == OK) { - /* Try to find a kind field: "kind:<kind>" or just "<kind>"*/ + // Try to find a kind field: "kind:<kind>" or just "<kind>" p = tagp->command; if (find_extra(&p) == OK) { tagp->command_end = p; @@ -2562,8 +2605,9 @@ parse_match( if (pc == NULL || (pt != NULL && pc > pt)) { tagp->tagkind = p; } - if (pt == NULL) + if (pt == NULL) { break; + } p = pt; MB_PTR_ADV(p); } @@ -2602,32 +2646,30 @@ static char_u *tag_full_fname(tagptrs_T *tagp) return fullname; } -/* - * Jump to a tag that has been found in one of the tag files - * - * returns OK for success, NOTAGFILE when file not found, FAIL otherwise. - */ -static int jumpto_tag( - const char_u *lbuf_arg, // line from the tags file for this tag - int forceit, // :ta with ! - int keep_help // keep help flag (FALSE for cscope) -) +/// Jump to a tag that has been found in one of the tag files +/// +/// @param lbuf_arg line from the tags file for this tag +/// @param forceit :ta with ! +/// @param keep_help keep help flag (FALSE for cscope) +/// +/// @return OK for success, NOTAGFILE when file not found, FAIL otherwise. +static int jumpto_tag(const char_u *lbuf_arg, int forceit, int keep_help) { int save_magic; bool save_p_ws; int save_p_scs, save_p_ic; linenr_T save_lnum; - char_u *str; - char_u *pbuf; /* search pattern buffer */ - char_u *pbuf_end; - char_u *tofree_fname = NULL; - char_u *fname; + char_u *str; + char_u *pbuf; // search pattern buffer + char_u *pbuf_end; + char_u *tofree_fname = NULL; + char_u *fname; tagptrs_T tagp; int retval = FAIL; int getfile_result = GETFILE_UNUSED; int search_options; - win_T *curwin_save = NULL; - char_u *full_fname = NULL; + win_T *curwin_save = NULL; + char_u *full_fname = NULL; const bool old_KeyTyped = KeyTyped; // getting the file may reset it const int l_g_do_tagpreview = g_do_tagpreview; const size_t len = matching_line_len(lbuf_arg) + 1; @@ -2636,7 +2678,7 @@ static int jumpto_tag( pbuf = xmalloc(LSIZE); - /* parse the match line into the tagp structure */ + // parse the match line into the tagp structure if (parse_match(lbuf, &tagp) == FAIL) { tagp.fname_end = NULL; goto erret; @@ -2646,7 +2688,7 @@ static int jumpto_tag( *tagp.fname_end = NUL; fname = tagp.fname; - /* copy the command to pbuf[], remove trailing CR/NL */ + // copy the command to pbuf[], remove trailing CR/NL str = tagp.command; for (pbuf_end = pbuf; *str && *str != '\n' && *str != '\r'; ) { *pbuf_end++ = *str++; @@ -2680,8 +2722,8 @@ static int jumpto_tag( * autocommand event (e.g., http://sys/file). */ if (!os_path_exists(fname) - && !has_autocmd(EVENT_BUFREADCMD, fname, NULL) - ) { + && !has_autocmd(EVENT_BUFREADCMD, fname, + NULL)) { retval = NOTAGFILE; xfree(nofile_fname); nofile_fname = vim_strsave(fname); @@ -2692,8 +2734,8 @@ static int jumpto_tag( if (l_g_do_tagpreview != 0) { - postponed_split = 0; /* don't split again below */ - curwin_save = curwin; /* Save current window */ + postponed_split = 0; // don't split again below + curwin_save = curwin; // Save current window /* * If we are reusing a window, we may change dir when @@ -2750,10 +2792,11 @@ static int jumpto_tag( if (keep_help) { /* A :ta from a help file will keep the b_help flag set. For ":ptag" * we need to use the flag from the window where we came from. */ - if (l_g_do_tagpreview != 0) + if (l_g_do_tagpreview != 0) { keep_help_flag = curwin_save->w_buffer->b_help; - else + } else { keep_help_flag = curbuf->b_help; + } } if (getfile_result == GETFILE_UNUSED) { @@ -2777,10 +2820,11 @@ static int jumpto_tag( * command. If 'cpoptions' does not contain 't', the search pattern * is not stored. */ - if (vim_strchr(p_cpo, CPO_TAGPAT) != NULL) + if (vim_strchr(p_cpo, CPO_TAGPAT) != NULL) { search_options = 0; - else + } else { search_options = SEARCH_KEEP; + } /* * If the command is a search, try here. @@ -2791,14 +2835,15 @@ static int jumpto_tag( * anything following. */ str = pbuf; - if (pbuf[0] == '/' || pbuf[0] == '?') + if (pbuf[0] == '/' || pbuf[0] == '?') { str = skip_regexp(pbuf + 1, pbuf[0], FALSE, NULL) + 1; - if (str > pbuf_end - 1) { /* search command with nothing following */ + } + if (str > pbuf_end - 1) { // search command with nothing following save_p_ws = p_ws; save_p_ic = p_ic; save_p_scs = p_scs; - p_ws = true; /* need 'wrapscan' for backward searches */ - p_ic = FALSE; /* don't ignore case now */ + p_ws = true; // need 'wrapscan' for backward searches + p_ic = FALSE; // don't ignore case now p_scs = FALSE; save_lnum = curwin->w_cursor.lnum; if (tagp.tagline > 0) { @@ -2898,15 +2943,17 @@ static int jumpto_tag( * For a help buffer: Put the cursor line at the top of the window, * the help subject will be below it. */ - if (curbuf->b_help) + if (curbuf->b_help) { set_topline(curwin, curwin->w_cursor.lnum); - if ((fdo_flags & FDO_TAG) && old_KeyTyped) + } + if ((fdo_flags & FDO_TAG) && old_KeyTyped) { foldOpenCursor(); + } } if (l_g_do_tagpreview != 0 && curwin != curwin_save && win_valid(curwin_save)) { - /* Return cursor to where we were */ + // Return cursor to where we were validate_cursor(); redraw_later(curwin, VALID); win_enter(curwin_save, true); @@ -2935,11 +2982,10 @@ erret: // If 'tagrelative' option set, change fname (name of file containing tag) // according to tag_fname (name of tag file containing fname). // Returns a pointer to allocated memory. -static char_u *expand_tag_fname(char_u *fname, char_u *const tag_fname, - const bool expand) +static char_u *expand_tag_fname(char_u *fname, char_u *const tag_fname, const bool expand) { - char_u *p; - char_u *expanded_fname = NULL; + char_u *p; + char_u *expanded_fname = NULL; expand_T xpc; /* @@ -2949,9 +2995,10 @@ static char_u *expand_tag_fname(char_u *fname, char_u *const tag_fname, ExpandInit(&xpc); xpc.xp_context = EXPAND_FILES; expanded_fname = ExpandOne(&xpc, fname, NULL, - WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE); - if (expanded_fname != NULL) + WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE); + if (expanded_fname != NULL) { fname = expanded_fname; + } } char_u *retval; @@ -2961,13 +3008,14 @@ static char_u *expand_tag_fname(char_u *fname, char_u *const tag_fname, retval = xmalloc(MAXPATHL); STRCPY(retval, tag_fname); STRLCPY(retval + (p - tag_fname), fname, - MAXPATHL - (p - tag_fname)); + MAXPATHL - (p - tag_fname)); /* * Translate names like "src/a/../b/file.c" into "src/b/file.c". */ simplify_filename(retval); - } else + } else { retval = vim_strsave(fname); + } xfree(expanded_fname); @@ -2984,9 +3032,9 @@ static int test_for_current(char_u *fname, char_u *fname_end, char_u *tag_fname, { int c; int retval = FALSE; - char_u *fullname; + char_u *fullname; - if (buf_ffname != NULL) { /* if the buffer has a name */ + if (buf_ffname != NULL) { // if the buffer has a name { c = *fname_end; *fname_end = NUL; @@ -3053,13 +3101,8 @@ static void tagstack_clear_entry(taggy_T *item) XFREE_CLEAR(item->user_data); } -int -expand_tags ( - int tagnames, /* expand tag names */ - char_u *pat, - int *num_file, - char_u ***file -) +/// @param tagnames expand tag names +int expand_tags(int tagnames, char_u *pat, int *num_file, char_u ***file) { int i; int extra_flag; @@ -3116,17 +3159,13 @@ expand_tags ( } -/* - * Add a tag field to the dictionary "dict". - * Return OK or FAIL. - */ -static int -add_tag_field( - dict_T *dict, - const char *field_name, - const char_u *start, // start of the value - const char_u *end // after the value; can be NULL -) +/// Add a tag field to the dictionary "dict". +/// Return OK or FAIL. +/// +/// @param start start of the value +/// @param end after the value; can be NULL +static int add_tag_field(dict_T *dict, const char *field_name, const char_u *start, + const char_u *end) FUNC_ATTR_NONNULL_ARG(1, 2) { int len = 0; @@ -3145,12 +3184,14 @@ add_tag_field( if (start != NULL) { if (end == NULL) { end = start + STRLEN(start); - while (end > start && (end[-1] == '\r' || end[-1] == '\n')) + while (end > start && (end[-1] == '\r' || end[-1] == '\n')) { --end; + } } len = (int)(end - start); - if (len > MAXPATHL - 1) + if (len > MAXPATHL - 1) { len = MAXPATHL - 1; + } STRLCPY(buf, start, len + 1); } buf[len] = NUL; @@ -3165,9 +3206,9 @@ add_tag_field( int get_tags(list_T *list, char_u *pat, char_u *buf_fname) { int num_matches, i, ret; - char_u **matches; - char_u *full_fname; - dict_T *dict; + char_u **matches; + char_u *full_fname; + dict_T *dict; tagptrs_T tp; bool is_static; @@ -3178,7 +3219,7 @@ int get_tags(list_T *list, char_u *pat, char_u *buf_fname) int parse_result = parse_match(matches[i], &tp); // Avoid an unused variable warning in release builds. - (void) parse_result; + (void)parse_result; assert(parse_result == OK); is_static = test_for_static(&tp); @@ -3216,29 +3257,35 @@ int get_tags(list_T *list, char_u *pat, char_u *buf_fname) // skip "file:" (static tag) p += 4; } else if (!ascii_iswhite(*p)) { - char_u *s, *n; + char_u *s, *n; int len; /* Add extra field as a dict entry. Fields are * separated by Tabs. */ n = p; - while (*p != NUL && *p >= ' ' && *p < 127 && *p != ':') + while (*p != NUL && *p >= ' ' && *p < 127 && *p != ':') { ++p; + } len = (int)(p - n); if (*p == ':' && len > 0) { s = ++p; - while (*p != NUL && *p >= ' ') + while (*p != NUL && *p >= ' ') { ++p; + } n[len] = NUL; - if (add_tag_field(dict, (char *)n, s, p) == FAIL) + if (add_tag_field(dict, (char *)n, s, p) == FAIL) { ret = FAIL; + } n[len] = ':'; - } else - /* Skip field without colon. */ - while (*p != NUL && *p >= ' ') + } else { + // Skip field without colon. + while (*p != NUL && *p >= ' ') { ++p; - if (*p == NUL) + } + } + if (*p == NUL) { break; + } } } } @@ -3319,14 +3366,8 @@ static void tagstack_shift(win_T *wp) } // Push a new item to the tag stack -static void tagstack_push_item( - win_T *wp, - char_u *tagname, - int cur_fnum, - int cur_match, - pos_T mark, - int fnum, - char_u *user_data) +static void tagstack_push_item(win_T *wp, char_u *tagname, int cur_fnum, int cur_match, pos_T mark, + int fnum, char_u *user_data) { taggy_T *tagstack = wp->w_tagstack; int idx = wp->w_tagstacklen; // top of the stack @@ -3382,13 +3423,12 @@ static void tagstack_push_items(win_T *wp, list_T *l) if (mark.col > 0) { mark.col--; } - tagstack_push_item( - wp, - tagname, - (int)tv_dict_get_number(itemdict, "bufnr"), - (int)tv_dict_get_number(itemdict, "matchnr") - 1, - mark, fnum, - (char_u *)tv_dict_get_string(itemdict, "user_data", true)); + tagstack_push_item(wp, + tagname, + (int)tv_dict_get_number(itemdict, "bufnr"), + (int)tv_dict_get_number(itemdict, "matchnr") - 1, + mark, fnum, + (char_u *)tv_dict_get_string(itemdict, "user_data", true)); } } diff --git a/src/nvim/tag.h b/src/nvim/tag.h index 9f671043b3..64bacceb1b 100644 --- a/src/nvim/tag.h +++ b/src/nvim/tag.h @@ -1,24 +1,24 @@ #ifndef NVIM_TAG_H #define NVIM_TAG_H -#include "nvim/types.h" #include "nvim/ex_cmds_defs.h" +#include "nvim/types.h" /* * Values for do_tag(). */ -#define DT_TAG 1 /* jump to newer position or same tag again */ -#define DT_POP 2 /* jump to older position */ -#define DT_NEXT 3 /* jump to next match of same tag */ -#define DT_PREV 4 /* jump to previous match of same tag */ -#define DT_FIRST 5 /* jump to first match of same tag */ -#define DT_LAST 6 /* jump to first match of same tag */ -#define DT_SELECT 7 /* jump to selection from list */ -#define DT_HELP 8 /* like DT_TAG, but no wildcards */ -#define DT_JUMP 9 /* jump to new tag or selection from list */ -#define DT_CSCOPE 10 /* cscope find command (like tjump) */ -#define DT_LTAG 11 /* tag using location list */ -#define DT_FREE 99 /* free cached matches */ +#define DT_TAG 1 // jump to newer position or same tag again +#define DT_POP 2 // jump to older position +#define DT_NEXT 3 // jump to next match of same tag +#define DT_PREV 4 // jump to previous match of same tag +#define DT_FIRST 5 // jump to first match of same tag +#define DT_LAST 6 // jump to first match of same tag +#define DT_SELECT 7 // jump to selection from list +#define DT_HELP 8 // like DT_TAG, but no wildcards +#define DT_JUMP 9 // jump to new tag or selection from list +#define DT_CSCOPE 10 // cscope find command (like tjump) +#define DT_LTAG 11 // tag using location list +#define DT_FREE 99 // free cached matches // // flags for find_tags(). @@ -40,11 +40,11 @@ * Structure used for get_tagfname(). */ typedef struct { - char_u *tn_tags; /* value of 'tags' when starting */ - char_u *tn_np; /* current position in tn_tags */ + char_u *tn_tags; // value of 'tags' when starting + char_u *tn_np; // current position in tn_tags int tn_did_filefind_init; int tn_hf_idx; - void *tn_search_ctx; + void *tn_search_ctx; } tagname_T; diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 3335fa500a..fb025265f2 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -37,45 +37,44 @@ // Some code from pangoterm http://www.leonerd.org.uk/code/pangoterm #include <assert.h> -#include <stdio.h> -#include <stdint.h> #include <stdbool.h> - +#include <stdint.h> +#include <stdio.h> #include <vterm.h> -#include "nvim/log.h" -#include "nvim/vim.h" -#include "nvim/terminal.h" -#include "nvim/message.h" -#include "nvim/memory.h" -#include "nvim/option.h" -#include "nvim/highlight.h" -#include "nvim/macros.h" -#include "nvim/mbyte.h" +#include "nvim/api/private/helpers.h" +#include "nvim/ascii.h" #include "nvim/buffer.h" #include "nvim/change.h" -#include "nvim/ascii.h" +#include "nvim/edit.h" +#include "nvim/event/loop.h" +#include "nvim/event/time.h" +#include "nvim/ex_cmds.h" +#include "nvim/ex_docmd.h" +#include "nvim/fileio.h" #include "nvim/getchar.h" -#include "nvim/ui.h" -#include "nvim/syntax.h" -#include "nvim/screen.h" +#include "nvim/highlight.h" #include "nvim/keymap.h" -#include "nvim/edit.h" -#include "nvim/mouse.h" -#include "nvim/memline.h" +#include "nvim/log.h" +#include "nvim/macros.h" +#include "nvim/main.h" #include "nvim/map.h" +#include "nvim/mbyte.h" +#include "nvim/memline.h" +#include "nvim/memory.h" +#include "nvim/message.h" #include "nvim/misc1.h" +#include "nvim/mouse.h" #include "nvim/move.h" -#include "nvim/main.h" +#include "nvim/option.h" +#include "nvim/os/input.h" +#include "nvim/screen.h" #include "nvim/state.h" -#include "nvim/ex_docmd.h" -#include "nvim/ex_cmds.h" +#include "nvim/syntax.h" +#include "nvim/terminal.h" +#include "nvim/ui.h" +#include "nvim/vim.h" #include "nvim/window.h" -#include "nvim/fileio.h" -#include "nvim/event/loop.h" -#include "nvim/event/time.h" -#include "nvim/os/input.h" -#include "nvim/api/private/helpers.h" typedef struct terminal_state { VimState state; @@ -210,7 +209,7 @@ Terminal *terminal_open(buf_T *buf, TerminalOptions opts) buf->b_p_ma = false; // 'nomodifiable' buf->b_p_ul = -1; // 'undolevels' buf->b_p_scbk = // 'scrollback' (initialize local from global) - (p_scbk < 0) ? 10000 : MAX(1, p_scbk); + (p_scbk < 0) ? 10000 : MAX(1, p_scbk); buf->b_p_tw = 0; // 'textwidth' set_option_value("wrap", false, NULL, OPT_LOCAL); set_option_value("list", false, NULL, OPT_LOCAL); @@ -359,11 +358,21 @@ void terminal_enter(void) // Disable these options in terminal-mode. They are nonsense because cursor is // placed at end of buffer to "follow" output. #11072 win_T *save_curwin = curwin; - int save_w_p_cul = curwin->w_p_cul; + bool save_w_p_cul = curwin->w_p_cul; + char_u *save_w_p_culopt = NULL; + char_u save_w_p_culopt_flags = curwin->w_p_culopt_flags; int save_w_p_cuc = curwin->w_p_cuc; long save_w_p_so = curwin->w_p_so; long save_w_p_siso = curwin->w_p_siso; - curwin->w_p_cul = false; + if (curwin->w_p_cul && curwin->w_p_culopt_flags & CULOPT_NBR) { + if (strcmp((char *)curwin->w_p_culopt, "number")) { + save_w_p_culopt = curwin->w_p_culopt; + curwin->w_p_culopt = (char_u *)xstrdup("number"); + } + curwin->w_p_culopt_flags = CULOPT_NBR; + } else { + curwin->w_p_cul = false; + } curwin->w_p_cuc = false; curwin->w_p_so = 0; curwin->w_p_siso = 0; @@ -387,9 +396,16 @@ void terminal_enter(void) if (save_curwin == curwin) { // save_curwin may be invalid (window closed)! curwin->w_p_cul = save_w_p_cul; + if (save_w_p_culopt) { + xfree(curwin->w_p_culopt); + curwin->w_p_culopt = save_w_p_culopt; + } + curwin->w_p_culopt_flags = save_w_p_culopt_flags; curwin->w_p_cuc = save_w_p_cuc; curwin->w_p_so = save_w_p_so; curwin->w_p_siso = save_w_p_siso; + } else if (save_w_p_culopt) { + xfree(save_w_p_culopt); } // draw the unfocused cursor @@ -452,56 +468,56 @@ static int terminal_execute(VimState *state, int key) TerminalState *s = (TerminalState *)state; switch (key) { - case K_LEFTMOUSE: - case K_LEFTDRAG: - case K_LEFTRELEASE: - case K_MOUSEMOVE: - case K_MIDDLEMOUSE: - case K_MIDDLEDRAG: - case K_MIDDLERELEASE: - case K_RIGHTMOUSE: - case K_RIGHTDRAG: - case K_RIGHTRELEASE: - case K_MOUSEDOWN: - case K_MOUSEUP: - if (send_mouse_event(s->term, key)) { - return 0; - } - break; - - case K_EVENT: - // We cannot let an event free the terminal yet. It is still needed. - s->term->refcount++; - state_handle_k_event(); - s->term->refcount--; - if (s->term->buf_handle == 0) { - s->close = true; - return 0; - } - break; + case K_LEFTMOUSE: + case K_LEFTDRAG: + case K_LEFTRELEASE: + case K_MOUSEMOVE: + case K_MIDDLEMOUSE: + case K_MIDDLEDRAG: + case K_MIDDLERELEASE: + case K_RIGHTMOUSE: + case K_RIGHTDRAG: + case K_RIGHTRELEASE: + case K_MOUSEDOWN: + case K_MOUSEUP: + if (send_mouse_event(s->term, key)) { + return 0; + } + break; + + case K_EVENT: + // We cannot let an event free the terminal yet. It is still needed. + s->term->refcount++; + state_handle_k_event(); + s->term->refcount--; + if (s->term->buf_handle == 0) { + s->close = true; + return 0; + } + break; - case K_COMMAND: - do_cmdline(NULL, getcmdkeycmd, NULL, 0); - break; + case K_COMMAND: + do_cmdline(NULL, getcmdkeycmd, NULL, 0); + break; - case Ctrl_N: - if (s->got_bsl) { - return 0; - } - FALLTHROUGH; + case Ctrl_N: + if (s->got_bsl) { + return 0; + } + FALLTHROUGH; - default: - if (key == Ctrl_BSL && !s->got_bsl) { - s->got_bsl = true; - break; - } - if (s->term->closed) { - s->close = true; - return 0; - } + default: + if (key == Ctrl_BSL && !s->got_bsl) { + s->got_bsl = true; + break; + } + if (s->term->closed) { + s->close = true; + return 0; + } - s->got_bsl = false; - terminal_send_key(s->term, key); + s->got_bsl = false; + terminal_send_key(s->term, key); } if (curbuf->terminal == NULL) { @@ -554,30 +570,30 @@ static bool is_filter_char(int c) { unsigned int flag = 0; switch (c) { - case 0x08: - flag = TPF_BS; - break; - case 0x09: - flag = TPF_HT; - break; - case 0x0A: - case 0x0D: - break; - case 0x0C: - flag = TPF_FF; - break; - case 0x1b: - flag = TPF_ESC; - break; - case 0x7F: - flag = TPF_DEL; - break; - default: - if (c < ' ') { - flag = TPF_C0; - } else if (c >= 0x80 && c <= 0x9F) { - flag = TPF_C1; - } + case 0x08: + flag = TPF_BS; + break; + case 0x09: + flag = TPF_HT; + break; + case 0x0A: + case 0x0D: + break; + case 0x0C: + flag = TPF_FF; + break; + case 0x1b: + flag = TPF_ESC; + break; + case 0x7F: + flag = TPF_DEL; + break; + default: + if (c < ' ') { + flag = TPF_C0; + } else if (c >= 0x80 && c <= 0x9F) { + flag = TPF_C1; + } } return !!(tpf_flags & flag); } @@ -666,8 +682,7 @@ static int get_rgb(VTermState *state, VTermColor color) } -void terminal_get_line_attributes(Terminal *term, win_T *wp, int linenr, - int *term_attrs) +void terminal_get_line_attributes(Terminal *term, win_T *wp, int linenr, int *term_attrs) { int height, width; vterm_get_size(term->vt, &height, &width); @@ -701,12 +716,12 @@ void terminal_get_line_attributes(Terminal *term, win_T *wp, int linenr, bool bg_set = vt_bg_idx && vt_bg_idx <= 16 && term->color_set[vt_bg_idx-1]; int hl_attrs = (cell.attrs.bold ? HL_BOLD : 0) - | (cell.attrs.italic ? HL_ITALIC : 0) - | (cell.attrs.reverse ? HL_INVERSE : 0) - | (cell.attrs.underline ? HL_UNDERLINE : 0) - | (cell.attrs.strike ? HL_STRIKETHROUGH: 0) - | ((fg_indexed && !fg_set) ? HL_FG_INDEXED : 0) - | ((bg_indexed && !bg_set) ? HL_BG_INDEXED : 0); + | (cell.attrs.italic ? HL_ITALIC : 0) + | (cell.attrs.reverse ? HL_INVERSE : 0) + | (cell.attrs.underline ? HL_UNDERLINE : 0) + | (cell.attrs.strike ? HL_STRIKETHROUGH: 0) + | ((fg_indexed && !fg_set) ? HL_FG_INDEXED : 0) + | ((bg_indexed && !bg_set) ? HL_BG_INDEXED : 0); int attr_id = 0; @@ -757,12 +772,11 @@ static int term_damage(VTermRect rect, void *data) static int term_moverect(VTermRect dest, VTermRect src, void *data) { invalidate_terminal(data, MIN(dest.start_row, src.start_row), - MAX(dest.end_row, src.end_row)); + MAX(dest.end_row, src.end_row)); return 1; } -static int term_movecursor(VTermPos new, VTermPos old, int visible, - void *data) +static int term_movecursor(VTermPos new, VTermPos old, int visible, void *data) { Terminal *term = data; term->cursor.row = new.row; @@ -791,26 +805,26 @@ static int term_settermprop(VTermProp prop, VTermValue *val, void *data) Terminal *term = data; switch (prop) { - case VTERM_PROP_ALTSCREEN: - break; - - case VTERM_PROP_CURSORVISIBLE: - term->cursor.visible = val->boolean; - invalidate_terminal(term, term->cursor.row, term->cursor.row + 1); - break; - - case VTERM_PROP_TITLE: { - buf_T *buf = handle_get_buffer(term->buf_handle); - buf_set_term_title(buf, val->string); - break; - } + case VTERM_PROP_ALTSCREEN: + break; + + case VTERM_PROP_CURSORVISIBLE: + term->cursor.visible = val->boolean; + invalidate_terminal(term, term->cursor.row, term->cursor.row + 1); + break; + + case VTERM_PROP_TITLE: { + buf_T *buf = handle_get_buffer(term->buf_handle); + buf_set_term_title(buf, val->string); + break; + } - case VTERM_PROP_MOUSE: - term->forward_mouse = (bool)val->number; - break; + case VTERM_PROP_MOUSE: + term->forward_mouse = (bool)val->number; + break; - default: - return 0; + default: + return 0; } return 1; @@ -844,12 +858,11 @@ static int term_sb_push(int cols, const VTermScreenCell *cells, void *data) // Make room at the start by shifting to the right. memmove(term->sb_buffer + 1, term->sb_buffer, - sizeof(term->sb_buffer[0]) * (term->sb_current - 1)); - + sizeof(term->sb_buffer[0]) * (term->sb_current - 1)); } else if (term->sb_current > 0) { // Make room at the start by shifting to the right. memmove(term->sb_buffer + 1, term->sb_buffer, - sizeof(term->sb_buffer[0]) * term->sb_current); + sizeof(term->sb_buffer[0]) * term->sb_current); } if (!sbrow) { @@ -894,7 +907,7 @@ static int term_sb_pop(int cols, VTermScreenCell *cells, void *data) term->sb_current--; // Forget the "popped" row by shifting the rest onto it. memmove(term->sb_buffer, term->sb_buffer + 1, - sizeof(term->sb_buffer[0]) * (term->sb_current)); + sizeof(term->sb_buffer[0]) * (term->sb_current)); size_t cols_to_copy = (size_t)cols; if (cols_to_copy > sbrow->cols) { @@ -919,35 +932,41 @@ static int term_sb_pop(int cols, VTermScreenCell *cells, void *data) static void convert_modifiers(int key, VTermModifier *statep) { - if (mod_mask & MOD_MASK_SHIFT) { *statep |= VTERM_MOD_SHIFT; } - if (mod_mask & MOD_MASK_CTRL) { *statep |= VTERM_MOD_CTRL; } - if (mod_mask & MOD_MASK_ALT) { *statep |= VTERM_MOD_ALT; } + if (mod_mask & MOD_MASK_SHIFT) { + *statep |= VTERM_MOD_SHIFT; + } + if (mod_mask & MOD_MASK_CTRL) { + *statep |= VTERM_MOD_CTRL; + } + if (mod_mask & MOD_MASK_ALT) { + *statep |= VTERM_MOD_ALT; + } switch (key) { - case K_S_TAB: - case K_S_UP: - case K_S_DOWN: - case K_S_LEFT: - case K_S_RIGHT: - case K_S_F1: - case K_S_F2: - case K_S_F3: - case K_S_F4: - case K_S_F5: - case K_S_F6: - case K_S_F7: - case K_S_F8: - case K_S_F9: - case K_S_F10: - case K_S_F11: - case K_S_F12: - *statep |= VTERM_MOD_SHIFT; - break; - - case K_C_LEFT: - case K_C_RIGHT: - *statep |= VTERM_MOD_CTRL; - break; + case K_S_TAB: + case K_S_UP: + case K_S_DOWN: + case K_S_LEFT: + case K_S_RIGHT: + case K_S_F1: + case K_S_F2: + case K_S_F3: + case K_S_F4: + case K_S_F5: + case K_S_F6: + case K_S_F7: + case K_S_F8: + case K_S_F9: + case K_S_F10: + case K_S_F11: + case K_S_F12: + *statep |= VTERM_MOD_SHIFT; + break; + + case K_C_LEFT: + case K_C_RIGHT: + *statep |= VTERM_MOD_CTRL; + break; } } @@ -956,115 +975,212 @@ static VTermKey convert_key(int key, VTermModifier *statep) convert_modifiers(key, statep); switch (key) { - case K_BS: return VTERM_KEY_BACKSPACE; - case K_S_TAB: FALLTHROUGH; - case TAB: return VTERM_KEY_TAB; - case Ctrl_M: return VTERM_KEY_ENTER; - case ESC: return VTERM_KEY_ESCAPE; - - case K_S_UP: FALLTHROUGH; - case K_UP: return VTERM_KEY_UP; - case K_S_DOWN: FALLTHROUGH; - case K_DOWN: return VTERM_KEY_DOWN; - case K_S_LEFT: FALLTHROUGH; - case K_C_LEFT: FALLTHROUGH; - case K_LEFT: return VTERM_KEY_LEFT; - case K_S_RIGHT: FALLTHROUGH; - case K_C_RIGHT: FALLTHROUGH; - case K_RIGHT: return VTERM_KEY_RIGHT; - - case K_INS: return VTERM_KEY_INS; - case K_DEL: return VTERM_KEY_DEL; - case K_HOME: return VTERM_KEY_HOME; - case K_END: return VTERM_KEY_END; - case K_PAGEUP: return VTERM_KEY_PAGEUP; - case K_PAGEDOWN: return VTERM_KEY_PAGEDOWN; - - case K_K0: FALLTHROUGH; - case K_KINS: return VTERM_KEY_KP_0; - case K_K1: FALLTHROUGH; - case K_KEND: return VTERM_KEY_KP_1; - case K_K2: FALLTHROUGH; - case K_KDOWN: return VTERM_KEY_KP_2; - case K_K3: FALLTHROUGH; - case K_KPAGEDOWN: return VTERM_KEY_KP_3; - case K_K4: FALLTHROUGH; - case K_KLEFT: return VTERM_KEY_KP_4; - case K_K5: FALLTHROUGH; - case K_KORIGIN: return VTERM_KEY_KP_5; - case K_K6: FALLTHROUGH; - case K_KRIGHT: return VTERM_KEY_KP_6; - case K_K7: FALLTHROUGH; - case K_KHOME: return VTERM_KEY_KP_7; - case K_K8: FALLTHROUGH; - case K_KUP: return VTERM_KEY_KP_8; - case K_K9: FALLTHROUGH; - case K_KPAGEUP: return VTERM_KEY_KP_9; - case K_KDEL: FALLTHROUGH; - case K_KPOINT: return VTERM_KEY_KP_PERIOD; - case K_KENTER: return VTERM_KEY_KP_ENTER; - case K_KPLUS: return VTERM_KEY_KP_PLUS; - case K_KMINUS: return VTERM_KEY_KP_MINUS; - case K_KMULTIPLY: return VTERM_KEY_KP_MULT; - case K_KDIVIDE: return VTERM_KEY_KP_DIVIDE; - - case K_S_F1: FALLTHROUGH; - case K_F1: return VTERM_KEY_FUNCTION(1); - case K_S_F2: FALLTHROUGH; - case K_F2: return VTERM_KEY_FUNCTION(2); - case K_S_F3: FALLTHROUGH; - case K_F3: return VTERM_KEY_FUNCTION(3); - case K_S_F4: FALLTHROUGH; - case K_F4: return VTERM_KEY_FUNCTION(4); - case K_S_F5: FALLTHROUGH; - case K_F5: return VTERM_KEY_FUNCTION(5); - case K_S_F6: FALLTHROUGH; - case K_F6: return VTERM_KEY_FUNCTION(6); - case K_S_F7: FALLTHROUGH; - case K_F7: return VTERM_KEY_FUNCTION(7); - case K_S_F8: FALLTHROUGH; - case K_F8: return VTERM_KEY_FUNCTION(8); - case K_S_F9: FALLTHROUGH; - case K_F9: return VTERM_KEY_FUNCTION(9); - case K_S_F10: FALLTHROUGH; - case K_F10: return VTERM_KEY_FUNCTION(10); - case K_S_F11: FALLTHROUGH; - case K_F11: return VTERM_KEY_FUNCTION(11); - case K_S_F12: FALLTHROUGH; - case K_F12: return VTERM_KEY_FUNCTION(12); - - case K_F13: return VTERM_KEY_FUNCTION(13); - case K_F14: return VTERM_KEY_FUNCTION(14); - case K_F15: return VTERM_KEY_FUNCTION(15); - case K_F16: return VTERM_KEY_FUNCTION(16); - case K_F17: return VTERM_KEY_FUNCTION(17); - case K_F18: return VTERM_KEY_FUNCTION(18); - case K_F19: return VTERM_KEY_FUNCTION(19); - case K_F20: return VTERM_KEY_FUNCTION(20); - case K_F21: return VTERM_KEY_FUNCTION(21); - case K_F22: return VTERM_KEY_FUNCTION(22); - case K_F23: return VTERM_KEY_FUNCTION(23); - case K_F24: return VTERM_KEY_FUNCTION(24); - case K_F25: return VTERM_KEY_FUNCTION(25); - case K_F26: return VTERM_KEY_FUNCTION(26); - case K_F27: return VTERM_KEY_FUNCTION(27); - case K_F28: return VTERM_KEY_FUNCTION(28); - case K_F29: return VTERM_KEY_FUNCTION(29); - case K_F30: return VTERM_KEY_FUNCTION(30); - case K_F31: return VTERM_KEY_FUNCTION(31); - case K_F32: return VTERM_KEY_FUNCTION(32); - case K_F33: return VTERM_KEY_FUNCTION(33); - case K_F34: return VTERM_KEY_FUNCTION(34); - case K_F35: return VTERM_KEY_FUNCTION(35); - case K_F36: return VTERM_KEY_FUNCTION(36); - case K_F37: return VTERM_KEY_FUNCTION(37); - - default: return VTERM_KEY_NONE; + case K_BS: + return VTERM_KEY_BACKSPACE; + case K_S_TAB: + FALLTHROUGH; + case TAB: + return VTERM_KEY_TAB; + case Ctrl_M: + return VTERM_KEY_ENTER; + case ESC: + return VTERM_KEY_ESCAPE; + + case K_S_UP: + FALLTHROUGH; + case K_UP: + return VTERM_KEY_UP; + case K_S_DOWN: + FALLTHROUGH; + case K_DOWN: + return VTERM_KEY_DOWN; + case K_S_LEFT: + FALLTHROUGH; + case K_C_LEFT: + FALLTHROUGH; + case K_LEFT: + return VTERM_KEY_LEFT; + case K_S_RIGHT: + FALLTHROUGH; + case K_C_RIGHT: + FALLTHROUGH; + case K_RIGHT: + return VTERM_KEY_RIGHT; + + case K_INS: + return VTERM_KEY_INS; + case K_DEL: + return VTERM_KEY_DEL; + case K_HOME: + return VTERM_KEY_HOME; + case K_END: + return VTERM_KEY_END; + case K_PAGEUP: + return VTERM_KEY_PAGEUP; + case K_PAGEDOWN: + return VTERM_KEY_PAGEDOWN; + + case K_K0: + FALLTHROUGH; + case K_KINS: + return VTERM_KEY_KP_0; + case K_K1: + FALLTHROUGH; + case K_KEND: + return VTERM_KEY_KP_1; + case K_K2: + FALLTHROUGH; + case K_KDOWN: + return VTERM_KEY_KP_2; + case K_K3: + FALLTHROUGH; + case K_KPAGEDOWN: + return VTERM_KEY_KP_3; + case K_K4: + FALLTHROUGH; + case K_KLEFT: + return VTERM_KEY_KP_4; + case K_K5: + FALLTHROUGH; + case K_KORIGIN: + return VTERM_KEY_KP_5; + case K_K6: + FALLTHROUGH; + case K_KRIGHT: + return VTERM_KEY_KP_6; + case K_K7: + FALLTHROUGH; + case K_KHOME: + return VTERM_KEY_KP_7; + case K_K8: + FALLTHROUGH; + case K_KUP: + return VTERM_KEY_KP_8; + case K_K9: + FALLTHROUGH; + case K_KPAGEUP: + return VTERM_KEY_KP_9; + case K_KDEL: + FALLTHROUGH; + case K_KPOINT: + return VTERM_KEY_KP_PERIOD; + case K_KENTER: + return VTERM_KEY_KP_ENTER; + case K_KPLUS: + return VTERM_KEY_KP_PLUS; + case K_KMINUS: + return VTERM_KEY_KP_MINUS; + case K_KMULTIPLY: + return VTERM_KEY_KP_MULT; + case K_KDIVIDE: + return VTERM_KEY_KP_DIVIDE; + + case K_S_F1: + FALLTHROUGH; + case K_F1: + return VTERM_KEY_FUNCTION(1); + case K_S_F2: + FALLTHROUGH; + case K_F2: + return VTERM_KEY_FUNCTION(2); + case K_S_F3: + FALLTHROUGH; + case K_F3: + return VTERM_KEY_FUNCTION(3); + case K_S_F4: + FALLTHROUGH; + case K_F4: + return VTERM_KEY_FUNCTION(4); + case K_S_F5: + FALLTHROUGH; + case K_F5: + return VTERM_KEY_FUNCTION(5); + case K_S_F6: + FALLTHROUGH; + case K_F6: + return VTERM_KEY_FUNCTION(6); + case K_S_F7: + FALLTHROUGH; + case K_F7: + return VTERM_KEY_FUNCTION(7); + case K_S_F8: + FALLTHROUGH; + case K_F8: + return VTERM_KEY_FUNCTION(8); + case K_S_F9: + FALLTHROUGH; + case K_F9: + return VTERM_KEY_FUNCTION(9); + case K_S_F10: + FALLTHROUGH; + case K_F10: + return VTERM_KEY_FUNCTION(10); + case K_S_F11: + FALLTHROUGH; + case K_F11: + return VTERM_KEY_FUNCTION(11); + case K_S_F12: + FALLTHROUGH; + case K_F12: + return VTERM_KEY_FUNCTION(12); + + case K_F13: + return VTERM_KEY_FUNCTION(13); + case K_F14: + return VTERM_KEY_FUNCTION(14); + case K_F15: + return VTERM_KEY_FUNCTION(15); + case K_F16: + return VTERM_KEY_FUNCTION(16); + case K_F17: + return VTERM_KEY_FUNCTION(17); + case K_F18: + return VTERM_KEY_FUNCTION(18); + case K_F19: + return VTERM_KEY_FUNCTION(19); + case K_F20: + return VTERM_KEY_FUNCTION(20); + case K_F21: + return VTERM_KEY_FUNCTION(21); + case K_F22: + return VTERM_KEY_FUNCTION(22); + case K_F23: + return VTERM_KEY_FUNCTION(23); + case K_F24: + return VTERM_KEY_FUNCTION(24); + case K_F25: + return VTERM_KEY_FUNCTION(25); + case K_F26: + return VTERM_KEY_FUNCTION(26); + case K_F27: + return VTERM_KEY_FUNCTION(27); + case K_F28: + return VTERM_KEY_FUNCTION(28); + case K_F29: + return VTERM_KEY_FUNCTION(29); + case K_F30: + return VTERM_KEY_FUNCTION(30); + case K_F31: + return VTERM_KEY_FUNCTION(31); + case K_F32: + return VTERM_KEY_FUNCTION(32); + case K_F33: + return VTERM_KEY_FUNCTION(33); + case K_F34: + return VTERM_KEY_FUNCTION(34); + case K_F35: + return VTERM_KEY_FUNCTION(35); + case K_F36: + return VTERM_KEY_FUNCTION(36); + case K_F37: + return VTERM_KEY_FUNCTION(37); + + default: + return VTERM_KEY_NONE; } } -static void mouse_action(Terminal *term, int button, int row, int col, - bool drag, VTermModifier mod) +static void mouse_action(Terminal *term, int button, int row, int col, bool drag, VTermModifier mod) { if (term->pressed_button && (term->pressed_button != button || !drag)) { // release the previous button @@ -1100,22 +1216,32 @@ static bool send_mouse_event(Terminal *term, int c) bool drag = false; switch (c) { - case K_LEFTDRAG: drag = true; FALLTHROUGH; - case K_LEFTMOUSE: button = 1; break; - case K_MOUSEMOVE: drag = true; button = 0; break; - case K_MIDDLEDRAG: drag = true; FALLTHROUGH; - case K_MIDDLEMOUSE: button = 2; break; - case K_RIGHTDRAG: drag = true; FALLTHROUGH; - case K_RIGHTMOUSE: button = 3; break; - case K_MOUSEDOWN: button = 4; break; - case K_MOUSEUP: button = 5; break; - default: return false; + case K_LEFTDRAG: + drag = true; FALLTHROUGH; + case K_LEFTMOUSE: + button = 1; break; + case K_MOUSEMOVE: + drag = true; button = 0; break; + case K_MIDDLEDRAG: + drag = true; FALLTHROUGH; + case K_MIDDLEMOUSE: + button = 2; break; + case K_RIGHTDRAG: + drag = true; FALLTHROUGH; + case K_RIGHTMOUSE: + button = 3; break; + case K_MOUSEDOWN: + button = 4; break; + case K_MOUSEUP: + button = 5; break; + default: + return false; } mouse_action(term, button, row, col - offset, drag, 0); size_t len = vterm_output_read(term->vt, term->textbuf, sizeof(term->textbuf)); - terminal_send(term, term->textbuf, (size_t)len); + terminal_send(term, term->textbuf, len); return false; } @@ -1162,7 +1288,7 @@ static void fetch_row(Terminal *term, int row, int end_col) if (cell.chars[0]) { for (int i = 0; cell.chars[i]; i++) { cell_len += utf_char2bytes((int)cell.chars[i], - (uint8_t *)ptr + cell_len); + (uint8_t *)ptr + cell_len); } } else { *ptr = ' '; @@ -1181,8 +1307,7 @@ static void fetch_row(Terminal *term, int row, int end_col) term->textbuf[line_len] = 0; } -static bool fetch_cell(Terminal *term, int row, int col, - VTermScreenCell *cell) +static bool fetch_cell(Terminal *term, int row, int col, VTermScreenCell *cell) { if (row < 0) { ScrollbackLine *sbrow = term->sb_buffer[-row - 1]; @@ -1197,8 +1322,8 @@ static bool fetch_cell(Terminal *term, int row, int col, return false; } } else { - vterm_screen_get_cell(term->vts, (VTermPos){.row = row, .col = col}, - cell); + vterm_screen_get_cell(term->vts, (VTermPos){ .row = row, .col = col }, + cell); } return true; } diff --git a/src/nvim/terminal.h b/src/nvim/terminal.h index f2b0e232c3..001adbadc3 100644 --- a/src/nvim/terminal.h +++ b/src/nvim/terminal.h @@ -1,8 +1,8 @@ #ifndef NVIM_TERMINAL_H #define NVIM_TERMINAL_H -#include <stddef.h> #include <stdbool.h> +#include <stddef.h> #include <stdint.h> typedef struct terminal Terminal; diff --git a/src/nvim/testdir/samples/memfile_test.c b/src/nvim/testdir/samples/memfile_test.c index 7023064637..73f67fb250 100644 --- a/src/nvim/testdir/samples/memfile_test.c +++ b/src/nvim/testdir/samples/memfile_test.c @@ -1,6 +1,8 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +// uncrustify:off + /* vi:set ts=8 sts=4 sw=4 noet: * * VIM - Vi IMproved by Bram Moolenaar diff --git a/src/nvim/testdir/test_arglist.vim b/src/nvim/testdir/test_arglist.vim index 01d8f32893..8fd60d6a5a 100644 --- a/src/nvim/testdir/test_arglist.vim +++ b/src/nvim/testdir/test_arglist.vim @@ -88,7 +88,7 @@ func Test_argadd_empty_curbuf() argadd Xargadd call assert_equal(curbuf, bufnr('%')) call assert_equal('', bufname('%')) - call assert_equal(1, line('$')) + call assert_equal(1, '$'->line()) rew call assert_notequal(curbuf, '%'->bufnr()) call assert_equal('Xargadd', '%'->bufname()) diff --git a/src/nvim/testdir/test_autochdir.vim b/src/nvim/testdir/test_autochdir.vim index d071f4b325..0b76828dd7 100644 --- a/src/nvim/testdir/test_autochdir.vim +++ b/src/nvim/testdir/test_autochdir.vim @@ -8,13 +8,21 @@ func Test_set_filename() let cwd = getcwd() call test_autochdir() set acd + + let s:li = [] + autocmd DirChanged auto call add(s:li, "autocd") + autocmd DirChanged auto call add(s:li, expand("<afile>")) + new w samples/Xtest call assert_equal("Xtest", expand('%')) call assert_equal("samples", substitute(getcwd(), '.*/\(\k*\)', '\1', '')) + call assert_equal(["autocd", getcwd()], s:li) + bwipe! + au! DirChanged set noacd - exe 'cd ' . cwd + call chdir(cwd) call delete('samples/Xtest') endfunc diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index 015979e1be..c350a17236 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -42,9 +42,7 @@ if has('timers') endfunc func Test_cursorhold_insert_with_timer_interrupt() - if !has('job') - return - endif + CheckFeature job " Need to move the cursor. call feedkeys("ggG", "xt") @@ -551,9 +549,7 @@ endfunc func Test_OptionSet() CheckFunction test_override - if !has("eval") || !exists("+autochdir") - return - endif + CheckOption autochdir call test_override('starting', 1) set nocp @@ -1328,6 +1324,71 @@ func Test_autocommand_all_events() call assert_fails('au * x bwipe', 'E1155:') endfunc +function s:Before_test_dirchanged() + augroup test_dirchanged + autocmd! + augroup END + let s:li = [] + let s:dir_this = getcwd() + let s:dir_foo = s:dir_this . '/Xfoo' + call mkdir(s:dir_foo) + let s:dir_bar = s:dir_this . '/Xbar' + call mkdir(s:dir_bar) +endfunc + +function s:After_test_dirchanged() + call chdir(s:dir_this) + call delete(s:dir_foo, 'd') + call delete(s:dir_bar, 'd') + augroup test_dirchanged + autocmd! + augroup END +endfunc + +function Test_dirchanged_global() + call s:Before_test_dirchanged() + autocmd test_dirchanged DirChanged global call add(s:li, "cd:") + autocmd test_dirchanged DirChanged global call add(s:li, expand("<afile>")) + call chdir(s:dir_foo) + call assert_equal(["cd:", s:dir_foo], s:li) + call chdir(s:dir_foo) + call assert_equal(["cd:", s:dir_foo], s:li) + exe 'lcd ' .. fnameescape(s:dir_bar) + call assert_equal(["cd:", s:dir_foo], s:li) + call s:After_test_dirchanged() +endfunc + +function Test_dirchanged_local() + call s:Before_test_dirchanged() + autocmd test_dirchanged DirChanged window call add(s:li, "lcd:") + autocmd test_dirchanged DirChanged window call add(s:li, expand("<afile>")) + call chdir(s:dir_foo) + call assert_equal([], s:li) + exe 'lcd ' .. fnameescape(s:dir_bar) + call assert_equal(["lcd:", s:dir_bar], s:li) + exe 'lcd ' .. fnameescape(s:dir_bar) + call assert_equal(["lcd:", s:dir_bar], s:li) + call s:After_test_dirchanged() +endfunc + +function Test_dirchanged_auto() + CheckFunction test_autochdir + CheckOption autochdir + call s:Before_test_dirchanged() + call test_autochdir() + autocmd test_dirchanged DirChanged auto call add(s:li, "auto:") + autocmd test_dirchanged DirChanged auto call add(s:li, expand("<afile>")) + set acd + cd .. + call assert_equal([], s:li) + exe 'edit ' . s:dir_foo . '/Xfile' + call assert_equal(s:dir_foo, getcwd()) + call assert_equal(["auto:", s:dir_foo], s:li) + set noacd + bwipe! + call s:After_test_dirchanged() +endfunc + " Test TextChangedI and TextChangedP " See test/functional/viml/completion_spec.lua' func Test_ChangedP() diff --git a/src/nvim/testdir/test_breakindent.vim b/src/nvim/testdir/test_breakindent.vim index 97b570e64f..277050876e 100644 --- a/src/nvim/testdir/test_breakindent.vim +++ b/src/nvim/testdir/test_breakindent.vim @@ -418,8 +418,8 @@ endfunc func Test_breakindent11() " test strdisplaywidth() call s:test_windows('setl cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4') - let text=getline(2) - let width = strlen(text[1:])+indent(2)+strlen(&sbr)*3 " text wraps 3 times + let text = getline(2) + let width = strlen(text[1:]) + indent(2) + strlen(&sbr) * 3 " text wraps 3 times call assert_equal(width, strdisplaywidth(text)) call s:close_windows('set sbr=') endfunc @@ -431,7 +431,7 @@ func Test_breakindent11_vartabs() " test strdisplaywidth() call s:test_windows('setl cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4 vts=4') let text = getline(2) - let width = strlen(text[1:])+indent(2)+strlen(&sbr)*3 " text wraps 3 times + let width = strlen(text[1:]) + 2->indent() + strlen(&sbr) * 3 " text wraps 3 times call assert_equal(width, strdisplaywidth(text)) call s:close_windows('set sbr= vts&') endfunc diff --git a/src/nvim/testdir/test_bufline.vim b/src/nvim/testdir/test_bufline.vim index b4e8a0bc71..765ae17736 100644 --- a/src/nvim/testdir/test_bufline.vim +++ b/src/nvim/testdir/test_bufline.vim @@ -9,7 +9,7 @@ func Test_setbufline_getbufline() hide call assert_equal(0, setbufline(b, 1, ['foo', 'bar'])) call assert_equal(['foo'], getbufline(b, 1)) - call assert_equal(['bar'], getbufline(b, 2)) + call assert_equal(['bar'], getbufline(b, '$')) call assert_equal(['foo', 'bar'], getbufline(b, 1, 2)) exe "bd!" b call assert_equal([], getbufline(b, 1, 2)) @@ -21,7 +21,7 @@ func Test_setbufline_getbufline() call assert_equal(1, setbufline(b, 5, ['x'])) call assert_equal(1, setbufline(1234, 1, ['x'])) call assert_equal(0, setbufline(b, 4, ['d', 'e'])) - call assert_equal(['c'], getbufline(b, 3)) + call assert_equal(['c'], b->getbufline(3)) call assert_equal(['d'], getbufline(b, 4)) call assert_equal(['e'], getbufline(b, 5)) call assert_equal([], getbufline(b, 6)) @@ -82,6 +82,7 @@ func Test_appendbufline() call setline(1, ['a', 'b', 'c']) let b = bufnr('%') wincmd w + call assert_equal(1, appendbufline(b, -1, ['x'])) call assert_equal(1, appendbufline(b, 4, ['x'])) call assert_equal(1, appendbufline(1234, 1, ['x'])) call assert_equal(0, appendbufline(b, 3, ['d', 'e'])) @@ -104,8 +105,11 @@ func Test_deletebufline() exe "bd!" b call assert_equal(1, b->deletebufline(1)) + call assert_equal(1, deletebufline(-1, 1)) + split Xtest call setline(1, ['a', 'b', 'c']) + call cursor(line('$'), 1) let b = bufnr('%') wincmd w call assert_equal(1, deletebufline(b, 4)) diff --git a/src/nvim/testdir/test_bufwintabinfo.vim b/src/nvim/testdir/test_bufwintabinfo.vim index 4b5b55e6bf..bb672cf0ec 100644 --- a/src/nvim/testdir/test_bufwintabinfo.vim +++ b/src/nvim/testdir/test_bufwintabinfo.vim @@ -77,7 +77,7 @@ function Test_getbufwintabinfo() call assert_equal('green', winlist[2].variables.signal) call assert_equal(w4_id, winlist[3].winid) - let winfo = getwininfo(w5_id)[0] + let winfo = w5_id->getwininfo()[0] call assert_equal(2, winfo.tabnr) call assert_equal([], getwininfo(3)) @@ -88,7 +88,7 @@ function Test_getbufwintabinfo() call assert_equal(2, tablist[1].tabnr) call assert_equal('build', tablist[0].variables.space) call assert_equal(w2_id, tablist[0].windows[0]) - call assert_equal([], gettabinfo(3)) + call assert_equal([], 3->gettabinfo()) tabonly | only @@ -106,7 +106,7 @@ function Test_getbufwintabinfo() endfunction function Test_get_buf_options() - let opts = getbufvar(bufnr('%'), '&') + let opts = bufnr()->getbufvar('&') call assert_equal(v:t_dict, type(opts)) call assert_equal(8, opts.tabstop) endfunc diff --git a/src/nvim/testdir/test_cd.vim b/src/nvim/testdir/test_cd.vim index 02a23bf82f..0bba321ee2 100644 --- a/src/nvim/testdir/test_cd.vim +++ b/src/nvim/testdir/test_cd.vim @@ -12,7 +12,7 @@ func Test_cd_up_and_down() let path = getcwd() cd .. call assert_notequal(path, getcwd()) - exe 'cd ' . path + exe 'cd ' .. fnameescape(path) call assert_equal(path, getcwd()) endfunc @@ -23,7 +23,7 @@ func Test_cd_no_arg() cd call assert_equal($HOME, getcwd()) call assert_notequal(path, getcwd()) - exe 'cd ' . path + exe 'cd ' .. fnameescape(path) call assert_equal(path, getcwd()) else " Test that cd without argument echoes cwd on non-Unix systems. @@ -43,6 +43,20 @@ func Test_cd_minus() call assert_equal(path_dotdot, getcwd()) cd - call assert_equal(path, getcwd()) + + " Test for :cd - without a previous directory + let lines =<< trim [SCRIPT] + call assert_fails('cd -', 'E186:') + call assert_fails('call chdir("-")', 'E186:') + call writefile(v:errors, 'Xresult') + qall! + [SCRIPT] + call writefile(lines, 'Xscript') + if RunVim([], [], '--clean -S Xscript') + call assert_equal([], readfile('Xresult')) + endif + call delete('Xscript') + call delete('Xresult') endfunc func Test_cd_with_cpo_chdir() @@ -61,7 +75,7 @@ func Test_cd_with_cpo_chdir() " :cd should succeed when buffer has been written. w! - exe 'cd ' . path + exe 'cd ' .. fnameescape(path) call assert_equal(path, getcwd()) call delete('Xfoo') @@ -69,6 +83,124 @@ func Test_cd_with_cpo_chdir() bw! endfunc +" Test for chdir() +func Test_chdir_func() + let topdir = getcwd() + call mkdir('Xdir/y/z', 'p') + + " Create a few tabpages and windows with different directories + new + cd Xdir + tabnew + tcd y + below new + below new + lcd z + + tabfirst + call assert_match('^\[global\] .*/Xdir$', trim(execute('verbose pwd'))) + call chdir('..') + call assert_equal('y', fnamemodify(getcwd(1, 2), ':t')) + call assert_equal('z', fnamemodify(getcwd(3, 2), ':t')) + tabnext | wincmd t + call assert_match('^\[tabpage\] .*/y$', trim(execute('verbose pwd'))) + call chdir('..') + call assert_equal('Xdir', fnamemodify(getcwd(1, 2), ':t')) + call assert_equal('Xdir', fnamemodify(getcwd(2, 2), ':t')) + call assert_equal('z', fnamemodify(getcwd(3, 2), ':t')) + call assert_equal('testdir', fnamemodify(getcwd(1, 1), ':t')) + 3wincmd w + call assert_match('^\[window\] .*/z$', trim(execute('verbose pwd'))) + call chdir('..') + call assert_equal('Xdir', fnamemodify(getcwd(1, 2), ':t')) + call assert_equal('Xdir', fnamemodify(getcwd(2, 2), ':t')) + call assert_equal('y', fnamemodify(getcwd(3, 2), ':t')) + call assert_equal('testdir', fnamemodify(getcwd(1, 1), ':t')) + + " Error case + call assert_fails("call chdir('dir-abcd')", 'E472:') + silent! let d = chdir("dir_abcd") + call assert_equal("", d) + " Should not crash + call chdir(d) + + only | tabonly + call chdir(topdir) + call delete('Xdir', 'rf') +endfunc + +" Test for changing to the previous directory '-' +func Test_prev_dir() + let topdir = getcwd() + call mkdir('Xdir/a/b/c', 'p') + + " Create a few tabpages and windows with different directories + new | only + tabnew | new + tabnew + tabfirst + cd Xdir + tabnext | wincmd t + tcd a + wincmd w + lcd b + tabnext + tcd a/b/c + + " Change to the previous directory twice in all the windows. + tabfirst + cd - | cd - + tabnext | wincmd t + tcd - | tcd - + wincmd w + lcd - | lcd - + tabnext + tcd - | tcd - + + " Check the directory of all the windows + tabfirst + call assert_equal('Xdir', fnamemodify(getcwd(), ':t')) + tabnext | wincmd t + call assert_equal('a', fnamemodify(getcwd(), ':t')) + wincmd w + call assert_equal('b', fnamemodify(getcwd(), ':t')) + tabnext + call assert_equal('c', fnamemodify(getcwd(), ':t')) + + " Change to the previous directory using chdir() + tabfirst + call chdir("-") | call chdir("-") + tabnext | wincmd t + call chdir("-") | call chdir("-") + wincmd w + call chdir("-") | call chdir("-") + tabnext + call chdir("-") | call chdir("-") + + " Check the directory of all the windows + tabfirst + call assert_equal('Xdir', fnamemodify(getcwd(), ':t')) + tabnext | wincmd t + call assert_equal('a', fnamemodify(getcwd(), ':t')) + wincmd w + call assert_equal('b', fnamemodify(getcwd(), ':t')) + tabnext + call assert_equal('c', fnamemodify(getcwd(), ':t')) + + only | tabonly + call chdir(topdir) + call delete('Xdir', 'rf') +endfunc + +func Test_lcd_split() + let curdir = getcwd() + lcd .. + split + lcd - + call assert_equal(curdir, getcwd()) + quit! +endfunc + func Test_cd_from_non_existing_dir() CheckNotMSWindows diff --git a/src/nvim/testdir/test_changelist.vim b/src/nvim/testdir/test_changelist.vim index dd6ea9600c..ce77c1f3c7 100644 --- a/src/nvim/testdir/test_changelist.vim +++ b/src/nvim/testdir/test_changelist.vim @@ -8,8 +8,8 @@ func Test_getchangelist() bwipe! enew - call assert_equal([], getchangelist(10)) - call assert_equal([[], 0], getchangelist('%')) + call assert_equal([], 10->getchangelist()) + call assert_equal([[], 0], getchangelist()) call writefile(['line1', 'line2', 'line3'], 'Xfile1.txt') call writefile(['line1', 'line2', 'line3'], 'Xfile2.txt') diff --git a/src/nvim/testdir/test_clientserver.vim b/src/nvim/testdir/test_clientserver.vim index 53704bd094..f3db472b03 100644 --- a/src/nvim/testdir/test_clientserver.vim +++ b/src/nvim/testdir/test_clientserver.vim @@ -34,7 +34,7 @@ func Test_client_server() " When using valgrind it takes much longer. call WaitForAssert({-> assert_match(name, serverlist())}) - call remote_foreground(name) + eval name->remote_foreground() call remote_send(name, ":let testvar = 'yes'\<CR>") call WaitFor('remote_expr("' . name . '", "exists(\"testvar\") ? testvar : \"\"", "", 1) == "yes"') @@ -53,7 +53,7 @@ func Test_client_server() endif " Wait for the server to be up and answering requests. sleep 100m - call WaitForAssert({-> assert_true(remote_expr(name, "v:version", "", 1) != "")}) + call WaitForAssert({-> assert_true(name->remote_expr("v:version", "", 1) != "")}) call remote_send(name, ":let testvar = 'maybe'\<CR>") call WaitForAssert({-> assert_equal('maybe', remote_expr(name, "testvar", "", 2))}) @@ -72,7 +72,7 @@ func Test_client_server() " Expression evaluated locally. if v:servername == '' - call remote_startserver('MYSELF') + eval 'MYSELF'->remote_startserver() " May get MYSELF1 when running the test again. call assert_match('MYSELF', v:servername) endif @@ -80,11 +80,11 @@ func Test_client_server() call assert_equal('myself', remote_expr(v:servername, 'testvar')) call remote_send(name, ":call server2client(expand('<client>'), 'got it')\<CR>", 'g:myserverid') - call assert_equal('got it', remote_read(g:myserverid, 2)) + call assert_equal('got it', g:myserverid->remote_read(2)) call remote_send(name, ":call server2client(expand('<client>'), 'another')\<CR>", 'g:myserverid') let peek_result = 'nothing' - let r = remote_peek(g:myserverid, 'peek_result') + let r = g:myserverid->remote_peek('peek_result') " unpredictable whether the result is already available. if r > 0 call assert_equal('another', peek_result) @@ -98,7 +98,7 @@ func Test_client_server() call assert_equal('another', g:peek_result) call assert_equal('another', remote_read(g:myserverid, 2)) - call remote_send(name, ":qa!\<CR>") + eval name->remote_send(":qa!\<CR>") try call WaitForAssert({-> assert_equal("dead", job_status(job))}) finally diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index 5a6824b5c1..ffca415282 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -260,7 +260,7 @@ func Test_getcompletion() endif let groupcount = len(getcompletion('', 'event')) call assert_true(groupcount > 0) - let matchcount = len(getcompletion('File', 'event')) + let matchcount = len('File'->getcompletion('event')) call assert_true(matchcount > 0) call assert_true(groupcount > matchcount) diff --git a/src/nvim/testdir/test_cursor_func.vim b/src/nvim/testdir/test_cursor_func.vim index 53b7da517e..46847e0663 100644 --- a/src/nvim/testdir/test_cursor_func.vim +++ b/src/nvim/testdir/test_cursor_func.vim @@ -25,6 +25,12 @@ func Test_move_cursor() call cursor(9, 1) call assert_equal([4, 1, 0, 1], getcurpos()[1:]) + call setline(1, ["\<TAB>"]) + call cursor(1, 1, 1) + call assert_equal([1, 1, 1], getcurpos()[1:3]) + + call assert_equal(-1, cursor(-1, -1)) + quit! endfunc diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim index e1393e875b..2b389c015f 100644 --- a/src/nvim/testdir/test_edit.vim +++ b/src/nvim/testdir/test_edit.vim @@ -201,11 +201,11 @@ func Test_edit_07() endfu au InsertCharPre <buffer> :call DoIt() call feedkeys("A\<f5>\<c-p>u\<cr>\<c-l>\<cr>", 'tx') - call assert_equal(["Jan\<c-l>",''], getline(1,'$')) + call assert_equal(["Jan\<c-l>",''], 1->getline('$')) %d call setline(1, 'J') call feedkeys("A\<f5>\<c-p>u\<down>\<c-l>\<cr>", 'tx') - call assert_equal(["January"], getline(1,'$')) + call assert_equal(["January"], 1->getline('$')) delfu ListMonths delfu DoIt @@ -348,7 +348,7 @@ func Test_edit_12() call cursor(2, 4) call feedkeys("R^\<c-d>", 'tnix') call assert_equal(["\tabc", "def"], getline(1, '$')) - call assert_equal([0, 2, 2, 0], getpos('.')) + call assert_equal([0, 2, 2, 0], '.'->getpos()) %d call setline(1, ["\tabc", "\t\tdef"]) call cursor(2, 2) diff --git a/src/nvim/testdir/test_environ.vim b/src/nvim/testdir/test_environ.vim index a25d83753c..cc15b63824 100644 --- a/src/nvim/testdir/test_environ.vim +++ b/src/nvim/testdir/test_environ.vim @@ -15,7 +15,7 @@ endfunc func Test_getenv() unlet! $TESTENV - call assert_equal(v:null, getenv('TESTENV')) + call assert_equal(v:null, 'TESTENV'->getenv()) let $TESTENV = 'foo' call assert_equal('foo', getenv('TESTENV')) endfunc diff --git a/src/nvim/testdir/test_escaped_glob.vim b/src/nvim/testdir/test_escaped_glob.vim index 2bfd82c296..1a4fd8bdab 100644 --- a/src/nvim/testdir/test_escaped_glob.vim +++ b/src/nvim/testdir/test_escaped_glob.vim @@ -16,7 +16,7 @@ function Test_glob() " Execute these commands in the sandbox, so that using the shell fails. " Setting 'shell' to an invalid name causes a memory leak. sandbox call assert_equal("", glob('Xxx\{')) - sandbox call assert_equal("", glob('Xxx\$')) + sandbox call assert_equal("", 'Xxx\$'->glob()) w! Xxx\{ " } to fix highlighting w! Xxx\$ @@ -28,7 +28,7 @@ endfunction function Test_globpath() sandbox call assert_equal(expand("sautest/autoload/globone.vim\nsautest/autoload/globtwo.vim"), - \ globpath('sautest/autoload', 'glob*.vim')) + \ globpath('sautest/autoload', 'glob*.vim')) sandbox call assert_equal([expand('sautest/autoload/globone.vim'), expand('sautest/autoload/globtwo.vim')], - \ globpath('sautest/autoload', 'glob*.vim', 0, 1)) + \ 'glob*.vim'->globpath('sautest/autoload', 0, 1)) endfunction diff --git a/src/nvim/testdir/test_eval_stuff.vim b/src/nvim/testdir/test_eval_stuff.vim index f7b6704610..883ba5de3d 100644 --- a/src/nvim/testdir/test_eval_stuff.vim +++ b/src/nvim/testdir/test_eval_stuff.vim @@ -174,6 +174,132 @@ func Test_number_max_min_size() call assert_true(v:numbermax > 9999999) endfunc +func Assert_reg(name, type, value, valuestr, expr, exprstr) + call assert_equal(a:type, getregtype(a:name)) + call assert_equal(a:value, getreg(a:name)) + call assert_equal(a:valuestr, string(getreg(a:name, 0, 1))) + call assert_equal(a:expr, getreg(a:name, 1)) + call assert_equal(a:exprstr, string(getreg(a:name, 1, 1))) +endfunc + +func Test_let_register() + let @" = 'abc' + call Assert_reg('"', 'v', "abc", "['abc']", "abc", "['abc']") + let @" = "abc\n" + call Assert_reg('"', 'V', "abc\n", "['abc']", "abc\n", "['abc']") + let @" = "abc\<C-m>" + call Assert_reg('"', 'V', "abc\r\n", "['abc\r']", "abc\r\n", "['abc\r']") + let @= = '"abc"' + call Assert_reg('=', 'v', "abc", "['abc']", '"abc"', "['\"abc\"']") +endfunc + +func Assert_regput(name, result) + new + execute "silent normal! o==\n==\e\"" . a:name . "P" + call assert_equal(a:result, getline(2, line('$'))) + bwipe! +endfunc + +func Test_setreg_basic() + call setreg('a', 'abcA', 'c') + call Assert_reg('a', 'v', "abcA", "['abcA']", "abcA", "['abcA']") + call Assert_regput('a', ['==', '=abcA=']) + + call setreg('A', 'abcAc', 'c') + call Assert_reg('A', 'v', "abcAabcAc", "['abcAabcAc']", "abcAabcAc", "['abcAabcAc']") + call Assert_regput('a', ['==', '=abcAabcAc=']) + + call setreg('A', 'abcAl', 'l') + call Assert_reg('A', 'V', "abcAabcAcabcAl\n", "['abcAabcAcabcAl']", "abcAabcAcabcAl\n", "['abcAabcAcabcAl']") + call Assert_regput('a', ['==', 'abcAabcAcabcAl', '==']) + + call setreg('A', 'abcAc2','c') + call Assert_reg('A', 'v', "abcAabcAcabcAl\nabcAc2", "['abcAabcAcabcAl', 'abcAc2']", "abcAabcAcabcAl\nabcAc2", "['abcAabcAcabcAl', 'abcAc2']") + call Assert_regput('a', ['==', '=abcAabcAcabcAl', 'abcAc2=']) + + call setreg('b', 'abcB', 'v') + call Assert_reg('b', 'v', "abcB", "['abcB']", "abcB", "['abcB']") + call Assert_regput('b', ['==', '=abcB=']) + + call setreg('b', 'abcBc', 'ca') + call Assert_reg('b', 'v', "abcBabcBc", "['abcBabcBc']", "abcBabcBc", "['abcBabcBc']") + call Assert_regput('b', ['==', '=abcBabcBc=']) + + call setreg('b', 'abcBb', 'ba') + call Assert_reg('b', "\<C-V>5", "abcBabcBcabcBb", "['abcBabcBcabcBb']", "abcBabcBcabcBb", "['abcBabcBcabcBb']") + call Assert_regput('b', ['==', '=abcBabcBcabcBb=']) + + call setreg('b', 'abcBc2','ca') + call Assert_reg('b', "v", "abcBabcBcabcBb\nabcBc2", "['abcBabcBcabcBb', 'abcBc2']", "abcBabcBcabcBb\nabcBc2", "['abcBabcBcabcBb', 'abcBc2']") + call Assert_regput('b', ['==', '=abcBabcBcabcBb', 'abcBc2=']) + + call setreg('b', 'abcBb2','b50a') + call Assert_reg('b', "\<C-V>50", "abcBabcBcabcBb\nabcBc2abcBb2", "['abcBabcBcabcBb', 'abcBc2abcBb2']", "abcBabcBcabcBb\nabcBc2abcBb2", "['abcBabcBcabcBb', 'abcBc2abcBb2']") + call Assert_regput('b', ['==', '=abcBabcBcabcBb =', ' abcBc2abcBb2']) + + call setreg('c', 'abcC', 'l') + call Assert_reg('c', 'V', "abcC\n", "['abcC']", "abcC\n", "['abcC']") + call Assert_regput('c', ['==', 'abcC', '==']) + + call setreg('C', 'abcCl', 'l') + call Assert_reg('C', 'V', "abcC\nabcCl\n", "['abcC', 'abcCl']", "abcC\nabcCl\n", "['abcC', 'abcCl']") + call Assert_regput('c', ['==', 'abcC', 'abcCl', '==']) + + call setreg('C', 'abcCc', 'c') + call Assert_reg('C', 'v', "abcC\nabcCl\nabcCc", "['abcC', 'abcCl', 'abcCc']", "abcC\nabcCl\nabcCc", "['abcC', 'abcCl', 'abcCc']") + call Assert_regput('c', ['==', '=abcC', 'abcCl', 'abcCc=']) + + call setreg('d', 'abcD', 'V') + call Assert_reg('d', 'V', "abcD\n", "['abcD']", "abcD\n", "['abcD']") + call Assert_regput('d', ['==', 'abcD', '==']) + + call setreg('D', 'abcDb', 'b') + call Assert_reg('d', "\<C-V>5", "abcD\nabcDb", "['abcD', 'abcDb']", "abcD\nabcDb", "['abcD', 'abcDb']") + call Assert_regput('d', ['==', '=abcD =', ' abcDb']) + + call setreg('e', 'abcE', 'b') + call Assert_reg('e', "\<C-V>4", "abcE", "['abcE']", "abcE", "['abcE']") + call Assert_regput('e', ['==', '=abcE=']) + + call setreg('E', 'abcEb', 'b') + call Assert_reg('E', "\<C-V>5", "abcE\nabcEb", "['abcE', 'abcEb']", "abcE\nabcEb", "['abcE', 'abcEb']") + call Assert_regput('e', ['==', '=abcE =', ' abcEb']) + + call setreg('E', 'abcEl', 'l') + call Assert_reg('E', "V", "abcE\nabcEb\nabcEl\n", "['abcE', 'abcEb', 'abcEl']", "abcE\nabcEb\nabcEl\n", "['abcE', 'abcEb', 'abcEl']") + call Assert_regput('e', ['==', 'abcE', 'abcEb', 'abcEl', '==']) + + call setreg('f', 'abcF', "\<C-v>") + call Assert_reg('f', "\<C-V>4", "abcF", "['abcF']", "abcF", "['abcF']") + call Assert_regput('f', ['==', '=abcF=']) + + call setreg('F', 'abcFc', 'c') + call Assert_reg('F', "v", "abcF\nabcFc", "['abcF', 'abcFc']", "abcF\nabcFc", "['abcF', 'abcFc']") + call Assert_regput('f', ['==', '=abcF', 'abcFc=']) + + call setreg('g', 'abcG', 'b10') + call Assert_reg('g', "\<C-V>10", "abcG", "['abcG']", "abcG", "['abcG']") + call Assert_regput('g', ['==', '=abcG =']) + + call setreg('h', 'abcH', "\<C-v>10") + call Assert_reg('h', "\<C-V>10", "abcH", "['abcH']", "abcH", "['abcH']") + call Assert_regput('h', ['==', '=abcH =']) + + call setreg('I', 'abcI') + call Assert_reg('I', "v", "abcI", "['abcI']", "abcI", "['abcI']") + call Assert_regput('I', ['==', '=abcI=']) + + " Error cases + call assert_fails('call setreg()', 'E119:') + call assert_fails('call setreg(1)', 'E119:') + call assert_fails('call setreg(1, 2, 3, 4)', 'E118:') + call assert_fails('call setreg([], 2)', 'E730:') + call assert_fails('call setreg(1, 2, [])', 'E730:') + call assert_fails('call setreg("/", ["1", "2"])', 'E883:') + call assert_fails('call setreg("=", ["1", "2"])', 'E883:') + call assert_fails('call setreg(1, ["", "", [], ""])', 'E730:') +endfunc + func Test_curly_assignment() let s:svar = 'svar' let g:gvar = 'gvar' diff --git a/src/nvim/testdir/test_expand_func.vim b/src/nvim/testdir/test_expand_func.vim index 9588d3b89d..44d2c156d5 100644 --- a/src/nvim/testdir/test_expand_func.vim +++ b/src/nvim/testdir/test_expand_func.vim @@ -37,6 +37,15 @@ func Test_expand_sflnum() delcommand Flnum endfunc +func Test_expand() + new + call assert_equal("", expand('%:S')) + call assert_equal('3', '<slnum>'->expand()) + call assert_equal(['4'], expand('<slnum>', v:false, v:true)) + " Don't add any line above this, otherwise <slnum> will change. + quit +endfunc + func Test_expand_sfile() call assert_match('test_expand_func\.vim$', s:sfile) call assert_match('^function .*\.\.Test_expand_sfile$', expand('<sfile>')) diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim index c49285621a..6343c47fde 100644 --- a/src/nvim/testdir/test_expr.vim +++ b/src/nvim/testdir/test_expr.vim @@ -147,7 +147,7 @@ function Test_printf_spec_s() call assert_equal(string(value), printf('%s', value)) " funcref - call assert_equal('printf', printf('%s', function('printf'))) + call assert_equal('printf', printf('%s', 'printf'->function())) " partial call assert_equal(string(function('printf', ['%s'])), printf('%s', function('printf', ['%s']))) @@ -477,7 +477,7 @@ func Test_funcref() endfunc call assert_equal(2, OneByName()) call assert_equal(1, OneByRef()) - let OneByRef = funcref('One') + let OneByRef = 'One'->funcref() call assert_equal(2, OneByRef()) call assert_fails('echo funcref("{")', 'E475:') let OneByRef = funcref("One", repeat(["foo"], 20)) diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index cc789cb6bd..18e59bb6b7 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -112,7 +112,7 @@ let s:filename_checks = { \ 'coco': ['file.atg'], \ 'conaryrecipe': ['file.recipe'], \ 'conf': ['auto.master'], - \ 'config': ['configure.in', 'configure.ac', 'Pipfile', '/etc/hostname.file'], + \ 'config': ['configure.in', 'configure.ac', '/etc/hostname.file'], \ 'context': ['tex/context/any/file.tex', 'file.mkii', 'file.mkiv', 'file.mkvi', 'file.mkxl', 'file.mklx'], \ 'cpp': ['file.cxx', 'file.c++', 'file.hh', 'file.hxx', 'file.hpp', 'file.ipp', 'file.moc', 'file.tcc', 'file.inl', 'file.tlh'], \ 'crm': ['file.crm'], @@ -259,7 +259,7 @@ let s:filename_checks = { \ 'jgraph': ['file.jgr'], \ 'jovial': ['file.jov', 'file.j73', 'file.jovial'], \ 'jproperties': ['file.properties', 'file.properties_xx', 'file.properties_xx_xx', 'some.properties_xx_xx_file'], - \ 'json': ['file.json', 'file.jsonp', 'file.json-patch', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb'], + \ 'json': ['file.json', 'file.jsonp', 'file.json-patch', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb', '.babelrc', '.eslintrc', '.prettierrc', '.firebaserc'], \ 'jsonc': ['file.jsonc'], \ 'jsp': ['file.jsp'], \ 'julia': ['file.jl'], @@ -344,6 +344,7 @@ let s:filename_checks = { \ 'nanorc': ['/etc/nanorc', 'file.nanorc', 'any/etc/nanorc'], \ 'ncf': ['file.ncf'], \ 'netrc': ['.netrc'], + \ 'nginx': ['file.nginx', 'nginxfile.conf', 'filenginx.conf', 'any/etc/nginx/file', 'any/usr/local/nginx/conf/file', 'any/nginx/file.conf'], \ 'ninja': ['file.ninja'], \ 'nqc': ['file.nqc'], \ 'nroff': ['file.tr', 'file.nr', 'file.roff', 'file.tmac', 'file.mom', 'tmac.file'], @@ -491,7 +492,7 @@ let s:filename_checks = { \ 'tak': ['file.tak'], \ 'taskdata': ['pending.data', 'completed.data', 'undo.data'], \ 'taskedit': ['file.task'], - \ 'tcl': ['file.tcl', 'file.tk', 'file.itcl', 'file.itk', 'file.jacl'], + \ 'tcl': ['file.tcl', 'file.tm', 'file.tk', 'file.itcl', 'file.itk', 'file.jacl', '.tclshrc', 'tclsh.rc', '.wishrc'], \ 'teraterm': ['file.ttl'], \ 'terminfo': ['file.ti'], \ 'tex': ['file.latex', 'file.sty', 'file.dtx', 'file.ltx', 'file.bbl'], @@ -502,8 +503,8 @@ let s:filename_checks = { \ 'tidy': ['.tidyrc', 'tidyrc', 'tidy.conf'], \ 'tilde': ['file.t.html'], \ 'tli': ['file.tli'], - \ 'tmux': ['tmuxfile.conf', '.tmuxfile.conf', '.tmux-file.conf', '.tmux.conf', 'tmux-file.conf', 'tmux.conf'], - \ 'toml': ['file.toml'], + \ 'tmux': ['tmuxfile.conf', '.tmuxfile.conf', '.tmux-file.conf', '.tmux.conf', 'tmux-file.conf', 'tmux.conf', 'tmux.conf.local'], + \ 'toml': ['file.toml', 'Gopkg.lock', 'Pipfile', '/home/user/.cargo/config'], \ 'tpp': ['file.tpp'], \ 'treetop': ['file.treetop'], \ 'trustees': ['trustees.conf'], @@ -553,6 +554,7 @@ let s:filename_checks = { \ 'xml': ['/etc/blkid.tab', '/etc/blkid.tab.old', 'file.xmi', 'file.csproj', 'file.csproj.user', 'file.ui', 'file.tpm', '/etc/xdg/menus/file.menu', 'fglrxrc', 'file.xlf', 'file.xliff', 'file.xul', 'file.wsdl', 'file.wpl', 'any/etc/blkid.tab', 'any/etc/blkid.tab.old', 'any/etc/xdg/menus/file.menu'], \ 'xmodmap': ['anyXmodmap', 'Xmodmap', 'some-Xmodmap', 'some-xmodmap', 'some-xmodmap-file', 'xmodmap', 'xmodmap-file'], \ 'xf86conf': ['xorg.conf', 'xorg.conf-4'], + \ 'xpm': ['file.xpm'], \ 'xpm2': ['file.xpm2'], \ 'xquery': ['file.xq', 'file.xql', 'file.xqm', 'file.xquery', 'file.xqy'], \ 'xs': ['file.xs'], @@ -567,7 +569,6 @@ let s:filename_checks = { \ 'zsh': ['.zprofile', '/etc/zprofile', '.zfbfmarks', 'file.zsh', '.zcompdump', '.zlogin', '.zlogout', '.zshenv', '.zshrc', '.zcompdump-file', '.zlog', '.zlog-file', '.zsh', '.zsh-file', 'any/etc/zprofile', 'zlog', 'zlog-file', 'zsh', 'zsh-file'], \ \ 'help': [$VIMRUNTIME . '/doc/help.txt'], - \ 'xpm': ['file.xpm'], \ } let s:filename_case_checks = { @@ -917,4 +918,17 @@ func Test_m_file() call delete('Xfile.m') filetype off endfunc + +func Test_xpm_file() + filetype on + + call writefile(['this is XPM2'], 'file.xpm') + split file.xpm + call assert_equal('xpm2', &filetype) + bwipe! + + call delete('file.xpm') + filetype off +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_find_complete.vim b/src/nvim/testdir/test_find_complete.vim index 0a00d9432f..32ca9672ef 100644 --- a/src/nvim/testdir/test_find_complete.vim +++ b/src/nvim/testdir/test_find_complete.vim @@ -36,7 +36,7 @@ func Test_find_complete() " We shouldn't find any file till this point call mkdir('in/path', 'p') - exe 'cd ' . cwd + call chdir(cwd) call writefile(['Holy Grail'], 'Xfind/file.txt') call writefile(['Jimmy Hoffa'], 'Xfind/in/file.txt') call writefile(['Another Holy Grail'], 'Xfind/in/stuff.txt') @@ -133,12 +133,12 @@ func Test_find_complete() call assert_equal('Voyager 2', getline(1)) " Check for correct handling of shorten_fname()'s behavior on windows - exec "cd " . cwd . "/Xfind/in" + call chdir(cwd .. "/Xfind/in") call feedkeys(":find file\t\n", "xt") call assert_equal('Jimmy Hoffa', getline(1)) " Test for relative to current buffer 'path' item - exec "cd " . cwd . "/Xfind/" + call chdir(cwd . "/Xfind/") set path=./path " Open the file where Jimmy Hoffa is found e in/file.txt @@ -157,7 +157,7 @@ func Test_find_complete() call assert_equal('Another Holy Grail', getline(1)) enew | only - exe 'cd ' . cwd + call chdir(cwd) call delete('Xfind', 'rf') set path& endfunc diff --git a/src/nvim/testdir/test_findfile.vim b/src/nvim/testdir/test_findfile.vim index 2195bf527e..5a20475d3d 100644 --- a/src/nvim/testdir/test_findfile.vim +++ b/src/nvim/testdir/test_findfile.vim @@ -50,7 +50,7 @@ func Test_findfile() set path=. call assert_equal('Xdir2/foo', findfile('foo')) call assert_equal('', findfile('bar')) - call assert_equal('Xdir2/foobar', findfile('foobar')) + call assert_equal('Xdir2/foobar', 'foobar'->findfile()) " Empty {path} 2nd argument is the same as no 2nd argument. call assert_equal('Xdir2/foo', findfile('foo', '')) @@ -113,7 +113,7 @@ func Test_findfile() call assert_match('.*/Xdir1/bar', findfile('bar', '**;', 2)) bwipe! - exe 'cd ' . save_dir + call chdir(save_dir) call CleanFiles() let &path = save_path let &shellslash = save_shellslash @@ -138,7 +138,7 @@ func Test_finddir() cd Xdir1 call assert_equal('Xdir2', finddir('Xdir2')) - call assert_equal('', finddir('Xdir3')) + call assert_equal('', 'Xdir3'->finddir()) " Files should not be found (findfile() finds them). call assert_equal('', finddir('foo')) @@ -171,7 +171,7 @@ func Test_finddir() call assert_match('.*/Xdir1/Xdir2', finddir('Xdir2', '**;', 2)) call assert_equal('Xdir3', finddir('Xdir3', '**;', 1)) - exe 'cd ' . save_dir + call chdir(save_dir) call CleanFiles() let &path = save_path let &shellslash = save_shellslash diff --git a/src/nvim/testdir/test_float_func.vim b/src/nvim/testdir/test_float_func.vim index 78675d7016..1e0c75c49d 100644 --- a/src/nvim/testdir/test_float_func.vim +++ b/src/nvim/testdir/test_float_func.vim @@ -15,6 +15,7 @@ func Test_abs() call assert_equal("str2float('inf')", string(abs(1.0/0.0))) call assert_equal("str2float('inf')", string(abs(-1.0/0.0))) call assert_equal("str2float('nan')", string(abs(0.0/0.0))) + call assert_equal('12', string(abs('12abc'))) call assert_equal('12', string(abs('-12abc'))) call assert_fails("call abs([])", 'E745:') call assert_fails("call abs({})", 'E728:') diff --git a/src/nvim/testdir/test_fnameescape.vim b/src/nvim/testdir/test_fnameescape.vim index 0bafdc29fb..cdb96ba5ff 100644 --- a/src/nvim/testdir/test_fnameescape.vim +++ b/src/nvim/testdir/test_fnameescape.vim @@ -13,7 +13,7 @@ func Test_fnameescape() let fname = 'Xemark!' let status = v:false try - exe "w! " . fnameescape(fname) + exe "w! " . fname->fnameescape() let status = v:true endtry call assert_true(status, "ExclamationMark") diff --git a/src/nvim/testdir/test_fnamemodify.vim b/src/nvim/testdir/test_fnamemodify.vim index fe1df8fd4a..411f7ebbb3 100644 --- a/src/nvim/testdir/test_fnamemodify.vim +++ b/src/nvim/testdir/test_fnamemodify.vim @@ -13,7 +13,7 @@ func Test_fnamemodify() call assert_equal('a', fnamemodify('../testdir/a', ':.')) call assert_equal('~/testdir/test.out', fnamemodify('test.out', ':~')) call assert_equal('~/testdir/a', fnamemodify('../testdir/a', ':~')) - call assert_equal('a', fnamemodify('../testdir/a', ':t')) + call assert_equal('a', '../testdir/a'->fnamemodify(':t')) call assert_equal('', fnamemodify('.', ':p:t')) call assert_equal('test.out', fnamemodify('test.out', ':p:t')) call assert_equal('out', fnamemodify('test.out', ':p:e')) diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim index 2cc5b47cb0..5586fe2151 100644 --- a/src/nvim/testdir/test_fold.vim +++ b/src/nvim/testdir/test_fold.vim @@ -88,7 +88,7 @@ func Test_indent_fold2() setl fen fdm=marker 2 norm! >> - let a=map(range(1,5), 'foldclosed(v:val)') + let a=map(range(1,5), 'v:val->foldclosed()') call assert_equal([-1,-1,-1,4,4], a) bw! endfunc @@ -132,7 +132,7 @@ func Test_indent_fold_with_read() call assert_equal(0, foldlevel(3)) call assert_equal(0, foldlevel(4)) call assert_equal(1, foldlevel(5)) - call assert_equal(7, foldclosedend(5)) + call assert_equal(7, 5->foldclosedend()) bwipe! set foldmethod& @@ -207,7 +207,7 @@ func Test_update_folds_expr_read() %foldclose call assert_equal(2, foldclosedend(1)) call assert_equal(0, foldlevel(3)) - call assert_equal(0, foldlevel(4)) + call assert_equal(0, 4->foldlevel()) call assert_equal(6, foldclosedend(5)) call assert_equal(10, foldclosedend(7)) call assert_equal(14, foldclosedend(11)) @@ -663,7 +663,7 @@ func Test_fold_move() call assert_equal(10, foldclosed(10)) call assert_equal(11, foldclosedend(10)) call assert_equal('+-- 2 lines: Line2', foldtextresult(2)) - call assert_equal('+-- 2 lines: Line8', foldtextresult(10)) + call assert_equal('+-- 2 lines: Line8', 10->foldtextresult()) set fdm& sw& fdl& enew! diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index e82fefc7fc..d10fad690c 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -56,6 +56,7 @@ func Test_empty() endif call assert_equal(0, empty(function('Test_empty'))) + call assert_equal(0, empty(function('Test_empty', [0]))) endfunc func Test_len() @@ -294,7 +295,7 @@ func Test_resolve_unix() call delete('Xlink') silent !ln -s -f Xlink2/ Xlink1 - call assert_equal('Xlink2', resolve('Xlink1')) + call assert_equal('Xlink2', 'Xlink1'->resolve()) call assert_equal('Xlink2/', resolve('Xlink1/')) call delete('Xlink1') @@ -359,10 +360,10 @@ endfunc func Test_pathshorten() call assert_equal('', pathshorten('')) call assert_equal('foo', pathshorten('foo')) - call assert_equal('/foo', pathshorten('/foo')) + call assert_equal('/foo', '/foo'->pathshorten()) call assert_equal('f/', pathshorten('foo/')) call assert_equal('f/bar', pathshorten('foo/bar')) - call assert_equal('f/b/foobar', pathshorten('foo/bar/foobar')) + call assert_equal('f/b/foobar', 'foo/bar/foobar'->pathshorten()) call assert_equal('/f/b/foobar', pathshorten('/foo/bar/foobar')) call assert_equal('.f/bar', pathshorten('.foo/bar')) call assert_equal('~f/bar', pathshorten('~foo/bar')) @@ -585,6 +586,8 @@ func Test_mode() exe "normal iabc\<C-X>\<C-L>\<F2>\<Esc>u" call assert_equal('i-ic', g:current_modes) + exe "normal R\<F2>\<Esc>" + call assert_equal('R-R', g:current_modes) " R_CTRL-P: Multiple matches exe "normal RBa\<C-P>\<F2>\<Esc>u" call assert_equal('R-Rc', g:current_modes) @@ -619,8 +622,44 @@ func Test_mode() exe "normal Rabc\<C-X>\<C-L>\<F2>\<Esc>u" call assert_equal('R-Rc', g:current_modes) - call assert_equal('n', mode(0)) - call assert_equal('n', mode(1)) + exe "normal gR\<F2>\<Esc>" + call assert_equal('R-Rv', g:current_modes) + " gR_CTRL-P: Multiple matches + exe "normal gRBa\<C-P>\<F2>\<Esc>u" + call assert_equal('R-Rvc', g:current_modes) + " gR_CTRL-P: Single match + exe "normal gRBro\<C-P>\<F2>\<Esc>u" + call assert_equal('R-Rvc', g:current_modes) + " gR_CTRL-X + exe "normal gRBa\<C-X>\<F2>\<Esc>u" + call assert_equal('R-Rvx', g:current_modes) + " gR_CTRL-X CTRL-P: Multiple matches + exe "normal gRBa\<C-X>\<C-P>\<F2>\<Esc>u" + call assert_equal('R-Rvc', g:current_modes) + " gR_CTRL-X CTRL-P: Single match + exe "normal gRBro\<C-X>\<C-P>\<F2>\<Esc>u" + call assert_equal('R-Rvc', g:current_modes) + " gR_CTRL-X CTRL-P + CTRL-P: Single match + exe "normal gRBro\<C-X>\<C-P>\<C-P>\<F2>\<Esc>u" + call assert_equal('R-Rvc', g:current_modes) + " gR_CTRL-X CTRL-L: Multiple matches + exe "normal gR\<C-X>\<C-L>\<F2>\<Esc>u" + call assert_equal('R-Rvc', g:current_modes) + " gR_CTRL-X CTRL-L: Single match + exe "normal gRBlu\<C-X>\<C-L>\<F2>\<Esc>u" + call assert_equal('R-Rvc', g:current_modes) + " gR_CTRL-P: No match + exe "normal gRCom\<C-P>\<F2>\<Esc>u" + call assert_equal('R-Rvc', g:current_modes) + " gR_CTRL-X CTRL-P: No match + exe "normal gRCom\<C-X>\<C-P>\<F2>\<Esc>u" + call assert_equal('R-Rvc', g:current_modes) + " gR_CTRL-X CTRL-L: No match + exe "normal gRabc\<C-X>\<C-L>\<F2>\<Esc>u" + call assert_equal('R-Rvc', g:current_modes) + + call assert_equal('n', 0->mode()) + call assert_equal('n', 1->mode()) " i_CTRL-O exe "normal i\<C-O>:call Save_mode()\<Cr>\<Esc>" @@ -672,10 +711,34 @@ func Test_mode() call assert_equal('c-cv', g:current_modes) " How to test Ex mode? + " Test mode in operatorfunc (it used to be Operator-pending). + set operatorfunc=OperatorFunc + function OperatorFunc(_) + call Save_mode() + endfunction + execute "normal! g@l\<Esc>" + call assert_equal('n-n', g:current_modes) + execute "normal! i\<C-o>g@l\<Esc>" + call assert_equal('n-niI', g:current_modes) + execute "normal! R\<C-o>g@l\<Esc>" + call assert_equal('n-niR', g:current_modes) + execute "normal! gR\<C-o>g@l\<Esc>" + call assert_equal('n-niV', g:current_modes) + + if has('terminal') + term + call feedkeys("\<C-W>N", 'xt') + call assert_equal('n', mode()) + call assert_equal('nt', mode(1)) + call feedkeys("aexit\<CR>", 'xt') + endif + bwipe! iunmap <F2> xunmap <F2> set complete& + set operatorfunc& + delfunction OperatorFunc endfunc func Test_append() @@ -776,7 +839,7 @@ endfunc func Test_match_func() call assert_equal(4, match('testing', 'ing')) - call assert_equal(4, match('testing', 'ing', 2)) + call assert_equal(4, 'testing'->match('ing', 2)) call assert_equal(-1, match('testing', 'ing', 5)) call assert_equal(-1, match('testing', 'ing', 8)) call assert_equal(1, match(['vim', 'testing', 'execute'], 'ing')) @@ -785,7 +848,7 @@ endfunc func Test_matchend() call assert_equal(7, matchend('testing', 'ing')) - call assert_equal(7, matchend('testing', 'ing', 2)) + call assert_equal(7, 'testing'->matchend('ing', 2)) call assert_equal(-1, matchend('testing', 'ing', 5)) call assert_equal(-1, matchend('testing', 'ing', 8)) call assert_equal(match(['vim', 'testing', 'execute'], 'ing'), matchend(['vim', 'testing', 'execute'], 'ing')) @@ -794,13 +857,13 @@ endfunc func Test_matchlist() call assert_equal(['acd', 'a', '', 'c', 'd', '', '', '', '', ''], matchlist('acd', '\(a\)\?\(b\)\?\(c\)\?\(.*\)')) - call assert_equal(['d', '', '', '', 'd', '', '', '', '', ''], matchlist('acd', '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 2)) + call assert_equal(['d', '', '', '', 'd', '', '', '', '', ''], 'acd'->matchlist('\(a\)\?\(b\)\?\(c\)\?\(.*\)', 2)) call assert_equal([], matchlist('acd', '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 4)) endfunc func Test_matchstr() call assert_equal('ing', matchstr('testing', 'ing')) - call assert_equal('ing', matchstr('testing', 'ing', 2)) + call assert_equal('ing', 'testing'->matchstr('ing', 2)) call assert_equal('', matchstr('testing', 'ing', 5)) call assert_equal('', matchstr('testing', 'ing', 8)) call assert_equal('testing', matchstr(['vim', 'testing', 'execute'], 'ing')) @@ -809,7 +872,7 @@ endfunc func Test_matchstrpos() call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing')) - call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing', 2)) + call assert_equal(['ing', 4, 7], 'testing'->matchstrpos('ing', 2)) call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 5)) call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 8)) call assert_equal(['ing', 1, 4, 7], matchstrpos(['vim', 'testing', 'execute'], 'ing')) @@ -830,21 +893,21 @@ Test call assert_equal(0, nextnonblank(-1)) call assert_equal(0, nextnonblank(0)) call assert_equal(1, nextnonblank(1)) - call assert_equal(4, nextnonblank(2)) + call assert_equal(4, 2->nextnonblank()) call assert_equal(4, nextnonblank(3)) call assert_equal(4, nextnonblank(4)) call assert_equal(6, nextnonblank(5)) call assert_equal(6, nextnonblank(6)) call assert_equal(7, nextnonblank(7)) - call assert_equal(0, nextnonblank(8)) + call assert_equal(0, 8->nextnonblank()) call assert_equal(0, prevnonblank(-1)) call assert_equal(0, prevnonblank(0)) - call assert_equal(1, prevnonblank(1)) + call assert_equal(1, 1->prevnonblank()) call assert_equal(1, prevnonblank(2)) call assert_equal(1, prevnonblank(3)) call assert_equal(4, prevnonblank(4)) - call assert_equal(4, prevnonblank(5)) + call assert_equal(4, 5->prevnonblank()) call assert_equal(6, prevnonblank(6)) call assert_equal(7, prevnonblank(7)) call assert_equal(0, prevnonblank(8)) @@ -866,7 +929,7 @@ func Test_byte2line_line2byte() call assert_equal([-1, -1, 1, 1, 2, 2, 2, 3, 3, -1], \ map(range(-1, 8), 'v:val->byte2line()')) call assert_equal([-1, -1, 1, 3, 6, 8, -1], - \ map(range(-1, 5), 'line2byte(v:val)')) + \ map(range(-1, 5), 'v:val->line2byte()')) set fileformat=dos call assert_equal([-1, -1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, -1], @@ -961,6 +1024,7 @@ func Test_count() call assert_equal(1, count(l, 'a', 0, 1)) call assert_equal(2, count(l, 'a', 1, 1)) call assert_fails('call count(l, "a", 0, 10)', 'E684:') + call assert_fails('call count(l, "a", [])', 'E745:') let d = {1: 'a', 2: 'a', 3: 'A', 4: 'b'} call assert_equal(2, count(d, 'a')) @@ -988,6 +1052,8 @@ func Test_count() call assert_equal(2, count("foo", "O", 1)) call assert_equal(2, count("fooooo", "oo")) call assert_equal(0, count("foo", "")) + + call assert_fails('call count(0, 0)', 'E712:') endfunc func Test_changenr() @@ -1015,7 +1081,7 @@ func Test_filewritable() call assert_equal(0, filewritable('Xfilewritable')) call assert_notequal(0, setfperm('Xfilewritable', 'rw-r-----')) - call assert_equal(1, filewritable('Xfilewritable')) + call assert_equal(1, 'Xfilewritable'->filewritable()) call assert_equal(0, filewritable('doesnotexist')) @@ -1026,12 +1092,12 @@ endfunc func Test_Executable() if has('win32') call assert_equal(1, executable('notepad')) - call assert_equal(1, executable('notepad.exe')) + call assert_equal(1, 'notepad.exe'->executable()) call assert_equal(0, executable('notepad.exe.exe')) call assert_equal(0, executable('shell32.dll')) call assert_equal(0, executable('win.ini')) elseif has('unix') - call assert_equal(1, executable('cat')) + call assert_equal(1, 'cat'->executable()) call assert_equal(0, executable('nodogshere')) " get "cat" path and remove the leading / @@ -1040,8 +1106,7 @@ func Test_Executable() " check that the relative path works in / lcd / call assert_equal(1, executable(catcmd)) - " let result = catcmd->exepath() - let result = exepath(catcmd) + let result = catcmd->exepath() " when using chroot looking for sbin/cat can return bin/cat, that is OK if catcmd =~ '\<sbin\>' && result =~ '\<bin\>' call assert_equal('/' .. substitute(catcmd, '\<sbin\>', 'bin', ''), result) @@ -1086,7 +1151,7 @@ endfunc func Test_hlexists() call assert_equal(0, hlexists('does_not_exist')) - " call assert_equal(0, hlexists('Number')) + " call assert_equal(0, 'Number'->hlexists()) call assert_equal(0, highlight_exists('does_not_exist')) " call assert_equal(0, highlight_exists('Number')) syntax on @@ -1119,7 +1184,7 @@ endfunc func Test_inputlist() call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>1\<cr>", 'tx') call assert_equal(1, c) - call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>2\<cr>", 'tx') + call feedkeys(":let c = ['Select color:', '1. red', '2. green', '3. blue']->inputlist()\<cr>2\<cr>", 'tx') call assert_equal(2, c) call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>3\<cr>", 'tx') call assert_equal(3, c) @@ -1251,7 +1316,7 @@ func Test_trim() call assert_fails('call trim(" vim ", " ", -1)', 'E475:') call assert_fails('call trim(" vim ", " ", 3)', 'E475:') - let chars = join(map(range(1, 0x20) + [0xa0], {n -> nr2char(n)}), '') + let chars = join(map(range(1, 0x20) + [0xa0], {n -> n->nr2char()}), '') call assert_equal("x", trim(chars . "x" . chars)) endfunc @@ -1265,7 +1330,7 @@ func Test_func_range_with_edit() " is invalid in that buffer. call writefile(['just one line'], 'Xfuncrange2') new - call setline(1, range(10)) + call setline(1, 10->range()) write Xfuncrange1 call assert_fails('5,8call EditAnotherFile()', 'E16:') @@ -1278,7 +1343,7 @@ func Test_func_exists_on_reload() call writefile(['func ExistingFunction()', 'echo "yes"', 'endfunc'], 'Xfuncexists') call assert_equal(0, exists('*ExistingFunction')) source Xfuncexists - call assert_equal(1, exists('*ExistingFunction')) + call assert_equal(1, '*ExistingFunction'->exists()) " Redefining a function when reloading a script is OK. source Xfuncexists call assert_equal(1, exists('*ExistingFunction')) @@ -1309,7 +1374,7 @@ func Test_func_sandbox() sandbox let F = {-> 'hello'} call assert_equal('hello', F()) - sandbox let F = {-> execute("normal ix\<Esc>")} + sandbox let F = {-> "normal ix\<Esc>"->execute()} call assert_fails('call F()', 'E48:') unlet F @@ -1372,7 +1437,7 @@ func Test_reg_executing_and_recording() let g:regs = [] func TestFunc() abort let g:regs += [reg_executing()] - let g:typed = input('?') + let g:typed = '?'->input() let g:regs += [reg_executing()] endfunc call feedkeys("@qy\<CR>", 'xt') @@ -1388,6 +1453,25 @@ func Test_reg_executing_and_recording() unlet s:reg_stat endfunc +func Test_inputsecret() + map W :call TestFunc()<CR> + let @q = "W" + let g:typed1 = '' + let g:typed2 = '' + let g:regs = [] + func TestFunc() abort + let g:typed1 = '?'->inputsecret() + let g:typed2 = inputsecret('password: ') + endfunc + call feedkeys("@qsomething\<CR>else\<CR>", 'xt') + call assert_equal("something", g:typed1) + call assert_equal("else", g:typed2) + delfunc TestFunc + unmap W + unlet g:typed1 + unlet g:typed2 +endfunc + func Test_getchar() call feedkeys('a', '') call assert_equal(char2nr('a'), getchar()) @@ -1445,17 +1529,17 @@ func Test_libcall_libcallnr() endif if has('win32') - call assert_equal($USERPROFILE, libcall(libc, 'getenv', 'USERPROFILE')) + call assert_equal($USERPROFILE, 'USERPROFILE'->libcall(libc, 'getenv')) else - call assert_equal($HOME, libcall(libc, 'getenv', 'HOME')) + call assert_equal($HOME, 'HOME'->libcall(libc, 'getenv')) endif " If function returns NULL, libcall() should return an empty string. call assert_equal('', libcall(libc, 'getenv', 'X_ENV_DOES_NOT_EXIT')) " Test libcallnr() with string and integer argument. - call assert_equal(4, libcallnr(libc, 'strlen', 'abcd')) - call assert_equal(char2nr('A'), libcallnr(libc, 'toupper', char2nr('a'))) + call assert_equal(4, 'abcd'->libcallnr(libc, 'strlen')) + call assert_equal(char2nr('A'), char2nr('a')->libcallnr(libc, 'toupper')) call assert_fails("call libcall(libc, 'Xdoesnotexist_', '')", 'E364:') call assert_fails("call libcallnr(libc, 'Xdoesnotexist_', '')", 'E364:') @@ -1518,7 +1602,7 @@ func Test_readdir() call assert_equal(['bar.txt', 'dir', 'foo.txt'], sort(files)) " Only results containing "f" - let files = readdir('Xdir', { x -> stridx(x, 'f') !=- 1 }) + let files = 'Xdir'->readdir({ x -> stridx(x, 'f') !=- 1 }) call assert_equal(['foo.txt'], sort(files)) " Only .txt files @@ -1551,6 +1635,14 @@ func Test_call() call assert_fails("call call('Mylen', [], 0)", 'E715:') endfunc +func Test_char2nr() + call assert_equal(12354, char2nr('あ', 1)) +endfunc + +func Test_eventhandler() + call assert_equal(0, eventhandler()) +endfunc + " Test for the eval() function func Test_eval() call assert_fails("call eval('5 a')", 'E488:') diff --git a/src/nvim/testdir/test_getcwd.vim b/src/nvim/testdir/test_getcwd.vim index ca098781e4..a75583cd2c 100644 --- a/src/nvim/testdir/test_getcwd.vim +++ b/src/nvim/testdir/test_getcwd.vim @@ -17,7 +17,7 @@ func GetCwdInfo(win, tab) let lflag = haslocaldir(a:win) else let dirname = fnamemodify(getcwd(a:win, a:tab), mod) - let lflag = haslocaldir(a:win, a:tab) + let lflag = a:win->haslocaldir(a:tab) endif return bufname . ' ' . dirname . ' ' . lflag endfunc @@ -35,7 +35,7 @@ function SetUp() " we start from a clean state. call delete("Xtopdir", "rf") new - call mkdir('Xtopdir') + eval 'Xtopdir'->mkdir() cd Xtopdir let g:topdir = getcwd() call mkdir('Xdir1') @@ -46,7 +46,7 @@ endfunction let g:cwd=getcwd() function TearDown() q - exec "cd " . g:cwd + call chdir(g:cwd) call delete("Xtopdir", "rf") endfunction diff --git a/src/nvim/testdir/test_getvar.vim b/src/nvim/testdir/test_getvar.vim index 3b61d68ebc..5a96548893 100644 --- a/src/nvim/testdir/test_getvar.vim +++ b/src/nvim/testdir/test_getvar.vim @@ -12,8 +12,8 @@ func Test_var() let def_str = "Chance" call assert_equal('Dance', getwinvar(1, 'var_str')) call assert_equal('Dance', getwinvar(1, 'var_str', def_str)) - call assert_equal({'var_str': 'Dance'}, getwinvar(1, '')) - call assert_equal({'var_str': 'Dance'}, getwinvar(1, '', def_str)) + call assert_equal({'var_str': 'Dance'}, 1->getwinvar('')) + call assert_equal({'var_str': 'Dance'}, 1->getwinvar('', def_str)) unlet w:var_str call assert_equal('Chance', getwinvar(1, 'var_str', def_str)) call assert_equal({}, getwinvar(1, '')) @@ -31,7 +31,7 @@ func Test_var() let t:other = 777 let def_list = [4, 5, 6, 7] tabrewind - call assert_equal([1, 2, 3], gettabvar(3, 'var_list')) + call assert_equal([1, 2, 3], 3->gettabvar('var_list')) call assert_equal([1, 2, 3], gettabvar(3, 'var_list', def_list)) call assert_equal({'var_list': [1, 2, 3], 'other': 777}, gettabvar(3, '')) call assert_equal({'var_list': [1, 2, 3], 'other': 777}, @@ -61,7 +61,7 @@ func Test_var() let def_dict = {'dict2': 'newval'} wincmd b tabrewind - call assert_equal({'dict': 'tabwin'}, gettabwinvar(2, 3, 'var_dict')) + call assert_equal({'dict': 'tabwin'}, 2->gettabwinvar(3, 'var_dict')) call assert_equal({'dict': 'tabwin'}, \ gettabwinvar(2, 3, 'var_dict', def_dict)) call assert_equal({'var_dict': {'dict': 'tabwin'}}, gettabwinvar(2, 3, '')) diff --git a/src/nvim/testdir/test_glob2regpat.vim b/src/nvim/testdir/test_glob2regpat.vim index 354f239ef1..a423a4a9f0 100644 --- a/src/nvim/testdir/test_glob2regpat.vim +++ b/src/nvim/testdir/test_glob2regpat.vim @@ -10,7 +10,7 @@ endfunc func Test_glob2regpat_valid() call assert_equal('^foo\.', glob2regpat('foo.*')) - call assert_equal('^foo.$', glob2regpat('foo?')) + call assert_equal('^foo.$', 'foo?'->glob2regpat()) call assert_equal('\.vim$', glob2regpat('*.vim')) call assert_equal('^[abc]$', glob2regpat('[abc]')) call assert_equal('^foo bar$', glob2regpat('foo\ bar')) diff --git a/src/nvim/testdir/test_history.vim b/src/nvim/testdir/test_history.vim index 16aad9889e..2f0dc2dae1 100644 --- a/src/nvim/testdir/test_history.vim +++ b/src/nvim/testdir/test_history.vim @@ -13,7 +13,7 @@ function History_Tests(hist) call assert_equal(-1, histnr(a:hist)) call assert_equal('', histget(a:hist)) - call assert_true(histadd(a:hist, 'ls')) + call assert_true('ls'->histadd(a:hist)) call assert_true(histadd(a:hist, 'buffers')) call assert_equal('buffers', histget(a:hist)) call assert_equal('ls', histget(a:hist, -2)) @@ -22,14 +22,14 @@ function History_Tests(hist) call assert_equal('', histget(a:hist, -5)) call assert_equal(2, histnr(a:hist)) call assert_true(histdel(a:hist, 2)) - call assert_false(histdel(a:hist, 7)) + call assert_false(a:hist->histdel(7)) call assert_equal(1, histnr(a:hist)) call assert_equal('ls', histget(a:hist, -1)) call assert_true(histadd(a:hist, 'buffers')) call assert_true(histadd(a:hist, 'ls')) - call assert_equal('ls', histget(a:hist, -1)) - call assert_equal(4, histnr(a:hist)) + call assert_equal('ls', a:hist->histget(-1)) + call assert_equal(4, a:hist->histnr()) let a=execute('history ' . a:hist) call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a) diff --git a/src/nvim/testdir/test_jumplist.vim b/src/nvim/testdir/test_jumplist.vim index be1af5e705..9cfbbe2029 100644 --- a/src/nvim/testdir/test_jumplist.vim +++ b/src/nvim/testdir/test_jumplist.vim @@ -39,7 +39,7 @@ func Test_getjumplist() " Traverse the jump list and verify the results 5 exe "normal \<C-O>" - call assert_equal(2, getjumplist(1)[1]) + call assert_equal(2, 1->getjumplist()[1]) exe "normal 2\<C-O>" call assert_equal(0, getjumplist(1, 1)[1]) exe "normal 3\<C-I>" diff --git a/src/nvim/testdir/test_lispwords.vim b/src/nvim/testdir/test_lispwords.vim index 4c05504cf1..aa5a738bdf 100644 --- a/src/nvim/testdir/test_lispwords.vim +++ b/src/nvim/testdir/test_lispwords.vim @@ -43,6 +43,9 @@ func Test_lisp_indent() \ ',@body', \ '(princ "</a>")))' \ ]) + call assert_equal(7, lispindent(2)) + call assert_equal(5, 6->lispindent()) + set lisp set lispwords& let save_copt = &cpoptions diff --git a/src/nvim/testdir/test_listdict.vim b/src/nvim/testdir/test_listdict.vim index ae035fa519..f6c404d390 100644 --- a/src/nvim/testdir/test_listdict.vim +++ b/src/nvim/testdir/test_listdict.vim @@ -573,7 +573,7 @@ func Test_lockvar_script_autoload() set rtp+=./sautest lockvar g:footest#x unlockvar g:footest#x - call assert_equal(-1, islocked('g:footest#x')) + call assert_equal(-1, 'g:footest#x'->islocked()) call assert_equal(0, exists('g:footest#x')) call assert_equal(1, g:footest#x) let &rtp = old_rtp diff --git a/src/nvim/testdir/test_maparg.vim b/src/nvim/testdir/test_maparg.vim index 238d2f900d..5b082198cf 100644 --- a/src/nvim/testdir/test_maparg.vim +++ b/src/nvim/testdir/test_maparg.vim @@ -1,5 +1,6 @@ " Tests for maparg(). " Also test utf8 map with a 0x80 byte. +" Also test mapcheck() function s:SID() return str2nr(matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')) @@ -22,7 +23,7 @@ function Test_maparg() call assert_equal({'silent': 1, 'noremap': 1, 'script': 1, 'lhs': 'bar', 'mode': 'v', \ 'nowait': 0, 'expr': 1, 'sid': sid, 'lnum': lnum + 2, \ 'rhs': 'isbar', 'buffer': 1}, - \ maparg('bar', '', 0, 1)) + \ 'bar'->maparg('', 0, 1)) let lnum = expand('<sflnum>') map <buffer> <nowait> foo bar call assert_equal({'silent': 0, 'noremap': 0, 'script': 0, 'lhs': 'foo', 'mode': ' ', @@ -51,6 +52,45 @@ function Test_maparg() unmap abc endfunction +func Test_mapcheck() + call assert_equal('', mapcheck('a')) + call assert_equal('', mapcheck('abc')) + call assert_equal('', mapcheck('ax')) + call assert_equal('', mapcheck('b')) + + map a something + call assert_equal('something', mapcheck('a')) + call assert_equal('something', mapcheck('a', 'n')) + call assert_equal('', mapcheck('a', 'c')) + call assert_equal('', mapcheck('a', 'i')) + call assert_equal('something', 'abc'->mapcheck()) + call assert_equal('something', 'ax'->mapcheck()) + call assert_equal('', mapcheck('b')) + unmap a + + map ab foobar + call assert_equal('foobar', mapcheck('a')) + call assert_equal('foobar', mapcheck('abc')) + call assert_equal('', mapcheck('ax')) + call assert_equal('', mapcheck('b')) + unmap ab + + map abc barfoo + call assert_equal('barfoo', mapcheck('a')) + call assert_equal('barfoo', mapcheck('a', 'n', 0)) + call assert_equal('', mapcheck('a', 'n', 1)) + call assert_equal('barfoo', mapcheck('abc')) + call assert_equal('', mapcheck('ax')) + call assert_equal('', mapcheck('b')) + unmap abc + + abbr ab abbrev + call assert_equal('abbrev', mapcheck('a', 'i', 1)) + call assert_equal('', mapcheck('a', 'n', 1)) + call assert_equal('', mapcheck('a', 'i', 0)) + unabbr ab +endfunc + function Test_range_map() new " Outside of the range, minimum diff --git a/src/nvim/testdir/test_match.vim b/src/nvim/testdir/test_match.vim index 505a052a19..70271aa32f 100644 --- a/src/nvim/testdir/test_match.vim +++ b/src/nvim/testdir/test_match.vim @@ -14,7 +14,7 @@ function Test_match() 2match MyGroup2 /FIXME/ 3match MyGroup3 /XXX/ call assert_equal(['MyGroup1', 'TODO'], matcharg(1)) - call assert_equal(['MyGroup2', 'FIXME'], matcharg(2)) + call assert_equal(['MyGroup2', 'FIXME'], 2->matcharg()) call assert_equal(['MyGroup3', 'XXX'], matcharg(3)) " --- Check that "matcharg()" returns an empty list if the argument is not 1, @@ -43,7 +43,7 @@ function Test_match() " --- Check that "matchdelete()" deletes the matches defined in the previous " --- test correctly. call matchdelete(m1) - call matchdelete(m2) + eval m2->matchdelete() call matchdelete(m3) call assert_equal([], getmatches()) @@ -55,7 +55,7 @@ function Test_match() " --- Check that "clearmatches()" clears all matches defined by ":match" and " --- "matchadd()". let m1 = matchadd("MyGroup1", "TODO") - let m2 = matchadd("MyGroup2", "FIXME", 42) + let m2 = "MyGroup2"->matchadd("FIXME", 42) let m3 = matchadd("MyGroup3", "XXX", 60, 17) match MyGroup1 /COFFEE/ 2match MyGroup2 /HUMPPA/ @@ -117,7 +117,7 @@ function Test_match() call clearmatches() call setline(1, 'abcdΣabcdef') - call matchaddpos("MyGroup1", [[1, 4, 2], [1, 9, 2]]) + eval "MyGroup1"->matchaddpos([[1, 4, 2], [1, 9, 2]]) 1 redraw! let v1 = screenattr(1, 1) diff --git a/src/nvim/testdir/test_method.vim b/src/nvim/testdir/test_method.vim index d34448e09e..cdf688b857 100644 --- a/src/nvim/testdir/test_method.vim +++ b/src/nvim/testdir/test_method.vim @@ -1,5 +1,7 @@ " Tests for ->method() +source check.vim + func Test_list_method() let l = [1, 2, 3] call assert_equal([1, 2, 3, 4], [1, 2, 3]->add(4)) @@ -118,6 +120,7 @@ func Test_method_funcref() endfunc func Test_method_float() + CheckFeature float eval 1.234->string()->assert_equal('1.234') eval -1.234->string()->assert_equal('-1.234') endfunc diff --git a/src/nvim/testdir/test_perl.vim b/src/nvim/testdir/test_perl.vim index 872194a804..b911a982f9 100644 --- a/src/nvim/testdir/test_perl.vim +++ b/src/nvim/testdir/test_perl.vim @@ -32,7 +32,7 @@ endfunc funct Test_VIM_Blob() call assert_equal('0z', perleval('VIM::Blob("")')) - call assert_equal('0z31326162', perleval('VIM::Blob("12ab")')) + call assert_equal('0z31326162', 'VIM::Blob("12ab")'->perleval()) call assert_equal('0z00010203', perleval('VIM::Blob("\x00\x01\x02\x03")')) call assert_equal('0z8081FEFF', perleval('VIM::Blob("\x80\x81\xfe\xff")')) endfunc diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim index 710450293c..eb367cfe5c 100644 --- a/src/nvim/testdir/test_popup.vim +++ b/src/nvim/testdir/test_popup.vim @@ -950,6 +950,10 @@ func Test_popup_complete_info_01() \ ["\<C-X>", 'ctrl_x'], \ ["\<C-X>\<C-N>", 'keyword'], \ ["\<C-X>\<C-P>", 'keyword'], + \ ["\<C-X>\<C-E>", 'scroll'], + \ ["\<C-X>\<C-Y>", 'scroll'], + \ ["\<C-X>\<C-E>\<C-E>\<C-Y>", 'scroll'], + \ ["\<C-X>\<C-Y>\<C-E>\<C-Y>", 'scroll'], \ ["\<C-X>\<C-L>", 'whole_line'], \ ["\<C-X>\<C-F>", 'files'], \ ["\<C-X>\<C-]>", 'tags'], diff --git a/src/nvim/testdir/test_prompt_buffer.vim b/src/nvim/testdir/test_prompt_buffer.vim index 6fc5850be3..3da46eb1a6 100644 --- a/src/nvim/testdir/test_prompt_buffer.vim +++ b/src/nvim/testdir/test_prompt_buffer.vim @@ -110,11 +110,8 @@ func Test_prompt_garbage_collect() new set buftype=prompt - " Nvim doesn't support method call syntax yet. - " eval bufnr('')->prompt_setcallback(function('MyPromptCallback', [{}])) - " eval bufnr('')->prompt_setinterrupt(function('MyPromptInterrupt', [{}])) - eval prompt_setcallback(bufnr(''), function('MyPromptCallback', [{}])) - eval prompt_setinterrupt(bufnr(''), function('MyPromptInterrupt', [{}])) + eval bufnr('')->prompt_setcallback(function('MyPromptCallback', [{}])) + eval bufnr('')->prompt_setinterrupt(function('MyPromptInterrupt', [{}])) call test_garbagecollect_now() " Must not crash call feedkeys("\<CR>\<C-C>", 'xt') diff --git a/src/nvim/testdir/test_python2.vim b/src/nvim/testdir/test_python2.vim index 5895ac85a8..ae8bc57c7f 100644 --- a/src/nvim/testdir/test_python2.vim +++ b/src/nvim/testdir/test_python2.vim @@ -59,7 +59,7 @@ func Test_vim_function() try py f = vim.Function('\x80\xfdR' + vim.eval('s:foo()')) - call assert_equal(name, pyeval('f.name')) + call assert_equal(name, 'f.name'->pyeval()) catch call assert_false(v:exception) endtry diff --git a/src/nvim/testdir/test_python3.vim b/src/nvim/testdir/test_python3.vim index 637648817c..54da3d2eba 100644 --- a/src/nvim/testdir/test_python3.vim +++ b/src/nvim/testdir/test_python3.vim @@ -59,7 +59,7 @@ func Test_vim_function() try py3 f = vim.Function(b'\x80\xfdR' + vim.eval('s:foo()').encode()) - call assert_equal(name, py3eval('f.name')) + call assert_equal(name, 'f.name'->py3eval()) catch call assert_false(v:exception) endtry diff --git a/src/nvim/testdir/test_pyx2.vim b/src/nvim/testdir/test_pyx2.vim index 10ff3b6e58..b6ed80f842 100644 --- a/src/nvim/testdir/test_pyx2.vim +++ b/src/nvim/testdir/test_pyx2.vim @@ -35,7 +35,7 @@ endfunc func Test_pyxeval() pyx import sys - call assert_match(s:py2pattern, split(pyxeval('sys.version'))[0]) + call assert_match(s:py2pattern, split('sys.version'->pyxeval())[0]) endfunc diff --git a/src/nvim/testdir/test_registers.vim b/src/nvim/testdir/test_registers.vim index 53069b3d31..fd8653a2eb 100644 --- a/src/nvim/testdir/test_registers.vim +++ b/src/nvim/testdir/test_registers.vim @@ -283,4 +283,84 @@ func Test_insert_small_delete() bwipe! endfunc +" Test for getting register info +func Test_get_reginfo() + enew + call setline(1, ['foo', 'bar']) + + exe 'norm! "zyy' + let info = getreginfo('"') + call assert_equal('z', info.points_to) + call setreg('y', 'baz') + call assert_equal('z', getreginfo('').points_to) + call setreg('y', { 'isunnamed': v:true }) + call assert_equal('y', getreginfo('"').points_to) + + exe '$put' + call assert_equal(getreg('y'), getline(3)) + call setreg('', 'qux') + call assert_equal('0', getreginfo('').points_to) + call setreg('x', 'quux') + call assert_equal('0', getreginfo('').points_to) + + let info = getreginfo('') + call assert_equal(getreg('', 1, 1), info.regcontents) + call assert_equal(getregtype(''), info.regtype) + + exe "norm! 0\<c-v>e" .. '"zy' + let info = getreginfo('z') + call assert_equal(getreg('z', 1, 1), info.regcontents) + call assert_equal(getregtype('z'), info.regtype) + call assert_equal(1, +info.isunnamed) + + let info = getreginfo('"') + call assert_equal('z', info.points_to) + + bwipe! +endfunc + +" Test for restoring register with dict from getreginfo +func Test_set_register_dict() + enew! + + call setreg('"', #{ regcontents: ['one', 'two'], + \ regtype: 'V', points_to: 'z' }) + call assert_equal(['one', 'two'], getreg('"', 1, 1)) + let info = getreginfo('"') + call assert_equal('z', info.points_to) + call assert_equal('V', info.regtype) + call assert_equal(1, +getreginfo('z').isunnamed) + + call setreg('x', #{ regcontents: ['three', 'four'], + \ regtype: 'v', isunnamed: v:true }) + call assert_equal(['three', 'four'], getreg('"', 1, 1)) + let info = getreginfo('"') + call assert_equal('x', info.points_to) + call assert_equal('v', info.regtype) + call assert_equal(1, +getreginfo('x').isunnamed) + + call setreg('y', #{ regcontents: 'five', + \ regtype: "\<c-v>", isunnamed: v:false }) + call assert_equal("\<c-v>4", getreginfo('y').regtype) + call assert_equal(0, +getreginfo('y').isunnamed) + call assert_equal(['three', 'four'], getreg('"', 1, 1)) + call assert_equal('x', getreginfo('"').points_to) + + call setreg('"', #{ regcontents: 'six' }) + call assert_equal('0', getreginfo('"').points_to) + call assert_equal(1, +getreginfo('0').isunnamed) + call assert_equal(['six'], getreginfo('0').regcontents) + call assert_equal(['six'], getreginfo('"').regcontents) + + let @x = 'one' + call setreg('x', {}) + call assert_equal(1, len(split(execute('reg x'), '\n'))) + + call assert_fails("call setreg('0', #{regtype: 'V'}, 'v')", 'E118:') + call assert_fails("call setreg('0', #{regtype: 'X'})", 'E475:') + call assert_fails("call setreg('0', #{regtype: 'vy'})", 'E475:') + + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_reltime.vim b/src/nvim/testdir/test_reltime.vim index 2ef2fbba23..37b9e783c6 100644 --- a/src/nvim/testdir/test_reltime.vim +++ b/src/nvim/testdir/test_reltime.vim @@ -8,11 +8,11 @@ func Test_reltime() let now = reltime() sleep 10m let later = reltime() - let elapsed = reltime(now) + let elapsed = now->reltime() call assert_true(reltimestr(elapsed) =~ '0\.0') - call assert_true(reltimestr(elapsed) != '0.0') + call assert_true(elapsed->reltimestr() != '0.0') call assert_true(reltimefloat(elapsed) < 0.1) - call assert_true(reltimefloat(elapsed) > 0.0) + call assert_true(elapsed->reltimefloat() > 0.0) let same = reltime(now, now) call assert_equal('0.000', split(reltimestr(same))[0][:4]) diff --git a/src/nvim/testdir/test_rename.vim b/src/nvim/testdir/test_rename.vim index 2311caf790..3887fcfabf 100644 --- a/src/nvim/testdir/test_rename.vim +++ b/src/nvim/testdir/test_rename.vim @@ -25,7 +25,7 @@ func Test_rename_file_ignore_case() set fileignorecase call writefile(['foo'], 'Xrename') - call assert_equal(0, rename('Xrename', 'XRENAME')) + call assert_equal(0, 'Xrename'->rename('XRENAME')) call assert_equal(['foo'], readfile('XRENAME')) diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim index 5ba24d047c..7570049e7c 100644 --- a/src/nvim/testdir/test_search.vim +++ b/src/nvim/testdir/test_search.vim @@ -1338,7 +1338,7 @@ func Test_search_display_pattern() call cursor(1, 1) let @/ = 'foo' - let pat = escape(@/, '()*?'. '\s\+') + let pat = @/->escape('()*?'. '\s\+') let g:a = execute(':unsilent :norm! n') call assert_match(pat, g:a) diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim index daebe25466..b140077111 100644 --- a/src/nvim/testdir/test_startup.vim +++ b/src/nvim/testdir/test_startup.vim @@ -27,8 +27,8 @@ func Test_after_comes_later() set guioptions+=M let $HOME = "/does/not/exist" set loadplugins - set rtp=Xhere,Xafter,Xanother - set packpath=Xhere,Xafter + set rtp=Xhere,Xdir/after,Xanother + set packpath=Xhere,Xdir/after set nomore let g:sequence = "" [CODE] @@ -50,8 +50,8 @@ func Test_after_comes_later() call mkdir('Xhere/pack/foo/start/foobar/plugin', 'p') call writefile(['let g:sequence .= "pack "'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim') - call mkdir('Xafter/plugin', 'p') - call writefile(['let g:sequence .= "after "'], 'Xafter/plugin/later.vim') + call mkdir('Xdir/after/plugin', 'p') + call writefile(['let g:sequence .= "after "'], 'Xdir/after/plugin/later.vim') if RunVim(before, after, '') @@ -74,7 +74,7 @@ func Test_after_comes_later() call delete('Xsequence') call delete('Xhere', 'rf') call delete('Xanother', 'rf') - call delete('Xafter', 'rf') + call delete('Xdir', 'rf') endfunc func Test_pack_in_rtp_when_plugins_run() diff --git a/src/nvim/testdir/test_stat.vim b/src/nvim/testdir/test_stat.vim index 5b7df33d2c..170358e023 100644 --- a/src/nvim/testdir/test_stat.vim +++ b/src/nvim/testdir/test_stat.vim @@ -10,7 +10,7 @@ func CheckFileTime(doSleep) let fl = ['Hello World!'] for fname in fnames call writefile(fl, fname) - call add(times, getftime(fname)) + call add(times, fname->getftime()) if a:doSleep sleep 1 endif @@ -19,8 +19,8 @@ func CheckFileTime(doSleep) let time_correct = (times[0] <= times[1] && times[1] <= times[2]) if a:doSleep || time_correct call assert_true(time_correct, printf('Expected %s <= %s <= %s', times[0], times[1], times[2])) - call assert_equal(strlen(fl[0] . "\n"), getfsize(fnames[0])) - call assert_equal('file', getftype(fnames[0])) + call assert_equal(strlen(fl[0] . "\n"), fnames[0]->getfsize()) + call assert_equal('file', fnames[0]->getftype()) call assert_equal('rw-', getfperm(fnames[0])[0:2]) let result = 1 endif diff --git a/src/nvim/testdir/test_syn_attr.vim b/src/nvim/testdir/test_syn_attr.vim index 353054fec8..fa0b08fde5 100644 --- a/src/nvim/testdir/test_syn_attr.vim +++ b/src/nvim/testdir/test_syn_attr.vim @@ -8,7 +8,7 @@ func Test_missing_attr() call assert_equal('1', synIDattr(hlID("Mine"), "inverse", 'cterm')) hi Mine cterm=standout gui=undercurl call assert_equal('1', synIDattr(hlID("Mine"), "standout", 'cterm')) - call assert_equal('1', synIDattr(hlID("Mine"), "undercurl", 'gui')) + call assert_equal('1', synIDattr("Mine"->hlID(), "undercurl", 'gui')) hi Mine gui=strikethrough call assert_equal('1', synIDattr(hlID("Mine"), "strikethrough", 'gui')) hi Mine cterm=NONE gui=NONE diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim index 0fa7f85f0d..15182893e9 100644 --- a/src/nvim/testdir/test_tagjump.vim +++ b/src/nvim/testdir/test_tagjump.vim @@ -316,7 +316,7 @@ func Test_getsettagstack() enew | only call settagstack(1, {'items' : []}) call assert_equal(0, gettagstack(1).length) - call assert_equal([], gettagstack(1).items) + call assert_equal([], 1->gettagstack().items) " Error cases call assert_equal({}, gettagstack(100)) call assert_equal(-1, settagstack(100, {'items' : []})) diff --git a/src/nvim/testdir/test_true_false.vim b/src/nvim/testdir/test_true_false.vim index 315ba188cb..f3c7fff4a6 100644 --- a/src/nvim/testdir/test_true_false.vim +++ b/src/nvim/testdir/test_true_false.vim @@ -104,7 +104,7 @@ func Test_true_false_arg() call Try_arg_true_false('maparg("asdf", "i", %v%)', "", "asdff") call Try_arg_true_false('FilterMapArg(maparg("asdf", "i", 1, %v%))', "asdff", {'rhs': 'asdff'}) - call Try_arg_true_false('hasmapto("asdf", "i", %v%)', 0, 1) + call Try_arg_true_false('"asdf"->hasmapto("i", %v%)', 0, 1) new colored call setline(1, '<here>') diff --git a/src/nvim/testdir/test_utf8.vim b/src/nvim/testdir/test_utf8.vim index 735efac36d..da72da087f 100644 --- a/src/nvim/testdir/test_utf8.vim +++ b/src/nvim/testdir/test_utf8.vim @@ -111,7 +111,7 @@ func Test_list2str_str2list_utf8() let s = "\u304b\u3099\u3044" let l = [0x304b, 0x3099, 0x3044] call assert_equal(l, str2list(s, 1)) - call assert_equal(s, list2str(l, 1)) + call assert_equal(s, l->list2str(1)) if &enc ==# 'utf-8' call assert_equal(str2list(s), str2list(s, 1)) call assert_equal(list2str(l), list2str(l, 1)) diff --git a/src/nvim/testdir/test_vimscript.vim b/src/nvim/testdir/test_vimscript.vim index b18ce563d3..34733f127f 100644 --- a/src/nvim/testdir/test_vimscript.vim +++ b/src/nvim/testdir/test_vimscript.vim @@ -635,7 +635,7 @@ function! MSG(enr, emsg) if v:errmsg == "" Xout "Message missing." else - let v:errmsg = escape(v:errmsg, '"') + let v:errmsg = v:errmsg->escape('"') Xout "Unexpected message:" v:errmsg endif endif diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h index ed76455189..2a8ea32a88 100644 --- a/src/nvim/tui/input.h +++ b/src/nvim/tui/input.h @@ -2,8 +2,8 @@ #define NVIM_TUI_INPUT_H #include <stdbool.h> - #include <termkey.h> + #include "nvim/event/stream.h" #include "nvim/event/time.h" diff --git a/src/nvim/tui/terminfo_defs.h b/src/nvim/tui/terminfo_defs.h index 8d77dc7225..40261058dc 100644 --- a/src/nvim/tui/terminfo_defs.h +++ b/src/nvim/tui/terminfo_defs.h @@ -1,6 +1,8 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +// uncrustify:off + // // Generated by scripts/update_terminfo.sh and ncurses 6.1.20180127 // diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index fb5e12c20e..fcfe862044 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -59,12 +59,12 @@ #define LINUXSET1C "\x1b[?1c" #ifdef NVIM_UNIBI_HAS_VAR_FROM -#define UNIBI_SET_NUM_VAR(var, num) \ +# define UNIBI_SET_NUM_VAR(var, num) \ do { \ (var) = unibi_var_from_num((num)); \ } while (0) #else -#define UNIBI_SET_NUM_VAR(var, num) (var).i = (num); +# define UNIBI_SET_NUM_VAR(var, num) (var).i = (num); #endif typedef struct { @@ -178,7 +178,7 @@ UI *tui_start(void) return ui_bridge_attach(ui, tui_main, tui_scheduler); } -static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index, char * buf, size_t len) +static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index, char *buf, size_t len) { const char *str = unibi_get_str(data->ut, unibi_index); if (!str) { @@ -1019,22 +1019,8 @@ static void tui_mouse_on(UI *ui) { TUIData *data = ui->data; if (!data->mouse_enabled) { -#ifdef WIN32 - // Windows versions with vtp(ENABLE_VIRTUAL_TERMINAL_PROCESSING) and - // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse tracking of - // libuv. For this reason, vtp (vterm) state of libuv is temporarily - // disabled because the control sequence needs to be processed by libuv - // instead of Windows vtp. - // ref. https://docs.microsoft.com/en-us/windows/console/setconsolemode - flush_buf(ui); - os_set_vtp(false); -#endif unibi_out_ext(ui, data->unibi_ext.enable_mouse); data->mouse_enabled = true; -#ifdef WIN32 - flush_buf(ui); - os_set_vtp(true); -#endif } } @@ -1042,22 +1028,8 @@ static void tui_mouse_off(UI *ui) { TUIData *data = ui->data; if (data->mouse_enabled) { -#ifdef WIN32 - // Windows versions with vtp(ENABLE_VIRTUAL_TERMINAL_PROCESSING) and - // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse tracking of - // libuv. For this reason, vtp (vterm) state of libuv is temporarily - // disabled because the control sequence needs to be processed by libuv - // instead of Windows vtp. - // ref. https://docs.microsoft.com/en-us/windows/console/setconsolemode - flush_buf(ui); - os_set_vtp(false); -#endif unibi_out_ext(ui, data->unibi_ext.disable_mouse); data->mouse_enabled = false; -#ifdef WIN32 - flush_buf(ui); - os_set_vtp(true); -#endif } } @@ -1483,7 +1455,7 @@ static void tui_guess_size(UI *ui) height = unibi_get_num(data->ut, unibi_lines); width = unibi_get_num(data->ut, unibi_columns); -end: + end: if (width <= 0 || height <= 0) { // use the defaults width = DFLT_COLS; @@ -1569,7 +1541,7 @@ static int unibi_find_ext_str(unibi_term *ut, const char *name) { size_t max = unibi_count_ext_str(ut); for (size_t i = 0; i < max; i++) { - const char * n = unibi_get_ext_str_name(ut, i); + const char *n = unibi_get_ext_str_name(ut, i); if (n && 0 == strcmp(n, name)) { return (int)i; } @@ -1581,7 +1553,7 @@ static int unibi_find_ext_bool(unibi_term *ut, const char *name) { size_t max = unibi_count_ext_bool(ut); for (size_t i = 0; i < max; i++) { - const char * n = unibi_get_ext_bool_name(ut, i); + const char *n = unibi_get_ext_bool_name(ut, i); if (n && 0 == strcmp(n, name)) { return (int)i; } @@ -2111,14 +2083,14 @@ static void flush_buf(UI *ui) static const char *tui_get_stty_erase(void) { static char stty_erase[2] = { 0 }; -#if defined(HAVE_TERMIOS_H) +# if defined(HAVE_TERMIOS_H) struct termios t; if (tcgetattr(input_global_fd(), &t) != -1) { stty_erase[0] = (char)t.c_cc[VERASE]; stty_erase[1] = '\0'; DLOG("stty/termios:erase=%s", stty_erase); } -#endif +# endif return stty_erase; } diff --git a/src/nvim/types.h b/src/nvim/types.h index 2dbeecbf6d..604155c33e 100644 --- a/src/nvim/types.h +++ b/src/nvim/types.h @@ -1,8 +1,8 @@ #ifndef NVIM_TYPES_H #define NVIM_TYPES_H -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> // dummy to pass an ACL to a function typedef void *vim_acl_T; diff --git a/src/nvim/ugrid.c b/src/nvim/ugrid.c index 9e4aaff878..ef84cdf334 100644 --- a/src/nvim/ugrid.c +++ b/src/nvim/ugrid.c @@ -2,14 +2,14 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <assert.h> +#include <limits.h> #include <stdbool.h> #include <stdio.h> -#include <limits.h> #include "nvim/assert.h" -#include "nvim/vim.h" -#include "nvim/ui.h" #include "nvim/ugrid.h" +#include "nvim/ui.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ugrid.c.generated.h" @@ -79,8 +79,7 @@ void ugrid_scroll(UGrid *grid, int top, int bot, int left, int right, int count) } } -static void clear_region(UGrid *grid, int top, int bot, int left, int right, - sattr_T attr) +static void clear_region(UGrid *grid, int top, int bot, int left, int right, sattr_T attr) { for (int row = top; row <= bot; row++) { UGRID_FOREACH_CELL(grid, row, left, right+1, { diff --git a/src/nvim/ugrid.h b/src/nvim/ugrid.h index 19c2e99ebb..ae11153c61 100644 --- a/src/nvim/ugrid.h +++ b/src/nvim/ugrid.h @@ -1,8 +1,8 @@ #ifndef NVIM_UGRID_H #define NVIM_UGRID_H -#include "nvim/ui.h" #include "nvim/globals.h" +#include "nvim/ui.h" typedef struct ucell UCell; typedef struct ugrid UGrid; diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 09709d0f43..aad72af025 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -3,40 +3,40 @@ #include <assert.h> #include <inttypes.h> +#include <limits.h> #include <stdbool.h> #include <string.h> -#include <limits.h> -#include "nvim/vim.h" -#include "nvim/log.h" +#include "nvim/ascii.h" #include "nvim/aucmd.h" -#include "nvim/ui.h" #include "nvim/charset.h" #include "nvim/cursor.h" +#include "nvim/cursor_shape.h" #include "nvim/diff.h" +#include "nvim/event/loop.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_getln.h" #include "nvim/fold.h" +#include "nvim/garray.h" +#include "nvim/highlight.h" +#include "nvim/log.h" #include "nvim/main.h" -#include "nvim/ascii.h" -#include "nvim/misc1.h" #include "nvim/mbyte.h" -#include "nvim/garray.h" #include "nvim/memory.h" +#include "nvim/misc1.h" #include "nvim/move.h" #include "nvim/normal.h" #include "nvim/option.h" -#include "nvim/os_unix.h" -#include "nvim/event/loop.h" -#include "nvim/os/time.h" #include "nvim/os/input.h" #include "nvim/os/signal.h" +#include "nvim/os/time.h" +#include "nvim/os_unix.h" #include "nvim/popupmnu.h" #include "nvim/screen.h" -#include "nvim/highlight.h" +#include "nvim/ui.h" #include "nvim/ui_compositor.h" +#include "nvim/vim.h" #include "nvim/window.h" -#include "nvim/cursor_shape.h" #ifdef FEAT_TUI # include "nvim/tui/tui.h" #else @@ -70,9 +70,9 @@ static int pending_has_mouse = -1; static size_t uilog_seen = 0; static char uilog_last_event[1024] = { 0 }; -#ifndef EXITFREE -#define entered_free_all_mem false -#endif +# ifndef EXITFREE +# define entered_free_all_mem false +# endif # define UI_LOG(funname) \ do { \ @@ -95,7 +95,7 @@ static char uilog_last_event[1024] = { 0 }; // UI_CALL invokes a function on all registered UI instances. // This is called by code generated by generators/gen_api_ui_events.lua // C code should use ui_call_{funname} instead. -# define UI_CALL(cond, funname, ...) \ +#define UI_CALL(cond, funname, ...) \ do { \ bool any_call = false; \ for (size_t i = 0; i < ui_count; i++) { \ @@ -115,7 +115,7 @@ static char uilog_last_event[1024] = { 0 }; #endif #ifndef EXITFREE -#undef entered_free_all_mem +# undef entered_free_all_mem #endif void ui_init(void) @@ -382,8 +382,8 @@ void ui_set_ext_option(UI *ui, UIExtension ext, bool active) } } -void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol, - int clearattr, bool wrap) +void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol, int clearattr, + bool wrap) { assert(0 <= row && row < grid->Rows); LineFlags flags = wrap ? kLineFlagWrap : 0; @@ -515,23 +515,23 @@ void ui_check_mouse(void) // normal editing mode (not at hit-return message). for (char_u *p = p_mouse; *p; p++) { switch (*p) { - case 'a': - if (vim_strchr((char_u *)MOUSE_A, checkfor) != NULL) { - has_mouse = true; - return; - } - break; - case MOUSE_HELP: - if (checkfor != MOUSE_RETURN && curbuf->b_help) { - has_mouse = true; - return; - } - break; - default: - if (checkfor == *p) { - has_mouse = true; - return; - } + case 'a': + if (vim_strchr((char_u *)MOUSE_A, checkfor) != NULL) { + has_mouse = true; + return; + } + break; + case MOUSE_HELP: + if (checkfor != MOUSE_RETURN && curbuf->b_help) { + has_mouse = true; + return; + } + break; + default: + if (checkfor == *p) { + has_mouse = true; + return; + } } } } diff --git a/src/nvim/ui.h b/src/nvim/ui.h index d00243d35f..7cc0bd9eff 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -1,12 +1,12 @@ #ifndef NVIM_UI_H #define NVIM_UI_H -#include <stddef.h> #include <stdbool.h> +#include <stddef.h> #include <stdint.h> -#include "nvim/globals.h" #include "nvim/api/private/defs.h" +#include "nvim/globals.h" #include "nvim/highlight_defs.h" typedef enum { @@ -70,6 +70,7 @@ struct ui_t { #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ui.h.generated.h" + # include "ui_events_call.h.generated.h" #endif diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index 25f45b8fe6..3402df817a 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -5,18 +5,18 @@ // Used by the built-in TUI and libnvim-based UIs. #include <assert.h> +#include <limits.h> #include <stdbool.h> #include <stdio.h> -#include <limits.h> +#include "nvim/api/private/helpers.h" #include "nvim/log.h" #include "nvim/main.h" -#include "nvim/vim.h" -#include "nvim/ui.h" #include "nvim/memory.h" -#include "nvim/ui_bridge.h" #include "nvim/ugrid.h" -#include "nvim/api/private/helpers.h" +#include "nvim/ui.h" +#include "nvim/ui_bridge.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ui_bridge.c.generated.h" @@ -26,8 +26,7 @@ // Schedule a function call on the UI bridge thread. #define UI_BRIDGE_CALL(ui, name, argc, ...) \ - ((UIBridgeData *)ui)->scheduler( \ - event_create(ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui)) + ((UIBridgeData *)ui)->scheduler(event_create(ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui)) #define INT2PTR(i) ((void *)(intptr_t)i) #define PTR2INT(p) ((Integer)(intptr_t)p) @@ -41,6 +40,8 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler) UIBridgeData *rv = xcalloc(1, sizeof(UIBridgeData)); rv->ui = ui; rv->bridge.rgb = ui->rgb; + rv->bridge.width = ui->width; + rv->bridge.height = ui->height; rv->bridge.stop = ui_bridge_stop; rv->bridge.grid_resize = ui_bridge_grid_resize; rv->bridge.grid_clear = ui_bridge_grid_clear; @@ -136,8 +137,8 @@ static void ui_bridge_stop_event(void **argv) ui->stop(ui); } -static void ui_bridge_hl_attr_define(UI *ui, Integer id, HlAttrs attrs, - HlAttrs cterm_attrs, Array info) +static void ui_bridge_hl_attr_define(UI *ui, Integer id, HlAttrs attrs, HlAttrs cterm_attrs, + Array info) { HlAttrs *a = xmalloc(sizeof(HlAttrs)); *a = attrs; @@ -161,11 +162,9 @@ static void ui_bridge_raw_line_event(void **argv) xfree(argv[8]); xfree(argv[9]); } -static void ui_bridge_raw_line(UI *ui, Integer grid, Integer row, - Integer startcol, Integer endcol, - Integer clearcol, Integer clearattr, - LineFlags flags, const schar_T *chunk, - const sattr_T *attrs) +static void ui_bridge_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Integer endcol, + Integer clearcol, Integer clearattr, LineFlags flags, + const schar_T *chunk, const sattr_T *attrs) { size_t ncol = (size_t)(endcol-startcol); schar_T *c = xmemdup(chunk, ncol * sizeof(schar_T)); diff --git a/src/nvim/ui_bridge.h b/src/nvim/ui_bridge.h index dba461550f..a62ed15621 100644 --- a/src/nvim/ui_bridge.h +++ b/src/nvim/ui_bridge.h @@ -5,11 +5,11 @@ #include <uv.h> -#include "nvim/ui.h" #include "nvim/event/defs.h" +#include "nvim/ui.h" typedef struct ui_bridge_data UIBridgeData; -typedef void(*ui_main_fn)(UIBridgeData *bridge, UI *ui); +typedef void (*ui_main_fn)(UIBridgeData *bridge, UI *ui); struct ui_bridge_data { UI bridge; // actual UI passed to ui_attach UI *ui; // UI pointer that will have its callback called in diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c index 9c9aec1cf5..d7becb4fd4 100644 --- a/src/nvim/ui_compositor.c +++ b/src/nvim/ui_compositor.c @@ -7,27 +7,27 @@ // Layer-based compositing: https://en.wikipedia.org/wiki/Digital_compositing #include <assert.h> +#include <limits.h> #include <stdbool.h> #include <stdio.h> -#include <limits.h> +#include "nvim/api/private/helpers.h" +#include "nvim/ascii.h" +#include "nvim/highlight.h" #include "nvim/lib/kvec.h" #include "nvim/log.h" +#include "nvim/lua/executor.h" #include "nvim/main.h" -#include "nvim/ascii.h" -#include "nvim/vim.h" -#include "nvim/ui.h" -#include "nvim/highlight.h" #include "nvim/memory.h" #include "nvim/message.h" +#include "nvim/os/os.h" #include "nvim/popupmnu.h" -#include "nvim/ui_compositor.h" -#include "nvim/ugrid.h" #include "nvim/screen.h" #include "nvim/syntax.h" -#include "nvim/api/private/helpers.h" -#include "nvim/lua/executor.h" -#include "nvim/os/os.h" +#include "nvim/ugrid.h" +#include "nvim/ui.h" +#include "nvim/ui_compositor.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ui_compositor.c.generated.h" @@ -89,10 +89,10 @@ void ui_comp_init(void) void ui_comp_syn_init(void) { - dbghl_normal = syn_check_group((char_u *)S_LEN("RedrawDebugNormal")); - dbghl_clear = syn_check_group((char_u *)S_LEN("RedrawDebugClear")); - dbghl_composed = syn_check_group((char_u *)S_LEN("RedrawDebugComposed")); - dbghl_recompose = syn_check_group((char_u *)S_LEN("RedrawDebugRecompose")); + dbghl_normal = syn_check_group(S_LEN("RedrawDebugNormal")); + dbghl_clear = syn_check_group(S_LEN("RedrawDebugClear")); + dbghl_composed = syn_check_group(S_LEN("RedrawDebugComposed")); + dbghl_recompose = syn_check_group(S_LEN("RedrawDebugRecompose")); } void ui_comp_attach(UI *ui) @@ -123,8 +123,8 @@ bool ui_comp_should_draw(void) /// TODO(bfredl): later on the compositor should just use win_float_pos events, /// though that will require slight event order adjustment: emit the win_pos /// events in the beginning of update_screen(0), rather than in ui_flush() -bool ui_comp_put_grid(ScreenGrid *grid, int row, int col, int height, int width, - bool valid, bool on_top) +bool ui_comp_put_grid(ScreenGrid *grid, int row, int col, int height, int width, bool valid, + bool on_top) { bool moved; @@ -257,8 +257,7 @@ static void ui_comp_raise_grid(ScreenGrid *grid, size_t new_index) } } -static void ui_comp_grid_cursor_goto(UI *ui, Integer grid_handle, - Integer r, Integer c) +static void ui_comp_grid_cursor_goto(UI *ui, Integer grid_handle, Integer r, Integer c) { if (!ui_comp_should_draw() || !ui_comp_set_grid((int)grid_handle)) { return; @@ -304,8 +303,7 @@ ScreenGrid *ui_comp_mouse_focus(int row, int col) /// Baseline implementation. This is always correct, but we can sometimes /// do something more efficient (where efficiency means smaller deltas to /// the downstream UI.) -static void compose_line(Integer row, Integer startcol, Integer endcol, - LineFlags flags) +static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlags flags) { // If rightleft is set, startcol may be -1. In such cases, the assertions // will fail because no overlap is found. Adjust startcol to prevent it. @@ -447,8 +445,8 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, (const sattr_T *)attrbuf+skipstart); } -static void compose_debug(Integer startrow, Integer endrow, Integer startcol, - Integer endcol, int syn_id, bool delay) +static void compose_debug(Integer startrow, Integer endrow, Integer startcol, Integer endcol, + int syn_id, bool delay) { if (!(rdb_flags & RDB_COMPOSITOR)) { return; @@ -479,8 +477,7 @@ static void debug_delay(Integer lines) } -static void compose_area(Integer startrow, Integer endrow, - Integer startcol, Integer endcol) +static void compose_area(Integer startrow, Integer endrow, Integer startcol, Integer endcol) { compose_debug(startrow, endrow, startcol, endcol, dbghl_recompose, true); endrow = MIN(endrow, default_grid.Rows); @@ -505,11 +502,9 @@ void ui_comp_compose_grid(ScreenGrid *grid) } } -static void ui_comp_raw_line(UI *ui, Integer grid, Integer row, - Integer startcol, Integer endcol, - Integer clearcol, Integer clearattr, - LineFlags flags, const schar_T *chunk, - const sattr_T *attrs) +static void ui_comp_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Integer endcol, + Integer clearcol, Integer clearattr, LineFlags flags, + const schar_T *chunk, const sattr_T *attrs) { if (!ui_comp_should_draw() || !ui_comp_set_grid((int)grid)) { return; @@ -529,11 +524,11 @@ static void ui_comp_raw_line(UI *ui, Integer grid, Integer row, // when resizing nvim, a window will be attempted to be drawn on the older // and possibly larger global screen size. if (row >= default_grid.Rows) { - DLOG("compositor: invalid row %"PRId64" on grid %"PRId64, row, grid); + DLOG("compositor: invalid row %" PRId64 " on grid %" PRId64, row, grid); return; } if (clearcol > default_grid.Columns) { - DLOG("compositor: invalid last column %"PRId64" on grid %"PRId64, + DLOG("compositor: invalid last column %" PRId64 " on grid %" PRId64, clearcol, grid); if (startcol >= default_grid.Columns) { return; @@ -572,8 +567,8 @@ void ui_comp_set_screen_valid(bool valid) } } -static void ui_comp_msg_set_pos(UI *ui, Integer grid, Integer row, - Boolean scrolled, String sep_char) +static void ui_comp_msg_set_pos(UI *ui, Integer grid, Integer row, Boolean scrolled, + String sep_char) { msg_grid.comp_row = (int)row; if (scrolled && row > 0) { @@ -617,9 +612,8 @@ static bool curgrid_covered_above(int row) return kv_size(layers)-(above_msg?1:0) > curgrid->comp_index+1; } -static void ui_comp_grid_scroll(UI *ui, Integer grid, Integer top, - Integer bot, Integer left, Integer right, - Integer rows, Integer cols) +static void ui_comp_grid_scroll(UI *ui, Integer grid, Integer top, Integer bot, Integer left, + Integer right, Integer rows, Integer cols) { if (!ui_comp_should_draw() || !ui_comp_set_grid((int)grid)) { return; @@ -653,8 +647,7 @@ static void ui_comp_grid_scroll(UI *ui, Integer grid, Integer top, } } -static void ui_comp_grid_resize(UI *ui, Integer grid, - Integer width, Integer height) +static void ui_comp_grid_resize(UI *ui, Integer grid, Integer width, Integer height) { if (grid == 1) { ui_composed_call_grid_resize(1, width, height); diff --git a/src/nvim/ui_compositor.h b/src/nvim/ui_compositor.h index 70e01c3a21..01538105cb 100644 --- a/src/nvim/ui_compositor.h +++ b/src/nvim/ui_compositor.h @@ -1,8 +1,8 @@ #ifndef NVIM_UI_COMPOSITOR_H #define NVIM_UI_COMPOSITOR_H -#include "nvim/ui.h" #include "nvim/event/defs.h" +#include "nvim/ui.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ui_compositor.h.generated.h" diff --git a/src/nvim/undo.c b/src/nvim/undo.c index fb96d7e6ff..5261f9e2ec 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -69,54 +69,53 @@ * All data is allocated and will all be freed when the buffer is unloaded. */ -/* Uncomment the next line for including the u_check() function. This warns - * for errors in the debug information. */ -/* #define U_DEBUG 1 */ -#define UH_MAGIC 0x18dade /* value for uh_magic when in use */ -#define UE_MAGIC 0xabc123 /* value for ue_magic when in use */ +// Uncomment the next line for including the u_check() function. This warns +// for errors in the debug information. +// #define U_DEBUG 1 +#define UH_MAGIC 0x18dade // value for uh_magic when in use +#define UE_MAGIC 0xabc123 // value for ue_magic when in use #include <assert.h> +#include <fcntl.h> #include <inttypes.h> #include <limits.h> #include <stdbool.h> #include <string.h> -#include <fcntl.h> #include "auto/config.h" - -#include "nvim/buffer.h" #include "nvim/ascii.h" +#include "nvim/buffer.h" +#include "nvim/buffer_updates.h" #include "nvim/change.h" -#include "nvim/undo.h" #include "nvim/cursor.h" #include "nvim/edit.h" +#include "nvim/extmark.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/buffer_updates.h" -#include "nvim/pos.h" // MAXLNUM +#include "nvim/garray.h" +#include "nvim/lib/kvec.h" #include "nvim/mark.h" -#include "nvim/extmark.h" #include "nvim/memline.h" +#include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/memory.h" -#include "nvim/garray.h" #include "nvim/option.h" +#include "nvim/os/os.h" +#include "nvim/os/time.h" #include "nvim/os_unix.h" #include "nvim/path.h" +#include "nvim/pos.h" // MAXLNUM #include "nvim/sha256.h" #include "nvim/state.h" #include "nvim/strings.h" #include "nvim/types.h" -#include "nvim/os/os.h" -#include "nvim/os/time.h" -#include "nvim/lib/kvec.h" +#include "nvim/undo.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "undo.c.generated.h" #endif -/* used in undo_end() to report number of added and deleted lines */ +// used in undo_end() to report number of added and deleted lines static long u_newcount, u_oldcount; /* @@ -136,13 +135,12 @@ static int seen_b_u_curhead; static int seen_b_u_newhead; static int header_count; -static void u_check_tree(u_header_T *uhp, - u_header_T *exp_uh_next, - u_header_T *exp_uh_alt_prev) { +static void u_check_tree(u_header_T *uhp, u_header_T *exp_uh_next, u_header_T *exp_uh_alt_prev) { u_entry_T *uep; - if (uhp == NULL) + if (uhp == NULL) { return; + } ++header_count; if (uhp == curbuf->b_u_curhead && ++seen_b_u_curhead > 1) { EMSG("b_u_curhead found twice (looping?)"); @@ -153,22 +151,22 @@ static void u_check_tree(u_header_T *uhp, return; } - if (uhp->uh_magic != UH_MAGIC) + if (uhp->uh_magic != UH_MAGIC) { EMSG("uh_magic wrong (may be using freed memory)"); - else { - /* Check pointers back are correct. */ + } else { + // Check pointers back are correct. if (uhp->uh_next.ptr != exp_uh_next) { EMSG("uh_next wrong"); smsg("expected: 0x%x, actual: 0x%x", - exp_uh_next, uhp->uh_next.ptr); + exp_uh_next, uhp->uh_next.ptr); } if (uhp->uh_alt_prev.ptr != exp_uh_alt_prev) { EMSG("uh_alt_prev wrong"); smsg("expected: 0x%x, actual: 0x%x", - exp_uh_alt_prev, uhp->uh_alt_prev.ptr); + exp_uh_alt_prev, uhp->uh_alt_prev.ptr); } - /* Check the undo tree at this header. */ + // Check the undo tree at this header. for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next) { if (uep->ue_magic != UE_MAGIC) { EMSG("ue_magic wrong (may be using freed memory)"); @@ -176,10 +174,10 @@ static void u_check_tree(u_header_T *uhp, } } - /* Check the next alt tree. */ + // Check the next alt tree. u_check_tree(uhp->uh_alt_next.ptr, uhp->uh_next.ptr, uhp); - /* Check the next header in this branch. */ + // Check the next header in this branch. u_check_tree(uhp->uh_prev.ptr, uhp, NULL); } } @@ -192,14 +190,16 @@ static void u_check(int newhead_may_be_NULL) { u_check_tree(curbuf->b_u_oldhead, NULL, NULL); if (seen_b_u_newhead == 0 && curbuf->b_u_oldhead != NULL - && !(newhead_may_be_NULL && curbuf->b_u_newhead == NULL)) + && !(newhead_may_be_NULL && curbuf->b_u_newhead == NULL)) { EMSGN("b_u_newhead invalid: 0x%x", curbuf->b_u_newhead); - if (curbuf->b_u_curhead != NULL && seen_b_u_curhead == 0) + } + if (curbuf->b_u_curhead != NULL && seen_b_u_curhead == 0) { EMSGN("b_u_curhead invalid: 0x%x", curbuf->b_u_curhead); + } if (header_count != curbuf->b_u_numhead) { EMSG("b_u_numhead invalid"); smsg("expected: %" PRId64 ", actual: %" PRId64, - (int64_t)header_count, (int64_t)curbuf->b_u_numhead); + (int64_t)header_count, (int64_t)curbuf->b_u_numhead); } } @@ -228,11 +228,12 @@ int u_save_cursor(void) int u_save(linenr_T top, linenr_T bot) { if (top >= bot || bot > (curbuf->b_ml.ml_line_count + 1)) { - return FAIL; /* rely on caller to do error messages */ + return FAIL; // rely on caller to do error messages } - if (top + 2 == bot) + if (top + 2 == bot) { u_saveline((linenr_T)(top + 1)); + } return u_savecommon(curbuf, top, bot, (linenr_T)0, false); } @@ -268,9 +269,8 @@ int u_inssub(linenr_T lnum) */ int u_savedel(linenr_T lnum, long nlines) { - return u_savecommon( - curbuf, lnum - 1, lnum + nlines, - nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, false); + return u_savecommon(curbuf, lnum - 1, lnum + nlines, + nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, false); } /// Return true when undo is allowed. Otherwise print an error message and @@ -291,8 +291,8 @@ bool undo_allowed(buf_T *buf) return false; } - /* Don't allow changes in the buffer while editing the cmdline. The - * caller of getcmdline() may get confused. */ + // Don't allow changes in the buffer while editing the cmdline. The + // caller of getcmdline() may get confused. if (textlock != 0) { EMSG(_(e_secure)); return false; @@ -327,16 +327,14 @@ static inline void zero_fmark_additional_data(fmark_T *fmarks) * Careful: may trigger autocommands that reload the buffer. * Returns FAIL when lines could not be saved, OK otherwise. */ -int u_savecommon(buf_T *buf, - linenr_T top, linenr_T bot, - linenr_T newbot, int reload) +int u_savecommon(buf_T *buf, linenr_T top, linenr_T bot, linenr_T newbot, int reload) { linenr_T lnum; long i; - u_header_T *uhp; - u_header_T *old_curhead; - u_entry_T *uep; - u_entry_T *prev_uep; + u_header_T *uhp; + u_header_T *old_curhead; + u_entry_T *uep; + u_entry_T *prev_uep; long size; if (!reload) { @@ -381,8 +379,9 @@ int u_savecommon(buf_T *buf, #ifdef U_DEBUG uhp->uh_magic = UH_MAGIC; #endif - } else + } else { uhp = NULL; + } /* * If we undid more than we redid, move the entry lists before and @@ -399,7 +398,7 @@ int u_savecommon(buf_T *buf, */ while (buf->b_u_numhead > get_undolevel(buf) && buf->b_u_oldhead != NULL) { - u_header_T *uhfree = buf->b_u_oldhead; + u_header_T *uhfree = buf->b_u_oldhead; if (uhfree == old_curhead) { // Can't reconnect the branch, delete all of it. @@ -459,11 +458,12 @@ int u_savecommon(buf_T *buf, uhp->uh_walk = 0; uhp->uh_entry = NULL; uhp->uh_getbot_entry = NULL; - uhp->uh_cursor = curwin->w_cursor; /* save cursor pos. for undo */ - if (virtual_active() && curwin->w_cursor.coladd > 0) + uhp->uh_cursor = curwin->w_cursor; // save cursor pos. for undo + if (virtual_active() && curwin->w_cursor.coladd > 0) { uhp->uh_cursor_vcol = getviscol(); - else + } else { uhp->uh_cursor_vcol = -1; + } // save changed and buffer empty flag for undo uhp->uh_flags = (buf->b_changed ? UH_CHANGED : 0) + @@ -499,8 +499,9 @@ int u_savecommon(buf_T *buf, uep = u_get_headentry(buf); prev_uep = NULL; for (i = 0; i < 10; ++i) { - if (uep == NULL) + if (uep == NULL) { break; + } /* If lines have been inserted/deleted we give up. * Also when the line was included in a multi-line save. */ @@ -509,14 +510,14 @@ int u_savecommon(buf_T *buf, != (uep->ue_bot == 0 ? buf->b_ml.ml_line_count + 1 : uep->ue_bot)) - : uep->ue_lcount != buf->b_ml.ml_line_count) + : uep->ue_lcount != buf->b_ml.ml_line_count) || (uep->ue_size > 1 && top >= uep->ue_top && top + 2 <= uep->ue_top + uep->ue_size + 1)) { break; } - /* If it's the same line we can skip saving it again. */ + // If it's the same line we can skip saving it again. if (uep->ue_size == 1 && uep->ue_top == top) { if (i > 0) { /* It's not the last entry: get ue_bot for the last @@ -609,25 +610,25 @@ int u_savecommon(buf_T *buf, // magic at start of undofile -# define UF_START_MAGIC "Vim\237UnDo\345" -# define UF_START_MAGIC_LEN 9 +#define UF_START_MAGIC "Vim\237UnDo\345" +#define UF_START_MAGIC_LEN 9 // magic at start of header -# define UF_HEADER_MAGIC 0x5fd0 +#define UF_HEADER_MAGIC 0x5fd0 // magic after last header -# define UF_HEADER_END_MAGIC 0xe7aa +#define UF_HEADER_END_MAGIC 0xe7aa // magic at start of entry -# define UF_ENTRY_MAGIC 0xf518 +#define UF_ENTRY_MAGIC 0xf518 // magic after last entry -# define UF_ENTRY_END_MAGIC 0x3581 +#define UF_ENTRY_END_MAGIC 0x3581 // 2-byte undofile version number -# define UF_VERSION 3 +#define UF_VERSION 3 -/* extra fields for header */ -# define UF_LAST_SAVE_NR 1 +// extra fields for header +#define UF_LAST_SAVE_NR 1 -/* extra fields for uhp */ -# define UHP_SAVE_NR 1 +// extra fields for uhp +#define UHP_SAVE_NR 1 static char_u e_not_open[] = N_("E828: Cannot open undo file for writing: %s"); @@ -640,7 +641,7 @@ void u_compute_hash(buf_T *buf, char_u *hash) { context_sha256_T ctx; linenr_T lnum; - char_u *p; + char_u *p; sha256_start(&ctx); for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) { @@ -688,7 +689,7 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading) // Loop over 'undodir'. When reading find the first file that exists. // When not reading use the first directory that exists or ".". - dirp = (char *) p_udir; + dirp = (char *)p_udir; while (*dirp != NUL) { size_t dir_len = copy_option_part((char_u **)&dirp, (char_u *)dir_name, MAXPATHL, ","); @@ -698,7 +699,7 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading) const size_t ffname_len = strlen(ffname); undo_file_name = xmalloc(ffname_len + 6); memmove(undo_file_name, ffname, ffname_len + 1); - char *const tail = (char *) path_tail((char_u *) undo_file_name); + char *const tail = (char *)path_tail((char_u *)undo_file_name); const size_t tail_len = strlen(tail); memmove(tail + 1, tail, tail_len + 1); *tail = '.'; @@ -754,8 +755,7 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading) /// /// @param[in] mesg Identifier of the corruption kind. /// @param[in] file_name File in which error occurred. -static void corruption_error(const char *const mesg, - const char *const file_name) +static void corruption_error(const char *const mesg, const char *const file_name) FUNC_ATTR_NONNULL_ALL { EMSG3(_("E825: Corrupted undo file (%s): %s"), mesg, file_name); @@ -763,8 +763,8 @@ static void corruption_error(const char *const mesg, static void u_free_uhp(u_header_T *uhp) { - u_entry_T *nuep; - u_entry_T *uep; + u_entry_T *nuep; + u_entry_T *uep; uep = uhp->uh_entry; while (uep != NULL) { @@ -890,8 +890,7 @@ static bool serialize_uhp(bufinfo_T *bi, u_header_T *uhp) return true; } -static u_header_T *unserialize_uhp(bufinfo_T *bi, - const char *file_name) +static u_header_T *unserialize_uhp(bufinfo_T *bi, const char *file_name) { u_header_T *uhp = xmalloc(sizeof(u_header_T)); memset(uhp, 0, sizeof(u_header_T)); @@ -999,7 +998,7 @@ static bool serialize_extmark(bufinfo_T *bi, ExtmarkUndoObject extup) undo_write_bytes(bi, (uintmax_t)extup.type, 4); if (!undo_write(bi, (uint8_t *)&(extup.data.splice), sizeof(ExtmarkSplice))) { - return false; + return false; } } else if (extup.type == kExtmarkMove) { undo_write_bytes(bi, (uintmax_t)UF_ENTRY_MAGIC, 2); @@ -1013,8 +1012,7 @@ static bool serialize_extmark(bufinfo_T *bi, ExtmarkUndoObject extup) return true; } -static ExtmarkUndoObject *unserialize_extmark(bufinfo_T *bi, bool *error, - const char *filename) +static ExtmarkUndoObject *unserialize_extmark(bufinfo_T *bi, bool *error, const char *filename) { UndoObjectType type; uint8_t *buf = NULL; @@ -1039,7 +1037,7 @@ static ExtmarkUndoObject *unserialize_extmark(bufinfo_T *bi, bool *error, } extup->data.move = *(ExtmarkMove *)buf; } else { - goto error; + goto error; } xfree(buf); @@ -1080,8 +1078,7 @@ static bool serialize_uep(bufinfo_T *bi, u_entry_T *uep) return true; } -static u_entry_T *unserialize_uep(bufinfo_T * bi, bool *error, - const char *file_name) +static u_entry_T *unserialize_uep(bufinfo_T *bi, bool *error, const char *file_name) { u_entry_T *uep = xmalloc(sizeof(u_entry_T)); memset(uep, 0, sizeof(u_entry_T)); @@ -1171,24 +1168,23 @@ static void unserialize_visualinfo(bufinfo_T *bi, visualinfo_T *info) /// @param[in] buf Buffer for which undo file is written. /// @param[in] hash Hash value of the buffer text. Must have #UNDO_HASH_SIZE /// size. -void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, - char_u *const hash) +void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, char_u *const hash) FUNC_ATTR_NONNULL_ARG(3, 4) { - u_header_T *uhp; + u_header_T *uhp; char *file_name; int mark; #ifdef U_DEBUG int headers_written = 0; #endif int fd; - FILE *fp = NULL; + FILE *fp = NULL; int perm; bool write_ok = false; bufinfo_T bi; if (name == NULL) { - file_name = u_get_undo_file_name((char *) buf->b_ffname, false); + file_name = u_get_undo_file_name((char *)buf->b_ffname, false); if (file_name == NULL) { if (p_verbose > 0) { verbose_enter(); @@ -1198,7 +1194,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, return; } } else { - file_name = (char *) name; + file_name = (char *)name; } /* @@ -1221,16 +1217,18 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, * file, and delete it. */ if (os_path_exists((char_u *)file_name)) { if (name == NULL || !forceit) { - /* Check we can read it and it's an undo file. */ + // Check we can read it and it's an undo file. fd = os_open(file_name, O_RDONLY, 0); if (fd < 0) { if (name != NULL || p_verbose > 0) { - if (name == NULL) + if (name == NULL) { verbose_enter(); + } smsg(_("Will not overwrite with undo file, cannot read: %s"), file_name); - if (name == NULL) + if (name == NULL) { verbose_leave(); + } } goto theend; } else { @@ -1240,12 +1238,14 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, if (len < UF_START_MAGIC_LEN || memcmp(mbuf, UF_START_MAGIC, UF_START_MAGIC_LEN) != 0) { if (name != NULL || p_verbose > 0) { - if (name == NULL) + if (name == NULL) { verbose_enter(); + } smsg(_("Will not overwrite, this is not an undo file: %s"), file_name); - if (name == NULL) + if (name == NULL) { verbose_leave(); + } } goto theend; } @@ -1276,7 +1276,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, } #ifdef U_DEBUG - /* Check there is no problem in undo info before writing. */ + // Check there is no problem in undo info before writing. u_check(FALSE); #endif @@ -1323,7 +1323,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, mark = ++lastmark; uhp = buf->b_u_oldhead; while (uhp != NULL) { - /* Serialize current UHP if we haven't seen it */ + // Serialize current UHP if we haven't seen it if (uhp->uh_walk != mark) { uhp->uh_walk = mark; #ifdef U_DEBUG @@ -1334,19 +1334,20 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, } } - /* Now walk through the tree - algorithm from undo_time(). */ - if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != mark) + // Now walk through the tree - algorithm from undo_time(). + if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != mark) { uhp = uhp->uh_prev.ptr; - else if (uhp->uh_alt_next.ptr != NULL - && uhp->uh_alt_next.ptr->uh_walk != mark) + } else if (uhp->uh_alt_next.ptr != NULL + && uhp->uh_alt_next.ptr->uh_walk != mark) { uhp = uhp->uh_alt_next.ptr; - else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL - && uhp->uh_next.ptr->uh_walk != mark) + } else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL + && uhp->uh_next.ptr->uh_walk != mark) { uhp = uhp->uh_next.ptr; - else if (uhp->uh_alt_prev.ptr != NULL) + } else if (uhp->uh_alt_prev.ptr != NULL) { uhp = uhp->uh_alt_prev.ptr; - else + } else { uhp = uhp->uh_next.ptr; + } } if (undo_write_bytes(&bi, (uintmax_t)UF_HEADER_END_MAGIC, 2)) { @@ -1361,14 +1362,15 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, write_error: fclose(fp); - if (!write_ok) + if (!write_ok) { EMSG2(_("E829: write error in undo file: %s"), file_name); + } #ifdef HAVE_ACL if (buf->b_ffname != NULL) { vim_acl_T acl; - /* For systems that support ACL: get the ACL from the original file. */ + // For systems that support ACL: get the ACL from the original file. acl = mch_get_acl(buf->b_ffname); mch_set_acl((char_u *)file_name, acl); mch_free_acl(acl); @@ -1376,8 +1378,9 @@ write_error: #endif theend: - if (file_name != name) + if (file_name != name) { xfree(file_name); + } } /// Loads the undo tree from an undo file. @@ -1385,8 +1388,7 @@ theend: /// a bit more verbose. /// Otherwise use curbuf->b_ffname to generate the undo file name. /// "hash[UNDO_HASH_SIZE]" must be the hash value of the buffer text. -void u_read_undo(char *name, const char_u *hash, - const char_u *orig_name FUNC_ATTR_UNUSED) +void u_read_undo(char *name, const char_u *hash, const char_u *orig_name FUNC_ATTR_UNUSED) FUNC_ATTR_NONNULL_ARG(2) { u_header_T **uhp_table = NULL; @@ -1394,7 +1396,7 @@ void u_read_undo(char *name, const char_u *hash, char *file_name; if (name == NULL) { - file_name = u_get_undo_file_name((char *) curbuf->b_ffname, true); + file_name = u_get_undo_file_name((char *)curbuf->b_ffname, true); if (file_name == NULL) { return; } @@ -1405,7 +1407,7 @@ void u_read_undo(char *name, const char_u *hash, FileInfo file_info_orig; FileInfo file_info_undo; if (os_fileinfo((const char *)orig_name, &file_info_orig) - && os_fileinfo((char *)file_name, &file_info_undo) + && os_fileinfo(file_name, &file_info_undo) && file_info_orig.stat.st_uid != file_info_undo.stat.st_uid && file_info_undo.stat.st_uid != getuid()) { if (p_verbose > 0) { @@ -1418,7 +1420,7 @@ void u_read_undo(char *name, const char_u *hash, } #endif } else { - file_name = (char *) name; + file_name = name; } if (p_verbose > 0) { @@ -1465,7 +1467,7 @@ void u_read_undo(char *name, const char_u *hash, verbose_enter(); } give_warning((char_u *) - _("File contents changed, cannot use undo info"), true); + _("File contents changed, cannot use undo info"), true); if (name == NULL) { verbose_leave(); } @@ -1508,15 +1510,15 @@ void u_read_undo(char *name, const char_u *hash, } int what = undo_read_byte(&bi); switch (what) { - case UF_LAST_SAVE_NR: - last_save_nr = undo_read_4c(&bi); - break; + case UF_LAST_SAVE_NR: + last_save_nr = undo_read_4c(&bi); + break; - default: - // field not supported, skip - while (--len >= 0) { - (void)undo_read_byte(&bi); - } + default: + // field not supported, skip + while (--len >= 0) { + (void)undo_read_byte(&bi); + } } } @@ -1559,7 +1561,7 @@ void u_read_undo(char *name, const char_u *hash, size_t amount = num_head * sizeof(int) + 1; int *uhp_table_used = xmalloc(amount); memset(uhp_table_used, 0, amount); -# define SET_FLAG(j) ++ uhp_table_used[j] +# define SET_FLAG(j) ++uhp_table_used[j] #else # define SET_FLAG(j) #endif @@ -1666,10 +1668,11 @@ void u_read_undo(char *name, const char_u *hash, error: xfree(line_ptr); if (uhp_table != NULL) { - for (long i = 0; i < num_read_uhps; i++) + for (long i = 0; i < num_read_uhps; i++) { if (uhp_table[i] != NULL) { u_free_uhp(uhp_table[i]); } + } xfree(uhp_table); } @@ -1844,7 +1847,7 @@ bool u_undo_and_forget(int count) to_forget->uh_alt_next.ptr = NULL; curbuf->b_u_curhead->uh_alt_prev.ptr = to_forget->uh_alt_prev.ptr; curbuf->b_u_seq_cur = curbuf->b_u_curhead->uh_next.ptr ? - curbuf->b_u_curhead->uh_next.ptr->uh_seq : 0; + curbuf->b_u_curhead->uh_next.ptr->uh_seq : 0; } else if (curbuf->b_u_newhead) { curbuf->b_u_seq_cur = curbuf->b_u_newhead->uh_seq; } @@ -1876,8 +1879,9 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event) u_newcount = 0; u_oldcount = 0; - if (curbuf->b_ml.ml_flags & ML_EMPTY) + if (curbuf->b_ml.ml_flags & ML_EMPTY) { u_oldcount = -1; + } while (count--) { /* Do the change warning now, so that it triggers FileChangedRO when * needed. This may cause the file to be reloaded, that must happen @@ -1894,7 +1898,7 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event) } // nothing to undo if (curbuf->b_u_numhead == 0 || curbuf->b_u_curhead == NULL) { - /* stick curbuf->b_u_curhead at end */ + // stick curbuf->b_u_curhead at end curbuf->b_u_curhead = curbuf->b_u_oldhead; beep_flush(); if (count == startcount - 1) { @@ -1917,10 +1921,11 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event) u_undoredo(false, do_buf_event); - /* Advance for next redo. Set "newhead" when at the end of the - * redoable changes. */ - if (curbuf->b_u_curhead->uh_prev.ptr == NULL) + // Advance for next redo. Set "newhead" when at the end of the + // redoable changes. + if (curbuf->b_u_curhead->uh_prev.ptr == NULL) { curbuf->b_u_newhead = curbuf->b_u_curhead; + } curbuf->b_u_curhead = curbuf->b_u_curhead->uh_prev.ptr; } } @@ -1941,8 +1946,8 @@ void undo_time(long step, bool sec, bool file, bool absolute) long closest_start; long closest_seq = 0; long val; - u_header_T *uhp = NULL; - u_header_T *last; + u_header_T *uhp = NULL; + u_header_T *last; int mark; int nomark = 0; // shut up compiler int round; @@ -1958,11 +1963,12 @@ void undo_time(long step, bool sec, bool file, bool absolute) u_newcount = 0; u_oldcount = 0; - if (curbuf->b_ml.ml_flags & ML_EMPTY) + if (curbuf->b_ml.ml_flags & ML_EMPTY) { u_oldcount = -1; + } - /* "target" is the node below which we want to be. - * Init "closest" to a value we can't reach. */ + // "target" is the node below which we want to be. + // Init "closest" to a value we can't reach. if (absolute) { target = step; closest = -1; @@ -1971,40 +1977,45 @@ void undo_time(long step, bool sec, bool file, bool absolute) target = (long)(curbuf->b_u_time_cur) + step; } else if (dofile) { if (step < 0) { - /* Going back to a previous write. If there were changes after - * the last write, count that as moving one file-write, so - * that ":earlier 1f" undoes all changes since the last save. */ + // Going back to a previous write. If there were changes after + // the last write, count that as moving one file-write, so + // that ":earlier 1f" undoes all changes since the last save. uhp = curbuf->b_u_curhead; - if (uhp != NULL) + if (uhp != NULL) { uhp = uhp->uh_next.ptr; - else + } else { uhp = curbuf->b_u_newhead; - if (uhp != NULL && uhp->uh_save_nr != 0) + } + if (uhp != NULL && uhp->uh_save_nr != 0) { /* "uh_save_nr" was set in the last block, that means * there were no changes since the last write */ target = curbuf->b_u_save_nr_cur + step; - else - /* count the changes since the last write as one step */ + } else { + // count the changes since the last write as one step target = curbuf->b_u_save_nr_cur + step + 1; - if (target <= 0) + } + if (target <= 0) { /* Go to before first write: before the oldest change. Use * the sequence number for that. */ dofile = false; + } } else { - /* Moving forward to a newer write. */ + // Moving forward to a newer write. target = curbuf->b_u_save_nr_cur + step; if (target > curbuf->b_u_save_nr_last) { - /* Go to after last write: after the latest change. Use - * the sequence number for that. */ + // Go to after last write: after the latest change. Use + // the sequence number for that. target = curbuf->b_u_seq_last + 1; dofile = false; } } - } else + } else { target = curbuf->b_u_seq_cur + step; + } if (step < 0) { - if (target < 0) + if (target < 0) { target = 0; + } closest = -1; } else { if (dosec) { @@ -2044,10 +2055,11 @@ void undo_time(long step, bool sec, bool file, bool absolute) mark = ++lastmark; nomark = ++lastmark; - if (curbuf->b_u_curhead == NULL) /* at leaf of the tree */ + if (curbuf->b_u_curhead == NULL) { // at leaf of the tree uhp = curbuf->b_u_newhead; - else + } else { uhp = curbuf->b_u_curhead; + } while (uhp != NULL) { uhp->uh_walk = mark; @@ -2060,22 +2072,22 @@ void undo_time(long step, bool sec, bool file, bool absolute) } if (round == 1 && !(dofile && val == 0)) { - /* Remember the header that is closest to the target. - * It must be at least in the right direction (checked with - * "b_u_seq_cur"). When the timestamp is equal find the - * highest/lowest sequence number. */ + // Remember the header that is closest to the target. + // It must be at least in the right direction (checked with + // "b_u_seq_cur"). When the timestamp is equal find the + // highest/lowest sequence number. if ((step < 0 ? uhp->uh_seq <= curbuf->b_u_seq_cur - : uhp->uh_seq > curbuf->b_u_seq_cur) + : uhp->uh_seq > curbuf->b_u_seq_cur) && ((dosec && val == closest) ? (step < 0 ? uhp->uh_seq < closest_seq - : uhp->uh_seq > closest_seq) - : closest == closest_start + : uhp->uh_seq > closest_seq) + : closest == closest_start || (val > target ? (closest > target ? val - target <= closest - target : val - target <= target - closest) - : (closest > target + : (closest > target ? target - val <= closest - target : target - val <= target - closest)))) { closest = val; @@ -2083,45 +2095,47 @@ void undo_time(long step, bool sec, bool file, bool absolute) } } - /* Quit searching when we found a match. But when searching for a - * time we need to continue looking for the best uh_seq. */ + // Quit searching when we found a match. But when searching for a + // time we need to continue looking for the best uh_seq. if (target == val && !dosec) { target = uhp->uh_seq; break; } - /* go down in the tree if we haven't been there */ + // go down in the tree if we haven't been there if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != nomark - && uhp->uh_prev.ptr->uh_walk != mark) + && uhp->uh_prev.ptr->uh_walk != mark) { uhp = uhp->uh_prev.ptr; - - /* go to alternate branch if we haven't been there */ + } + // go to alternate branch if we haven't been there else if (uhp->uh_alt_next.ptr != NULL && uhp->uh_alt_next.ptr->uh_walk != nomark - && uhp->uh_alt_next.ptr->uh_walk != mark) + && uhp->uh_alt_next.ptr->uh_walk != mark) { uhp = uhp->uh_alt_next.ptr; - - /* go up in the tree if we haven't been there and we are at the - * start of alternate branches */ - else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL - && uhp->uh_next.ptr->uh_walk != nomark - && uhp->uh_next.ptr->uh_walk != mark) { - /* If still at the start we don't go through this change. */ - if (uhp == curbuf->b_u_curhead) + } else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL + // go up in the tree if we haven't been there and we are at the + // start of alternate branches + && uhp->uh_next.ptr->uh_walk != nomark + && uhp->uh_next.ptr->uh_walk != mark) { + // If still at the start we don't go through this change. + if (uhp == curbuf->b_u_curhead) { uhp->uh_walk = nomark; + } uhp = uhp->uh_next.ptr; } else { - /* need to backtrack; mark this node as useless */ + // need to backtrack; mark this node as useless uhp->uh_walk = nomark; - if (uhp->uh_alt_prev.ptr != NULL) + if (uhp->uh_alt_prev.ptr != NULL) { uhp = uhp->uh_alt_prev.ptr; - else + } else { uhp = uhp->uh_next.ptr; + } } } - if (uhp != NULL) /* found it */ + if (uhp != NULL) { // found it break; + } if (absolute) { EMSGN(_("E830: Undo number %" PRId64 " not found"), step); @@ -2129,10 +2143,11 @@ void undo_time(long step, bool sec, bool file, bool absolute) } if (closest == closest_start) { - if (step < 0) + if (step < 0) { MSG(_("Already at oldest change")); - else + } else { MSG(_("Already at newest change")); + } return; } @@ -2153,10 +2168,11 @@ target_zero: change_warning(curbuf, 0); uhp = curbuf->b_u_curhead; - if (uhp == NULL) + if (uhp == NULL) { uhp = curbuf->b_u_newhead; - else + } else { uhp = uhp->uh_next.ptr; + } if (uhp == NULL || (target > 0 && uhp->uh_walk != mark) || (uhp->uh_seq == target && !above)) { @@ -2264,24 +2280,24 @@ target_zero: /// @param do_buf_event If `true`, send buffer updates. static void u_undoredo(int undo, bool do_buf_event) { - char_u **newarray = NULL; + char_u **newarray = NULL; linenr_T oldsize; linenr_T newsize; linenr_T top, bot; linenr_T lnum; linenr_T newlnum = MAXLNUM; long i; - u_entry_T *uep, *nuep; - u_entry_T *newlist = NULL; + u_entry_T *uep, *nuep; + u_entry_T *newlist = NULL; int old_flags; int new_flags; fmark_T namedm[NMARKS]; visualinfo_T visualinfo; bool empty_buffer; // buffer became empty - u_header_T *curhead = curbuf->b_u_curhead; + u_header_T *curhead = curbuf->b_u_curhead; - /* Don't want autocommands using the undo structures here, they are - * invalid till the end. */ + // Don't want autocommands using the undo structures here, they are + // invalid till the end. block_autocmds(); #ifdef U_DEBUG @@ -2307,8 +2323,9 @@ static void u_undoredo(int undo, bool do_buf_event) for (uep = curhead->uh_entry; uep != NULL; uep = nuep) { top = uep->ue_top; bot = uep->ue_bot; - if (bot == 0) + if (bot == 0) { bot = curbuf->b_ml.ml_line_count + 1; + } if (top > curbuf->b_ml.ml_line_count || top >= bot || bot > curbuf->b_ml.ml_line_count + 1) { unblock_autocmds(); @@ -2317,8 +2334,8 @@ static void u_undoredo(int undo, bool do_buf_event) return; } - oldsize = bot - top - 1; /* number of lines before undo */ - newsize = uep->ue_size; /* number of lines after undo */ + oldsize = bot - top - 1; // number of lines before undo + newsize = uep->ue_size; // number of lines after undo if (top < newlnum) { /* If the saved cursor is somewhere in this undo block, move it to @@ -2332,13 +2349,15 @@ static void u_undoredo(int undo, bool do_buf_event) /* Use the first line that actually changed. Avoids that * undoing auto-formatting puts the cursor in the previous * line. */ - for (i = 0; i < newsize && i < oldsize; ++i) - if (STRCMP(uep->ue_array[i], ml_get(top + 1 + i)) != 0) + for (i = 0; i < newsize && i < oldsize; ++i) { + if (STRCMP(uep->ue_array[i], ml_get(top + 1 + i)) != 0) { break; + } + } if (i == newsize && newlnum == MAXLNUM && uep->ue_next == NULL) { newlnum = top; curwin->w_cursor.lnum = newlnum + 1; - } else if (i < newsize) { + } else if (i < newsize) { newlnum = top + i; curwin->w_cursor.lnum = newlnum + 1; } @@ -2347,12 +2366,12 @@ static void u_undoredo(int undo, bool do_buf_event) empty_buffer = false; - /* delete the lines between top and bot and save them in newarray */ + // delete the lines between top and bot and save them in newarray if (oldsize > 0) { newarray = xmalloc(sizeof(char_u *) * (size_t)oldsize); - /* delete backwards, it goes faster in most cases */ + // delete backwards, it goes faster in most cases for (lnum = bot - 1, i = oldsize; --i >= 0; --lnum) { - /* what can we do when we run out of memory? */ + // what can we do when we run out of memory? newarray[i] = u_save_line(lnum); /* remember we deleted the last line in the buffer, and a * dummy empty line will be inserted */ @@ -2361,10 +2380,11 @@ static void u_undoredo(int undo, bool do_buf_event) } ml_delete(lnum, false); } - } else + } else { newarray = NULL; + } - /* insert the lines in u_array between top and bot */ + // insert the lines in u_array between top and bot if (newsize) { for (lnum = top, i = 0; i < newsize; ++i, ++lnum) { /* @@ -2395,13 +2415,15 @@ static void u_undoredo(int undo, bool do_buf_event) changed_lines(top + 1, 0, bot, newsize - oldsize, do_buf_event); - /* set '[ and '] mark */ - if (top + 1 < curbuf->b_op_start.lnum) + // set '[ and '] mark + if (top + 1 < curbuf->b_op_start.lnum) { curbuf->b_op_start.lnum = top + 1; - if (newsize == 0 && top + 1 > curbuf->b_op_end.lnum) + } + if (newsize == 0 && top + 1 > curbuf->b_op_end.lnum) { curbuf->b_op_end.lnum = top + 1; - else if (top + newsize > curbuf->b_op_end.lnum) + } else if (top + newsize > curbuf->b_op_end.lnum) { curbuf->b_op_end.lnum = top + newsize; + } u_newcount += newsize; u_oldcount += oldsize; @@ -2424,7 +2446,7 @@ static void u_undoredo(int undo, bool do_buf_event) undo_info = kv_A(curhead->uh_extmark, i); extmark_apply_undo(undo_info, undo); } - // redo + // redo } else { for (i = 0; i < (int)kv_size(curhead->uh_extmark); i++) { undo_info = kv_A(curhead->uh_extmark, i); @@ -2482,17 +2504,20 @@ static void u_undoredo(int undo, bool do_buf_event) * Otherwise the cursor should go to the first undone line. */ if (curhead->uh_cursor.lnum + 1 == curwin->w_cursor.lnum - && curwin->w_cursor.lnum > 1) + && curwin->w_cursor.lnum > 1) { --curwin->w_cursor.lnum; + } if (curwin->w_cursor.lnum <= curbuf->b_ml.ml_line_count) { if (curhead->uh_cursor.lnum == curwin->w_cursor.lnum) { curwin->w_cursor.col = curhead->uh_cursor.col; - if (virtual_active() && curhead->uh_cursor_vcol >= 0) + if (virtual_active() && curhead->uh_cursor_vcol >= 0) { coladvance((colnr_T)curhead->uh_cursor_vcol); - else + } else { curwin->w_cursor.coladd = 0; - } else + } + } else { beginline(BL_SOL | BL_FIX); + } } else { /* We get here with the current cursor line being past the end (eg * after adding lines at the end of the file, and then undoing it). @@ -2502,27 +2527,29 @@ static void u_undoredo(int undo, bool do_buf_event) curwin->w_cursor.coladd = 0; } - /* Make sure the cursor is on an existing line and column. */ + // Make sure the cursor is on an existing line and column. check_cursor(); - /* Remember where we are for "g-" and ":earlier 10s". */ + // Remember where we are for "g-" and ":earlier 10s". curbuf->b_u_seq_cur = curhead->uh_seq; - if (undo) + if (undo) { /* We are below the previous undo. However, to make ":earlier 1s" * work we compute this as being just above the just undone change. */ curbuf->b_u_seq_cur = curhead->uh_next.ptr ? - curhead->uh_next.ptr->uh_seq : 0; + curhead->uh_next.ptr->uh_seq : 0; + } - /* Remember where we are for ":earlier 1f" and ":later 1f". */ + // Remember where we are for ":earlier 1f" and ":later 1f". if (curhead->uh_save_nr != 0) { - if (undo) + if (undo) { curbuf->b_u_save_nr_cur = curhead->uh_save_nr - 1; - else + } else { curbuf->b_u_save_nr_cur = curhead->uh_save_nr; + } } - /* The timestamp can be the same for multiple changes, just use the one of - * the undone/redone change. */ + // The timestamp can be the same for multiple changes, just use the one of + // the undone/redone change. curbuf->b_u_time_cur = curhead->uh_time; unblock_autocmds(); @@ -2534,17 +2561,18 @@ static void u_undoredo(int undo, bool do_buf_event) /// If we deleted or added lines, report the number of less/more lines. /// Otherwise, report the number of changes (this may be incorrect /// in some cases, but it's better than nothing). -static void u_undo_end( - bool did_undo, ///< just did an undo - bool absolute, ///< used ":undo N" - bool quiet) +/// +/// @param did_undo just did an undo +/// @param absolute used ":undo N" +static void u_undo_end(bool did_undo, bool absolute, bool quiet) { - char *msgstr; - u_header_T *uhp; + char *msgstr; + u_header_T *uhp; char_u msgbuf[80]; - if ((fdo_flags & FDO_UNDO) && KeyTyped) + if ((fdo_flags & FDO_UNDO) && KeyTyped) { foldOpenCursor(); + } if (quiet || global_busy // no messages until global is finished @@ -2552,28 +2580,30 @@ static void u_undo_end( return; } - if (curbuf->b_ml.ml_flags & ML_EMPTY) + if (curbuf->b_ml.ml_flags & ML_EMPTY) { --u_newcount; + } u_oldcount -= u_newcount; - if (u_oldcount == -1) + if (u_oldcount == -1) { msgstr = N_("more line"); - else if (u_oldcount < 0) + } else if (u_oldcount < 0) { msgstr = N_("more lines"); - else if (u_oldcount == 1) + } else if (u_oldcount == 1) { msgstr = N_("line less"); - else if (u_oldcount > 1) + } else if (u_oldcount > 1) { msgstr = N_("fewer lines"); - else { + } else { u_oldcount = u_newcount; - if (u_newcount == 1) + if (u_newcount == 1) { msgstr = N_("change"); - else + } else { msgstr = N_("changes"); + } } if (curbuf->b_u_curhead != NULL) { - /* For ":undo N" we prefer a "after #N" message. */ + // For ":undo N" we prefer a "after #N" message. if (absolute && curbuf->b_u_curhead->uh_next.ptr != NULL) { uhp = curbuf->b_u_curhead->uh_next.ptr; did_undo = false; @@ -2600,14 +2630,13 @@ static void u_undo_end( } } - smsg_attr_keep( - 0, - _("%" PRId64 " %s; %s #%" PRId64 " %s"), - u_oldcount < 0 ? (int64_t)-u_oldcount : (int64_t)u_oldcount, - _(msgstr), - did_undo ? _("before") : _("after"), - uhp == NULL ? (int64_t)0L : (int64_t)uhp->uh_seq, - msgbuf); + smsg_attr_keep(0, + _("%" PRId64 " %s; %s #%" PRId64 " %s"), + u_oldcount < 0 ? (int64_t)-u_oldcount : (int64_t)u_oldcount, + _(msgstr), + did_undo ? _("before") : _("after"), + uhp == NULL ? (int64_t)0L : (int64_t)uhp->uh_seq, + msgbuf); } /// u_sync: stop adding to the current entry list @@ -2634,7 +2663,7 @@ void u_sync(bool force) void ex_undolist(exarg_T *eap) { garray_T ga; - u_header_T *uhp; + u_header_T *uhp; int mark; int nomark; int changes = 1; @@ -2657,50 +2686,50 @@ void ex_undolist(exarg_T *eap) add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff), uhp->uh_time); if (uhp->uh_save_nr > 0) { - while (STRLEN(IObuff) < 33) + while (STRLEN(IObuff) < 33) { STRCAT(IObuff, " "); + } vim_snprintf_add((char *)IObuff, IOSIZE, - " %3ld", uhp->uh_save_nr); + " %3ld", uhp->uh_save_nr); } GA_APPEND(char_u *, &ga, vim_strsave(IObuff)); } uhp->uh_walk = mark; - /* go down in the tree if we haven't been there */ + // go down in the tree if we haven't been there if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != nomark && uhp->uh_prev.ptr->uh_walk != mark) { uhp = uhp->uh_prev.ptr; ++changes; } - /* go to alternate branch if we haven't been there */ + // go to alternate branch if we haven't been there else if (uhp->uh_alt_next.ptr != NULL && uhp->uh_alt_next.ptr->uh_walk != nomark - && uhp->uh_alt_next.ptr->uh_walk != mark) + && uhp->uh_alt_next.ptr->uh_walk != mark) { uhp = uhp->uh_alt_next.ptr; - - /* go up in the tree if we haven't been there and we are at the - * start of alternate branches */ - else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL - && uhp->uh_next.ptr->uh_walk != nomark - && uhp->uh_next.ptr->uh_walk != mark) { + } else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL + // go up in the tree if we haven't been there and we are at the + // start of alternate branches + && uhp->uh_next.ptr->uh_walk != nomark + && uhp->uh_next.ptr->uh_walk != mark) { uhp = uhp->uh_next.ptr; --changes; } else { - /* need to backtrack; mark this node as done */ + // need to backtrack; mark this node as done uhp->uh_walk = nomark; - if (uhp->uh_alt_prev.ptr != NULL) + if (uhp->uh_alt_prev.ptr != NULL) { uhp = uhp->uh_alt_prev.ptr; - else { + } else { uhp = uhp->uh_next.ptr; --changes; } } } - if (GA_EMPTY(&ga)) + if (GA_EMPTY(&ga)) { MSG(_("Nothing to undo")); - else { + } else { sort_strings((char_u **)ga.ga_data, ga.ga_len); msg_start(); @@ -2757,17 +2786,18 @@ void u_unchanged(buf_T *buf) */ void u_find_first_changed(void) { - u_header_T *uhp = curbuf->b_u_newhead; - u_entry_T *uep; + u_header_T *uhp = curbuf->b_u_newhead; + u_entry_T *uep; linenr_T lnum; - if (curbuf->b_u_curhead != NULL || uhp == NULL) - return; /* undid something in an autocmd? */ - - /* Check that the last undo block was for the whole file. */ + if (curbuf->b_u_curhead != NULL || uhp == NULL) { + return; // undid something in an autocmd? + } + // Check that the last undo block was for the whole file. uep = uhp->uh_entry; - if (uep->ue_top != 0 || uep->ue_bot != 0) + if (uep->ue_top != 0 || uep->ue_bot != 0) { return; + } for (lnum = 1; lnum < curbuf->b_ml.ml_line_count && lnum <= uep->ue_size; lnum++) { @@ -2778,7 +2808,7 @@ void u_find_first_changed(void) } } if (curbuf->b_ml.ml_line_count != uep->ue_size) { - /* lines added or deleted at the end, put the cursor there */ + // lines added or deleted at the end, put the cursor there clearpos(&(uhp->uh_cursor)); uhp->uh_cursor.lnum = lnum; } @@ -2790,27 +2820,30 @@ void u_find_first_changed(void) */ void u_update_save_nr(buf_T *buf) { - u_header_T *uhp; + u_header_T *uhp; ++buf->b_u_save_nr_last; buf->b_u_save_nr_cur = buf->b_u_save_nr_last; uhp = buf->b_u_curhead; - if (uhp != NULL) + if (uhp != NULL) { uhp = uhp->uh_next.ptr; - else + } else { uhp = buf->b_u_newhead; - if (uhp != NULL) + } + if (uhp != NULL) { uhp->uh_save_nr = buf->b_u_save_nr_last; + } } static void u_unch_branch(u_header_T *uhp) { - u_header_T *uh; + u_header_T *uh; for (uh = uhp; uh != NULL; uh = uh->uh_prev.ptr) { uh->uh_flags |= UH_CHANGED; - if (uh->uh_alt_next.ptr != NULL) - u_unch_branch(uh->uh_alt_next.ptr); /* recursive */ + if (uh->uh_alt_next.ptr != NULL) { + u_unch_branch(uh->uh_alt_next.ptr); // recursive + } } } @@ -2829,11 +2862,11 @@ static u_entry_T *u_get_headentry(buf_T *buf) /* * u_getbot(): compute the line number of the previous u_save - * It is called only when b_u_synced is false. + * It is called only when b_u_synced is false. */ static void u_getbot(buf_T *buf) { - u_entry_T *uep; + u_entry_T *uep; linenr_T extra; uep = u_get_headentry(buf); // check for corrupt undo list @@ -2864,95 +2897,91 @@ static void u_getbot(buf_T *buf) buf->b_u_synced = true; } -/* - * Free one header "uhp" and its entry list and adjust the pointers. - */ -static void -u_freeheader( - buf_T *buf, - u_header_T *uhp, - u_header_T **uhpp // if not NULL reset when freeing this header -) -{ - u_header_T *uhap; - - /* When there is an alternate redo list free that branch completely, - * because we can never go there. */ - if (uhp->uh_alt_next.ptr != NULL) +/// Free one header "uhp" and its entry list and adjust the pointers. +/// +/// @param uhpp if not NULL reset when freeing this header +static void u_freeheader(buf_T *buf, u_header_T *uhp, u_header_T **uhpp) +{ + u_header_T *uhap; + + // When there is an alternate redo list free that branch completely, + // because we can never go there. + if (uhp->uh_alt_next.ptr != NULL) { u_freebranch(buf, uhp->uh_alt_next.ptr, uhpp); + } - if (uhp->uh_alt_prev.ptr != NULL) + if (uhp->uh_alt_prev.ptr != NULL) { uhp->uh_alt_prev.ptr->uh_alt_next.ptr = NULL; + } - /* Update the links in the list to remove the header. */ - if (uhp->uh_next.ptr == NULL) + // Update the links in the list to remove the header. + if (uhp->uh_next.ptr == NULL) { buf->b_u_oldhead = uhp->uh_prev.ptr; - else + } else { uhp->uh_next.ptr->uh_prev.ptr = uhp->uh_prev.ptr; + } - if (uhp->uh_prev.ptr == NULL) + if (uhp->uh_prev.ptr == NULL) { buf->b_u_newhead = uhp->uh_next.ptr; - else + } else { for (uhap = uhp->uh_prev.ptr; uhap != NULL; - uhap = uhap->uh_alt_next.ptr) + uhap = uhap->uh_alt_next.ptr) { uhap->uh_next.ptr = uhp->uh_next.ptr; + } + } u_freeentries(buf, uhp, uhpp); } -/* - * Free an alternate branch and any following alternate branches. - */ -static void -u_freebranch( - buf_T *buf, - u_header_T *uhp, - u_header_T **uhpp // if not NULL reset when freeing this header -) +/// Free an alternate branch and any following alternate branches. +/// +/// @param uhpp if not NULL reset when freeing this header +static void u_freebranch(buf_T *buf, u_header_T *uhp, u_header_T **uhpp) { - u_header_T *tofree, *next; + u_header_T *tofree, *next; - /* If this is the top branch we may need to use u_freeheader() to update - * all the pointers. */ + // If this is the top branch we may need to use u_freeheader() to update + // all the pointers. if (uhp == buf->b_u_oldhead) { - while (buf->b_u_oldhead != NULL) + while (buf->b_u_oldhead != NULL) { u_freeheader(buf, buf->b_u_oldhead, uhpp); + } return; } - if (uhp->uh_alt_prev.ptr != NULL) + if (uhp->uh_alt_prev.ptr != NULL) { uhp->uh_alt_prev.ptr->uh_alt_next.ptr = NULL; + } next = uhp; while (next != NULL) { tofree = next; - if (tofree->uh_alt_next.ptr != NULL) - u_freebranch(buf, tofree->uh_alt_next.ptr, uhpp); /* recursive */ + if (tofree->uh_alt_next.ptr != NULL) { + u_freebranch(buf, tofree->uh_alt_next.ptr, uhpp); // recursive + } next = tofree->uh_prev.ptr; u_freeentries(buf, tofree, uhpp); } } -/* - * Free all the undo entries for one header and the header itself. - * This means that "uhp" is invalid when returning. - */ -static void -u_freeentries( - buf_T *buf, - u_header_T *uhp, - u_header_T **uhpp // if not NULL reset when freeing this header -) +/// Free all the undo entries for one header and the header itself. +/// This means that "uhp" is invalid when returning. +/// +/// @param uhpp if not NULL reset when freeing this header +static void u_freeentries(buf_T *buf, u_header_T *uhp, u_header_T **uhpp) { - u_entry_T *uep, *nuep; + u_entry_T *uep, *nuep; - /* Check for pointers to the header that become invalid now. */ - if (buf->b_u_curhead == uhp) + // Check for pointers to the header that become invalid now. + if (buf->b_u_curhead == uhp) { buf->b_u_curhead = NULL; - if (buf->b_u_newhead == uhp) - buf->b_u_newhead = NULL; /* freeing the newest entry */ - if (uhpp != NULL && uhp == *uhpp) + } + if (buf->b_u_newhead == uhp) { + buf->b_u_newhead = NULL; // freeing the newest entry + } + if (uhpp != NULL && uhp == *uhpp) { *uhpp = NULL; + } for (uep = uhp->uh_entry; uep != NULL; uep = nuep) { nuep = uep->ue_next; @@ -2973,8 +3002,9 @@ u_freeentries( */ static void u_freeentry(u_entry_T *uep, long n) { - while (n > 0) + while (n > 0) { xfree(uep->ue_array[--n]); + } xfree((char_u *)uep->ue_array); #ifdef U_DEBUG uep->ue_magic = 0; @@ -2999,16 +3029,19 @@ void u_clearall(buf_T *buf) */ void u_saveline(linenr_T lnum) { - if (lnum == curbuf->b_u_line_lnum) /* line is already saved */ + if (lnum == curbuf->b_u_line_lnum) { // line is already saved return; - if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) /* should never happen */ + } + if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) { // should never happen return; + } u_clearline(); curbuf->b_u_line_lnum = lnum; - if (curwin->w_cursor.lnum == lnum) + if (curwin->w_cursor.lnum == lnum) { curbuf->b_u_line_colnr = curwin->w_cursor.col; - else + } else { curbuf->b_u_line_colnr = 0; + } curbuf->b_u_line_ptr = u_save_line(lnum); } @@ -3033,7 +3066,7 @@ void u_clearline(void) void u_undoline(void) { colnr_T t; - char_u *oldp; + char_u *oldp; if (curbuf->b_u_line_ptr == NULL || curbuf->b_u_line_lnum > curbuf->b_ml.ml_line_count) { @@ -3050,12 +3083,15 @@ void u_undoline(void) oldp = u_save_line(curbuf->b_u_line_lnum); ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, true); changed_bytes(curbuf->b_u_line_lnum, 0); + extmark_splice_cols(curbuf, (int)curbuf->b_u_line_lnum-1, 0, (colnr_T)STRLEN(oldp), + (colnr_T)STRLEN(curbuf->b_u_line_ptr), kExtmarkUndo); xfree(curbuf->b_u_line_ptr); curbuf->b_u_line_ptr = oldp; t = curbuf->b_u_line_colnr; - if (curwin->w_cursor.lnum == curbuf->b_u_line_lnum) + if (curwin->w_cursor.lnum == curbuf->b_u_line_lnum) { curbuf->b_u_line_colnr = curwin->w_cursor.col; + } curwin->w_cursor.col = t; curwin->w_cursor.lnum = curbuf->b_u_line_lnum; check_cursor_col(); @@ -3106,8 +3142,8 @@ bool bufIsChanged(buf_T *buf) { // In a "prompt" buffer we do respect 'modified', so that we can control // closing the window by setting or resetting that option. - return (!bt_dontwrite(buf) || bt_prompt(buf)) - && (buf->b_changed || file_ff_differs(buf, true)); + return (!bt_dontwrite(buf) || bt_prompt(buf)) + && (buf->b_changed || file_ff_differs(buf, true)); } // Return true if any buffer has changes. Also buffers that are not written. diff --git a/src/nvim/undo.h b/src/nvim/undo.h index 802cdc5583..f494d4de86 100644 --- a/src/nvim/undo.h +++ b/src/nvim/undo.h @@ -1,8 +1,8 @@ #ifndef NVIM_UNDO_H #define NVIM_UNDO_H -#include "nvim/undo_defs.h" #include "nvim/ex_cmds_defs.h" +#include "nvim/undo_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "undo.h.generated.h" diff --git a/src/nvim/undo_defs.h b/src/nvim/undo_defs.h index b46295a15d..3267b2f71e 100644 --- a/src/nvim/undo_defs.h +++ b/src/nvim/undo_defs.h @@ -3,32 +3,32 @@ #include <time.h> // for time_t -#include "nvim/pos.h" #include "nvim/extmark_defs.h" #include "nvim/mark_defs.h" +#include "nvim/pos.h" typedef struct u_header u_header_T; -/* Structure to store info about the Visual area. */ +// Structure to store info about the Visual area. typedef struct { - pos_T vi_start; /* start pos of last VIsual */ - pos_T vi_end; /* end position of last VIsual */ - int vi_mode; /* VIsual_mode of last VIsual */ - colnr_T vi_curswant; /* MAXCOL from w_curswant */ + pos_T vi_start; // start pos of last VIsual + pos_T vi_end; // end position of last VIsual + int vi_mode; // VIsual_mode of last VIsual + colnr_T vi_curswant; // MAXCOL from w_curswant } visualinfo_T; #include "nvim/buffer_defs.h" typedef struct u_entry u_entry_T; struct u_entry { - u_entry_T *ue_next; /* pointer to next entry in list */ - linenr_T ue_top; /* number of line above undo block */ - linenr_T ue_bot; /* number of line below undo block */ - linenr_T ue_lcount; /* linecount when u_save called */ - char_u **ue_array; /* array of lines in undo block */ - long ue_size; /* number of lines in ue_array */ + u_entry_T *ue_next; // pointer to next entry in list + linenr_T ue_top; // number of line above undo block + linenr_T ue_bot; // number of line below undo block + linenr_T ue_lcount; // linecount when u_save called + char_u **ue_array; // array of lines in undo block + long ue_size; // number of lines in ue_array #ifdef U_DEBUG - int ue_magic; /* magic number to check allocation */ + int ue_magic; // magic number to check allocation #endif }; @@ -36,26 +36,26 @@ struct u_header { /* The following have a pointer and a number. The number is used when * reading the undo file in u_read_undo() */ union { - u_header_T *ptr; /* pointer to next undo header in list */ + u_header_T *ptr; // pointer to next undo header in list long seq; } uh_next; union { - u_header_T *ptr; /* pointer to previous header in list */ + u_header_T *ptr; // pointer to previous header in list long seq; } uh_prev; union { - u_header_T *ptr; /* pointer to next header for alt. redo */ + u_header_T *ptr; // pointer to next header for alt. redo long seq; } uh_alt_next; union { - u_header_T *ptr; /* pointer to previous header for alt. redo */ + u_header_T *ptr; // pointer to previous header for alt. redo long seq; } uh_alt_prev; - long uh_seq; /* sequence number, higher == newer undo */ - int uh_walk; /* used by undo_time() */ - u_entry_T *uh_entry; /* pointer to first entry */ - u_entry_T *uh_getbot_entry; /* pointer to where ue_bot must be set */ - pos_T uh_cursor; /* cursor position before saving */ + long uh_seq; // sequence number, higher == newer undo + int uh_walk; // used by undo_time() + u_entry_T *uh_entry; // pointer to first entry + u_entry_T *uh_getbot_entry; // pointer to where ue_bot must be set + pos_T uh_cursor; // cursor position before saving long uh_cursor_vcol; int uh_flags; // see below fmark_T uh_namedm[NMARKS]; // marks before undo/after redo diff --git a/src/nvim/version.c b/src/nvim/version.c index 7c197f1b7f..9e2358c9a3 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -6,32 +6,32 @@ /// Nvim was forked from Vim 7.4.160. /// Vim originated from Stevie version 3.6 (Fish disk 217) by GRWalter (Fred). -#include <inttypes.h> #include <assert.h> +#include <inttypes.h> #include <limits.h> #include "nvim/api/private/helpers.h" -#include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/buffer.h" -#include "nvim/iconv.h" -#include "nvim/version.h" #include "nvim/charset.h" +#include "nvim/iconv.h" +#include "nvim/lua/executor.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/screen.h" #include "nvim/strings.h" -#include "nvim/lua/executor.h" +#include "nvim/version.h" +#include "nvim/vim.h" // version info generated by the build system #include "auto/versiondef.h" // for ":version", ":intro", and "nvim --version" #ifndef NVIM_VERSION_MEDIUM -#define NVIM_VERSION_MEDIUM "v" STR(NVIM_VERSION_MAJOR)\ -"." STR(NVIM_VERSION_MINOR) "." STR(NVIM_VERSION_PATCH)\ -NVIM_VERSION_PRERELEASE +# define NVIM_VERSION_MEDIUM "v" STR(NVIM_VERSION_MAJOR)\ + "." STR(NVIM_VERSION_MINOR) "." STR(NVIM_VERSION_PATCH)\ + NVIM_VERSION_PRERELEASE #endif #define NVIM_VERSION_LONG "NVIM " NVIM_VERSION_MEDIUM @@ -50,23 +50,23 @@ char *version_cflags = "Compilation: " NVIM_VERSION_CFLAGS; static char *features[] = { #ifdef HAVE_ACL -"+acl", + "+acl", #else -"-acl", + "-acl", #endif #if defined(HAVE_ICONV) -"+iconv", + "+iconv", #else -"-iconv", + "-iconv", #endif #ifdef FEAT_TUI -"+tui", + "+tui", #else -"-tui", + "-tui", #endif -NULL + NULL }; // clang-format off @@ -2017,9 +2017,9 @@ void ex_version(exarg_T *eap) /// When "wrap" is TRUE wrap the string in []. /// @param s /// @param wrap -static void version_msg_wrap(char_u *s, int wrap) +static void version_msg_wrap(char *s, int wrap) { - int len = (int)vim_strsize(s) + (wrap ? 2 : 0); + int len = vim_strsize((char_u *)s) + (wrap ? 2 : 0); if (!got_int && (len < Columns) @@ -2032,7 +2032,7 @@ static void version_msg_wrap(char_u *s, int wrap) if (wrap) { msg_puts("["); } - msg_puts((char *)s); + msg_puts(s); if (wrap) { msg_puts("]"); } @@ -2041,7 +2041,7 @@ static void version_msg_wrap(char_u *s, int wrap) static void version_msg(char *s) { - version_msg_wrap((char_u *)s, false); + version_msg_wrap(s, false); } /// List all features. @@ -2070,7 +2070,7 @@ void list_in_columns(char_u **items, int size, int current) // Find the length of the longest item, use that + 1 as the column width. int i; for (i = 0; size < 0 ? items[i] != NULL : i < size; i++) { - int l = (int)vim_strsize(items[i]) + (i == current ? 2 : 0); + int l = vim_strsize(items[i]) + (i == current ? 2 : 0); if (l > width) { width = l; @@ -2082,7 +2082,7 @@ void list_in_columns(char_u **items, int size, int current) if (Columns < width) { // Not enough screen columns - show one per line for (i = 0; i < item_count; i++) { - version_msg_wrap(items[i], i == current); + version_msg_wrap((char *)items[i], i == current); if (msg_col > 0 && i < item_count - 1) { msg_putchar('\n'); } diff --git a/src/nvim/version.h b/src/nvim/version.h index 4af038dd6c..a19e863152 100644 --- a/src/nvim/version.h +++ b/src/nvim/version.h @@ -5,8 +5,8 @@ #include "nvim/macros.h" // defined in version.c -extern char* Version; -extern char* longVersion; +extern char *Version; +extern char *longVersion; // // Vim version number, name, etc. Patchlevel is defined in version.c. diff --git a/src/nvim/vim.h b/src/nvim/vim.h index f61f9a5e01..7d49ca6ff1 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -1,8 +1,8 @@ #ifndef NVIM_VIM_H #define NVIM_VIM_H -#include "nvim/types.h" #include "nvim/pos.h" // for linenr_T, MAXCOL, etc... +#include "nvim/types.h" // Some defines from the old feature.h #define SESSION_FILE "Session.vim" @@ -30,11 +30,10 @@ enum { NUMBUFLEN = 65 }; #define ROOT_UID 0 +#include "nvim/gettext.h" #include "nvim/keymap.h" #include "nvim/macros.h" -#include "nvim/gettext.h" - // special attribute addition: Put message in history #define MSG_HIST 0x1000 @@ -57,8 +56,8 @@ enum { NUMBUFLEN = 65 }; #define REPLACE_FLAG 0x40 // Replace mode flag #define REPLACE (REPLACE_FLAG + INSERT) -# define VREPLACE_FLAG 0x80 // Virtual-replace mode flag -# define VREPLACE (REPLACE_FLAG + VREPLACE_FLAG + INSERT) +#define VREPLACE_FLAG 0x80 // Virtual-replace mode flag +#define VREPLACE (REPLACE_FLAG + VREPLACE_FLAG + INSERT) #define LREPLACE (REPLACE_FLAG + LANGMAP) #define NORMAL_BUSY (0x100 + NORMAL) // Normal mode, busy with a command @@ -251,7 +250,7 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext() #define STRNCAT(d, s, n) strncat((char *)(d), (char *)(s), (size_t)(n)) #define STRLCAT(d, s, n) xstrlcat((char *)(d), (char *)(s), (size_t)(n)) -# define vim_strpbrk(s, cs) (char_u *)strpbrk((char *)(s), (char *)(cs)) +#define vim_strpbrk(s, cs) (char_u *)strpbrk((char *)(s), (char *)(cs)) // Character used as separated in autoload function/variable names. #define AUTOLOAD_CHAR '#' @@ -260,7 +259,7 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext() // Prefer using emsgf(), because perror() may send the output to the wrong // destination and mess up the screen. -#define PERROR(msg) (void) emsgf("%s: %s", msg, strerror(errno)) +#define PERROR(msg) (void)emsgf("%s: %s", msg, strerror(errno)) #define SHOWCMD_COLS 10 // columns needed by shown command @@ -301,28 +300,16 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext() # define mch_msg(str) printf("%s", (str)) #endif -#include "nvim/globals.h" // global variables and messages #include "nvim/buffer_defs.h" // buffer and windows #include "nvim/ex_cmds_defs.h" // Ex command defines - -// Used for flags in do_in_path() -#define DIP_ALL 0x01 // all matches, not just the first one -#define DIP_DIR 0x02 // find directories instead of files -#define DIP_ERR 0x04 // give an error message when none found -#define DIP_START 0x08 // also use "start" directory in 'packpath' -#define DIP_OPT 0x10 // also use "opt" directory in 'packpath' -#define DIP_NORTP 0x20 // do not use 'runtimepath' -#define DIP_NOAFTER 0x40 // skip "after" directories -#define DIP_AFTER 0x80 // only use "after" directories -#define DIP_LUA 0x100 // also use ".lua" files -#define DIP_DIRFILE 0x200 // find both files and directories +#include "nvim/globals.h" // global variables and messages // Lowest number used for window ID. Cannot have this many windows per tab. #define LOWEST_WIN_ID 1000 // BSD is supposed to cover FreeBSD and similar systems. #if (defined(BSD) || defined(__FreeBSD_kernel__)) \ - && (defined(S_ISCHR) || defined(S_IFCHR)) + && (defined(S_ISCHR) || defined(S_IFCHR)) # define OPEN_CHR_FILES #endif diff --git a/src/nvim/viml/parser/expressions.c b/src/nvim/viml/parser/expressions.c index c2aa923c49..39687a8e8d 100644 --- a/src/nvim/viml/parser/expressions.c +++ b/src/nvim/viml/parser/expressions.c @@ -936,7 +936,7 @@ static const char *intchar2str(const int ch) } #ifdef UNIT_TESTING -#include <stdio.h> +# include <stdio.h> REAL_FATTR_UNUSED static inline void viml_pexpr_debug_print_ast_node(const ExprASTNode *const *const eastnode_p, @@ -971,14 +971,14 @@ static inline void viml_pexpr_debug_print_token(const ParserState *const pstate, { fprintf(stderr, "\ntkn: %s\n", viml_pexpr_repr_token(pstate, token, NULL)); } -#define PSTACK(msg) \ +# define PSTACK(msg) \ viml_pexpr_debug_print_ast_stack(&ast_stack, #msg) -#define PSTACK_P(msg) \ +# define PSTACK_P(msg) \ viml_pexpr_debug_print_ast_stack(ast_stack, #msg) -#define PNODE_P(eastnode_p, msg) \ +# define PNODE_P(eastnode_p, msg) \ viml_pexpr_debug_print_ast_node((const ExprASTNode *const *)eastnode_p, \ (#msg)) -#define PTOKEN(tkn) \ +# define PTOKEN(tkn) \ viml_pexpr_debug_print_token(pstate, tkn) #endif diff --git a/src/nvim/viml/parser/expressions.h b/src/nvim/viml/parser/expressions.h index 838a742271..325df643e7 100644 --- a/src/nvim/viml/parser/expressions.h +++ b/src/nvim/viml/parser/expressions.h @@ -1,13 +1,13 @@ #ifndef NVIM_VIML_PARSER_EXPRESSIONS_H #define NVIM_VIML_PARSER_EXPRESSIONS_H +#include <stdbool.h> #include <stddef.h> #include <stdint.h> -#include <stdbool.h> +#include "nvim/eval/typval.h" #include "nvim/types.h" #include "nvim/viml/parser/parser.h" -#include "nvim/eval/typval.h" // Defines whether to ignore case: // == kCCStrategyUseOption @@ -80,7 +80,7 @@ typedef enum { } ExprAssignmentType; #define EXPR_OPT_SCOPE_LIST \ - ((char[]){ kExprOptScopeGlobal, kExprOptScopeLocal }) + ((char[]){ kExprOptScopeGlobal, kExprOptScopeLocal }) /// All possible variable scopes typedef enum { @@ -96,11 +96,11 @@ typedef enum { } ExprVarScope; #define EXPR_VAR_SCOPE_LIST \ - ((char[]) { \ - kExprVarScopeScript, kExprVarScopeGlobal, kExprVarScopeVim, \ - kExprVarScopeBuffer, kExprVarScopeWindow, kExprVarScopeTabpage, \ - kExprVarScopeLocal, kExprVarScopeBuffer, kExprVarScopeArguments, \ - }) + ((char[]) { \ + kExprVarScopeScript, kExprVarScopeGlobal, kExprVarScopeVim, \ + kExprVarScopeBuffer, kExprVarScopeWindow, kExprVarScopeTabpage, \ + kExprVarScopeLocal, kExprVarScopeBuffer, kExprVarScopeArguments, \ + }) /// Lexer token typedef struct { diff --git a/src/nvim/viml/parser/parser.h b/src/nvim/viml/parser/parser.h index 7ac49709d8..b2933c3781 100644 --- a/src/nvim/viml/parser/parser.h +++ b/src/nvim/viml/parser/parser.h @@ -1,12 +1,12 @@ #ifndef NVIM_VIML_PARSER_PARSER_H #define NVIM_VIML_PARSER_PARSER_H +#include <assert.h> #include <stdbool.h> #include <stddef.h> -#include <assert.h> -#include "nvim/lib/kvec.h" #include "nvim/func_attr.h" +#include "nvim/lib/kvec.h" #include "nvim/mbyte.h" #include "nvim/memory.h" @@ -82,9 +82,9 @@ typedef struct { } ParserState; static inline void viml_parser_init( - ParserState *const ret_pstate, - const ParserLineGetter get_line, void *const cookie, - ParserHighlight *const colors) + ParserState *const ret_pstate, + const ParserLineGetter get_line, void *const cookie, + ParserHighlight *const colors) REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ARG(1, 2); /// Initialize a new parser state instance @@ -94,10 +94,8 @@ static inline void viml_parser_init( /// @param[in] cookie Argument for the get_line function. /// @param[in] colors Where to save highlighting. May be NULL if it is not /// needed. -static inline void viml_parser_init( - ParserState *const ret_pstate, - const ParserLineGetter get_line, void *const cookie, - ParserHighlight *const colors) +static inline void viml_parser_init(ParserState *const ret_pstate, const ParserLineGetter get_line, + void *const cookie, ParserHighlight *const colors) { *ret_pstate = (ParserState) { .reader = { @@ -194,8 +192,7 @@ static inline void viml_parser_advance(ParserState *const pstate, /// /// @param pstate Parser state to advance. /// @param[in] len Number of bytes to advance. -static inline void viml_parser_advance(ParserState *const pstate, - const size_t len) +static inline void viml_parser_advance(ParserState *const pstate, const size_t len) { assert(pstate->pos.line == kv_size(pstate->reader.lines) - 1); const ParserLine pline = kv_last(pstate->reader.lines); @@ -219,10 +216,8 @@ static inline void viml_parser_highlight(ParserState *const pstate, /// @param[in] start Start position of the highlight. /// @param[in] len Highlighting chunk length. /// @param[in] group Highlight group. -static inline void viml_parser_highlight(ParserState *const pstate, - const ParserPosition start, - const size_t len, - const char *const group) +static inline void viml_parser_highlight(ParserState *const pstate, const ParserPosition start, + const size_t len, const char *const group) { if (pstate->colors == NULL || len == 0) { return; @@ -231,9 +226,9 @@ static inline void viml_parser_highlight(ParserState *const pstate, || kv_Z(*pstate->colors, 0).start.line < start.line || kv_Z(*pstate->colors, 0).end_col <= start.col); kvi_push(*pstate->colors, ((ParserHighlightChunk) { - .start = start, - .end_col = start.col + len, - .group = group, + .start = start, + .end_col = start.col + len, + .group = group, })); } diff --git a/src/nvim/window.c b/src/nvim/window.c index 4bbdaefd1f..dfe1ffdbd4 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -23,6 +23,7 @@ #include "nvim/fold.h" #include "nvim/garray.h" #include "nvim/getchar.h" +#include "nvim/globals.h" #include "nvim/hashtab.h" #include "nvim/main.h" #include "nvim/mark.h" @@ -62,7 +63,7 @@ #define NOWIN (win_T *)-1 // non-existing window -# define ROWS_AVAIL (Rows - p_ch - tabline_height()) +#define ROWS_AVAIL (Rows - p_ch - tabline_height()) /// flags for win_enter_ext() typedef enum { @@ -90,7 +91,7 @@ void do_window(int nchar, long Prenum, int xchar) Prenum1 = Prenum == 0 ? 1 : Prenum; -# define CHECK_CMDWIN \ +#define CHECK_CMDWIN \ do { \ if (cmdwin_type != 0) { \ EMSG(_(e_cmdwin)); \ @@ -298,8 +299,8 @@ newwindow: tabpage_T *oldtab = curtab; tabpage_T *newtab; - /* First create a new tab with the window, then go back to - * the old tab and close the window there. */ + // First create a new tab with the window, then go back to + // the old tab and close the window there. wp = curwin; if (win_new_tabpage((int)Prenum, NULL) == OK && valid_tabpage(oldtab)) { @@ -519,8 +520,8 @@ wingotofile: postponed_split = -1; } - /* Execute the command right here, required when - * "wincmd g}" was used in a function. */ + // Execute the command right here, required when + // "wincmd g}" was used in a function. do_nv_ident('g', xchar); break; @@ -853,12 +854,12 @@ void ui_ext_win_position(win_T *wp) bool east = c.anchor & kFloatAnchorEast; bool south = c.anchor & kFloatAnchorSouth; - int comp_row = (int)row - (south ? wp->w_height : 0); - int comp_col = (int)col - (east ? wp->w_width : 0); + int comp_row = (int)row - (south ? wp->w_height_outer : 0); + int comp_col = (int)col - (east ? wp->w_width_outer : 0); comp_row += grid->comp_row; comp_col += grid->comp_col; - comp_row = MAX(MIN(comp_row, Rows-wp->w_height_outer-1), 0); - comp_col = MAX(MIN(comp_col, Columns-wp->w_width_outer), 0); + comp_row = MAX(MIN(comp_row, Rows - wp->w_height_outer - 1), 0); + comp_col = MAX(MIN(comp_col, Columns - wp->w_width_outer), 0); wp->w_winrow = comp_row; wp->w_wincol = comp_col; bool valid = (wp->w_redr_type == 0); @@ -922,8 +923,8 @@ int win_split(int size, int flags) return FAIL; } - /* When creating the help window make a snapshot of the window layout. - * Otherwise clear the snapshot, it's now invalid. */ + // When creating the help window make a snapshot of the window layout. + // Otherwise clear the snapshot, it's now invalid. if (flags & WSP_HELP) { make_snapshot(SNAP_HELP_IDX); } else { @@ -1260,8 +1261,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) frame_append(curfrp, frp); } - /* Set w_fraction now so that the cursor keeps the same relative - * vertical position. */ + // Set w_fraction now so that the cursor keeps the same relative + // vertical position. if (!did_set_fraction) { set_fraction(oldwin); } @@ -1287,8 +1288,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) } frp->fr_height = curfrp->fr_height; - /* "new_size" of the current window goes to the new window, use - * one column for the vertical separator */ + // "new_size" of the current window goes to the new window, use + // one column for the vertical separator win_new_width(wp, new_size); if (before) { wp->w_vsep_width = 1; @@ -1328,8 +1329,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) } frp->fr_width = curfrp->fr_width; - /* "new_size" of the current window goes to the new window, use - * one row for the status line */ + // "new_size" of the current window goes to the new window, use + // one row for the status line win_new_height(wp, new_size); if (flags & (WSP_TOP | WSP_BOT)) { int new_fr_height = curfrp->fr_height - new_size; @@ -1388,8 +1389,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) 'v'); } - /* Don't change the window height/width to 'winheight' / 'winwidth' if a - * size was given. */ + // Don't change the window height/width to 'winheight' / 'winwidth' if a + // size was given. if (flags & WSP_VERT) { i = p_wiw; if (size != 0) { @@ -1462,6 +1463,8 @@ static void win_init(win_T *newp, win_T *oldp, int flags) } newp->w_localdir = (oldp->w_localdir == NULL) ? NULL : vim_strsave(oldp->w_localdir); + newp->w_prevdir = (oldp->w_prevdir == NULL) + ? NULL : vim_strsave(oldp->w_prevdir); // copy tagstack and folds for (i = 0; i < oldp->w_tagstacklen; i++) { @@ -1589,8 +1592,8 @@ int make_windows(int count, bool vertical) int todo; if (vertical) { - /* Each windows needs at least 'winminwidth' lines and a separator - * column. */ + // Each windows needs at least 'winminwidth' lines and a separator + // column. maxcount = (curwin->w_width + curwin->w_vsep_width - (p_wiw - p_wmw)) / (p_wmw + 1); } else { @@ -1679,8 +1682,8 @@ static void win_exchange(long Prenum) frp = curwin->w_frame->fr_prev; } - /* We can only exchange a window with another window, not with a frame - * containing windows. */ + // We can only exchange a window with another window, not with a frame + // containing windows. if (frp == NULL || frp->fr_win == NULL || frp->fr_win == curwin) { return; } @@ -1890,8 +1893,8 @@ void win_move_after(win_T *win1, win_T *win2) win1->w_status_height = win2->w_status_height; win2->w_status_height = height; if (win1->w_vsep_width == 1) { - /* Remove the vertical separator from win1, add it to the last - * window, win2. Adjust the frame widths. */ + // Remove the vertical separator from win1, add it to the last + // window, win2. Adjust the frame widths. win2->w_vsep_width = 1; win2->w_frame->fr_width += 1; win1->w_vsep_width = 0; @@ -1955,8 +1958,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int bool hnc; if (topfr->fr_layout == FR_LEAF) { - /* Set the width/height of this frame. - * Redraw when size or position changes */ + // Set the width/height of this frame. + // Redraw when size or position changes if (topfr->fr_height != height || topfr->fr_win->w_winrow != row || topfr->fr_width != width || topfr->fr_win->w_wincol != col) { @@ -2028,8 +2031,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int } else if (totwincount > 1 && (room + (totwincount - 2)) / (totwincount - 1) > p_wiw) { - /* Can make all windows wider than 'winwidth', spread - * the room equally. */ + // Can make all windows wider than 'winwidth', spread + // the room equally. next_curwin_size = (room + p_wiw + (totwincount - 1) * p_wmw + (totwincount - 1)) / totwincount; @@ -2084,8 +2087,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int new_size += n; } - /* Skip frame that is full width when splitting or closing a - * window, unless equalizing all frames. */ + // Skip frame that is full width when splitting or closing a + // window, unless equalizing all frames. if (!current || dir != 'v' || topfr->fr_parent != NULL || (new_size != fr->fr_width) || frame_has_win(fr, next_curwin)) { @@ -2120,8 +2123,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int m = frame_minheight(topfr, next_curwin); room = height - m; if (room < 0) { - /* The room is less then 'winheight', use all space for the - * current window. */ + // The room is less then 'winheight', use all space for the + // current window. next_curwin_size = p_wh + room; room = 0; } else { @@ -2159,8 +2162,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int } else if (totwincount > 1 && (room + (totwincount - 2)) / (totwincount - 1) > p_wh) { - /* can make all windows higher than 'winheight', - * spread the room equally. */ + // can make all windows higher than 'winheight', + // spread the room equally. next_curwin_size = (room + p_wh + (totwincount - 1) * p_wmh + (totwincount - 1)) / totwincount; @@ -2214,8 +2217,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int } new_size += n; } - /* Skip frame that is full width when splitting or closing a - * window, unless equalizing all frames. */ + // Skip frame that is full width when splitting or closing a + // window, unless equalizing all frames. if (!current || dir != 'h' || topfr->fr_parent != NULL || (new_size != fr->fr_height) || frame_has_win(fr, next_curwin)) { @@ -2263,8 +2266,8 @@ void close_windows(buf_T *buf, int keep_curwin) && !(wp->w_closing || wp->w_buffer->b_locked > 0)) { win_close_othertab(wp, false, tp); - /* Start all over, the tab page may be closed and - * autocommands may change the window layout. */ + // Start all over, the tab page may be closed and + // autocommands may change the window layout. nexttp = first_tabpage; break; } @@ -2630,8 +2633,8 @@ int win_close(win_T *win, bool free_buf) */ last_status(false); - /* After closing the help window, try restoring the window layout from - * before it was opened. */ + // After closing the help window, try restoring the window layout from + // before it was opened. if (help_window) { restore_snapshot(SNAP_HELP_IDX, close_curwin); } @@ -2703,8 +2706,8 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, false); } - /* Careful: Autocommands may have closed the tab page or made it the - * current tab page. */ + // Careful: Autocommands may have closed the tab page or made it the + // current tab page. for (ptp = first_tabpage; ptp != NULL && ptp != tp; ptp = ptp->tp_next) { ; } @@ -2863,9 +2866,9 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp) frame_remove(frp_close); if (frp_close->fr_parent->fr_layout == FR_COL) { - /* When 'winfixheight' is set, try to find another frame in the column - * (as close to the closed frame as possible) to distribute the height - * to. */ + // When 'winfixheight' is set, try to find another frame in the column + // (as close to the closed frame as possible) to distribute the height + // to. if (frp2->fr_win != NULL && frp2->fr_win->w_p_wfh) { frp = frp_close->fr_prev; frp3 = frp_close->fr_next; @@ -2922,8 +2925,8 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp) *dirp = 'h'; } - /* If rows/columns go to a window below/right its positions need to be - * updated. Can only be done after the sizes have been updated. */ + // If rows/columns go to a window below/right its positions need to be + // updated. Can only be done after the sizes have been updated. if (frp2 == frp_close->fr_next) { int row = win->w_winrow; int col = win->w_wincol; @@ -2932,8 +2935,8 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp) } if (frp2->fr_next == NULL && frp2->fr_prev == NULL) { - /* There is no other frame in this list, move its info to the parent - * and remove it. */ + // There is no other frame in this list, move its info to the parent + // and remove it. frp2->fr_parent->fr_layout = frp2->fr_layout; frp2->fr_parent->fr_child = frp2->fr_child; FOR_ALL_FRAMES(frp, frp2->fr_child) { @@ -2951,8 +2954,8 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp) frp2 = frp->fr_parent; if (frp2 != NULL && frp2->fr_layout == frp->fr_layout) { - /* The frame above the parent has the same layout, have to merge - * the frames into this list. */ + // The frame above the parent has the same layout, have to merge + // the frames into this list. if (frp2->fr_child == frp) { frp2->fr_child = frp->fr_child; } @@ -3641,8 +3644,8 @@ static int win_alloc_firstwin(win_T *oldwin) { curwin = win_alloc(NULL, false); if (oldwin == NULL) { - /* Very first window, need to create an empty buffer for it and - * initialize from scratch. */ + // Very first window, need to create an empty buffer for it and + // initialize from scratch. curbuf = buflist_new(NULL, NULL, 1L, BLN_LISTED); if (curbuf == NULL) { return FAIL; @@ -3732,6 +3735,7 @@ void free_tabpage(tabpage_T *tp) } xfree(tp->tp_localdir); + xfree(tp->tp_prevdir); xfree(tp); } @@ -4014,10 +4018,10 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a const int row = win_comp_pos(); // recompute w_winrow for all windows diff_need_scrollbind = true; - /* The tabpage line may have appeared or disappeared, may need to resize - * the frames for that. When the Vim window was resized need to update - * frame sizes too. Use the stored value of p_ch, so that it can be - * different for each tab page. */ + // The tabpage line may have appeared or disappeared, may need to resize + // the frames for that. When the Vim window was resized need to update + // frame sizes too. Use the stored value of p_ch, so that it can be + // different for each tab page. if (p_ch != curtab->tp_ch_used) { clear_cmdline = true; } @@ -4112,8 +4116,8 @@ void goto_tabpage(int n) tp = curtab->tp_next; } } else if (n < 0) { - /* "gT": go to previous tab page, wrap around end. "N gT" repeats - * this N times. */ + // "gT": go to previous tab page, wrap around end. "N gT" repeats + // this N times. ttp = curtab; for (i = n; i < 0; ++i) { for (tp = first_tabpage; tp->tp_next != ttp && tp->tp_next != NULL; @@ -4540,9 +4544,9 @@ static void win_enter_ext(win_T *const wp, const int flags) } } if (os_chdir(new_dir) == 0) { - if (!p_acd && !strequal(new_dir, cwd)) { + if (!p_acd && pathcmp(new_dir, cwd, -1) != 0) { do_autocmd_dirchanged(new_dir, curwin->w_localdir - ? kCdScopeWindow : kCdScopeTab, true); + ? kCdScopeWindow : kCdScopeTabpage, kCdCauseWindow); } shorten_fnames(true); } @@ -4550,8 +4554,8 @@ static void win_enter_ext(win_T *const wp, const int flags) // Window doesn't have a local directory and we are not in the global // directory: Change to the global directory. if (os_chdir((char *)globaldir) == 0) { - if (!p_acd && !strequal((char *)globaldir, cwd)) { - do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, true); + if (!p_acd && pathcmp((char *)globaldir, cwd, -1) != 0) { + do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, kCdCauseWindow); } } XFREE_CLEAR(globaldir); @@ -4677,9 +4681,9 @@ static win_T *win_alloc(win_T *after, bool hidden) new_wp->w_vars = tv_dict_alloc(); init_var_dict(new_wp->w_vars, &new_wp->w_winvar, VAR_SCOPE); - /* Don't execute autocommands while the window is not properly - * initialized yet. gui_create_scrollbar() may trigger a FocusGained - * event. */ + // Don't execute autocommands while the window is not properly + // initialized yet. gui_create_scrollbar() may trigger a FocusGained + // event. block_autocmds(); /* * link the window in the window list @@ -4742,8 +4746,8 @@ static void win_free(win_T *wp, tabpage_T *tp) // reduce the reference count to the argument list. alist_unlink(wp->w_alist); - /* Don't execute autocommands while the window is halfway being deleted. - * gui_mch_destroy_scrollbar() may trigger a FocusGained event. */ + // Don't execute autocommands while the window is halfway being deleted. + // gui_mch_destroy_scrollbar() may trigger a FocusGained event. block_autocmds(); clear_winopt(&wp->w_onebuf_opt); @@ -4770,6 +4774,7 @@ static void win_free(win_T *wp, tabpage_T *tp) } xfree(wp->w_localdir); + xfree(wp->w_prevdir); /* Remove the window from the b_wininfo lists, it may happen that the * freed memory is re-used for another window. */ @@ -5200,8 +5205,8 @@ static void frame_setheight(frame_T *curfrp, int height) frame_new_height(curfrp, height, false, false); } } else if (curfrp->fr_parent->fr_layout == FR_ROW) { - /* Row of frames: Also need to resize frames left and right of this - * one. First check for the minimal height of these. */ + // Row of frames: Also need to resize frames left and right of this + // one. First check for the minimal height of these. h = frame_minheight(curfrp->fr_parent, NULL); if (height < h) { height = h; @@ -5261,13 +5266,13 @@ static void frame_setheight(frame_T *curfrp, int height) */ take = height - curfrp->fr_height; - /* If there is not enough room, also reduce the height of a window - * with 'winfixheight' set. */ + // If there is not enough room, also reduce the height of a window + // with 'winfixheight' set. if (height > room + room_cmdline - room_reserved) { room_reserved = room + room_cmdline - height; } - /* If there is only a 'winfixheight' window and making the - * window smaller, need to make the other window taller. */ + // If there is only a 'winfixheight' window and making the + // window smaller, need to make the other window taller. if (take < 0 && room - curfrp->fr_height < room_reserved) { room_reserved = 0; } @@ -5342,8 +5347,8 @@ void win_setwidth(int width) void win_setwidth_win(int width, win_T *wp) { - /* Always keep current window at least one column wide, even when - * 'winminwidth' is zero. */ + // Always keep current window at least one column wide, even when + // 'winminwidth' is zero. if (wp == curwin) { if (width < p_wmw) { width = p_wmw; @@ -5394,8 +5399,8 @@ static void frame_setwidth(frame_T *curfrp, int width) } if (curfrp->fr_parent->fr_layout == FR_COL) { - /* Column of frames: Also need to resize frames above and below of - * this one. First check for the minimal width of these. */ + // Column of frames: Also need to resize frames above and below of + // this one. First check for the minimal width of these. w = frame_minwidth(curfrp->fr_parent, NULL); if (width < w) { width = w; @@ -5442,13 +5447,13 @@ static void frame_setwidth(frame_T *curfrp, int width) */ take = width - curfrp->fr_width; - /* If there is not enough room, also reduce the width of a window - * with 'winfixwidth' set. */ + // If there is not enough room, also reduce the width of a window + // with 'winfixwidth' set. if (width > room - room_reserved) { room_reserved = room - width; } - /* If there is only a 'winfixwidth' window and making the - * window smaller, need to make the other window narrower. */ + // If there is only a 'winfixwidth' window and making the + // window smaller, need to make the other window narrower. if (take < 0 && room - curfrp->fr_width < room_reserved) { room_reserved = 0; } @@ -5557,8 +5562,8 @@ void win_drag_status_line(win_T *dragwin, int offset) curfr = fr; if (fr != topframe) { // more than one window fr = fr->fr_parent; - /* When the parent frame is not a column of frames, its parent should - * be. */ + // When the parent frame is not a column of frames, its parent should + // be. if (fr->fr_layout != FR_COL) { curfr = fr; if (fr != topframe) { // only a row of windows, may drag statusline @@ -6009,9 +6014,9 @@ void command_height(void) frame_T *frp; int old_p_ch = curtab->tp_ch_used; - /* Use the value of p_ch that we remembered. This is needed for when the - * GUI starts up, we can't be sure in what order things happen. And when - * p_ch was changed in another tab page. */ + // Use the value of p_ch that we remembered. This is needed for when the + // GUI starts up, we can't be sure in what order things happen. And when + // p_ch was changed in another tab page. curtab->tp_ch_used = p_ch; // Find bottom frame with width of screen. @@ -6270,8 +6275,8 @@ static void last_status_rec(frame_T *fr, bool statusline) EMSG(_(e_noroom)); return; } - /* In a column of frames: go to frame above. If already at - * the top or in a row of frames: go to parent. */ + // In a column of frames: go to frame above. If already at + // the top or in a row of frames: go to parent. if (fp->fr_parent->fr_layout == FR_COL && fp->fr_prev != NULL) { fp = fp->fr_prev; } else { @@ -6693,7 +6698,7 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, int prio, cur = cur->next; } } - if ((hlg_id = syn_check_group((const char_u *)grp, strlen(grp))) == 0) { + if ((hlg_id = syn_check_group(grp, strlen(grp))) == 0) { return -1; } if (pat != NULL && (regprog = vim_regcomp((char_u *)pat, RE_MAGIC)) == NULL) { @@ -7058,13 +7063,13 @@ void win_id2tabwin(typval_T *const argvars, typval_T *const rettv) tv_list_append_number(list, winnr); } -win_T * win_id2wp(typval_T *argvars) +win_T *win_id2wp(typval_T *argvars) { return win_id2wp_tp(argvars, NULL); } // Return the window and tab pointer of window "id". -win_T * win_id2wp_tp(typval_T *argvars, tabpage_T **tpp) +win_T *win_id2wp_tp(typval_T *argvars, tabpage_T **tpp) { int id = tv_get_number(&argvars[0]); diff --git a/src/nvim/window.h b/src/nvim/window.h index 82b3fe5e88..7e465a9f08 100644 --- a/src/nvim/window.h +++ b/src/nvim/window.h @@ -5,11 +5,11 @@ #include "nvim/buffer_defs.h" -/* Values for file_name_in_line() */ -#define FNAME_MESS 1 /* give error message */ -#define FNAME_EXP 2 /* expand to path */ -#define FNAME_HYP 4 /* check for hypertext link */ -#define FNAME_INCL 8 /* apply 'includeexpr' */ +// Values for file_name_in_line() +#define FNAME_MESS 1 // give error message +#define FNAME_EXP 2 // expand to path +#define FNAME_HYP 4 // check for hypertext link +#define FNAME_INCL 8 // apply 'includeexpr' #define FNAME_REL 16 /* ".." and "./" are relative to the (current) file instead of the current directory */ #define FNAME_UNESC 32 // remove backslashes used for escaping @@ -17,20 +17,20 @@ /* * arguments for win_split() */ -#define WSP_ROOM 1 /* require enough room */ -#define WSP_VERT 2 /* split vertically */ -#define WSP_TOP 4 /* window at top-left of shell */ -#define WSP_BOT 8 /* window at bottom-right of shell */ -#define WSP_HELP 16 /* creating the help window */ -#define WSP_BELOW 32 /* put new window below/right */ -#define WSP_ABOVE 64 /* put new window above/left */ -#define WSP_NEWLOC 128 /* don't copy location list */ +#define WSP_ROOM 1 // require enough room +#define WSP_VERT 2 // split vertically +#define WSP_TOP 4 // window at top-left of shell +#define WSP_BOT 8 // window at bottom-right of shell +#define WSP_HELP 16 // creating the help window +#define WSP_BELOW 32 // put new window below/right +#define WSP_ABOVE 64 // put new window above/left +#define WSP_NEWLOC 128 // don't copy location list /* * Minimum screen size */ -#define MIN_COLUMNS 12 /* minimal columns for screen */ -#define MIN_LINES 2 /* minimal lines for screen */ +#define MIN_COLUMNS 12 // minimal columns for screen +#define MIN_LINES 2 // minimal lines for screen #ifdef INCLUDE_GENERATED_DECLARATIONS # include "window.h.generated.h" diff --git a/src/uncrustify.cfg b/src/uncrustify.cfg new file mode 100644 index 0000000000..13d1f472ed --- /dev/null +++ b/src/uncrustify.cfg @@ -0,0 +1,3311 @@ +# Uncrustify-0.73.0-199-0dfafb27 + +# +# General options +# + +# The type of line endings. +# +# Default: auto +newlines = auto # lf/crlf/cr/auto + +# The original size of tabs in the input. +# +# Default: 8 +input_tab_size = 8 # unsigned number + +# The size of tabs in the output (only used if align_with_tabs=true). +# +# Default: 8 +output_tab_size = 8 # unsigned number + +# The ASCII value of the string escape char, usually 92 (\) or (Pawn) 94 (^). +# +# Default: 92 +string_escape_char = 92 # unsigned number + +# Alternate string escape char (usually only used for Pawn). +# Only works right before the quote char. +string_escape_char2 = 0 # unsigned number + +# Replace tab characters found in string literals with the escape sequence \t +# instead. +string_replace_tab_chars = false # true/false + +# Allow interpreting '>=' and '>>=' as part of a template in code like +# 'void f(list<list<B>>=val);'. If true, 'assert(x<0 && y>=3)' will be broken. +# Improvements to template detection may make this option obsolete. +tok_split_gte = false # true/false + +# Disable formatting of NL_CONT ('\\n') ended lines (e.g. multi-line macros). +disable_processing_nl_cont = false # true/false + +# Specify the marker used in comments to disable processing of part of the +# file. +# +# Default: *INDENT-OFF* +disable_processing_cmt = "uncrustify:off" # string + +# Specify the marker used in comments to (re)enable processing in a file. +# +# Default: *INDENT-ON* +enable_processing_cmt = "uncrustify:on" # string + +# Enable parsing of digraphs. +enable_digraphs = false # true/false + +# Option to allow both disable_processing_cmt and enable_processing_cmt +# strings, if specified, to be interpreted as ECMAScript regular expressions. +# If true, a regex search will be performed within comments according to the +# specified patterns in order to disable/enable processing. +processing_cmt_as_regex = false # true/false + +# Add or remove the UTF-8 BOM (recommend 'remove'). +utf8_bom = remove # ignore/add/remove/force/not_defined + +# If the file contains bytes with values between 128 and 255, but is not +# UTF-8, then output as UTF-8. +utf8_byte = false # true/false + +# Force the output encoding to UTF-8. +utf8_force = false # true/false + +# +# Spacing options +# + +# Add or remove space around non-assignment symbolic operators ('+', '/', '%', +# '<<', and so forth). +sp_arith = ignore # ignore/add/remove/force/not_defined + +# Add or remove space around arithmetic operators '+' and '-'. +# +# Overrides sp_arith. +sp_arith_additive = ignore # ignore/add/remove/force/not_defined + +# Add or remove space around assignment operator '=', '+=', etc. +sp_assign = ignore # ignore/add/remove/force/not_defined + +# Add or remove space around '=' in C++11 lambda capture specifications. +# +# Overrides sp_assign. +sp_cpp_lambda_assign = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after the capture specification of a C++11 lambda when +# an argument list is present, as in '[] <here> (int x){ ... }'. +sp_cpp_lambda_square_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after the capture specification of a C++11 lambda with +# no argument list is present, as in '[] <here> { ... }'. +sp_cpp_lambda_square_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after the opening parenthesis and before the closing +# parenthesis of a argument list of a C++11 lambda, as in +# '[]( <here> int x <here> ){ ... }'. +sp_cpp_lambda_argument_list = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after the argument list of a C++11 lambda, as in +# '[](int x) <here> { ... }'. +sp_cpp_lambda_paren_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between a lambda body and its call operator of an +# immediately invoked lambda, as in '[]( ... ){ ... } <here> ( ... )'. +sp_cpp_lambda_fparen = ignore # ignore/add/remove/force/not_defined + +# Add or remove space around assignment operator '=' in a prototype. +# +# If set to ignore, use sp_assign. +sp_assign_default = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before assignment operator '=', '+=', etc. +# +# Overrides sp_assign. +sp_before_assign = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after assignment operator '=', '+=', etc. +# +# Overrides sp_assign. +sp_after_assign = ignore # ignore/add/remove/force/not_defined + +# Add or remove space in 'NS_ENUM ('. +sp_enum_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space around assignment '=' in enum. +sp_enum_assign = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before assignment '=' in enum. +# +# Overrides sp_enum_assign. +sp_enum_before_assign = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after assignment '=' in enum. +# +# Overrides sp_enum_assign. +sp_enum_after_assign = ignore # ignore/add/remove/force/not_defined + +# Add or remove space around assignment ':' in enum. +sp_enum_colon = ignore # ignore/add/remove/force/not_defined + +# Add or remove space around preprocessor '##' concatenation operator. +# +# Default: add +sp_pp_concat = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after preprocessor '#' stringify operator. +# Also affects the '#@' charizing operator. +sp_pp_stringify = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before preprocessor '#' stringify operator +# as in '#define x(y) L#y'. +sp_before_pp_stringify = ignore # ignore/add/remove/force/not_defined + +# Add or remove space around boolean operators '&&' and '||'. +sp_bool = ignore # ignore/add/remove/force/not_defined + +# Add or remove space around compare operator '<', '>', '==', etc. +sp_compare = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside '(' and ')'. +sp_inside_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between nested parentheses, i.e. '((' vs. ') )'. +sp_paren_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between back-to-back parentheses, i.e. ')(' vs. ') ('. +sp_cparen_oparen = ignore # ignore/add/remove/force/not_defined + +# Whether to balance spaces inside nested parentheses. +sp_balance_nested_parens = false # true/false + +# Add or remove space between ')' and '{'. +sp_paren_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between nested braces, i.e. '{{' vs. '{ {'. +sp_brace_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before pointer star '*'. +sp_before_ptr_star = force # ignore/add/remove/force/not_defined + +# Add or remove space before pointer star '*' that isn't followed by a +# variable name. If set to ignore, sp_before_ptr_star is used instead. +sp_before_unnamed_ptr_star = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between pointer stars '*', as in 'int ***a;'. +sp_between_ptr_star = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after pointer star '*', if followed by a word. +# +# Overrides sp_type_func. +sp_after_ptr_star = remove # ignore/add/remove/force/not_defined + +# Add or remove space after pointer caret '^', if followed by a word. +sp_after_ptr_block_caret = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after pointer star '*', if followed by a qualifier. +sp_after_ptr_star_qualifier = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after a pointer star '*', if followed by a function +# prototype or function definition. +# +# Overrides sp_after_ptr_star and sp_type_func. +sp_after_ptr_star_func = remove # ignore/add/remove/force/not_defined + +# Add or remove space after a pointer star '*' in the trailing return of a +# function prototype or function definition. +sp_after_ptr_star_trailing = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after a pointer star '*', if followed by an open +# parenthesis, as in 'void* (*)()'. +sp_ptr_star_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before a pointer star '*', if followed by a function +# prototype or function definition. +sp_before_ptr_star_func = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before a pointer star '*' in the trailing return of a +# function prototype or function definition. +sp_before_ptr_star_trailing = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before a reference sign '&'. +sp_before_byref = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before a reference sign '&' that isn't followed by a +# variable name. If set to ignore, sp_before_byref is used instead. +sp_before_unnamed_byref = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after reference sign '&', if followed by a word. +# +# Overrides sp_type_func. +sp_after_byref = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after a reference sign '&', if followed by a function +# prototype or function definition. +# +# Overrides sp_after_byref and sp_type_func. +sp_after_byref_func = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before a reference sign '&', if followed by a function +# prototype or function definition. +sp_before_byref_func = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between type and word. In cases where total removal of +# whitespace would be a syntax error, a value of 'remove' is treated the same +# as 'force'. +# +# This also affects some other instances of space following a type that are +# not covered by other options; for example, between the return type and +# parenthesis of a function type template argument, between the type and +# parenthesis of an array parameter, or between 'decltype(...)' and the +# following word. +# +# Default: force +sp_after_type = force # ignore/add/remove/force/not_defined + +# Add or remove space between 'decltype(...)' and word, +# brace or function call. +sp_after_decltype = ignore # ignore/add/remove/force/not_defined + +# (D) Add or remove space before the parenthesis in the D constructs +# 'template Foo(' and 'class Foo('. +sp_before_template_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'template' and '<'. +# If set to ignore, sp_before_angle is used. +sp_template_angle = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before '<'. +sp_before_angle = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside '<' and '>'. +sp_inside_angle = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside '<>'. +sp_inside_angle_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between '>' and ':'. +sp_angle_colon = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after '>'. +sp_after_angle = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between '>' and '(' as found in 'new List<byte>(foo);'. +sp_angle_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between '>' and '()' as found in 'new List<byte>();'. +sp_angle_paren_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between '>' and a word as in 'List<byte> m;' or +# 'template <typename T> static ...'. +sp_angle_word = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between '>' and '>' in '>>' (template stuff). +# +# Default: add +sp_angle_shift = ignore # ignore/add/remove/force/not_defined + +# (C++11) Permit removal of the space between '>>' in 'foo<bar<int> >'. Note +# that sp_angle_shift cannot remove the space without this option. +sp_permit_cpp11_shift = false # true/false + +# Add or remove space before '(' of control statements ('if', 'for', 'switch', +# 'while', etc.). +sp_before_sparen = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside '(' and ')' of control statements. +sp_inside_sparen = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after '(' of control statements. +# +# Overrides sp_inside_sparen. +sp_inside_sparen_open = remove # ignore/add/remove/force/not_defined + +# Add or remove space before ')' of control statements. +# +# Overrides sp_inside_sparen. +sp_inside_sparen_close = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between '((' or '))' of control statements. +sp_sparen_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after ')' of control statements. +sp_after_sparen = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between ')' and '{' of control statements. +sp_sparen_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'do' and '{'. +sp_do_brace_open = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between '}' and 'while'. +sp_brace_close_while = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'while' and '('. Overrides sp_before_sparen. +sp_while_paren_open = ignore # ignore/add/remove/force/not_defined + +# (D) Add or remove space between 'invariant' and '('. +sp_invariant_paren = ignore # ignore/add/remove/force/not_defined + +# (D) Add or remove space after the ')' in 'invariant (C) c'. +sp_after_invariant_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before empty statement ';' on 'if', 'for' and 'while'. +sp_special_semi = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before ';'. +# +# Default: remove +sp_before_semi = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before ';' in non-empty 'for' statements. +sp_before_semi_for = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before a semicolon of an empty left part of a for +# statement, as in 'for ( <here> ; ; )'. +sp_before_semi_for_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between the semicolons of an empty middle part of a for +# statement, as in 'for ( ; <here> ; )'. +sp_between_semi_for_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after ';', except when followed by a comment. +# +# Default: add +sp_after_semi = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after ';' in non-empty 'for' statements. +# +# Default: force +sp_after_semi_for = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after the final semicolon of an empty part of a for +# statement, as in 'for ( ; ; <here> )'. +sp_after_semi_for_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before '[' (except '[]'). +sp_before_square = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before '[' for a variable definition. +# +# Default: remove +sp_before_vardef_square = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before '[' for asm block. +sp_before_square_asm_block = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before '[]'. +sp_before_squares = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before C++17 structured bindings. +sp_cpp_before_struct_binding = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside a non-empty '[' and ']'. +sp_inside_square = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside '[]'. +sp_inside_square_empty = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space inside a non-empty Objective-C boxed array '@[' and +# ']'. If set to ignore, sp_inside_square is used. +sp_inside_square_oc_array = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after ',', i.e. 'a,b' vs. 'a, b'. +sp_after_comma = add # ignore/add/remove/force/not_defined + +# Add or remove space before ',', i.e. 'a,b' vs. 'a ,b'. +# +# Default: remove +sp_before_comma = remove # ignore/add/remove/force/not_defined + +# (C#) Add or remove space between ',' and ']' in multidimensional array type +# like 'int[,,]'. +sp_after_mdatype_commas = ignore # ignore/add/remove/force/not_defined + +# (C#) Add or remove space between '[' and ',' in multidimensional array type +# like 'int[,,]'. +sp_before_mdatype_commas = ignore # ignore/add/remove/force/not_defined + +# (C#) Add or remove space between ',' in multidimensional array type +# like 'int[,,]'. +sp_between_mdatype_commas = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between an open parenthesis and comma, +# i.e. '(,' vs. '( ,'. +# +# Default: force +sp_paren_comma = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after the variadic '...' when preceded by a +# non-punctuator. +# The value REMOVE will be overriden with FORCE +sp_after_ellipsis = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before the variadic '...' when preceded by a +# non-punctuator. +# The value REMOVE will be overriden with FORCE +sp_before_ellipsis = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between a type and '...'. +sp_type_ellipsis = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between a '*' and '...'. +sp_ptr_type_ellipsis = ignore # ignore/add/remove/force/not_defined + +# (D) Add or remove space between a type and '?'. +sp_type_question = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between ')' and '...'. +sp_paren_ellipsis = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between '&&' and '...'. +sp_byref_ellipsis = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between ')' and a qualifier such as 'const'. +sp_paren_qualifier = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between ')' and 'noexcept'. +sp_paren_noexcept = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after class ':'. +sp_after_class_colon = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before class ':'. +sp_before_class_colon = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after class constructor ':'. +# +# Default: add +sp_after_constr_colon = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before class constructor ':'. +# +# Default: add +sp_before_constr_colon = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before case ':'. +# +# Default: remove +sp_before_case_colon = remove # ignore/add/remove/force/not_defined + +# Add or remove space between 'operator' and operator sign. +sp_after_operator = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between the operator symbol and the open parenthesis, as +# in 'operator ++('. +sp_after_operator_sym = ignore # ignore/add/remove/force/not_defined + +# Overrides sp_after_operator_sym when the operator has no arguments, as in +# 'operator *()'. +sp_after_operator_sym_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after C/D cast, i.e. 'cast(int)a' vs. 'cast(int) a' or +# '(int)a' vs. '(int) a'. +sp_after_cast = remove # ignore/add/remove/force/not_defined + +# Add or remove spaces inside cast parentheses. +sp_inside_paren_cast = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between the type and open parenthesis in a C++ cast, +# i.e. 'int(exp)' vs. 'int (exp)'. +sp_cpp_cast_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'sizeof' and '('. +sp_sizeof_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'sizeof' and '...'. +sp_sizeof_ellipsis = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'sizeof...' and '('. +sp_sizeof_ellipsis_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between '...' and a parameter pack. +sp_ellipsis_parameter_pack = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between a parameter pack and '...'. +sp_parameter_pack_ellipsis = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'decltype' and '('. +sp_decltype_paren = ignore # ignore/add/remove/force/not_defined + +# (Pawn) Add or remove space after the tag keyword. +sp_after_tag = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside enum '{' and '}'. +sp_inside_braces_enum = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside struct/union '{' and '}'. +sp_inside_braces_struct = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space inside Objective-C boxed dictionary '{' and '}' +sp_inside_braces_oc_dict = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after open brace in an unnamed temporary +# direct-list-initialization +# if statement is a brace_init_lst +# works only if sp_brace_brace is set to ignore. +sp_after_type_brace_init_lst_open = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before close brace in an unnamed temporary +# direct-list-initialization +# if statement is a brace_init_lst +# works only if sp_brace_brace is set to ignore. +sp_before_type_brace_init_lst_close = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside an unnamed temporary direct-list-initialization +# if statement is a brace_init_lst +# works only if sp_brace_brace is set to ignore +# works only if sp_before_type_brace_init_lst_close is set to ignore. +sp_inside_type_brace_init_lst = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside '{' and '}'. +sp_inside_braces = add # ignore/add/remove/force/not_defined + +# Add or remove space inside '{}'. +sp_inside_braces_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove space around trailing return operator '->'. +sp_trailing_return = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between return type and function name. A minimum of 1 +# is forced except for pointer return types. +sp_type_func = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between type and open brace of an unnamed temporary +# direct-list-initialization. +sp_type_brace_init_lst = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between function name and '(' on function declaration. +sp_func_proto_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between function name and '()' on function declaration +# without parameters. +sp_func_proto_paren_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between function name and '(' with a typedef specifier. +sp_func_type_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between alias name and '(' of a non-pointer function type typedef. +sp_func_def_paren = remove # ignore/add/remove/force/not_defined + +# Add or remove space between function name and '()' on function definition +# without parameters. +sp_func_def_paren_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside empty function '()'. +# Overrides sp_after_angle unless use_sp_after_angle_always is set to true. +sp_inside_fparens = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside function '(' and ')'. +sp_inside_fparen = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside the first parentheses in a function type, as in +# 'void (*x)(...)'. +sp_inside_tparen = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between the ')' and '(' in a function type, as in +# 'void (*x)(...)'. +sp_after_tparen_close = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between ']' and '(' when part of a function call. +sp_square_fparen = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between ')' and '{' of function. +sp_fparen_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between ')' and '{' of a function call in object +# initialization. +# +# Overrides sp_fparen_brace. +sp_fparen_brace_initializer = ignore # ignore/add/remove/force/not_defined + +# (Java) Add or remove space between ')' and '{{' of double brace initializer. +sp_fparen_dbrace = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between function name and '(' on function calls. +sp_func_call_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between function name and '()' on function calls without +# parameters. If set to ignore (the default), sp_func_call_paren is used. +sp_func_call_paren_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between the user function name and '(' on function +# calls. You need to set a keyword to be a user function in the config file, +# like: +# set func_call_user tr _ i18n +sp_func_call_user_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside user function '(' and ')'. +sp_func_call_user_inside_fparen = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between nested parentheses with user functions, +# i.e. '((' vs. '( ('. +sp_func_call_user_paren_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between a constructor/destructor and the open +# parenthesis. +sp_func_class_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between a constructor without parameters or destructor +# and '()'. +sp_func_class_paren_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'return' and '('. +sp_return_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'return' and '{'. +sp_return_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between '__attribute__' and '('. +sp_attribute_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'defined' and '(' in '#if defined (FOO)'. +sp_defined_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'throw' and '(' in 'throw (something)'. +sp_throw_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'throw' and anything other than '(' as in +# '@throw [...];'. +sp_after_throw = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'catch' and '(' in 'catch (something) { }'. +# If set to ignore, sp_before_sparen is used. +sp_catch_paren = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space between '@catch' and '(' +# in '@catch (something) { }'. If set to ignore, sp_catch_paren is used. +sp_oc_catch_paren = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space before Objective-C protocol list +# as in '@protocol Protocol<here><Protocol_A>' or '@interface MyClass : NSObject<here><MyProtocol>'. +sp_before_oc_proto_list = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space between class name and '(' +# in '@interface className(categoryName)<ProtocolName>:BaseClass' +sp_oc_classname_paren = ignore # ignore/add/remove/force/not_defined + +# (D) Add or remove space between 'version' and '(' +# in 'version (something) { }'. If set to ignore, sp_before_sparen is used. +sp_version_paren = ignore # ignore/add/remove/force/not_defined + +# (D) Add or remove space between 'scope' and '(' +# in 'scope (something) { }'. If set to ignore, sp_before_sparen is used. +sp_scope_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'super' and '(' in 'super (something)'. +# +# Default: remove +sp_super_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'this' and '(' in 'this (something)'. +# +# Default: remove +sp_this_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between a macro name and its definition. +sp_macro = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between a macro function ')' and its definition. +sp_macro_func = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'else' and '{' if on the same line. +sp_else_brace = add # ignore/add/remove/force/not_defined + +# Add or remove space between '}' and 'else' if on the same line. +sp_brace_else = add # ignore/add/remove/force/not_defined + +# Add or remove space between '}' and the name of a typedef on the same line. +sp_brace_typedef = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before the '{' of a 'catch' statement, if the '{' and +# 'catch' are on the same line, as in 'catch (decl) <here> {'. +sp_catch_brace = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space before the '{' of a '@catch' statement, if the '{' +# and '@catch' are on the same line, as in '@catch (decl) <here> {'. +# If set to ignore, sp_catch_brace is used. +sp_oc_catch_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between '}' and 'catch' if on the same line. +sp_brace_catch = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space between '}' and '@catch' if on the same line. +# If set to ignore, sp_brace_catch is used. +sp_oc_brace_catch = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'finally' and '{' if on the same line. +sp_finally_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between '}' and 'finally' if on the same line. +sp_brace_finally = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'try' and '{' if on the same line. +sp_try_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between get/set and '{' if on the same line. +sp_getset_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between a variable and '{' for C++ uniform +# initialization. +sp_word_brace_init_lst = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between a variable and '{' for a namespace. +# +# Default: add +sp_word_brace_ns = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before the '::' operator. +sp_before_dc = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after the '::' operator. +sp_after_dc = ignore # ignore/add/remove/force/not_defined + +# (D) Add or remove around the D named array initializer ':' operator. +sp_d_array_colon = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after the '!' (not) unary operator. +# +# Default: remove +sp_not = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after the '~' (invert) unary operator. +# +# Default: remove +sp_inv = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after the '&' (address-of) unary operator. This does not +# affect the spacing after a '&' that is part of a type. +# +# Default: remove +sp_addr = ignore # ignore/add/remove/force/not_defined + +# Add or remove space around the '.' or '->' operators. +# +# Default: remove +sp_member = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after the '*' (dereference) unary operator. This does +# not affect the spacing after a '*' that is part of a type. +# +# Default: remove +sp_deref = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. +# +# Default: remove +sp_sign = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between '++' and '--' the word to which it is being +# applied, as in '(--x)' or 'y++;'. +# +# Default: remove +sp_incdec = remove # ignore/add/remove/force/not_defined + +# Add or remove space before a backslash-newline at the end of a line. +# +# Default: add +sp_before_nl_cont = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space after the scope '+' or '-', as in '-(void) foo;' +# or '+(int) bar;'. +sp_after_oc_scope = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space after the colon in message specs, +# i.e. '-(int) f:(int) x;' vs. '-(int) f: (int) x;'. +sp_after_oc_colon = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space before the colon in message specs, +# i.e. '-(int) f: (int) x;' vs. '-(int) f : (int) x;'. +sp_before_oc_colon = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space after the colon in immutable dictionary expression +# 'NSDictionary *test = @{@"foo" :@"bar"};'. +sp_after_oc_dict_colon = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space before the colon in immutable dictionary expression +# 'NSDictionary *test = @{@"foo" :@"bar"};'. +sp_before_oc_dict_colon = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space after the colon in message specs, +# i.e. '[object setValue:1];' vs. '[object setValue: 1];'. +sp_after_send_oc_colon = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space before the colon in message specs, +# i.e. '[object setValue:1];' vs. '[object setValue :1];'. +sp_before_send_oc_colon = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space after the (type) in message specs, +# i.e. '-(int)f: (int) x;' vs. '-(int)f: (int)x;'. +sp_after_oc_type = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space after the first (type) in message specs, +# i.e. '-(int) f:(int)x;' vs. '-(int)f:(int)x;'. +sp_after_oc_return_type = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space between '@selector' and '(', +# i.e. '@selector(msgName)' vs. '@selector (msgName)'. +# Also applies to '@protocol()' constructs. +sp_after_oc_at_sel = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space between '@selector(x)' and the following word, +# i.e. '@selector(foo) a:' vs. '@selector(foo)a:'. +sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space inside '@selector' parentheses, +# i.e. '@selector(foo)' vs. '@selector( foo )'. +# Also applies to '@protocol()' constructs. +sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space before a block pointer caret, +# i.e. '^int (int arg){...}' vs. ' ^int (int arg){...}'. +sp_before_oc_block_caret = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space after a block pointer caret, +# i.e. '^int (int arg){...}' vs. '^ int (int arg){...}'. +sp_after_oc_block_caret = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space between the receiver and selector in a message, +# as in '[receiver selector ...]'. +sp_after_oc_msg_receiver = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space after '@property'. +sp_after_oc_property = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove space between '@synchronized' and the open parenthesis, +# i.e. '@synchronized(foo)' vs. '@synchronized (foo)'. +sp_after_oc_synchronized = ignore # ignore/add/remove/force/not_defined + +# Add or remove space around the ':' in 'b ? t : f'. +sp_cond_colon = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before the ':' in 'b ? t : f'. +# +# Overrides sp_cond_colon. +sp_cond_colon_before = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after the ':' in 'b ? t : f'. +# +# Overrides sp_cond_colon. +sp_cond_colon_after = ignore # ignore/add/remove/force/not_defined + +# Add or remove space around the '?' in 'b ? t : f'. +sp_cond_question = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before the '?' in 'b ? t : f'. +# +# Overrides sp_cond_question. +sp_cond_question_before = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after the '?' in 'b ? t : f'. +# +# Overrides sp_cond_question. +sp_cond_question_after = ignore # ignore/add/remove/force/not_defined + +# In the abbreviated ternary form '(a ?: b)', add or remove space between '?' +# and ':'. +# +# Overrides all other sp_cond_* options. +sp_cond_ternary_short = ignore # ignore/add/remove/force/not_defined + +# Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make +# sense here. +sp_case_label = ignore # ignore/add/remove/force/not_defined + +# (D) Add or remove space around the D '..' operator. +sp_range = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after ':' in a Java/C++11 range-based 'for', +# as in 'for (Type var : <here> expr)'. +sp_after_for_colon = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before ':' in a Java/C++11 range-based 'for', +# as in 'for (Type var <here> : expr)'. +sp_before_for_colon = ignore # ignore/add/remove/force/not_defined + +# (D) Add or remove space between 'extern' and '(' as in 'extern <here> (C)'. +sp_extern_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after the opening of a C++ comment, as in '// <here> A'. +sp_cmt_cpp_start = ignore # ignore/add/remove/force/not_defined + +# Add or remove space in a C++ region marker comment, as in '// <here> BEGIN'. +# A region marker is defined as a comment which is not preceded by other text +# (i.e. the comment is the first non-whitespace on the line), and which starts +# with either 'BEGIN' or 'END'. +# +# Overrides sp_cmt_cpp_start. +sp_cmt_cpp_region = ignore # ignore/add/remove/force/not_defined + +# If true, space added with sp_cmt_cpp_start will be added after Doxygen +# sequences like '///', '///<', '//!' and '//!<'. +sp_cmt_cpp_doxygen = false # true/false + +# If true, space added with sp_cmt_cpp_start will be added after Qt translator +# or meta-data comments like '//:', '//=', and '//~'. +sp_cmt_cpp_qttr = false # true/false + +# Add or remove space between #else or #endif and a trailing comment. +sp_endif_cmt = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after 'new', 'delete' and 'delete[]'. +sp_after_new = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between 'new' and '(' in 'new()'. +sp_between_new_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between ')' and type in 'new(foo) BAR'. +sp_after_newop_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside parenthesis of the new operator +# as in 'new(foo) BAR'. +sp_inside_newop_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after the open parenthesis of the new operator, +# as in 'new(foo) BAR'. +# +# Overrides sp_inside_newop_paren. +sp_inside_newop_paren_open = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before the close parenthesis of the new operator, +# as in 'new(foo) BAR'. +# +# Overrides sp_inside_newop_paren. +sp_inside_newop_paren_close = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before a trailing or embedded comment. +sp_before_tr_emb_cmt = add # ignore/add/remove/force/not_defined + +# Number of spaces before a trailing or embedded comment. +sp_num_before_tr_emb_cmt = 2 # unsigned number + +# (Java) Add or remove space between an annotation and the open parenthesis. +sp_annotation_paren = ignore # ignore/add/remove/force/not_defined + +# If true, vbrace tokens are dropped to the previous token and skipped. +sp_skip_vbrace_tokens = false # true/false + +# Add or remove space after 'noexcept'. +sp_after_noexcept = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after '_'. +sp_vala_after_translation = ignore # ignore/add/remove/force/not_defined + +# If true, a <TAB> is inserted after #define. +force_tab_after_define = false # true/false + +# +# Indenting options +# + +# The number of columns to indent per level. Usually 2, 3, 4, or 8. +# +# Default: 8 +indent_columns = 2 # unsigned number + +# The continuation indent. If non-zero, this overrides the indent of '(', '[' +# and '=' continuation indents. Negative values are OK; negative value is +# absolute and not increased for each '(' or '[' level. +# +# For FreeBSD, this is set to 4. +indent_continue = 0 # number + +# The continuation indent, only for class header line(s). If non-zero, this +# overrides the indent of 'class' continuation indents. +indent_continue_class_head = 0 # unsigned number + +# Whether to indent empty lines (i.e. lines which contain only spaces before +# the newline character). +indent_single_newlines = false # true/false + +# The continuation indent for func_*_param if they are true. If non-zero, this +# overrides the indent. +indent_param = 0 # unsigned number + +# How to use tabs when indenting code. +# +# 0: Spaces only +# 1: Indent with tabs to brace level, align with spaces (default) +# 2: Indent and align with tabs, using spaces when not on a tabstop +# +# Default: 1 +indent_with_tabs = 0 # unsigned number + +# Whether to indent comments that are not at a brace level with tabs on a +# tabstop. Requires indent_with_tabs=2. If false, will use spaces. +indent_cmt_with_tabs = false # true/false + +# Whether to indent strings broken by '\' so that they line up. +indent_align_string = false # true/false + +# The number of spaces to indent multi-line XML strings. +# Requires indent_align_string=true. +indent_xml_string = 0 # unsigned number + +# Spaces to indent '{' from level. +indent_brace = 0 # unsigned number + +# Whether braces are indented to the body level. +indent_braces = false # true/false + +# Whether to disable indenting function braces if indent_braces=true. +indent_braces_no_func = false # true/false + +# Whether to disable indenting class braces if indent_braces=true. +indent_braces_no_class = false # true/false + +# Whether to disable indenting struct braces if indent_braces=true. +indent_braces_no_struct = false # true/false + +# Whether to indent based on the size of the brace parent, +# i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc. +indent_brace_parent = false # true/false + +# Whether to indent based on the open parenthesis instead of the open brace +# in '({\n'. +indent_paren_open_brace = false # true/false + +# (C#) Whether to indent the brace of a C# delegate by another level. +indent_cs_delegate_brace = false # true/false + +# (C#) Whether to indent a C# delegate (to handle delegates with no brace) by +# another level. +indent_cs_delegate_body = false # true/false + +# Whether to indent the body of a 'namespace'. +indent_namespace = false # true/false + +# Whether to indent only the first namespace, and not any nested namespaces. +# Requires indent_namespace=true. +indent_namespace_single_indent = false # true/false + +# The number of spaces to indent a namespace block. +# If set to zero, use the value indent_columns +indent_namespace_level = 0 # unsigned number + +# If the body of the namespace is longer than this number, it won't be +# indented. Requires indent_namespace=true. 0 means no limit. +indent_namespace_limit = 0 # unsigned number + +# Whether the 'extern "C"' body is indented. +indent_extern = false # true/false + +# Whether the 'class' body is indented. +indent_class = false # true/false + +# Additional indent before the leading base class colon. +# Negative values decrease indent down to the first column. +# Requires a newline break before colon (see pos_class_colon +# and nl_class_colon) +indent_before_class_colon = 0 # number + +# Whether to indent the stuff after a leading base class colon. +indent_class_colon = false # true/false + +# Whether to indent based on a class colon instead of the stuff after the +# colon. Requires indent_class_colon=true. +indent_class_on_colon = false # true/false + +# Whether to indent the stuff after a leading class initializer colon. +indent_constr_colon = false # true/false + +# Virtual indent from the ':' for leading member initializers. +# +# Default: 2 +indent_ctor_init_leading = 2 # unsigned number + +# Virtual indent from the ':' for following member initializers. +# +# Default: 2 +indent_ctor_init_following = 2 # unsigned number + +# Additional indent for constructor initializer list. +# Negative values decrease indent down to the first column. +indent_ctor_init = 0 # number + +# Whether to indent 'if' following 'else' as a new block under the 'else'. +# If false, 'else\nif' is treated as 'else if' for indenting purposes. +indent_else_if = false # true/false + +# Amount to indent variable declarations after a open brace. +# +# <0: Relative +# >=0: Absolute +indent_var_def_blk = 0 # number + +# Whether to indent continued variable declarations instead of aligning. +indent_var_def_cont = false # true/false + +# Whether to indent continued shift expressions ('<<' and '>>') instead of +# aligning. Set align_left_shift=false when enabling this. +indent_shift = false # true/false + +# Whether to force indentation of function definitions to start in column 1. +indent_func_def_force_col1 = false # true/false + +# Whether to indent continued function call parameters one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_call_param = false # true/false + +# Whether to indent continued function definition parameters one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_def_param = false # true/false + +# for function definitions, only if indent_func_def_param is false +# Allows to align params when appropriate and indent them when not +# behave as if it was true if paren position is more than this value +# if paren position is more than the option value +indent_func_def_param_paren_pos_threshold = 0 # unsigned number + +# Whether to indent continued function call prototype one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_proto_param = false # true/false + +# Whether to indent continued function call declaration one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_class_param = false # true/false + +# Whether to indent continued class variable constructors one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_ctor_var_param = false # true/false + +# Whether to indent continued template parameter list one indent level, +# rather than aligning parameters under the open parenthesis. +indent_template_param = false # true/false + +# Double the indent for indent_func_xxx_param options. +# Use both values of the options indent_columns and indent_param. +indent_func_param_double = false # true/false + +# Indentation column for standalone 'const' qualifier on a function +# prototype. +indent_func_const = 0 # unsigned number + +# Indentation column for standalone 'throw' qualifier on a function +# prototype. +indent_func_throw = 0 # unsigned number + +# How to indent within a macro followed by a brace on the same line +# This allows reducing the indent in macros that have (for example) +# `do { ... } while (0)` blocks bracketing them. +# +# true: add an indent for the brace on the same line as the macro +# false: do not add an indent for the brace on the same line as the macro +# +# Default: true +indent_macro_brace = false # true/false + +# The number of spaces to indent a continued '->' or '.'. +# Usually set to 0, 1, or indent_columns. +indent_member = 0 # unsigned number + +# Whether lines broken at '.' or '->' should be indented by a single indent. +# The indent_member option will not be effective if this is set to true. +indent_member_single = false # true/false + +# Spaces to indent single line ('//') comments on lines before code. +indent_single_line_comments_before = 0 # unsigned number + +# Spaces to indent single line ('//') comments on lines after code. +indent_single_line_comments_after = 0 # unsigned number + +# When opening a paren for a control statement (if, for, while, etc), increase +# the indent level by this value. Negative values decrease the indent level. +indent_sparen_extra = 0 # number + +# Whether to indent trailing single line ('//') comments relative to the code +# instead of trying to keep the same absolute column. +indent_relative_single_line_comments = true # true/false + +# Spaces to indent 'case' from 'switch'. Usually 0 or indent_columns. +# It might wise to choose the same value for the option indent_case_brace. +indent_switch_case = 0 # unsigned number + +# Spaces to indent '{' from 'case'. By default, the brace will appear under +# the 'c' in case. Usually set to 0 or indent_columns. Negative values are OK. +# It might wise to choose the same value for the option indent_switch_case. +indent_case_brace = 0 # number + +# indent 'break' with 'case' from 'switch'. +indent_switch_break_with_case = false # true/false + +# Whether to indent preprocessor statements inside of switch statements. +# +# Default: true +indent_switch_pp = true # true/false + +# Spaces to shift the 'case' line, without affecting any other lines. +# Usually 0. +indent_case_shift = 0 # unsigned number + +# Whether to indent comments found in first column. +indent_col1_comment = false # true/false + +# Whether to indent multi string literal in first column. +indent_col1_multi_string_literal = false # true/false + +# How to indent goto labels. +# +# >0: Absolute column where 1 is the leftmost column +# <=0: Subtract from brace indent +# +# Default: 1 +indent_label = 1 # number + +# How to indent access specifiers that are followed by a +# colon. +# +# >0: Absolute column where 1 is the leftmost column +# <=0: Subtract from brace indent +# +# Default: 1 +indent_access_spec = 1 # number + +# Whether to indent the code after an access specifier by one level. +# If true, this option forces 'indent_access_spec=0'. +indent_access_spec_body = false # true/false + +# If an open parenthesis is followed by a newline, whether to indent the next +# line so that it lines up after the open parenthesis (not recommended). +indent_paren_nl = false # true/false + +# How to indent a close parenthesis after a newline. +# +# 0: Indent to body level (default) +# 1: Align under the open parenthesis +# 2: Indent to the brace level +indent_paren_close = 0 # unsigned number + +# Whether to indent the open parenthesis of a function definition, +# if the parenthesis is on its own line. +indent_paren_after_func_def = false # true/false + +# Whether to indent the open parenthesis of a function declaration, +# if the parenthesis is on its own line. +indent_paren_after_func_decl = false # true/false + +# Whether to indent the open parenthesis of a function call, +# if the parenthesis is on its own line. +indent_paren_after_func_call = true # true/false + +# Whether to indent a comma when inside a brace. +# If true, aligns under the open brace. +indent_comma_brace = false # true/false + +# Whether to indent a comma when inside a parenthesis. +# If true, aligns under the open parenthesis. +indent_comma_paren = false # true/false + +# Whether to indent a Boolean operator when inside a parenthesis. +# If true, aligns under the open parenthesis. +indent_bool_paren = false # true/false + +# Whether to indent a semicolon when inside a for parenthesis. +# If true, aligns under the open for parenthesis. +indent_semicolon_for_paren = false # true/false + +# Whether to align the first expression to following ones +# if indent_bool_paren=true. +indent_first_bool_expr = false # true/false + +# Whether to align the first expression to following ones +# if indent_semicolon_for_paren=true. +indent_first_for_expr = false # true/false + +# If an open square is followed by a newline, whether to indent the next line +# so that it lines up after the open square (not recommended). +indent_square_nl = false # true/false + +# (ESQL/C) Whether to preserve the relative indent of 'EXEC SQL' bodies. +indent_preserve_sql = false # true/false + +# Whether to align continued statements at the '='. If false or if the '=' is +# followed by a newline, the next line is indent one tab. +# +# Default: true +indent_align_assign = true # true/false + +# If true, the indentation of the chunks after a '=' sequence will be set at +# LHS token indentation column before '='. +indent_off_after_assign = false # true/false + +# Whether to align continued statements at the '('. If false or the '(' is +# followed by a newline, the next line indent is one tab. +# +# Default: true +indent_align_paren = true # true/false + +# (OC) Whether to indent Objective-C code inside message selectors. +indent_oc_inside_msg_sel = false # true/false + +# (OC) Whether to indent Objective-C blocks at brace level instead of usual +# rules. +indent_oc_block = false # true/false + +# (OC) Indent for Objective-C blocks in a message relative to the parameter +# name. +# +# =0: Use indent_oc_block rules +# >0: Use specified number of spaces to indent +indent_oc_block_msg = 0 # unsigned number + +# (OC) Minimum indent for subsequent parameters +indent_oc_msg_colon = 0 # unsigned number + +# (OC) Whether to prioritize aligning with initial colon (and stripping spaces +# from lines, if necessary). +# +# Default: true +indent_oc_msg_prioritize_first_colon = true # true/false + +# (OC) Whether to indent blocks the way that Xcode does by default +# (from the keyword if the parameter is on its own line; otherwise, from the +# previous indentation level). Requires indent_oc_block_msg=true. +indent_oc_block_msg_xcode_style = false # true/false + +# (OC) Whether to indent blocks from where the brace is, relative to a +# message keyword. Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_keyword = false # true/false + +# (OC) Whether to indent blocks from where the brace is, relative to a message +# colon. Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_colon = false # true/false + +# (OC) Whether to indent blocks from where the block caret is. +# Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_caret = false # true/false + +# (OC) Whether to indent blocks from where the brace caret is. +# Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_brace = false # true/false + +# When indenting after virtual brace open and newline add further spaces to +# reach this minimum indent. +indent_min_vbrace_open = 0 # unsigned number + +# Whether to add further spaces after regular indent to reach next tabstop +# when indenting after virtual brace open and newline. +indent_vbrace_open_on_tabstop = false # true/false + +# How to indent after a brace followed by another token (not a newline). +# true: indent all contained lines to match the token +# false: indent all contained lines to match the brace +# +# Default: true +indent_token_after_brace = true # true/false + +# Whether to indent the body of a C++11 lambda. +indent_cpp_lambda_body = false # true/false + +# How to indent compound literals that are being returned. +# true: add both the indent from return & the compound literal open brace +# (i.e. 2 indent levels) +# false: only indent 1 level, don't add the indent for the open brace, only +# add the indent for the return. +# +# Default: true +indent_compound_literal_return = false # true/false + +# (C#) Whether to indent a 'using' block if no braces are used. +# +# Default: true +indent_using_block = true # true/false + +# How to indent the continuation of ternary operator. +# +# 0: Off (default) +# 1: When the `if_false` is a continuation, indent it under `if_false` +# 2: When the `:` is a continuation, indent it under `?` +indent_ternary_operator = 2 # unsigned number + +# Whether to indent the statements inside ternary operator. +indent_inside_ternary_operator = false # true/false + +# If true, the indentation of the chunks after a `return` sequence will be set at return indentation column. +indent_off_after_return = false # true/false + +# If true, the indentation of the chunks after a `return new` sequence will be set at return indentation column. +indent_off_after_return_new = false # true/false + +# If true, the tokens after return are indented with regular single indentation. By default (false) the indentation is after the return token. +indent_single_after_return = false # true/false + +# Whether to ignore indent and alignment for 'asm' blocks (i.e. assume they +# have their own indentation). +indent_ignore_asm_block = false # true/false + +# Don't indent the close parenthesis of a function definition, +# if the parenthesis is on its own line. +donot_indent_func_def_close_paren = false # true/false + +# +# Newline adding and removing options +# + +# Whether to collapse empty blocks between '{' and '}'. +# If true, overrides nl_inside_empty_func +nl_collapse_empty_body = false # true/false + +# Don't split one-line braced assignments, as in 'foo_t f = { 1, 2 };'. +nl_assign_leave_one_liners = false # true/false + +# Don't split one-line braced statements inside a 'class xx { }' body. +nl_class_leave_one_liners = false # true/false + +# Don't split one-line enums, as in 'enum foo { BAR = 15 };' +nl_enum_leave_one_liners = false # true/false + +# Don't split one-line get or set functions. +nl_getset_leave_one_liners = false # true/false + +# (C#) Don't split one-line property get or set functions. +nl_cs_property_leave_one_liners = false # true/false + +# Don't split one-line function definitions, as in 'int foo() { return 0; }'. +# might modify nl_func_type_name +nl_func_leave_one_liners = false # true/false + +# Don't split one-line C++11 lambdas, as in '[]() { return 0; }'. +nl_cpp_lambda_leave_one_liners = false # true/false + +# Don't split one-line if/else statements, as in 'if(...) b++;'. +nl_if_leave_one_liners = false # true/false + +# Don't split one-line while statements, as in 'while(...) b++;'. +nl_while_leave_one_liners = false # true/false + +# Don't split one-line do statements, as in 'do { b++; } while(...);'. +nl_do_leave_one_liners = false # true/false + +# Don't split one-line for statements, as in 'for(...) b++;'. +nl_for_leave_one_liners = false # true/false + +# (OC) Don't split one-line Objective-C messages. +nl_oc_msg_leave_one_liner = false # true/false + +# (OC) Add or remove newline between method declaration and '{'. +nl_oc_mdef_brace = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove newline between Objective-C block signature and '{'. +nl_oc_block_brace = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove blank line before '@interface' statement. +nl_oc_before_interface = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove blank line before '@implementation' statement. +nl_oc_before_implementation = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove blank line before '@end' statement. +nl_oc_before_end = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove newline between '@interface' and '{'. +nl_oc_interface_brace = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove newline between '@implementation' and '{'. +nl_oc_implementation_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newlines at the start of the file. +nl_start_of_file = ignore # ignore/add/remove/force/not_defined + +# The minimum number of newlines at the start of the file (only used if +# nl_start_of_file is 'add' or 'force'). +nl_start_of_file_min = 0 # unsigned number + +# Add or remove newline at the end of the file. +nl_end_of_file = ignore # ignore/add/remove/force/not_defined + +# The minimum number of newlines at the end of the file (only used if +# nl_end_of_file is 'add' or 'force'). +nl_end_of_file_min = 0 # unsigned number + +# Add or remove newline between '=' and '{'. +nl_assign_brace = ignore # ignore/add/remove/force/not_defined + +# (D) Add or remove newline between '=' and '['. +nl_assign_square = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between '[]' and '{'. +nl_tsquare_brace = ignore # ignore/add/remove/force/not_defined + +# (D) Add or remove newline after '= ['. Will also affect the newline before +# the ']'. +nl_after_square_assign = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between a function call's ')' and '{', as in +# 'list_for_each(item, &list) { }'. +nl_fcall_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'enum' and '{'. +nl_enum_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'enum' and 'class'. +nl_enum_class = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'enum class' and the identifier. +nl_enum_class_identifier = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'enum class' type and ':'. +nl_enum_identifier_colon = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'enum class identifier :' and type. +nl_enum_colon_type = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'struct and '{'. +nl_struct_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'union' and '{'. +nl_union_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'if' and '{'. +nl_if_brace = remove # ignore/add/remove/force/not_defined + +# Add or remove newline between '}' and 'else'. +nl_brace_else = remove # ignore/add/remove/force/not_defined + +# Add or remove newline between 'else if' and '{'. If set to ignore, +# nl_if_brace is used instead. +nl_elseif_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'else' and '{'. +nl_else_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'else' and 'if'. +nl_else_if = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline before '{' opening brace +nl_before_opening_brace_func_class_def = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline before 'if'/'else if' closing parenthesis. +nl_before_if_closing_paren = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between '}' and 'finally'. +nl_brace_finally = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'finally' and '{'. +nl_finally_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'try' and '{'. +nl_try_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between get/set and '{'. +nl_getset_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'for' and '{'. +nl_for_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline before the '{' of a 'catch' statement, as in +# 'catch (decl) <here> {'. +nl_catch_brace = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove newline before the '{' of a '@catch' statement, as in +# '@catch (decl) <here> {'. If set to ignore, nl_catch_brace is used. +nl_oc_catch_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between '}' and 'catch'. +nl_brace_catch = ignore # ignore/add/remove/force/not_defined + +# (OC) Add or remove newline between '}' and '@catch'. If set to ignore, +# nl_brace_catch is used. +nl_oc_brace_catch = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between '}' and ']'. +nl_brace_square = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between '}' and ')' in a function invocation. +nl_brace_fparen = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'while' and '{'. +nl_while_brace = ignore # ignore/add/remove/force/not_defined + +# (D) Add or remove newline between 'scope (x)' and '{'. +nl_scope_brace = ignore # ignore/add/remove/force/not_defined + +# (D) Add or remove newline between 'unittest' and '{'. +nl_unittest_brace = ignore # ignore/add/remove/force/not_defined + +# (D) Add or remove newline between 'version (x)' and '{'. +nl_version_brace = ignore # ignore/add/remove/force/not_defined + +# (C#) Add or remove newline between 'using' and '{'. +nl_using_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between two open or close braces. Due to general +# newline/brace handling, REMOVE may not work. +nl_brace_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'do' and '{'. +nl_do_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between '}' and 'while' of 'do' statement. +nl_brace_while = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'switch' and '{'. +nl_switch_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'synchronized' and '{'. +nl_synchronized_brace = ignore # ignore/add/remove/force/not_defined + +# Add a newline between ')' and '{' if the ')' is on a different line than the +# if/for/etc. +# +# Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch and +# nl_catch_brace. +nl_multi_line_cond = false # true/false + +# Add a newline after '(' if an if/for/while/switch condition spans multiple +# lines +nl_multi_line_sparen_open = ignore # ignore/add/remove/force/not_defined + +# Add a newline before ')' if an if/for/while/switch condition spans multiple +# lines. Overrides nl_before_if_closing_paren if both are specified. +nl_multi_line_sparen_close = remove # ignore/add/remove/force/not_defined + +# Force a newline in a define after the macro name for multi-line defines. +nl_multi_line_define = false # true/false + +# Whether to add a newline before 'case', and a blank line before a 'case' +# statement that follows a ';' or '}'. +nl_before_case = false # true/false + +# Whether to add a newline after a 'case' statement. +nl_after_case = true # true/false + +# Add or remove newline between a case ':' and '{'. +# +# Overrides nl_after_case. +nl_case_colon_brace = remove # ignore/add/remove/force/not_defined + +# Add or remove newline between ')' and 'throw'. +nl_before_throw = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'namespace' and '{'. +nl_namespace_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after 'template<...>' of a template class. +nl_template_class = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after 'template<...>' of a template class declaration. +# +# Overrides nl_template_class. +nl_template_class_decl = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after 'template<>' of a specialized class declaration. +# +# Overrides nl_template_class_decl. +nl_template_class_decl_special = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after 'template<...>' of a template class definition. +# +# Overrides nl_template_class. +nl_template_class_def = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after 'template<>' of a specialized class definition. +# +# Overrides nl_template_class_def. +nl_template_class_def_special = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after 'template<...>' of a template function. +nl_template_func = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after 'template<...>' of a template function +# declaration. +# +# Overrides nl_template_func. +nl_template_func_decl = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after 'template<>' of a specialized function +# declaration. +# +# Overrides nl_template_func_decl. +nl_template_func_decl_special = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after 'template<...>' of a template function +# definition. +# +# Overrides nl_template_func. +nl_template_func_def = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after 'template<>' of a specialized function +# definition. +# +# Overrides nl_template_func_def. +nl_template_func_def_special = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after 'template<...>' of a template variable. +nl_template_var = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'template<...>' and 'using' of a templated +# type alias. +nl_template_using = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'class' and '{'. +nl_class_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline before or after (depending on pos_class_comma, +# may not be IGNORE) each',' in the base class list. +nl_class_init_args = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after each ',' in the constructor member +# initialization. Related to nl_constr_colon, pos_constr_colon and +# pos_constr_comma. +nl_constr_init_args = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline before first element, after comma, and after last +# element, in 'enum'. +nl_enum_own_lines = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between return type and function name in a function +# definition. +# might be modified by nl_func_leave_one_liners +nl_func_type_name = remove # ignore/add/remove/force/not_defined + +# Add or remove newline between return type and function name inside a class +# definition. If set to ignore, nl_func_type_name or nl_func_proto_type_name +# is used instead. +nl_func_type_name_class = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between class specification and '::' +# in 'void A::f() { }'. Only appears in separate member implementation (does +# not appear with in-line implementation). +nl_func_class_scope = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between function scope and name, as in +# 'void A :: <here> f() { }'. +nl_func_scope_name = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between return type and function name in a prototype. +nl_func_proto_type_name = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between a function name and the opening '(' in the +# declaration. +nl_func_paren = ignore # ignore/add/remove/force/not_defined + +# Overrides nl_func_paren for functions with no parameters. +nl_func_paren_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between a function name and the opening '(' in the +# definition. +nl_func_def_paren = ignore # ignore/add/remove/force/not_defined + +# Overrides nl_func_def_paren for functions with no parameters. +nl_func_def_paren_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between a function name and the opening '(' in the +# call. +nl_func_call_paren = ignore # ignore/add/remove/force/not_defined + +# Overrides nl_func_call_paren for functions with no parameters. +nl_func_call_paren_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after '(' in a function declaration. +nl_func_decl_start = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after '(' in a function definition. +nl_func_def_start = remove # ignore/add/remove/force/not_defined + +# Overrides nl_func_decl_start when there is only one parameter. +nl_func_decl_start_single = ignore # ignore/add/remove/force/not_defined + +# Overrides nl_func_def_start when there is only one parameter. +nl_func_def_start_single = ignore # ignore/add/remove/force/not_defined + +# Whether to add a newline after '(' in a function declaration if '(' and ')' +# are in different lines. If false, nl_func_decl_start is used instead. +nl_func_decl_start_multi_line = false # true/false + +# Whether to add a newline after '(' in a function definition if '(' and ')' +# are in different lines. If false, nl_func_def_start is used instead. +nl_func_def_start_multi_line = false # true/false + +# Add or remove newline after each ',' in a function declaration. +nl_func_decl_args = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after each ',' in a function definition. +nl_func_def_args = remove # ignore/add/remove/force/not_defined + +# Add or remove newline after each ',' in a function call. +nl_func_call_args = ignore # ignore/add/remove/force/not_defined + +# Whether to add a newline after each ',' in a function declaration if '(' +# and ')' are in different lines. If false, nl_func_decl_args is used instead. +nl_func_decl_args_multi_line = false # true/false + +# Whether to add a newline after each ',' in a function definition if '(' +# and ')' are in different lines. If false, nl_func_def_args is used instead. +nl_func_def_args_multi_line = false # true/false + +# Add or remove newline before the ')' in a function declaration. +nl_func_decl_end = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline before the ')' in a function definition. +nl_func_def_end = remove # ignore/add/remove/force/not_defined + +# Overrides nl_func_decl_end when there is only one parameter. +nl_func_decl_end_single = ignore # ignore/add/remove/force/not_defined + +# Overrides nl_func_def_end when there is only one parameter. +nl_func_def_end_single = ignore # ignore/add/remove/force/not_defined + +# Whether to add a newline before ')' in a function declaration if '(' and ')' +# are in different lines. If false, nl_func_decl_end is used instead. +nl_func_decl_end_multi_line = false # true/false + +# Whether to add a newline before ')' in a function definition if '(' and ')' +# are in different lines. If false, nl_func_def_end is used instead. +nl_func_def_end_multi_line = false # true/false + +# Add or remove newline between '()' in a function declaration. +nl_func_decl_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between '()' in a function definition. +nl_func_def_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between '()' in a function call. +nl_func_call_empty = ignore # ignore/add/remove/force/not_defined + +# Whether to add a newline after '(' in a function call, +# has preference over nl_func_call_start_multi_line. +nl_func_call_start = remove # ignore/add/remove/force/not_defined + +# Whether to add a newline before ')' in a function call. +nl_func_call_end = ignore # ignore/add/remove/force/not_defined + +# Whether to add a newline after '(' in a function call if '(' and ')' are in +# different lines. +nl_func_call_start_multi_line = false # true/false + +# Whether to add a newline after each ',' in a function call if '(' and ')' +# are in different lines. +nl_func_call_args_multi_line = false # true/false + +# Whether to add a newline before ')' in a function call if '(' and ')' are in +# different lines. +nl_func_call_end_multi_line = false # true/false + +# Whether to respect nl_func_call_XXX option in case of closure args. +nl_func_call_args_multi_line_ignore_closures = false # true/false + +# Whether to add a newline after '<' of a template parameter list. +nl_template_start = false # true/false + +# Whether to add a newline after each ',' in a template parameter list. +nl_template_args = false # true/false + +# Whether to add a newline before '>' of a template parameter list. +nl_template_end = false # true/false + +# (OC) Whether to put each Objective-C message parameter on a separate line. +# See nl_oc_msg_leave_one_liner. +nl_oc_msg_args = false # true/false + +# Add or remove newline between function signature and '{'. +nl_fdef_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between function signature and '{', +# if signature ends with ')'. Overrides nl_fdef_brace. +nl_fdef_brace_cond = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between C++11 lambda signature and '{'. +nl_cpp_ldef_brace = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between 'return' and the return expression. +nl_return_expr = ignore # ignore/add/remove/force/not_defined + +# Whether to add a newline after semicolons, except in 'for' statements. +nl_after_semicolon = false # true/false + +# (Java) Add or remove newline between the ')' and '{{' of the double brace +# initializer. +nl_paren_dbrace_open = ignore # ignore/add/remove/force/not_defined + +# Whether to add a newline after the type in an unnamed temporary +# direct-list-initialization. +nl_type_brace_init_lst = ignore # ignore/add/remove/force/not_defined + +# Whether to add a newline after the open brace in an unnamed temporary +# direct-list-initialization. +nl_type_brace_init_lst_open = ignore # ignore/add/remove/force/not_defined + +# Whether to add a newline before the close brace in an unnamed temporary +# direct-list-initialization. +nl_type_brace_init_lst_close = ignore # ignore/add/remove/force/not_defined + +# Whether to add a newline before '{'. +nl_before_brace_open = false # true/false + +# Whether to add a newline after '{'. +nl_after_brace_open = false # true/false + +# Whether to add a newline between the open brace and a trailing single-line +# comment. Requires nl_after_brace_open=true. +nl_after_brace_open_cmt = false # true/false + +# Whether to add a newline after a virtual brace open with a non-empty body. +# These occur in un-braced if/while/do/for statement bodies. +nl_after_vbrace_open = false # true/false + +# Whether to add a newline after a virtual brace open with an empty body. +# These occur in un-braced if/while/do/for statement bodies. +nl_after_vbrace_open_empty = false # true/false + +# Whether to add a newline after '}'. Does not apply if followed by a +# necessary ';'. +nl_after_brace_close = false # true/false + +# Whether to add a newline after a virtual brace close, +# as in 'if (foo) a++; <here> return;'. +nl_after_vbrace_close = false # true/false + +# Add or remove newline between the close brace and identifier, +# as in 'struct { int a; } <here> b;'. Affects enumerations, unions and +# structures. If set to ignore, uses nl_after_brace_close. +nl_brace_struct_var = ignore # ignore/add/remove/force/not_defined + +# Whether to alter newlines in '#define' macros. +nl_define_macro = false # true/false + +# Whether to alter newlines between consecutive parenthesis closes. The number +# of closing parentheses in a line will depend on respective open parenthesis +# lines. +nl_squeeze_paren_close = false # true/false + +# Whether to remove blanks after '#ifxx' and '#elxx', or before '#elxx' and +# '#endif'. Does not affect top-level #ifdefs. +nl_squeeze_ifdef = false # true/false + +# Makes the nl_squeeze_ifdef option affect the top-level #ifdefs as well. +nl_squeeze_ifdef_top_level = false # true/false + +# Add or remove blank line before 'if'. +nl_before_if = ignore # ignore/add/remove/force/not_defined + +# Add or remove blank line after 'if' statement. Add/Force work only if the +# next token is not a closing brace. +nl_after_if = ignore # ignore/add/remove/force/not_defined + +# Add or remove blank line before 'for'. +nl_before_for = ignore # ignore/add/remove/force/not_defined + +# Add or remove blank line after 'for' statement. +nl_after_for = ignore # ignore/add/remove/force/not_defined + +# Add or remove blank line before 'while'. +nl_before_while = ignore # ignore/add/remove/force/not_defined + +# Add or remove blank line after 'while' statement. +nl_after_while = ignore # ignore/add/remove/force/not_defined + +# Add or remove blank line before 'switch'. +nl_before_switch = ignore # ignore/add/remove/force/not_defined + +# Add or remove blank line after 'switch' statement. +nl_after_switch = ignore # ignore/add/remove/force/not_defined + +# Add or remove blank line before 'synchronized'. +nl_before_synchronized = ignore # ignore/add/remove/force/not_defined + +# Add or remove blank line after 'synchronized' statement. +nl_after_synchronized = ignore # ignore/add/remove/force/not_defined + +# Add or remove blank line before 'do'. +nl_before_do = ignore # ignore/add/remove/force/not_defined + +# Add or remove blank line after 'do/while' statement. +nl_after_do = ignore # ignore/add/remove/force/not_defined + +# Ignore nl_before_{if,for,switch,do,synchronized} if the control +# statement is immediately after a case statement. +# if nl_before_{if,for,switch,do} is set to remove, this option +# does nothing. +nl_before_ignore_after_case = false # true/false + +# Whether to put a blank line before 'return' statements, unless after an open +# brace. +nl_before_return = false # true/false + +# Whether to put a blank line after 'return' statements, unless followed by a +# close brace. +nl_after_return = false # true/false + +# Whether to put a blank line before a member '.' or '->' operators. +nl_before_member = ignore # ignore/add/remove/force/not_defined + +# (Java) Whether to put a blank line after a member '.' or '->' operators. +nl_after_member = ignore # ignore/add/remove/force/not_defined + +# Whether to double-space commented-entries in 'struct'/'union'/'enum'. +nl_ds_struct_enum_cmt = false # true/false + +# Whether to force a newline before '}' of a 'struct'/'union'/'enum'. +# (Lower priority than eat_blanks_before_close_brace.) +nl_ds_struct_enum_close_brace = false # true/false + +# Add or remove newline before or after (depending on pos_class_colon) a class +# colon, as in 'class Foo <here> : <or here> public Bar'. +nl_class_colon = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline around a class constructor colon. The exact position +# depends on nl_constr_init_args, pos_constr_colon and pos_constr_comma. +nl_constr_colon = ignore # ignore/add/remove/force/not_defined + +# Whether to collapse a two-line namespace, like 'namespace foo\n{ decl; }' +# into a single line. If true, prevents other brace newline rules from turning +# such code into four lines. If true, it also preserves one-liner namespaces. +nl_namespace_two_to_one_liner = false # true/false + +# Whether to remove a newline in simple unbraced if statements, turning them +# into one-liners, as in 'if(b)\n i++;' => 'if(b) i++;'. +nl_create_if_one_liner = false # true/false + +# Whether to remove a newline in simple unbraced for statements, turning them +# into one-liners, as in 'for (...)\n stmt;' => 'for (...) stmt;'. +nl_create_for_one_liner = false # true/false + +# Whether to remove a newline in simple unbraced while statements, turning +# them into one-liners, as in 'while (expr)\n stmt;' => 'while (expr) stmt;'. +nl_create_while_one_liner = false # true/false + +# Whether to collapse a function definition whose body (not counting braces) +# is only one line so that the entire definition (prototype, braces, body) is +# a single line. +nl_create_func_def_one_liner = false # true/false + +# Whether to split one-line simple list definitions into three lines by +# adding newlines, as in 'int a[12] = { <here> 0 <here> };'. +nl_create_list_one_liner = false # true/false + +# Whether to split one-line simple unbraced if statements into two lines by +# adding a newline, as in 'if(b) <here> i++;'. +nl_split_if_one_liner = false # true/false + +# Whether to split one-line simple unbraced for statements into two lines by +# adding a newline, as in 'for (...) <here> stmt;'. +nl_split_for_one_liner = false # true/false + +# Whether to split one-line simple unbraced while statements into two lines by +# adding a newline, as in 'while (expr) <here> stmt;'. +nl_split_while_one_liner = false # true/false + +# Don't add a newline before a cpp-comment in a parameter list of a function +# call. +donot_add_nl_before_cpp_comment = false # true/false + +# +# Blank line options +# + +# The maximum number of consecutive newlines (3 = 2 blank lines). +nl_max = 0 # unsigned number + +# The maximum number of consecutive newlines in a function. +nl_max_blank_in_func = 0 # unsigned number + +# The number of newlines inside an empty function body. +# This option overrides eat_blanks_after_open_brace and +# eat_blanks_before_close_brace, but is ignored when +# nl_collapse_empty_body=true +nl_inside_empty_func = 0 # unsigned number + +# The number of newlines before a function prototype. +nl_before_func_body_proto = 0 # unsigned number + +# The number of newlines before a multi-line function definition. Where +# applicable, this option is overridden with eat_blanks_after_open_brace=true +nl_before_func_body_def = 0 # unsigned number + +# The number of newlines before a class constructor/destructor prototype. +nl_before_func_class_proto = 0 # unsigned number + +# The number of newlines before a class constructor/destructor definition. +nl_before_func_class_def = 0 # unsigned number + +# The number of newlines after a function prototype. +nl_after_func_proto = 0 # unsigned number + +# The number of newlines after a function prototype, if not followed by +# another function prototype. +nl_after_func_proto_group = 0 # unsigned number + +# The number of newlines after a class constructor/destructor prototype. +nl_after_func_class_proto = 0 # unsigned number + +# The number of newlines after a class constructor/destructor prototype, +# if not followed by another constructor/destructor prototype. +nl_after_func_class_proto_group = 0 # unsigned number + +# Whether one-line method definitions inside a class body should be treated +# as if they were prototypes for the purposes of adding newlines. +# +# Requires nl_class_leave_one_liners=true. Overrides nl_before_func_body_def +# and nl_before_func_class_def for one-liners. +nl_class_leave_one_liner_groups = false # true/false + +# The number of newlines after '}' of a multi-line function body. +nl_after_func_body = 0 # unsigned number + +# The number of newlines after '}' of a multi-line function body in a class +# declaration. Also affects class constructors/destructors. +# +# Overrides nl_after_func_body. +nl_after_func_body_class = 0 # unsigned number + +# The number of newlines after '}' of a single line function body. Also +# affects class constructors/destructors. +# +# Overrides nl_after_func_body and nl_after_func_body_class. +nl_after_func_body_one_liner = 0 # unsigned number + +# The number of blank lines after a block of variable definitions at the top +# of a function body. +# +# 0: No change (default). +nl_func_var_def_blk = 0 # unsigned number + +# The number of newlines before a block of typedefs. If nl_after_access_spec +# is non-zero, that option takes precedence. +# +# 0: No change (default). +nl_typedef_blk_start = 0 # unsigned number + +# The number of newlines after a block of typedefs. +# +# 0: No change (default). +nl_typedef_blk_end = 0 # unsigned number + +# The maximum number of consecutive newlines within a block of typedefs. +# +# 0: No change (default). +nl_typedef_blk_in = 0 # unsigned number + +# The number of newlines before a block of variable definitions not at the top +# of a function body. If nl_after_access_spec is non-zero, that option takes +# precedence. +# +# 0: No change (default). +nl_var_def_blk_start = 0 # unsigned number + +# The number of newlines after a block of variable definitions not at the top +# of a function body. +# +# 0: No change (default). +nl_var_def_blk_end = 0 # unsigned number + +# The maximum number of consecutive newlines within a block of variable +# definitions. +# +# 0: No change (default). +nl_var_def_blk_in = 0 # unsigned number + +# The minimum number of newlines before a multi-line comment. +# Doesn't apply if after a brace open or another multi-line comment. +nl_before_block_comment = 0 # unsigned number + +# The minimum number of newlines before a single-line C comment. +# Doesn't apply if after a brace open or other single-line C comments. +nl_before_c_comment = 0 # unsigned number + +# The minimum number of newlines before a CPP comment. +# Doesn't apply if after a brace open or other CPP comments. +nl_before_cpp_comment = 0 # unsigned number + +# Whether to force a newline after a multi-line comment. +nl_after_multiline_comment = false # true/false + +# Whether to force a newline after a label's colon. +nl_after_label_colon = false # true/false + +# The number of newlines before a struct definition. +nl_before_struct = 0 # unsigned number + +# The number of newlines after '}' or ';' of a struct/enum/union definition. +nl_after_struct = 0 # unsigned number + +# The number of newlines before a class definition. +nl_before_class = 0 # unsigned number + +# The number of newlines after '}' or ';' of a class definition. +nl_after_class = 0 # unsigned number + +# The number of newlines before a namespace. +nl_before_namespace = 0 # unsigned number + +# The number of newlines after '{' of a namespace. This also adds newlines +# before the matching '}'. +# +# 0: Apply eat_blanks_after_open_brace or eat_blanks_before_close_brace if +# applicable, otherwise no change. +# +# Overrides eat_blanks_after_open_brace and eat_blanks_before_close_brace. +nl_inside_namespace = 0 # unsigned number + +# The number of newlines after '}' of a namespace. +nl_after_namespace = 0 # unsigned number + +# The number of newlines before an access specifier label. This also includes +# the Qt-specific 'signals:' and 'slots:'. Will not change the newline count +# if after a brace open. +# +# 0: No change (default). +nl_before_access_spec = 0 # unsigned number + +# The number of newlines after an access specifier label. This also includes +# the Qt-specific 'signals:' and 'slots:'. Will not change the newline count +# if after a brace open. +# +# 0: No change (default). +# +# Overrides nl_typedef_blk_start and nl_var_def_blk_start. +nl_after_access_spec = 0 # unsigned number + +# The number of newlines between a function definition and the function +# comment, as in '// comment\n <here> void foo() {...}'. +# +# 0: No change (default). +nl_comment_func_def = 0 # unsigned number + +# The number of newlines after a try-catch-finally block that isn't followed +# by a brace close. +# +# 0: No change (default). +nl_after_try_catch_finally = 0 # unsigned number + +# (C#) The number of newlines before and after a property, indexer or event +# declaration. +# +# 0: No change (default). +nl_around_cs_property = 0 # unsigned number + +# (C#) The number of newlines between the get/set/add/remove handlers. +# +# 0: No change (default). +nl_between_get_set = 0 # unsigned number + +# (C#) Add or remove newline between property and the '{'. +nl_property_brace = ignore # ignore/add/remove/force/not_defined + +# Whether to remove blank lines after '{'. +eat_blanks_after_open_brace = true # true/false + +# Whether to remove blank lines before '}'. +eat_blanks_before_close_brace = true # true/false + +# How aggressively to remove extra newlines not in preprocessor. +# +# 0: No change (default) +# 1: Remove most newlines not handled by other config +# 2: Remove all newlines and reformat completely by config +nl_remove_extra_newlines = 0 # unsigned number + +# (Java) Add or remove newline after an annotation statement. Only affects +# annotations that are after a newline. +nl_after_annotation = ignore # ignore/add/remove/force/not_defined + +# (Java) Add or remove newline between two annotations. +nl_between_annotation = ignore # ignore/add/remove/force/not_defined + +# The number of newlines before a whole-file #ifdef. +# +# 0: No change (default). +nl_before_whole_file_ifdef = 0 # unsigned number + +# The number of newlines after a whole-file #ifdef. +# +# 0: No change (default). +nl_after_whole_file_ifdef = 0 # unsigned number + +# The number of newlines before a whole-file #endif. +# +# 0: No change (default). +nl_before_whole_file_endif = 0 # unsigned number + +# The number of newlines after a whole-file #endif. +# +# 0: No change (default). +nl_after_whole_file_endif = 0 # unsigned number + +# +# Positioning options +# + +# The position of arithmetic operators in wrapped expressions. +pos_arith = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of assignment in wrapped expressions. Do not affect '=' +# followed by '{'. +pos_assign = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of Boolean operators in wrapped expressions. +pos_bool = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of comparison operators in wrapped expressions. +pos_compare = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of conditional operators, as in the '?' and ':' of +# 'expr ? stmt : stmt', in wrapped expressions. +pos_conditional = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in wrapped expressions. +pos_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in enum entries. +pos_enum_comma = trail # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in the base class list if there is more than one +# line. Affects nl_class_init_args. +pos_class_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in the constructor initialization list. +# Related to nl_constr_colon, nl_constr_init_args and pos_constr_colon. +pos_constr_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of trailing/leading class colon, between class and base class +# list. Affects nl_class_colon. +pos_class_colon = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of colons between constructor and member initialization. +# Related to nl_constr_colon, nl_constr_init_args and pos_constr_comma. +pos_constr_colon = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of shift operators in wrapped expressions. +pos_shift = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# +# Line splitting options +# + +# Try to limit code width to N columns. +code_width = 100 # unsigned number + +# Whether to fully split long 'for' statements at semi-colons. +ls_for_split_full = false # true/false + +# Whether to fully split long function prototypes/calls at commas. +# The option ls_code_width has priority over the option ls_func_split_full. +ls_func_split_full = false # true/false + +# Whether to split lines as close to code_width as possible and ignore some +# groupings. +# The option ls_code_width has priority over the option ls_func_split_full. +ls_code_width = false # true/false + +# +# Code alignment options (not left column spaces/tabs) +# + +# Whether to keep non-indenting tabs. +align_keep_tabs = false # true/false + +# Whether to use tabs for aligning. +align_with_tabs = false # true/false + +# Whether to bump out to the next tab when aligning. +align_on_tabstop = false # true/false + +# Whether to right-align numbers. +align_number_right = false # true/false + +# Whether to keep whitespace not required for alignment. +align_keep_extra_space = false # true/false + +# Whether to align variable definitions in prototypes and functions. +align_func_params = false # true/false + +# The span for aligning parameter definitions in function on parameter name. +# +# 0: Don't align (default). +align_func_params_span = 0 # unsigned number + +# The threshold for aligning function parameter definitions. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_func_params_thresh = 0 # number + +# The gap for aligning function parameter definitions. +align_func_params_gap = 0 # unsigned number + +# The span for aligning constructor value. +# +# 0: Don't align (default). +align_constr_value_span = 0 # unsigned number + +# The threshold for aligning constructor value. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_constr_value_thresh = 0 # number + +# The gap for aligning constructor value. +align_constr_value_gap = 0 # unsigned number + +# Whether to align parameters in single-line functions that have the same +# name. The function names must already be aligned with each other. +align_same_func_call_params = false # true/false + +# The span for aligning function-call parameters for single line functions. +# +# 0: Don't align (default). +align_same_func_call_params_span = 0 # unsigned number + +# The threshold for aligning function-call parameters for single line +# functions. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_same_func_call_params_thresh = 0 # number + +# The span for aligning variable definitions. +# +# 0: Don't align (default). +align_var_def_span = 0 # unsigned number + +# How to consider (or treat) the '*' in the alignment of variable definitions. +# +# 0: Part of the type 'void * foo;' (default) +# 1: Part of the variable 'void *foo;' +# 2: Dangling 'void *foo;' +# Dangling: the '*' will not be taken into account when aligning. +align_var_def_star_style = 0 # unsigned number + +# How to consider (or treat) the '&' in the alignment of variable definitions. +# +# 0: Part of the type 'long & foo;' (default) +# 1: Part of the variable 'long &foo;' +# 2: Dangling 'long &foo;' +# Dangling: the '&' will not be taken into account when aligning. +align_var_def_amp_style = 0 # unsigned number + +# The threshold for aligning variable definitions. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_var_def_thresh = 0 # number + +# The gap for aligning variable definitions. +align_var_def_gap = 0 # unsigned number + +# Whether to align the colon in struct bit fields. +align_var_def_colon = false # true/false + +# The gap for aligning the colon in struct bit fields. +align_var_def_colon_gap = 0 # unsigned number + +# Whether to align any attribute after the variable name. +align_var_def_attribute = false # true/false + +# Whether to align inline struct/enum/union variable definitions. +align_var_def_inline = false # true/false + +# The span for aligning on '=' in assignments. +# +# 0: Don't align (default). +align_assign_span = 0 # unsigned number + +# The span for aligning on '=' in function prototype modifier. +# +# 0: Don't align (default). +align_assign_func_proto_span = 0 # unsigned number + +# The threshold for aligning on '=' in assignments. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_assign_thresh = 0 # number + +# How to apply align_assign_span to function declaration "assignments", i.e. +# 'virtual void foo() = 0' or '~foo() = {default|delete}'. +# +# 0: Align with other assignments (default) +# 1: Align with each other, ignoring regular assignments +# 2: Don't align +align_assign_decl_func = 0 # unsigned number + +# The span for aligning on '=' in enums. +# +# 0: Don't align (default). +align_enum_equ_span = 0 # unsigned number + +# The threshold for aligning on '=' in enums. +# Use a negative number for absolute thresholds. +# +# 0: no limit (default). +align_enum_equ_thresh = 0 # number + +# The span for aligning class member definitions. +# +# 0: Don't align (default). +align_var_class_span = 0 # unsigned number + +# The threshold for aligning class member definitions. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_var_class_thresh = 0 # number + +# The gap for aligning class member definitions. +align_var_class_gap = 0 # unsigned number + +# The span for aligning struct/union member definitions. +# +# 0: Don't align (default). +align_var_struct_span = 0 # unsigned number + +# The threshold for aligning struct/union member definitions. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_var_struct_thresh = 0 # number + +# The gap for aligning struct/union member definitions. +align_var_struct_gap = 0 # unsigned number + +# The span for aligning struct initializer values. +# +# 0: Don't align (default). +align_struct_init_span = 0 # unsigned number + +# The span for aligning single-line typedefs. +# +# 0: Don't align (default). +align_typedef_span = 0 # unsigned number + +# The minimum space between the type and the synonym of a typedef. +align_typedef_gap = 0 # unsigned number + +# How to align typedef'd functions with other typedefs. +# +# 0: Don't mix them at all (default) +# 1: Align the open parenthesis with the types +# 2: Align the function type name with the other type names +align_typedef_func = 0 # unsigned number + +# How to consider (or treat) the '*' in the alignment of typedefs. +# +# 0: Part of the typedef type, 'typedef int * pint;' (default) +# 1: Part of type name: 'typedef int *pint;' +# 2: Dangling: 'typedef int *pint;' +# Dangling: the '*' will not be taken into account when aligning. +align_typedef_star_style = 0 # unsigned number + +# How to consider (or treat) the '&' in the alignment of typedefs. +# +# 0: Part of the typedef type, 'typedef int & intref;' (default) +# 1: Part of type name: 'typedef int &intref;' +# 2: Dangling: 'typedef int &intref;' +# Dangling: the '&' will not be taken into account when aligning. +align_typedef_amp_style = 0 # unsigned number + +# The span for aligning comments that end lines. +# +# 0: Don't align (default). +align_right_cmt_span = 0 # unsigned number + +# Minimum number of columns between preceding text and a trailing comment in +# order for the comment to qualify for being aligned. Must be non-zero to have +# an effect. +align_right_cmt_gap = 0 # unsigned number + +# If aligning comments, whether to mix with comments after '}' and #endif with +# less than three spaces before the comment. +align_right_cmt_mix = false # true/false + +# Whether to only align trailing comments that are at the same brace level. +align_right_cmt_same_level = false # true/false + +# Minimum column at which to align trailing comments. Comments which are +# aligned beyond this column, but which can be aligned in a lesser column, +# may be "pulled in". +# +# 0: Ignore (default). +align_right_cmt_at_col = 0 # unsigned number + +# The span for aligning function prototypes. +# +# 0: Don't align (default). +align_func_proto_span = 0 # unsigned number + +# The threshold for aligning function prototypes. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_func_proto_thresh = 0 # number + +# Minimum gap between the return type and the function name. +align_func_proto_gap = 0 # unsigned number + +# Whether to align function prototypes on the 'operator' keyword instead of +# what follows. +align_on_operator = false # true/false + +# Whether to mix aligning prototype and variable declarations. If true, +# align_var_def_XXX options are used instead of align_func_proto_XXX options. +align_mix_var_proto = false # true/false + +# Whether to align single-line functions with function prototypes. +# Uses align_func_proto_span. +align_single_line_func = false # true/false + +# Whether to align the open brace of single-line functions. +# Requires align_single_line_func=true. Uses align_func_proto_span. +align_single_line_brace = false # true/false + +# Gap for align_single_line_brace. +align_single_line_brace_gap = 0 # unsigned number + +# (OC) The span for aligning Objective-C message specifications. +# +# 0: Don't align (default). +align_oc_msg_spec_span = 0 # unsigned number + +# Whether to align macros wrapped with a backslash and a newline. This will +# not work right if the macro contains a multi-line comment. +align_nl_cont = false # true/false + +# Whether to align macro functions and variables together. +align_pp_define_together = false # true/false + +# The span for aligning on '#define' bodies. +# +# =0: Don't align (default) +# >0: Number of lines (including comments) between blocks +align_pp_define_span = 0 # unsigned number + +# The minimum space between label and value of a preprocessor define. +align_pp_define_gap = 0 # unsigned number + +# Whether to align lines that start with '<<' with previous '<<'. +# +# Default: true +align_left_shift = true # true/false + +# Whether to align comma-separated statements following '<<' (as used to +# initialize Eigen matrices). +align_eigen_comma_init = false # true/false + +# Whether to align text after 'asm volatile ()' colons. +align_asm_colon = false # true/false + +# (OC) Span for aligning parameters in an Objective-C message call +# on the ':'. +# +# 0: Don't align. +align_oc_msg_colon_span = 0 # unsigned number + +# (OC) Whether to always align with the first parameter, even if it is too +# short. +align_oc_msg_colon_first = false # true/false + +# (OC) Whether to align parameters in an Objective-C '+' or '-' declaration +# on the ':'. +align_oc_decl_colon = false # true/false + +# (OC) Whether to not align parameters in an Objectve-C message call if first +# colon is not on next line of the message call (the same way Xcode does +# aligment) +align_oc_msg_colon_xcode_like = false # true/false + +# +# Comment modification options +# + +# Try to wrap comments at N columns. +cmt_width = 0 # unsigned number + +# How to reflow comments. +# +# 0: No reflowing (apart from the line wrapping due to cmt_width) (default) +# 1: No touching at all +# 2: Full reflow (enable cmt_indent_multi for indent with line wrapping due to cmt_width) +cmt_reflow_mode = 0 # unsigned number + +# Path to a file that contains regular expressions describing patterns for +# which the end of one line and the beginning of the next will be folded into +# the same sentence or paragraph during full comment reflow. The regular +# expressions are described using ECMAScript syntax. The syntax for this +# specification is as follows, where "..." indicates the custom regular +# expression and "n" indicates the nth end_of_prev_line_regex and +# beg_of_next_line_regex regular expression pair: +# +# end_of_prev_line_regex[1] = "...$" +# beg_of_next_line_regex[1] = "^..." +# end_of_prev_line_regex[2] = "...$" +# beg_of_next_line_regex[2] = "^..." +# . +# . +# . +# end_of_prev_line_regex[n] = "...$" +# beg_of_next_line_regex[n] = "^..." +# +# Note that use of this option overrides the default reflow fold regular +# expressions, which are internally defined as follows: +# +# end_of_prev_line_regex[1] = "[\w,\]\)]$" +# beg_of_next_line_regex[1] = "^[\w,\[\(]" +# end_of_prev_line_regex[2] = "\.$" +# beg_of_next_line_regex[2] = "^[A-Z]" +cmt_reflow_fold_regex_file = "" # string + +# Whether to indent wrapped lines to the start of the encompassing paragraph +# during full comment reflow (cmt_reflow_mode = 2). Overrides the value +# specified by cmt_sp_after_star_cont. +# +# Note that cmt_align_doxygen_javadoc_tags overrides this option for +# paragraphs associated with javadoc tags +cmt_reflow_indent_to_paragraph_start = false # true/false + +# Whether to convert all tabs to spaces in comments. If false, tabs in +# comments are left alone, unless used for indenting. +cmt_convert_tab_to_spaces = true # true/false + +# Whether to apply changes to multi-line comments, including cmt_width, +# keyword substitution and leading chars. +# +# Default: true +cmt_indent_multi = true # true/false + +# Whether to align doxygen javadoc-style tags ('@param', '@return', etc.) +# and corresponding fields such that groups of consecutive block tags, +# parameter names, and descriptions align with one another. Overrides that +# which is specified by the cmt_sp_after_star_cont. If cmt_width > 0, it may +# be necessary to enable cmt_indent_multi and set cmt_reflow_mode = 2 +# in order to achieve the desired alignment for line-wrapping. +cmt_align_doxygen_javadoc_tags = false # true/false + +# The number of spaces to insert after the star and before doxygen +# javadoc-style tags (@param, @return, etc). Requires enabling +# cmt_align_doxygen_javadoc_tags. Overrides that which is specified by the +# cmt_sp_after_star_cont. +# +# Default: 1 +cmt_sp_before_doxygen_javadoc_tags = 1 # unsigned number + +# Whether to change trailing, single-line c-comments into cpp-comments. +cmt_trailing_single_line_c_to_cpp = true # true/false + +# Whether to group c-comments that look like they are in a block. +cmt_c_group = false # true/false + +# Whether to put an empty '/*' on the first line of the combined c-comment. +cmt_c_nl_start = false # true/false + +# Whether to add a newline before the closing '*/' of the combined c-comment. +cmt_c_nl_end = false # true/false + +# Whether to change cpp-comments into c-comments. +cmt_cpp_to_c = false # true/false + +# Whether to group cpp-comments that look like they are in a block. Only +# meaningful if cmt_cpp_to_c=true. +cmt_cpp_group = false # true/false + +# Whether to put an empty '/*' on the first line of the combined cpp-comment +# when converting to a c-comment. +# +# Requires cmt_cpp_to_c=true and cmt_cpp_group=true. +cmt_cpp_nl_start = false # true/false + +# Whether to add a newline before the closing '*/' of the combined cpp-comment +# when converting to a c-comment. +# +# Requires cmt_cpp_to_c=true and cmt_cpp_group=true. +cmt_cpp_nl_end = false # true/false + +# Whether to put a star on subsequent comment lines. +cmt_star_cont = false # true/false + +# The number of spaces to insert at the start of subsequent comment lines. +cmt_sp_before_star_cont = 0 # unsigned number + +# The number of spaces to insert after the star on subsequent comment lines. +cmt_sp_after_star_cont = 0 # unsigned number + +# For multi-line comments with a '*' lead, remove leading spaces if the first +# and last lines of the comment are the same length. +# +# Default: true +cmt_multi_check_last = true # true/false + +# For multi-line comments with a '*' lead, remove leading spaces if the first +# and last lines of the comment are the same length AND if the length is +# bigger as the first_len minimum. +# +# Default: 4 +cmt_multi_first_len_minimum = 4 # unsigned number + +# Path to a file that contains text to insert at the beginning of a file if +# the file doesn't start with a C/C++ comment. If the inserted text contains +# '$(filename)', that will be replaced with the current file's name. +cmt_insert_file_header = "" # string + +# Path to a file that contains text to insert at the end of a file if the +# file doesn't end with a C/C++ comment. If the inserted text contains +# '$(filename)', that will be replaced with the current file's name. +cmt_insert_file_footer = "" # string + +# Path to a file that contains text to insert before a function definition if +# the function isn't preceded by a C/C++ comment. If the inserted text +# contains '$(function)', '$(javaparam)' or '$(fclass)', these will be +# replaced with, respectively, the name of the function, the javadoc '@param' +# and '@return' stuff, or the name of the class to which the member function +# belongs. +cmt_insert_func_header = "" # string + +# Path to a file that contains text to insert before a class if the class +# isn't preceded by a C/C++ comment. If the inserted text contains '$(class)', +# that will be replaced with the class name. +cmt_insert_class_header = "" # string + +# Path to a file that contains text to insert before an Objective-C message +# specification, if the method isn't preceded by a C/C++ comment. If the +# inserted text contains '$(message)' or '$(javaparam)', these will be +# replaced with, respectively, the name of the function, or the javadoc +# '@param' and '@return' stuff. +cmt_insert_oc_msg_header = "" # string + +# Whether a comment should be inserted if a preprocessor is encountered when +# stepping backwards from a function name. +# +# Applies to cmt_insert_oc_msg_header, cmt_insert_func_header and +# cmt_insert_class_header. +cmt_insert_before_preproc = false # true/false + +# Whether a comment should be inserted if a function is declared inline to a +# class definition. +# +# Applies to cmt_insert_func_header. +# +# Default: true +cmt_insert_before_inlines = true # true/false + +# Whether a comment should be inserted if the function is a class constructor +# or destructor. +# +# Applies to cmt_insert_func_header. +cmt_insert_before_ctor_dtor = false # true/false + +# +# Code modifying options (non-whitespace) +# + +# Add or remove braces on a single-line 'do' statement. +mod_full_brace_do = ignore # ignore/add/remove/force/not_defined + +# Add or remove braces on a single-line 'for' statement. +mod_full_brace_for = add # ignore/add/remove/force/not_defined + +# (Pawn) Add or remove braces on a single-line function definition. +mod_full_brace_function = ignore # ignore/add/remove/force/not_defined + +# Add or remove braces on a single-line 'if' statement. Braces will not be +# removed if the braced statement contains an 'else'. +mod_full_brace_if = add # ignore/add/remove/force/not_defined + +# Whether to enforce that all blocks of an 'if'/'else if'/'else' chain either +# have, or do not have, braces. If true, braces will be added if any block +# needs braces, and will only be removed if they can be removed from all +# blocks. +# +# Overrides mod_full_brace_if. +mod_full_brace_if_chain = false # true/false + +# Whether to add braces to all blocks of an 'if'/'else if'/'else' chain. +# If true, mod_full_brace_if_chain will only remove braces from an 'if' that +# does not have an 'else if' or 'else'. +mod_full_brace_if_chain_only = false # true/false + +# Add or remove braces on single-line 'while' statement. +mod_full_brace_while = add # ignore/add/remove/force/not_defined + +# Add or remove braces on single-line 'using ()' statement. +mod_full_brace_using = ignore # ignore/add/remove/force/not_defined + +# Don't remove braces around statements that span N newlines +mod_full_brace_nl = 0 # unsigned number + +# Whether to prevent removal of braces from 'if'/'for'/'while'/etc. blocks +# which span multiple lines. +# +# Affects: +# mod_full_brace_for +# mod_full_brace_if +# mod_full_brace_if_chain +# mod_full_brace_if_chain_only +# mod_full_brace_while +# mod_full_brace_using +# +# Does not affect: +# mod_full_brace_do +# mod_full_brace_function +mod_full_brace_nl_block_rem_mlcond = false # true/false + +# Add or remove unnecessary parenthesis on 'return' statement. +mod_paren_on_return = ignore # ignore/add/remove/force/not_defined + +# (Pawn) Whether to change optional semicolons to real semicolons. +mod_pawn_semicolon = false # true/false + +# Whether to fully parenthesize Boolean expressions in 'while' and 'if' +# statement, as in 'if (a && b > c)' => 'if (a && (b > c))'. +mod_full_paren_if_bool = false # true/false + +# Whether to remove superfluous semicolons. +mod_remove_extra_semicolon = false # true/false + +# Whether to remove duplicate include. +mod_remove_duplicate_include = false # true/false + +# If a function body exceeds the specified number of newlines and doesn't have +# a comment after the close brace, a comment will be added. +mod_add_long_function_closebrace_comment = 0 # unsigned number + +# If a namespace body exceeds the specified number of newlines and doesn't +# have a comment after the close brace, a comment will be added. +mod_add_long_namespace_closebrace_comment = 0 # unsigned number + +# If a class body exceeds the specified number of newlines and doesn't have a +# comment after the close brace, a comment will be added. +mod_add_long_class_closebrace_comment = 0 # unsigned number + +# If a switch body exceeds the specified number of newlines and doesn't have a +# comment after the close brace, a comment will be added. +mod_add_long_switch_closebrace_comment = 0 # unsigned number + +# If an #ifdef body exceeds the specified number of newlines and doesn't have +# a comment after the #endif, a comment will be added. +mod_add_long_ifdef_endif_comment = 0 # unsigned number + +# If an #ifdef or #else body exceeds the specified number of newlines and +# doesn't have a comment after the #else, a comment will be added. +mod_add_long_ifdef_else_comment = 0 # unsigned number + +# Whether to take care of the case by the mod_sort_xx options. +mod_sort_case_sensitive = false # true/false + +# Whether to sort consecutive single-line 'import' statements. +mod_sort_import = false # true/false + +# (C#) Whether to sort consecutive single-line 'using' statements. +mod_sort_using = false # true/false + +# Whether to sort consecutive single-line '#include' statements (C/C++) and +# '#import' statements (Objective-C). Be aware that this has the potential to +# break your code if your includes/imports have ordering dependencies. +mod_sort_include = true # true/false + +# Whether to prioritize '#include' and '#import' statements that contain +# filename without extension when sorting is enabled. +mod_sort_incl_import_prioritize_filename = false # true/false + +# Whether to prioritize '#include' and '#import' statements that does not +# contain extensions when sorting is enabled. +mod_sort_incl_import_prioritize_extensionless = false # true/false + +# Whether to prioritize '#include' and '#import' statements that contain +# angle over quotes when sorting is enabled. +mod_sort_incl_import_prioritize_angle_over_quotes = true # true/false + +# Whether to ignore file extension in '#include' and '#import' statements +# for sorting comparison. +mod_sort_incl_import_ignore_extension = false # true/false + +# Whether to group '#include' and '#import' statements when sorting is enabled. +mod_sort_incl_import_grouping_enabled = true # true/false + +# Whether to move a 'break' that appears after a fully braced 'case' before +# the close brace, as in 'case X: { ... } break;' => 'case X: { ... break; }'. +mod_move_case_break = false # true/false + +# Add or remove braces around a fully braced case statement. Will only remove +# braces if there are no variable declarations in the block. +mod_case_brace = remove # ignore/add/remove/force/not_defined + +# Whether to remove a void 'return;' that appears as the last statement in a +# function. +mod_remove_empty_return = false # true/false + +# Add or remove the comma after the last value of an enumeration. +mod_enum_last_comma = ignore # ignore/add/remove/force/not_defined + +# (OC) Whether to organize the properties. If true, properties will be +# rearranged according to the mod_sort_oc_property_*_weight factors. +mod_sort_oc_properties = false # true/false + +# (OC) Weight of a class property modifier. +mod_sort_oc_property_class_weight = 0 # number + +# (OC) Weight of 'atomic' and 'nonatomic'. +mod_sort_oc_property_thread_safe_weight = 0 # number + +# (OC) Weight of 'readwrite' when organizing properties. +mod_sort_oc_property_readwrite_weight = 0 # number + +# (OC) Weight of a reference type specifier ('retain', 'copy', 'assign', +# 'weak', 'strong') when organizing properties. +mod_sort_oc_property_reference_weight = 0 # number + +# (OC) Weight of getter type ('getter=') when organizing properties. +mod_sort_oc_property_getter_weight = 0 # number + +# (OC) Weight of setter type ('setter=') when organizing properties. +mod_sort_oc_property_setter_weight = 0 # number + +# (OC) Weight of nullability type ('nullable', 'nonnull', 'null_unspecified', +# 'null_resettable') when organizing properties. +mod_sort_oc_property_nullability_weight = 0 # number + +# +# Preprocessor options +# + +# Add or remove indentation of preprocessor directives inside #if blocks +# at brace level 0 (file-level). +pp_indent = remove # ignore/add/remove/force/not_defined + +# Whether to indent #if/#else/#endif at the brace level. If false, these are +# indented from column 1. +pp_indent_at_level = false # true/false + +# Specifies the number of columns to indent preprocessors per level +# at brace level 0 (file-level). If pp_indent_at_level=false, also specifies +# the number of columns to indent preprocessors per level +# at brace level > 0 (function-level). +# +# Default: 1 +pp_indent_count = 1 # unsigned number + +# Add or remove space after # based on pp_level of #if blocks. +pp_space = force # ignore/add/remove/force/not_defined + +# Sets the number of spaces per level added with pp_space. +pp_space_count = 0 # unsigned number + +# The indent for '#region' and '#endregion' in C# and '#pragma region' in +# C/C++. Negative values decrease indent down to the first column. +pp_indent_region = 0 # number + +# Whether to indent the code between #region and #endregion. +pp_region_indent_code = false # true/false + +# If pp_indent_at_level=true, sets the indent for #if, #else and #endif when +# not at file-level. Negative values decrease indent down to the first column. +# +# =0: Indent preprocessors using output_tab_size +# >0: Column at which all preprocessors will be indented +pp_indent_if = 0 # number + +# Whether to indent the code between #if, #else and #endif. +pp_if_indent_code = false # true/false + +# Whether to indent the body of an #if that encompasses all the code in the file. +pp_indent_in_guard = false # true/false + +# Whether to indent '#define' at the brace level. If false, these are +# indented from column 1. +pp_define_at_level = false # true/false + +# Whether to ignore the '#define' body while formatting. +pp_ignore_define_body = false # true/false + +# Whether to indent case statements between #if, #else, and #endif. +# Only applies to the indent of the preprocesser that the case statements +# directly inside of. +# +# Default: true +pp_indent_case = true # true/false + +# Whether to indent whole function definitions between #if, #else, and #endif. +# Only applies to the indent of the preprocesser that the function definition +# is directly inside of. +# +# Default: true +pp_indent_func_def = true # true/false + +# Whether to indent extern C blocks between #if, #else, and #endif. +# Only applies to the indent of the preprocesser that the extern block is +# directly inside of. +# +# Default: true +pp_indent_extern = true # true/false + +# Whether to indent braces directly inside #if, #else, and #endif. +# Only applies to the indent of the preprocesser that the braces are directly +# inside of. +# +# Default: true +pp_indent_brace = true # true/false + +# +# Sort includes options +# + +# The regex for include category with priority 0. +include_category_0 = "" # string + +# The regex for include category with priority 1. +include_category_1 = "" # string + +# The regex for include category with priority 2. +include_category_2 = "" # string + +# +# Use or Do not Use options +# + +# true: indent_func_call_param will be used (default) +# false: indent_func_call_param will NOT be used +# +# Default: true +use_indent_func_call_param = true # true/false + +# The value of the indentation for a continuation line is calculated +# differently if the statement is: +# - a declaration: your case with QString fileName ... +# - an assignment: your case with pSettings = new QSettings( ... +# +# At the second case the indentation value might be used twice: +# - at the assignment +# - at the function call (if present) +# +# To prevent the double use of the indentation value, use this option with the +# value 'true'. +# +# true: indent_continue will be used only once +# false: indent_continue will be used every time (default) +use_indent_continue_only_once = false # true/false + +# The value might be used twice: +# - at the assignment +# - at the opening brace +# +# To prevent the double use of the indentation value, use this option with the +# value 'true'. +# +# true: indentation will be used only once +# false: indentation will be used every time (default) +indent_cpp_lambda_only_once = false # true/false + +# Whether sp_after_angle takes precedence over sp_inside_fparen. This was the +# historic behavior, but is probably not the desired behavior, so this is off +# by default. +use_sp_after_angle_always = false # true/false + +# Whether to apply special formatting for Qt SIGNAL/SLOT macros. Essentially, +# this tries to format these so that they match Qt's normalized form (i.e. the +# result of QMetaObject::normalizedSignature), which can slightly improve the +# performance of the QObject::connect call, rather than how they would +# otherwise be formatted. +# +# See options_for_QT.cpp for details. +# +# Default: true +use_options_overriding_for_qt_macros = true # true/false + +# If true: the form feed character is removed from the list of whitespace +# characters. See https://en.cppreference.com/w/cpp/string/byte/isspace. +use_form_feed_no_more_as_whitespace_character = false # true/false + +# +# Warn levels - 1: error, 2: warning (default), 3: note +# + +# (C#) Warning is given if doing tab-to-\t replacement and we have found one +# in a C# verbatim string literal. +# +# Default: 2 +warn_level_tabs_found_in_verbatim_string_literals = 2 # unsigned number + +# Limit the number of loops. +# Used by uncrustify.cpp to exit from infinite loop. +# 0: no limit. +debug_max_number_of_loops = 0 # number + +# Set the number of the line to protocol; +# Used in the function prot_the_line if the 2. parameter is zero. +# 0: nothing protocol. +debug_line_number_to_protocol = 0 # number + +# Set the number of second(s) before terminating formatting the current file, +# 0: no timeout. +# only for linux +debug_timeout = 0 # number + +# Set the number of characters to be printed if the text is too long, +# 0: do not truncate. +debug_truncate = 0 # unsigned number + +# Meaning of the settings: +# Ignore - do not do any changes +# Add - makes sure there is 1 or more space/brace/newline/etc +# Force - makes sure there is exactly 1 space/brace/newline/etc, +# behaves like Add in some contexts +# Remove - removes space/brace/newline/etc +# +# +# - Token(s) can be treated as specific type(s) with the 'set' option: +# `set tokenType tokenString [tokenString...]` +# +# Example: +# `set BOOL __AND__ __OR__` +# +# tokenTypes are defined in src/token_enum.h, use them without the +# 'CT_' prefix: 'CT_BOOL' => 'BOOL' +# +# +# - Token(s) can be treated as type(s) with the 'type' option. +# `type tokenString [tokenString...]` +# +# Example: +# `type int c_uint_8 Rectangle` +# +# This can also be achieved with `set TYPE int c_uint_8 Rectangle` +# +# +# To embed whitespace in tokenStrings use the '\' escape character, or quote +# the tokenStrings. These quotes are supported: "'` +# +# +# - Support for the auto detection of languages through the file ending can be +# added using the 'file_ext' command. +# `file_ext langType langString [langString..]` +# +# Example: +# `file_ext CPP .ch .cxx .cpp.in` +# +# langTypes are defined in uncrusify_types.h in the lang_flag_e enum, use +# them without the 'LANG_' prefix: 'LANG_CPP' => 'CPP' +# +# +# - Custom macro-based indentation can be set up using 'macro-open', +# 'macro-else' and 'macro-close'. +# `(macro-open | macro-else | macro-close) tokenString` +# +# Example: +# `macro-open BEGIN_TEMPLATE_MESSAGE_MAP` +# `macro-open BEGIN_MESSAGE_MAP` +# `macro-close END_MESSAGE_MAP` +# +# +set QUESTION FUNC_API_CHECK_TEXTLOCK +set QUESTION FUNC_API_DEPRECATED_SINCE +set QUESTION FUNC_API_FAST +set QUESTION FUNC_API_LUA_ONLY +set QUESTION FUNC_API_NOEXPORT +set QUESTION FUNC_API_REMOTE_ONLY +set QUESTION FUNC_API_SINCE +set QUESTION FUNC_ATTR_ALWAYS_INLINE +set QUESTION FUNC_ATTR_CONST +set QUESTION FUNC_ATTR_MALLOC +set QUESTION FUNC_ATTR_NONNULL_ALL +set QUESTION FUNC_ATTR_NONNULL_ARG +set QUESTION FUNC_ATTR_NONNULL_RET +set QUESTION FUNC_ATTR_NORETURN +set QUESTION FUNC_ATTR_NO_SANITIZE_UNDEFINED +set QUESTION FUNC_ATTR_PRINTF +set QUESTION FUNC_ATTR_PURE +set QUESTION FUNC_ATTR_UNUSED +set QUESTION FUNC_ATTR_WARN_UNUSED_RESULT +set QUESTION REAL_FATTR_ALWAYS_INLINE +set QUESTION REAL_FATTR_CONST +set QUESTION REAL_FATTR_NONNULL_ALL +set QUESTION REAL_FATTR_PURE +set QUESTION REAL_FATTR_WARN_UNUSED_RESULT +# option(s) with 'not default' value: 66 +# |