aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordundargoc <33953936+dundargoc@users.noreply.github.com>2021-09-18 18:34:23 +0200
committerGitHub <noreply@github.com>2021-09-18 09:34:23 -0700
commit51a98aa0c2fe3231a0ffc8a78189bc6fafd6abf6 (patch)
treeb0a582d67883864eda3231bce45dc7c159cbe97f
parent6cad86fffdb91d3997a707ff6adb0b5991587b3e (diff)
downloadrneovim-51a98aa0c2fe3231a0ffc8a78189bc6fafd6abf6.tar.gz
rneovim-51a98aa0c2fe3231a0ffc8a78189bc6fafd6abf6.tar.bz2
rneovim-51a98aa0c2fe3231a0ffc8a78189bc6fafd6abf6.zip
refactor: format #15702
-rw-r--r--src/nvim/api/buffer.c164
-rw-r--r--src/nvim/api/deprecated.c39
-rw-r--r--src/nvim/api/private/dispatch.c25
-rw-r--r--src/nvim/api/private/helpers.c585
-rw-r--r--src/nvim/api/tabpage.c11
-rw-r--r--src/nvim/api/ui.c68
-rw-r--r--src/nvim/api/vim.c598
-rw-r--r--src/nvim/api/window.c21
-rw-r--r--src/nvim/eval/decode.c946
-rw-r--r--src/nvim/eval/encode.c830
-rw-r--r--src/nvim/eval/executor.c193
-rw-r--r--src/nvim/eval/funcs.c1341
-rw-r--r--src/nvim/eval/gc.c2
-rw-r--r--src/nvim/eval/typval.c1030
-rw-r--r--src/nvim/eval/userfunc.c399
-rw-r--r--src/nvim/viml/parser/expressions.c3267
16 files changed, 4631 insertions, 4888 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 3808f601d9..8973f8fef6 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -3,40 +3,39 @@
// Some of this code was adapted from 'if_py_both.h' from the original
// vim source
+#include <lauxlib.h>
+#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
-#include <limits.h>
-
-#include <lauxlib.h>
#include "nvim/api/buffer.h"
-#include "nvim/api/private/helpers.h"
#include "nvim/api/private/defs.h"
-#include "nvim/lua/executor.h"
-#include "nvim/vim.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/buffer.h"
+#include "nvim/buffer_updates.h"
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/decoration.h"
+#include "nvim/ex_cmds.h"
+#include "nvim/ex_docmd.h"
+#include "nvim/extmark.h"
+#include "nvim/fileio.h"
#include "nvim/getchar.h"
+#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/misc1.h"
-#include "nvim/ex_cmds.h"
-#include "nvim/map_defs.h"
-#include "nvim/map.h"
-#include "nvim/mark.h"
-#include "nvim/ops.h"
-#include "nvim/extmark.h"
-#include "nvim/decoration.h"
-#include "nvim/fileio.h"
#include "nvim/move.h"
+#include "nvim/ops.h"
#include "nvim/syntax.h"
-#include "nvim/window.h"
#include "nvim/undo.h"
-#include "nvim/ex_docmd.h"
-#include "nvim/buffer_updates.h"
+#include "nvim/vim.h"
+#include "nvim/window.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "api/buffer.c.generated.h"
@@ -149,11 +148,8 @@ Integer nvim_buf_line_count(Buffer buffer, Error *err)
/// @param[out] err Error details, if any
/// @return False if attach failed (invalid parameter, or buffer isn't loaded);
/// otherwise True. TODO: LUA_API_NO_EVAL
-Boolean nvim_buf_attach(uint64_t channel_id,
- Buffer buffer,
- Boolean send_buffer,
- DictionaryOf(LuaRef) opts,
- Error *err)
+Boolean nvim_buf_attach(uint64_t channel_id, Buffer buffer, Boolean send_buffer,
+ DictionaryOf(LuaRef) opts, Error *err)
FUNC_API_SINCE(4)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -237,9 +233,7 @@ error:
/// @param[out] err Error details, if any
/// @return False if detach failed (because the buffer isn't loaded);
/// otherwise True.
-Boolean nvim_buf_detach(uint64_t channel_id,
- Buffer buffer,
- Error *err)
+Boolean nvim_buf_detach(uint64_t channel_id, Buffer buffer, Error *err)
FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -252,8 +246,7 @@ Boolean nvim_buf_detach(uint64_t channel_id,
return true;
}
-void nvim__buf_redraw_range(Buffer buffer, Integer first, Integer last,
- Error *err)
+void nvim__buf_redraw_range(Buffer buffer, Integer first, Integer last, Error *err)
FUNC_API_LUA_ONLY
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -376,13 +369,8 @@ static bool check_string_array(Array arr, bool disallow_nl, Error *err)
/// @param strict_indexing Whether out-of-bounds should be an error.
/// @param replacement Array of lines to use as replacement
/// @param[out] err Error details, if any
-void nvim_buf_set_lines(uint64_t channel_id,
- Buffer buffer,
- Integer start,
- Integer end,
- Boolean strict_indexing,
- ArrayOf(String) replacement,
- Error *err)
+void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integer end,
+ Boolean strict_indexing, ArrayOf(String) replacement, Error *err)
FUNC_API_SINCE(1)
FUNC_API_CHECK_TEXTLOCK
{
@@ -554,10 +542,8 @@ end:
/// @param end_column Last column
/// @param replacement Array of lines to use as replacement
/// @param[out] err Error details, if any
-void nvim_buf_set_text(uint64_t channel_id, Buffer buffer,
- Integer start_row, Integer start_col,
- Integer end_row, Integer end_col,
- ArrayOf(String) replacement, Error *err)
+void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, Integer start_col,
+ Integer end_row, Integer end_col, ArrayOf(String) replacement, Error *err)
FUNC_API_SINCE(7)
{
FIXED_TEMP_ARRAY(scratch, 1);
@@ -617,17 +603,17 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer,
// calculate byte size of old region before it gets modified/deleted
if (start_row == end_row) {
- old_byte = (bcount_t)end_col - start_col;
+ old_byte = (bcount_t)end_col - start_col;
} else {
- const char *bufline;
- old_byte += (bcount_t)strlen(str_at_start) - start_col;
- for (int64_t i = 1; i < end_row - start_row; i++) {
- int64_t lnum = start_row + i;
+ const char *bufline;
+ old_byte += (bcount_t)strlen(str_at_start) - start_col;
+ for (int64_t i = 1; i < end_row - start_row; i++) {
+ int64_t lnum = start_row + i;
- bufline = (char *)ml_get_buf(buf, lnum, false);
- old_byte += (bcount_t)(strlen(bufline))+1;
- }
- old_byte += (bcount_t)end_col+1;
+ bufline = (char *)ml_get_buf(buf, lnum, false);
+ old_byte += (bcount_t)(strlen(bufline))+1;
+ }
+ old_byte += (bcount_t)end_col+1;
}
String first_item = replacement.items[0].data.string;
@@ -824,7 +810,7 @@ Object nvim_buf_get_var(Buffer buffer, String name, Error *err)
buf_T *buf = find_buffer_by_handle(buffer, err);
if (!buf) {
- return (Object) OBJECT_INIT;
+ return (Object)OBJECT_INIT;
}
return dict_get_value(buf->b_vars, name, err);
@@ -872,8 +858,8 @@ 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, Error *err)
+void nvim_buf_set_keymap(Buffer buffer, String mode, String lhs, String rhs, Dictionary opts,
+ Error *err)
FUNC_API_SINCE(6)
{
modify_keymap(buffer, false, mode, lhs, rhs, opts, err);
@@ -980,7 +966,7 @@ Object nvim_buf_get_option(Buffer buffer, String name, Error *err)
buf_T *buf = find_buffer_by_handle(buffer, err);
if (!buf) {
- return (Object) OBJECT_INIT;
+ return (Object)OBJECT_INIT;
}
return get_option_from(buf, SREQ_BUF, name, err);
@@ -994,8 +980,7 @@ Object nvim_buf_get_option(Buffer buffer, String name, Error *err)
/// @param name Option name
/// @param value Option value
/// @param[out] err Error details, if any
-void nvim_buf_set_option(uint64_t channel_id, Buffer buffer,
- String name, Object value, Error *err)
+void nvim_buf_set_option(uint64_t channel_id, Buffer buffer, String name, Object value, Error *err)
FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -1044,7 +1029,7 @@ void nvim_buf_set_name(Buffer buffer, String name, Error *err)
// Using aucmd_*: autocommands will be executed by rename_buffer
aco_save_T aco;
aucmd_prepbuf(&aco, buf);
- int ren_ret = rename_buffer((char_u *) name.data);
+ int ren_ret = rename_buffer((char_u *)name.data);
aucmd_restbuf(&aco);
if (try_end(err)) {
@@ -1105,12 +1090,11 @@ void nvim_buf_delete(Buffer buffer, Dictionary opts, Error *err)
return;
}
- int result = do_buffer(
- unload ? DOBUF_UNLOAD : DOBUF_WIPE,
- DOBUF_FIRST,
- FORWARD,
- buf->handle,
- force);
+ int result = do_buffer(unload ? DOBUF_UNLOAD : DOBUF_WIPE,
+ DOBUF_FIRST,
+ FORWARD,
+ buf->handle,
+ force);
if (result == FAIL) {
api_set_error(err, kErrorTypeException, "Failed to unload buffer.");
@@ -1213,8 +1197,7 @@ static Array extmark_to_array(ExtmarkInfo extmark, bool id, bool add_dict)
ADD(chunk, STRING_OBJ(cstr_to_string(vtc->text)));
if (vtc->hl_id > 0) {
ADD(chunk,
- STRING_OBJ(cstr_to_string(
- (const char *)syn_id2name(vtc->hl_id))));
+ STRING_OBJ(cstr_to_string((const char *)syn_id2name(vtc->hl_id))));
}
ADD(chunks, ARRAY_OBJ(chunk));
}
@@ -1330,9 +1313,8 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id,
/// - details Whether to include the details dict
/// @param[out] err Error details, if any
/// @return List of [extmark_id, row, col] tuples in "traversal order".
-Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id,
- Object start, Object end,
- Dictionary opts, Error *err)
+Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object end, Dictionary opts,
+ Error *err)
FUNC_API_SINCE(7)
{
Array rv = ARRAY_DICT_INIT;
@@ -1480,8 +1462,7 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id,
/// example treesitter highlighting uses a value of 100.
/// @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,
+Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer col,
Dictionary opts, Error *err)
FUNC_API_SINCE(7)
{
@@ -1546,19 +1527,18 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
} 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;
+ 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) {
@@ -1692,8 +1672,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
if (col2 >= 0) {
if (line2 >= 0 && line2 < buf->b_ml.ml_line_count) {
- len = ephemeral ? MAXCOL : STRLEN(
- ml_get_buf(buf, (linenr_T)line2 + 1, false));
+ len = ephemeral ? MAXCOL : STRLEN(ml_get_buf(buf, (linenr_T)line2 + 1, false));
} else if (line2 == buf->b_ml.ml_line_count) {
// We are trying to add an extmark past final newline
len = 0;
@@ -1713,7 +1692,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
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);
+ += (int)mb_string2cells((char_u *)kv_A(decor.virt_text, i).text);
}
}
@@ -1761,10 +1740,7 @@ error:
/// @param id Extmark id
/// @param[out] err Error details, if any
/// @return true if the extmark was found, else false
-Boolean nvim_buf_del_extmark(Buffer buffer,
- Integer ns_id,
- Integer id,
- Error *err)
+Boolean nvim_buf_del_extmark(Buffer buffer, Integer ns_id, Integer id, Error *err)
FUNC_API_SINCE(7)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -1810,13 +1786,8 @@ Boolean nvim_buf_del_extmark(Buffer buffer,
/// or -1 to highlight to end of line
/// @param[out] err Error details, if any
/// @return The ns_id that was used
-Integer nvim_buf_add_highlight(Buffer buffer,
- Integer ns_id,
- String hl_group,
- Integer line,
- Integer col_start,
- Integer col_end,
- Error *err)
+Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, Integer line,
+ Integer col_start, Integer col_end, Error *err)
FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -1875,10 +1846,7 @@ Integer nvim_buf_add_highlight(Buffer buffer,
/// @param line_end End of range of lines to clear (exclusive) or -1 to clear
/// to end of buffer.
/// @param[out] err Error details, if any
-void nvim_buf_clear_namespace(Buffer buffer,
- Integer ns_id,
- Integer line_start,
- Integer line_end,
+void nvim_buf_clear_namespace(Buffer buffer, Integer ns_id, Integer line_start, Integer line_end,
Error *err)
FUNC_API_SINCE(5)
{
diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c
index 554966e266..21b9db85c0 100644
--- a/src/nvim/api/deprecated.c
+++ b/src/nvim/api/deprecated.c
@@ -1,18 +1,18 @@
// 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 <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
-#include <limits.h>
-#include "nvim/api/deprecated.h"
#include "nvim/api/buffer.h"
-#include "nvim/api/vim.h"
-#include "nvim/api/private/helpers.h"
+#include "nvim/api/deprecated.h"
#include "nvim/api/private/defs.h"
-#include "nvim/lua/executor.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/vim.h"
#include "nvim/extmark.h"
+#include "nvim/lua/executor.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "api/deprecated.c.generated.h"
@@ -69,10 +69,7 @@ Integer nvim_buf_get_number(Buffer buffer, Error *err)
/// @param line_end End of range of lines to clear (exclusive) or -1 to clear
/// to end of file.
/// @param[out] err Error details, if any
-void nvim_buf_clear_highlight(Buffer buffer,
- Integer ns_id,
- Integer line_start,
- Integer line_end,
+void nvim_buf_clear_highlight(Buffer buffer, Integer ns_id, Integer line_start, Integer line_end,
Error *err)
FUNC_API_SINCE(1)
FUNC_API_DEPRECATED_SINCE(7)
@@ -111,12 +108,8 @@ void nvim_buf_clear_highlight(Buffer buffer,
/// @param opts Optional parameters. Currently not used.
/// @param[out] err Error details, if any
/// @return The ns_id that was used
-Integer nvim_buf_set_virtual_text(Buffer buffer,
- Integer src_id,
- Integer line,
- Array chunks,
- Dictionary opts,
- Error *err)
+Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, Array chunks,
+ Dictionary opts, Error *err)
FUNC_API_SINCE(5)
FUNC_API_DEPRECATED_SINCE(8)
{
@@ -171,10 +164,7 @@ Integer nvim_buf_set_virtual_text(Buffer buffer,
/// the end of the buffer.
/// @param lines Array of lines
/// @param[out] err Error details, if any
-void buffer_insert(Buffer buffer,
- Integer lnum,
- ArrayOf(String) lines,
- Error *err)
+void buffer_insert(Buffer buffer, Integer lnum, ArrayOf(String) lines, Error *err)
{
// "lnum" will be the index of the line after inserting,
// no matter if it is negative or not
@@ -268,7 +258,7 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer,
{
start = convert_index(start) + !include_start;
end = convert_index(end) + include_end;
- return nvim_buf_get_lines(0, buffer, start , end, false, err);
+ return nvim_buf_get_lines(0, buffer, start, end, false, err);
}
/// Replaces a line range on the buffer
@@ -286,13 +276,8 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer,
/// @param replacement Array of lines to use as replacement (0-length
// array will delete the line range)
/// @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)
+void buffer_set_line_slice(Buffer buffer, Integer start, Integer end, Boolean include_start,
+ Boolean include_end, ArrayOf(String) replacement, Error *err)
{
start = convert_index(start) + !include_start;
end = convert_index(end) + include_end;
diff --git a/src/nvim/api/private/dispatch.c b/src/nvim/api/private/dispatch.c
index 9f16da4078..38ce7ca78c 100644
--- a/src/nvim/api/private/dispatch.c
+++ b/src/nvim/api/private/dispatch.c
@@ -1,38 +1,35 @@
// 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 <inttypes.h>
-#include <stdbool.h>
#include <assert.h>
+#include <inttypes.h>
#include <msgpack.h>
+#include <stdbool.h>
-#include "nvim/map.h"
-#include "nvim/log.h"
-#include "nvim/vim.h"
-#include "nvim/msgpack_rpc/helpers.h"
+#include "nvim/api/buffer.h"
+#include "nvim/api/deprecated.h"
+#include "nvim/api/private/defs.h"
#include "nvim/api/private/dispatch.h"
#include "nvim/api/private/helpers.h"
-#include "nvim/api/private/defs.h"
-
-#include "nvim/api/buffer.h"
#include "nvim/api/tabpage.h"
#include "nvim/api/ui.h"
#include "nvim/api/vim.h"
#include "nvim/api/window.h"
-#include "nvim/api/deprecated.h"
+#include "nvim/log.h"
+#include "nvim/map.h"
+#include "nvim/msgpack_rpc/helpers.h"
+#include "nvim/vim.h"
static Map(String, MsgpackRpcRequestHandler) methods = MAP_INIT;
-static void msgpack_rpc_add_method_handler(String method,
- MsgpackRpcRequestHandler handler)
+static void msgpack_rpc_add_method_handler(String method, MsgpackRpcRequestHandler handler)
{
map_put(String, MsgpackRpcRequestHandler)(&methods, method, handler);
}
/// @param name API method name
/// @param name_len name size (includes terminating NUL)
-MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name,
- size_t name_len,
+MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name, size_t name_len,
Error *error)
{
String m = { .data = (char *)name, .size = name_len };
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index ecbd4e13a3..541793e528 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -7,33 +7,33 @@
#include <stdlib.h>
#include <string.h>
-#include "nvim/api/private/helpers.h"
#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/api/vim.h"
-#include "nvim/msgpack_rpc/helpers.h"
-#include "nvim/lua/executor.h"
#include "nvim/ascii.h"
#include "nvim/assert.h"
-#include "nvim/charset.h"
-#include "nvim/syntax.h"
-#include "nvim/vim.h"
#include "nvim/buffer.h"
-#include "nvim/window.h"
-#include "nvim/memline.h"
-#include "nvim/memory.h"
+#include "nvim/charset.h"
+#include "nvim/decoration.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
-#include "nvim/map_defs.h"
-#include "nvim/map.h"
#include "nvim/extmark.h"
-#include "nvim/decoration.h"
+#include "nvim/fileio.h"
+#include "nvim/getchar.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/lua/executor.h"
+#include "nvim/map.h"
+#include "nvim/map_defs.h"
+#include "nvim/memline.h"
+#include "nvim/memory.h"
+#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/option.h"
#include "nvim/option_defs.h"
-#include "nvim/version.h"
-#include "nvim/lib/kvec.h"
-#include "nvim/getchar.h"
-#include "nvim/fileio.h"
+#include "nvim/syntax.h"
#include "nvim/ui.h"
+#include "nvim/version.h"
+#include "nvim/vim.h"
+#include "nvim/window.h"
/// Helper structure for vim_to_object
typedef struct {
@@ -41,8 +41,8 @@ typedef struct {
} EncodedData;
#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "api/private/helpers.c.generated.h"
# include "api/private/funcs_metadata.generated.h"
+# include "api/private/helpers.c.generated.h"
# include "api/private/ui_events_metadata.generated.h"
#endif
@@ -210,8 +210,7 @@ dictitem_T *dict_check_writable(dict_T *dict, String key, bool del, Error *err)
/// @param retval If true the old value will be converted and returned.
/// @param[out] err Details of an error that may have occurred
/// @return The old value if `retval` is true and the key was present, else NIL
-Object dict_set_var(dict_T *dict, String key, Object value, bool del,
- bool retval, Error *err)
+Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retval, Error *err)
{
Object rv = OBJECT_INIT;
dictitem_T *di = dict_check_writable(dict, key, del, err);
@@ -326,8 +325,7 @@ Object get_option_from(void *from, int type, String name, Error *err)
/// @param type One of `SREQ_GLOBAL`, `SREQ_WIN` or `SREQ_BUF`
/// @param name The option name
/// @param[out] err Details of an error that may have occurred
-void set_option_to(uint64_t channel_id, void *to, int type,
- String name, Object value, Error *err)
+void set_option_to(uint64_t channel_id, void *to, int type, String name, Object value, Error *err)
{
if (name.size == 0) {
api_set_error(err, kErrorTypeValidation, "Empty option name");
@@ -418,61 +416,60 @@ void set_option_to(uint64_t channel_id, void *to, int type,
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
#define TYPVAL_ENCODE_CONV_NIL(tv) \
- kvi_push(edata->stack, NIL)
+ kvi_push(edata->stack, NIL)
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
- kvi_push(edata->stack, BOOLEAN_OBJ((Boolean)(num)))
+ kvi_push(edata->stack, BOOLEAN_OBJ((Boolean)(num)))
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
- kvi_push(edata->stack, INTEGER_OBJ((Integer)(num)))
+ kvi_push(edata->stack, INTEGER_OBJ((Integer)(num)))
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER TYPVAL_ENCODE_CONV_NUMBER
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
- kvi_push(edata->stack, FLOAT_OBJ((Float)(flt)))
+ kvi_push(edata->stack, FLOAT_OBJ((Float)(flt)))
#define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \
- do { \
- const size_t len_ = (size_t)(len); \
- const char *const str_ = (const char *)(str); \
- assert(len_ == 0 || str_ != NULL); \
- kvi_push(edata->stack, STRING_OBJ(cbuf_to_string((len_?str_:""), len_))); \
- } while (0)
+ do { \
+ const size_t len_ = (size_t)(len); \
+ const char *const str_ = (const char *)(str); \
+ assert(len_ == 0 || str_ != NULL); \
+ kvi_push(edata->stack, STRING_OBJ(cbuf_to_string((len_?str_:""), len_))); \
+ } while (0)
#define TYPVAL_ENCODE_CONV_STR_STRING TYPVAL_ENCODE_CONV_STRING
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, str, len, type) \
- TYPVAL_ENCODE_CONV_NIL(tv)
+ TYPVAL_ENCODE_CONV_NIL(tv)
#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \
- do { \
- const size_t len_ = (size_t)(len); \
- const blob_T *const blob_ = (blob); \
- kvi_push(edata->stack, STRING_OBJ(((String) { \
- .data = len_ != 0 ? xmemdup(blob_->bv_ga.ga_data, len_) : NULL, \
- .size = len_ \
- }))); \
- } while (0)
+ do { \
+ const size_t len_ = (size_t)(len); \
+ const blob_T *const blob_ = (blob); \
+ kvi_push(edata->stack, STRING_OBJ(((String) { \
+ .data = len_ != 0 ? xmemdup(blob_->bv_ga.ga_data, len_) : NULL, \
+ .size = len_ \
+ }))); \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
- do { \
- TYPVAL_ENCODE_CONV_NIL(tv); \
- goto typval_encode_stop_converting_one_item; \
- } while (0)
+ do { \
+ TYPVAL_ENCODE_CONV_NIL(tv); \
+ goto typval_encode_stop_converting_one_item; \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_END(tv)
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
- kvi_push(edata->stack, ARRAY_OBJ(((Array) { .capacity = 0, .size = 0 })))
+ kvi_push(edata->stack, ARRAY_OBJ(((Array) { .capacity = 0, .size = 0 })))
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
- kvi_push(edata->stack, \
- DICTIONARY_OBJ(((Dictionary) { .capacity = 0, .size = 0 })))
+ kvi_push(edata->stack, \
+ DICTIONARY_OBJ(((Dictionary) { .capacity = 0, .size = 0 })))
-static inline void typval_encode_list_start(EncodedData *const edata,
- const size_t len)
+static inline void typval_encode_list_start(EncodedData *const edata, const size_t len)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
{
kvi_push(edata->stack, ARRAY_OBJ(((Array) {
@@ -483,7 +480,7 @@ static inline void typval_encode_list_start(EncodedData *const edata,
}
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
- typval_encode_list_start(edata, (size_t)(len))
+ typval_encode_list_start(edata, (size_t)(len))
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
@@ -498,7 +495,7 @@ static inline void typval_encode_between_list_items(EncodedData *const edata)
}
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv) \
- typval_encode_between_list_items(edata)
+ typval_encode_between_list_items(edata)
static inline void typval_encode_list_end(EncodedData *const edata)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
@@ -511,22 +508,21 @@ static inline void typval_encode_list_end(EncodedData *const edata)
}
#define TYPVAL_ENCODE_CONV_LIST_END(tv) \
- typval_encode_list_end(edata)
+ typval_encode_list_end(edata)
-static inline void typval_encode_dict_start(EncodedData *const edata,
- const size_t len)
+static inline void typval_encode_dict_start(EncodedData *const edata, const size_t len)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
{
kvi_push(edata->stack, DICTIONARY_OBJ(((Dictionary) {
.capacity = len,
.size = 0,
.items = xmalloc(len * sizeof(
- *((Object)OBJECT_INIT).data.dictionary.items)),
+ *((Object)OBJECT_INIT).data.dictionary.items)),
})));
}
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
- typval_encode_dict_start(edata, (size_t)(len))
+ typval_encode_dict_start(edata, (size_t)(len))
#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv)
@@ -541,16 +537,16 @@ static inline void typval_encode_after_key(EncodedData *const edata)
assert(dict->data.dictionary.size < dict->data.dictionary.capacity);
if (key.type == kObjectTypeString) {
dict->data.dictionary.items[dict->data.dictionary.size].key
- = key.data.string;
+ = key.data.string;
} else {
api_free_object(key);
dict->data.dictionary.items[dict->data.dictionary.size].key
- = STATIC_CSTR_TO_STRING("__INVALID_KEY__");
+ = STATIC_CSTR_TO_STRING("__INVALID_KEY__");
}
}
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict) \
- typval_encode_after_key(edata)
+ typval_encode_after_key(edata)
static inline void typval_encode_between_dict_items(EncodedData *const edata)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
@@ -563,7 +559,7 @@ static inline void typval_encode_between_dict_items(EncodedData *const edata)
}
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict) \
- typval_encode_between_dict_items(edata)
+ typval_encode_between_dict_items(edata)
static inline void typval_encode_dict_end(EncodedData *const edata)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
@@ -576,10 +572,10 @@ static inline void typval_encode_dict_end(EncodedData *const edata)
}
#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
- typval_encode_dict_end(edata)
+ typval_encode_dict_end(edata)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
- TYPVAL_ENCODE_CONV_NIL(val)
+ TYPVAL_ENCODE_CONV_NIL(val)
#define TYPVAL_ENCODE_SCOPE static
#define TYPVAL_ENCODE_NAME object
@@ -708,15 +704,15 @@ String cchar_to_string(char c)
/// empty String is returned
String cstr_to_string(const char *str)
{
- if (str == NULL) {
- return (String)STRING_INIT;
- }
+ if (str == NULL) {
+ return (String)STRING_INIT;
+ }
- size_t len = strlen(str);
- return (String){
- .data = xmemdupz(str, len),
- .size = len,
- };
+ size_t len = strlen(str);
+ return (String){
+ .data = xmemdupz(str, len),
+ .size = len,
+ };
}
/// Copies buffer to an allocated String.
@@ -817,8 +813,8 @@ Array string_to_array(const String input, bool crlf)
/// @param buffer Buffer handle for a specific buffer, or 0 for the current
/// 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)
+void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String rhs,
+ Dictionary 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
@@ -916,21 +912,21 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs,
}
switch (buf_do_map(maptype_val, &parsed_args, mode_val, 0, target_buf)) {
- case 0:
- break;
- case 1:
- api_set_error(err, kErrorTypeException, (char *)e_invarg, 0);
- goto fail_and_free;
- case 2:
- api_set_error(err, kErrorTypeException, (char *)e_nomap, 0);
- goto fail_and_free;
- case 5:
- api_set_error(err, kErrorTypeException,
- "E227: mapping already exists for %s", parsed_args.lhs);
- goto fail_and_free;
- default:
- assert(false && "Unrecognized return code!");
- goto fail_and_free;
+ case 0:
+ break;
+ case 1:
+ api_set_error(err, kErrorTypeException, (char *)e_invarg, 0);
+ goto fail_and_free;
+ case 2:
+ api_set_error(err, kErrorTypeException, (char *)e_nomap, 0);
+ goto fail_and_free;
+ case 5:
+ api_set_error(err, kErrorTypeException,
+ "E227: mapping already exists for %s", parsed_args.lhs);
+ goto fail_and_free;
+ default:
+ assert(false && "Unrecognized return code!");
+ goto fail_and_free;
} // switch
xfree(lhs_buf);
@@ -986,44 +982,44 @@ Integer parse_keymap_opts(Dictionary opts, MapArguments *out, Error *err)
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;
+ // 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";
@@ -1050,8 +1046,7 @@ fail_with_message:
/// @param[out] l Lines are copied here
/// @param err[out] Error, if any
/// @return true unless `err` was set
-bool buf_collect_lines(buf_T *buf, size_t n, int64_t start, bool replace_nl,
- Array *l, Error *err)
+bool buf_collect_lines(buf_T *buf, size_t n, int64_t start, bool replace_nl, Array *l, Error *err)
{
for (size_t i = 0; i < n; i++) {
int64_t lnum = start + (int64_t)i;
@@ -1089,96 +1084,96 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err)
tv->v_lock = VAR_UNLOCKED;
switch (obj.type) {
- case kObjectTypeNil:
- tv->v_type = VAR_SPECIAL;
- tv->vval.v_special = kSpecialVarNull;
- break;
-
- case kObjectTypeBoolean:
- tv->v_type = VAR_BOOL;
- tv->vval.v_bool = obj.data.boolean? kBoolVarTrue: kBoolVarFalse;
- break;
-
- case kObjectTypeBuffer:
- case kObjectTypeWindow:
- case kObjectTypeTabpage:
- case kObjectTypeInteger:
- STATIC_ASSERT(sizeof(obj.data.integer) <= sizeof(varnumber_T),
- "Integer size must be <= VimL number size");
- tv->v_type = VAR_NUMBER;
- tv->vval.v_number = (varnumber_T)obj.data.integer;
- break;
-
- case kObjectTypeFloat:
- tv->v_type = VAR_FLOAT;
- tv->vval.v_float = obj.data.floating;
- break;
-
- case kObjectTypeString:
- tv->v_type = VAR_STRING;
- if (obj.data.string.data == NULL) {
- tv->vval.v_string = NULL;
- } else {
- tv->vval.v_string = xmemdupz(obj.data.string.data,
- obj.data.string.size);
- }
- break;
-
- case kObjectTypeArray: {
- list_T *const list = tv_list_alloc((ptrdiff_t)obj.data.array.size);
+ case kObjectTypeNil:
+ tv->v_type = VAR_SPECIAL;
+ tv->vval.v_special = kSpecialVarNull;
+ break;
+
+ case kObjectTypeBoolean:
+ tv->v_type = VAR_BOOL;
+ tv->vval.v_bool = obj.data.boolean? kBoolVarTrue: kBoolVarFalse;
+ break;
+
+ case kObjectTypeBuffer:
+ case kObjectTypeWindow:
+ case kObjectTypeTabpage:
+ case kObjectTypeInteger:
+ STATIC_ASSERT(sizeof(obj.data.integer) <= sizeof(varnumber_T),
+ "Integer size must be <= VimL number size");
+ tv->v_type = VAR_NUMBER;
+ tv->vval.v_number = (varnumber_T)obj.data.integer;
+ break;
+
+ case kObjectTypeFloat:
+ tv->v_type = VAR_FLOAT;
+ tv->vval.v_float = obj.data.floating;
+ break;
+
+ case kObjectTypeString:
+ tv->v_type = VAR_STRING;
+ if (obj.data.string.data == NULL) {
+ tv->vval.v_string = NULL;
+ } else {
+ tv->vval.v_string = xmemdupz(obj.data.string.data,
+ obj.data.string.size);
+ }
+ break;
- for (uint32_t i = 0; i < obj.data.array.size; i++) {
- Object item = obj.data.array.items[i];
- typval_T li_tv;
+ case kObjectTypeArray: {
+ list_T *const list = tv_list_alloc((ptrdiff_t)obj.data.array.size);
- if (!object_to_vim(item, &li_tv, err)) {
- tv_list_free(list);
- return false;
- }
+ for (uint32_t i = 0; i < obj.data.array.size; i++) {
+ Object item = obj.data.array.items[i];
+ typval_T li_tv;
- tv_list_append_owned_tv(list, li_tv);
+ if (!object_to_vim(item, &li_tv, err)) {
+ tv_list_free(list);
+ return false;
}
- tv_list_ref(list);
- tv->v_type = VAR_LIST;
- tv->vval.v_list = list;
- break;
+ tv_list_append_owned_tv(list, li_tv);
}
+ tv_list_ref(list);
- case kObjectTypeDictionary: {
- dict_T *const dict = tv_dict_alloc();
+ tv->v_type = VAR_LIST;
+ tv->vval.v_list = list;
+ break;
+ }
- for (uint32_t i = 0; i < obj.data.dictionary.size; i++) {
- KeyValuePair item = obj.data.dictionary.items[i];
- String key = item.key;
+ case kObjectTypeDictionary: {
+ dict_T *const dict = tv_dict_alloc();
- if (key.size == 0) {
- api_set_error(err, kErrorTypeValidation,
- "Empty dictionary keys aren't allowed");
- // cleanup
- tv_dict_free(dict);
- return false;
- }
+ for (uint32_t i = 0; i < obj.data.dictionary.size; i++) {
+ KeyValuePair item = obj.data.dictionary.items[i];
+ String key = item.key;
- dictitem_T *const di = tv_dict_item_alloc(key.data);
+ if (key.size == 0) {
+ api_set_error(err, kErrorTypeValidation,
+ "Empty dictionary keys aren't allowed");
+ // cleanup
+ tv_dict_free(dict);
+ return false;
+ }
- if (!object_to_vim(item.value, &di->di_tv, err)) {
- // cleanup
- tv_dict_item_free(di);
- tv_dict_free(dict);
- return false;
- }
+ dictitem_T *const di = tv_dict_item_alloc(key.data);
- tv_dict_add(dict, di);
+ if (!object_to_vim(item.value, &di->di_tv, err)) {
+ // cleanup
+ tv_dict_item_free(di);
+ tv_dict_free(dict);
+ return false;
}
- dict->dv_refcount++;
- tv->v_type = VAR_DICT;
- tv->vval.v_dict = dict;
- break;
+ tv_dict_add(dict, di);
}
- default:
- abort();
+ dict->dv_refcount++;
+
+ tv->v_type = VAR_DICT;
+ tv->vval.v_dict = dict;
+ break;
+ }
+ default:
+ abort();
}
return true;
@@ -1196,33 +1191,33 @@ void api_free_string(String value)
void api_free_object(Object value)
{
switch (value.type) {
- case kObjectTypeNil:
- case kObjectTypeBoolean:
- case kObjectTypeInteger:
- case kObjectTypeFloat:
- case kObjectTypeBuffer:
- case kObjectTypeWindow:
- case kObjectTypeTabpage:
- break;
-
- case kObjectTypeString:
- api_free_string(value.data.string);
- break;
-
- case kObjectTypeArray:
- api_free_array(value.data.array);
- break;
-
- case kObjectTypeDictionary:
- api_free_dictionary(value.data.dictionary);
- break;
-
- case kObjectTypeLuaRef:
- api_free_luaref(value.data.luaref);
- break;
-
- default:
- abort();
+ case kObjectTypeNil:
+ case kObjectTypeBoolean:
+ case kObjectTypeInteger:
+ case kObjectTypeFloat:
+ case kObjectTypeBuffer:
+ case kObjectTypeWindow:
+ case kObjectTypeTabpage:
+ break;
+
+ case kObjectTypeString:
+ api_free_string(value.data.string);
+ break;
+
+ case kObjectTypeArray:
+ api_free_array(value.data.array);
+ break;
+
+ case kObjectTypeDictionary:
+ api_free_dictionary(value.data.dictionary);
+ break;
+
+ case kObjectTypeLuaRef:
+ api_free_luaref(value.data.luaref);
+ break;
+
+ default:
+ abort();
}
}
@@ -1385,36 +1380,30 @@ Dictionary copy_dictionary(Dictionary dict)
Object copy_object(Object obj)
{
switch (obj.type) {
- case kObjectTypeBuffer:
- case kObjectTypeTabpage:
- case kObjectTypeWindow:
- case kObjectTypeNil:
- case kObjectTypeBoolean:
- case kObjectTypeInteger:
- case kObjectTypeFloat:
- return obj;
-
- case kObjectTypeString:
- return STRING_OBJ(copy_string(obj.data.string));
-
- case kObjectTypeArray:
- return ARRAY_OBJ(copy_array(obj.data.array));
-
- case kObjectTypeDictionary: {
- return DICTIONARY_OBJ(copy_dictionary(obj.data.dictionary));
- }
- default:
- abort();
+ case kObjectTypeBuffer:
+ case kObjectTypeTabpage:
+ case kObjectTypeWindow:
+ case kObjectTypeNil:
+ case kObjectTypeBoolean:
+ case kObjectTypeInteger:
+ case kObjectTypeFloat:
+ return obj;
+
+ case kObjectTypeString:
+ return STRING_OBJ(copy_string(obj.data.string));
+
+ case kObjectTypeArray:
+ return ARRAY_OBJ(copy_array(obj.data.array));
+
+ case kObjectTypeDictionary:
+ return DICTIONARY_OBJ(copy_dictionary(obj.data.dictionary));
+ default:
+ abort();
}
}
-static void set_option_value_for(char *key,
- int numval,
- char *stringval,
- int opt_flags,
- int opt_type,
- void *from,
- Error *err)
+static void set_option_value_for(char *key, int numval, char *stringval, int opt_flags,
+ int opt_type, void *from, Error *err)
{
win_T *save_curwin = NULL;
tabpage_T *save_curtab = NULL;
@@ -1423,29 +1412,28 @@ static void set_option_value_for(char *key,
try_start();
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 (try_end(err)) {
- return;
- }
- api_set_error(err,
- kErrorTypeException,
- "Problem while switching windows");
+ case SREQ_WIN:
+ if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
+ win_find_tabpage((win_T *)from), false) == FAIL) {
+ if (try_end(err)) {
return;
}
- set_option_value_err(key, numval, stringval, opt_flags, err);
- restore_win(save_curwin, save_curtab, true);
- break;
- case SREQ_BUF:
- aucmd_prepbuf(&aco, (buf_T *)from);
- set_option_value_err(key, numval, stringval, opt_flags, err);
- aucmd_restbuf(&aco);
- break;
- case SREQ_GLOBAL:
- set_option_value_err(key, numval, stringval, opt_flags, err);
- break;
+ api_set_error(err,
+ kErrorTypeException,
+ "Problem while switching windows");
+ return;
+ }
+ set_option_value_err(key, numval, stringval, opt_flags, err);
+ restore_win(save_curwin, save_curtab, true);
+ break;
+ case SREQ_BUF:
+ aucmd_prepbuf(&aco, (buf_T *)from);
+ set_option_value_err(key, numval, stringval, opt_flags, err);
+ aucmd_restbuf(&aco);
+ break;
+ case SREQ_GLOBAL:
+ set_option_value_err(key, numval, stringval, opt_flags, err);
+ break;
}
if (ERROR_SET(err)) {
@@ -1456,11 +1444,7 @@ static void set_option_value_for(char *key,
}
-static void set_option_value_err(char *key,
- int numval,
- char *stringval,
- int opt_flags,
- Error *err)
+static void set_option_value_err(char *key, int numval, char *stringval, int opt_flags, Error *err)
{
char *errmsg;
@@ -1519,8 +1503,7 @@ ArrayOf(Dictionary) keymap_array(String mode, buf_T *buf)
// Check for correct mode
if (int_mode & current_maphash->m_mode) {
mapblock_fill_dict(dict, current_maphash, buffer_value, false);
- ADD(mappings, vim_to_object(
- (typval_T[]) { { .v_type = VAR_DICT, .vval.v_dict = dict } }));
+ ADD(mappings, vim_to_object((typval_T[]) { { .v_type = VAR_DICT, .vval.v_dict = dict } }));
tv_dict_clear(dict);
}
@@ -1556,13 +1539,13 @@ bool extmark_get_index_from_obj(buf_T *buf, Integer ns_id, Object obj, int
if (obj.type == kObjectTypeInteger) {
Integer id = obj.data.integer;
if (id == 0) {
- *row = 0;
- *col = 0;
- return true;
+ *row = 0;
+ *col = 0;
+ return true;
} else if (id == -1) {
- *row = MAXLNUM;
- *col = MAXCOL;
- return true;
+ *row = MAXLNUM;
+ *col = MAXCOL;
+ return true;
} else if (id < 0) {
api_set_error(err, kErrorTypeValidation, "Mark id must be positive");
return false;
@@ -1578,7 +1561,7 @@ bool extmark_get_index_from_obj(buf_T *buf, Integer ns_id, Object obj, int
return false;
}
- // Check if it is a position
+ // Check if it is a position
} else if (obj.type == kObjectTypeArray) {
Array pos = obj.data.array;
if (pos.size != 2
@@ -1662,8 +1645,7 @@ free_exit:
/// @param what The name of the object, used for error message
/// @param nil_value What to return if the type is nil.
/// @param err Set if there was an error in converting to a bool
-bool api_object_to_bool(Object obj, const char *what,
- bool nil_value, Error *err)
+bool api_object_to_bool(Object obj, const char *what, bool nil_value, Error *err)
{
if (obj.type == kObjectTypeBoolean) {
return obj.data.boolean;
@@ -1766,7 +1748,7 @@ static bool parse_float_relative(String relative, FloatRelative *out)
char *str = relative.data;
if (striequal(str, "editor")) {
*out = kFloatRelativeEditor;
- } else if (striequal(str, "win")) {
+ } else if (striequal(str, "win")) {
*out = kFloatRelativeWindow;
} else if (striequal(str, "cursor")) {
*out = kFloatRelativeCursor;
@@ -1800,7 +1782,7 @@ static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
{ "shadow", { "", "", " ", " ", " ", " ", " ", "" }, true },
{ "rounded", { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, false },
{ "solid", { " ", " ", " ", " ", " ", " ", " ", " " }, false },
- { NULL, { { NUL } } , false },
+ { NULL, { { NUL } }, false },
};
schar_T *chars = fconfig->border_chars;
@@ -1837,7 +1819,6 @@ static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
return;
}
}
-
} else if (iytem.type == kObjectTypeString) {
string = iytem.data.string;
} else {
@@ -1896,8 +1877,8 @@ static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
}
}
-bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
- bool new_win, Error *err)
+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
@@ -1998,13 +1979,13 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
has_bufpos = true;
} else if (!strcmp(key, "external")) {
has_external = fconfig->external
- = api_object_to_bool(val, "'external' key", false, err);
+ = 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);
+ = api_object_to_bool(val, "'focusable' key", true, err);
if (ERROR_SET(err)) {
return false;
}
@@ -2031,13 +2012,13 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
fconfig->style = kWinStyleUnused;
} else if (striequal(val.data.string.data, "minimal")) {
fconfig->style = kWinStyleMinimal;
- } else {
+ } 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);
+ = api_object_to_bool(val, "'noautocmd' key", false, err);
if (ERROR_SET(err)) {
return false;
}
diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c
index 5f727dbc38..14b6be8eeb 100644
--- a/src/nvim/api/tabpage.c
+++ b/src/nvim/api/tabpage.c
@@ -5,10 +5,10 @@
#include <stdint.h>
#include <stdlib.h>
-#include "nvim/api/tabpage.h"
-#include "nvim/api/vim.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/api/tabpage.h"
+#include "nvim/api/vim.h"
#include "nvim/memory.h"
#include "nvim/window.h"
@@ -53,7 +53,7 @@ Object nvim_tabpage_get_var(Tabpage tabpage, String name, Error *err)
tabpage_T *tab = find_tab_by_handle(tabpage, err);
if (!tab) {
- return (Object) OBJECT_INIT;
+ return (Object)OBJECT_INIT;
}
return dict_get_value(tab->tp_vars, name, err);
@@ -65,10 +65,7 @@ Object nvim_tabpage_get_var(Tabpage tabpage, String name, Error *err)
/// @param name Variable name
/// @param value Variable value
/// @param[out] err Error details, if any
-void nvim_tabpage_set_var(Tabpage tabpage,
- String name,
- Object value,
- Error *err)
+void nvim_tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err)
FUNC_API_SINCE(1)
{
tabpage_T *tab = find_tab_by_handle(tabpage, err);
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index 713980ca68..9b200dcba2 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -2,22 +2,22 @@
// 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 <stdbool.h>
-#include "nvim/vim.h"
-#include "nvim/ui.h"
-#include "nvim/memory.h"
-#include "nvim/map.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/popupmnu.h"
+#include "nvim/api/ui.h"
#include "nvim/cursor_shape.h"
#include "nvim/highlight.h"
+#include "nvim/map.h"
+#include "nvim/memory.h"
+#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/popupmnu.h"
#include "nvim/screen.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -85,8 +85,8 @@ void remote_ui_wait_for_attach(void)
/// @param height Requested screen rows
/// @param options |ui-option| map
/// @param[out] err Error details, if any
-void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
- Dictionary options, Error *err)
+void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictionary options,
+ Error *err)
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
if (pmap_has(uint64_t)(&connected_uis, channel_id)) {
@@ -171,8 +171,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
}
/// @deprecated
-void ui_attach(uint64_t channel_id, Integer width, Integer height,
- Boolean enable_rgb, Error *err)
+void ui_attach(uint64_t channel_id, Integer width, Integer height, Boolean enable_rgb, Error *err)
{
Dictionary opts = ARRAY_DICT_INIT;
PUT(opts, "rgb", BOOLEAN_OBJ(enable_rgb));
@@ -198,8 +197,7 @@ void nvim_ui_detach(uint64_t channel_id, Error *err)
}
-void nvim_ui_try_resize(uint64_t channel_id, Integer width,
- Integer height, Error *err)
+void nvim_ui_try_resize(uint64_t channel_id, Integer width, Integer height, Error *err)
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
if (!pmap_has(uint64_t)(&connected_uis, channel_id)) {
@@ -220,8 +218,7 @@ void nvim_ui_try_resize(uint64_t channel_id, Integer width,
ui_refresh();
}
-void nvim_ui_set_option(uint64_t channel_id, String name,
- Object value, Error *error)
+void nvim_ui_set_option(uint64_t channel_id, String name, Object value, Error *error)
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
if (!pmap_has(uint64_t)(&connected_uis, channel_id)) {
@@ -234,8 +231,7 @@ void nvim_ui_set_option(uint64_t channel_id, String name,
ui_set_option(ui, false, name, value, error);
}
-static void ui_set_option(UI *ui, bool init, String name, Object value,
- Error *error)
+static void ui_set_option(UI *ui, bool init, String name, Object value, Error *error)
{
if (strequal(name.data, "override")) {
if (value.type != kObjectTypeBoolean) {
@@ -300,8 +296,8 @@ static void ui_set_option(UI *ui, bool init, String name, Object value,
/// @param width The new requested width.
/// @param height The new requested height.
/// @param[out] err Error details, if any
-void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width,
- Integer height, Error *err)
+void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width, Integer height,
+ Error *err)
FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY
{
if (!pmap_has(uint64_t)(&connected_uis, channel_id)) {
@@ -359,8 +355,8 @@ void nvim_ui_pum_set_height(uint64_t channel_id, Integer height, Error *err)
/// @param row Popupmenu row.
/// @param col Popupmenu height.
/// @param[out] err Error details, if any.
-void nvim_ui_pum_set_bounds(uint64_t channel_id, Float width, Float height,
- Float row, Float col, Error *err)
+void nvim_ui_pum_set_bounds(uint64_t channel_id, Float width, Float height, Float row, Float col,
+ Error *err)
FUNC_API_SINCE(7) FUNC_API_REMOTE_ONLY
{
if (!pmap_has(uint64_t)(&connected_uis, channel_id)) {
@@ -424,8 +420,7 @@ static void remote_ui_grid_clear(UI *ui, Integer grid)
push_call(ui, name, args);
}
-static void remote_ui_grid_resize(UI *ui, Integer grid,
- Integer width, Integer height)
+static void remote_ui_grid_resize(UI *ui, Integer grid, Integer width, Integer height)
{
Array args = ARRAY_DICT_INIT;
if (ui->ui_ext[kUILinegrid]) {
@@ -437,9 +432,8 @@ static void remote_ui_grid_resize(UI *ui, Integer grid,
push_call(ui, name, args);
}
-static void remote_ui_grid_scroll(UI *ui, Integer grid, Integer top,
- Integer bot, Integer left, Integer right,
- Integer rows, Integer cols)
+static void remote_ui_grid_scroll(UI *ui, Integer grid, Integer top, Integer bot, Integer left,
+ Integer right, Integer rows, Integer cols)
{
if (ui->ui_ext[kUILinegrid]) {
Array args = ARRAY_DICT_INIT;
@@ -474,8 +468,7 @@ static void remote_ui_grid_scroll(UI *ui, Integer grid, Integer top,
}
}
-static void remote_ui_default_colors_set(UI *ui, Integer rgb_fg,
- Integer rgb_bg, Integer rgb_sp,
+static void remote_ui_default_colors_set(UI *ui, Integer rgb_fg, Integer rgb_bg, Integer rgb_sp,
Integer cterm_fg, Integer cterm_bg)
{
if (!ui->ui_ext[kUITermColors]) {
@@ -505,8 +498,8 @@ static void remote_ui_default_colors_set(UI *ui, Integer rgb_fg,
}
}
-static void remote_ui_hl_attr_define(UI *ui, Integer id, HlAttrs rgb_attrs,
- HlAttrs cterm_attrs, Array info)
+static void remote_ui_hl_attr_define(UI *ui, Integer id, HlAttrs rgb_attrs, HlAttrs cterm_attrs,
+ Array info)
{
if (!ui->ui_ext[kUILinegrid]) {
return;
@@ -543,8 +536,7 @@ static void remote_ui_highlight_set(UI *ui, int id)
}
/// "true" cursor used only for input focus
-static void remote_ui_grid_cursor_goto(UI *ui, Integer grid, Integer row,
- Integer col)
+static void remote_ui_grid_cursor_goto(UI *ui, Integer grid, Integer row, Integer col)
{
if (ui->ui_ext[kUILinegrid]) {
Array args = ARRAY_DICT_INIT;
@@ -584,11 +576,9 @@ static void remote_ui_put(UI *ui, const char *cell)
push_call(ui, "put", args);
}
-static void remote_ui_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 remote_ui_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)
{
UIData *data = ui->data;
if (ui->ui_ext[kUILinegrid]) {
@@ -729,7 +719,7 @@ static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed)
if (ui->ui_ext[kUIWildmenu]) {
if (strequal(name, "popupmenu_show")) {
data->wildmenu_active = (args.items[4].data.integer == -1)
- || !ui->ui_ext[kUIPopupmenu];
+ || !ui->ui_ext[kUIPopupmenu];
if (data->wildmenu_active) {
Array new_args = ARRAY_DICT_INIT;
Array items = args.items[0].data.array;
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index e764c45f0e..3be45d0cf7 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -3,54 +3,54 @@
#include <assert.h>
#include <inttypes.h>
+#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
-#include <limits.h>
-#include "nvim/api/vim.h"
-#include "nvim/ascii.h"
-#include "nvim/api/private/helpers.h"
+#include "nvim/api/buffer.h"
+#include "nvim/api/deprecated.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/dispatch.h"
-#include "nvim/api/buffer.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/vim.h"
#include "nvim/api/window.h"
-#include "nvim/api/deprecated.h"
-#include "nvim/msgpack_rpc/channel.h"
-#include "nvim/msgpack_rpc/helpers.h"
-#include "nvim/lua/executor.h"
-#include "nvim/vim.h"
+#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/context.h"
-#include "nvim/file_search.h"
-#include "nvim/highlight.h"
-#include "nvim/window.h"
-#include "nvim/types.h"
-#include "nvim/ex_cmds2.h"
-#include "nvim/ex_docmd.h"
-#include "nvim/screen.h"
-#include "nvim/memline.h"
-#include "nvim/mark.h"
-#include "nvim/memory.h"
-#include "nvim/message.h"
-#include "nvim/popupmnu.h"
+#include "nvim/decoration.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
#include "nvim/eval/userfunc.h"
+#include "nvim/ex_cmds2.h"
+#include "nvim/ex_docmd.h"
+#include "nvim/file_search.h"
#include "nvim/fileio.h"
+#include "nvim/getchar.h"
+#include "nvim/highlight.h"
+#include "nvim/lua/executor.h"
+#include "nvim/mark.h"
+#include "nvim/memline.h"
+#include "nvim/memory.h"
+#include "nvim/message.h"
#include "nvim/move.h"
+#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/ops.h"
#include "nvim/option.h"
-#include "nvim/state.h"
-#include "nvim/decoration.h"
-#include "nvim/syntax.h"
-#include "nvim/getchar.h"
#include "nvim/os/input.h"
#include "nvim/os/process.h"
+#include "nvim/popupmnu.h"
+#include "nvim/screen.h"
+#include "nvim/state.h"
+#include "nvim/syntax.h"
+#include "nvim/types.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#include "nvim/viml/parser/expressions.h"
#include "nvim/viml/parser/parser.h"
-#include "nvim/ui.h"
+#include "nvim/window.h"
#define LINE_BUFFER_SIZE 4096
@@ -301,12 +301,18 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_csi)
for (size_t i = 0; i < mode.size; ++i) {
switch (mode.data[i]) {
- case 'n': remap = false; break;
- case 'm': remap = true; break;
- case 't': typed = true; break;
- case 'i': insert = true; break;
- case 'x': execute = true; break;
- case '!': dangerous = true; break;
+ case 'n':
+ remap = false; break;
+ case 'm':
+ remap = true; break;
+ case 't':
+ typed = true; break;
+ case 'i':
+ insert = true; break;
+ case 'x':
+ execute = true; break;
+ case '!':
+ dangerous = true; break;
}
}
@@ -316,11 +322,11 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_csi)
char *keys_esc;
if (escape_csi) {
- // Need to escape K_SPECIAL and CSI before putting the string in the
- // typeahead buffer.
- keys_esc = (char *)vim_strsave_escape_csi((char_u *)keys.data);
+ // Need to escape K_SPECIAL and CSI before putting the string in the
+ // typeahead buffer.
+ keys_esc = (char *)vim_strsave_escape_csi((char_u *)keys.data);
} else {
- keys_esc = keys.data;
+ keys_esc = keys.data;
}
ins_typebuf((char_u *)keys_esc, (remap ? REMAP_YES : REMAP_NONE),
insert ? 0 : typebuf.tb_len, !typed, false);
@@ -329,7 +335,7 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_csi)
}
if (escape_csi) {
- xfree(keys_esc);
+ xfree(keys_esc);
}
if (execute) {
@@ -391,8 +397,8 @@ Integer nvim_input(String keys)
/// @param row Mouse row-position (zero-based, like redraw events)
/// @param col Mouse column-position (zero-based, like redraw events)
/// @param[out] err Error details, if any
-void nvim_input_mouse(String button, String action, String modifier,
- Integer grid, Integer row, Integer col, Error *err)
+void nvim_input_mouse(String button, String action, String modifier, Integer grid, Integer row,
+ Integer col, Error *err)
FUNC_API_SINCE(6) FUNC_API_FAST
{
if (button.data == NULL || action.data == NULL) {
@@ -469,8 +475,7 @@ error:
/// @param special Replace |keycodes|, e.g. <CR> becomes a "\n" char.
/// @see replace_termcodes
/// @see cpoptions
-String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt,
- Boolean special)
+String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, Boolean special)
FUNC_API_SINCE(1)
{
if (str.size == 0) {
@@ -499,32 +504,32 @@ Object nvim_eval(String expr, Error *err)
Object rv = OBJECT_INIT;
TRY_WRAP({
- // Initialize `force_abort` and `suppress_errthrow` at the top level.
- if (!recursive) {
- force_abort = false;
- suppress_errthrow = false;
- current_exception = NULL;
- // `did_emsg` is set by emsg(), which cancels execution.
- did_emsg = false;
- }
- recursive++;
- try_start();
+ // Initialize `force_abort` and `suppress_errthrow` at the top level.
+ if (!recursive) {
+ force_abort = false;
+ suppress_errthrow = false;
+ current_exception = NULL;
+ // `did_emsg` is set by emsg(), which cancels execution.
+ did_emsg = false;
+ }
+ recursive++;
+ try_start();
- typval_T rettv;
- int ok = eval0((char_u *)expr.data, &rettv, NULL, true);
+ typval_T rettv;
+ int ok = eval0((char_u *)expr.data, &rettv, NULL, true);
- if (!try_end(err)) {
- if (ok == FAIL) {
- // Should never happen, try_end() should get the error. #8371
- api_set_error(err, kErrorTypeException,
- "Failed to evaluate expression: '%.*s'", 256, expr.data);
- } else {
- rv = vim_to_object(&rettv);
+ if (!try_end(err)) {
+ if (ok == FAIL) {
+ // Should never happen, try_end() should get the error. #8371
+ api_set_error(err, kErrorTypeException,
+ "Failed to evaluate expression: '%.*s'", 256, expr.data);
+ } else {
+ rv = vim_to_object(&rettv);
+ }
}
- }
- tv_clear(&rettv);
- recursive--;
+ tv_clear(&rettv);
+ recursive--;
});
return rv;
@@ -597,31 +602,31 @@ static Object _call_function(String fn, Array args, dict_T *self, Error *err)
}
TRY_WRAP({
- // Initialize `force_abort` and `suppress_errthrow` at the top level.
- if (!recursive) {
- force_abort = false;
- suppress_errthrow = false;
- current_exception = NULL;
- // `did_emsg` is set by emsg(), which cancels execution.
- did_emsg = false;
- }
- recursive++;
- try_start();
- typval_T rettv;
- funcexe_T funcexe = FUNCEXE_INIT;
- funcexe.firstline = curwin->w_cursor.lnum;
- funcexe.lastline = curwin->w_cursor.lnum;
- funcexe.evaluate = true;
- funcexe.selfdict = self;
- // call_func() retval is deceptive, ignore it. Instead we set `msg_list`
- // (see above) to capture abort-causing non-exception errors.
- (void)call_func((char_u *)fn.data, (int)fn.size, &rettv, (int)args.size,
- vim_args, &funcexe);
- if (!try_end(err)) {
- rv = vim_to_object(&rettv);
- }
- tv_clear(&rettv);
- recursive--;
+ // Initialize `force_abort` and `suppress_errthrow` at the top level.
+ if (!recursive) {
+ force_abort = false;
+ suppress_errthrow = false;
+ current_exception = NULL;
+ // `did_emsg` is set by emsg(), which cancels execution.
+ did_emsg = false;
+ }
+ recursive++;
+ try_start();
+ typval_T rettv;
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.firstline = curwin->w_cursor.lnum;
+ funcexe.lastline = curwin->w_cursor.lnum;
+ funcexe.evaluate = true;
+ funcexe.selfdict = self;
+ // call_func() retval is deceptive, ignore it. Instead we set `msg_list`
+ // (see above) to capture abort-causing non-exception errors.
+ (void)call_func((char_u *)fn.data, (int)fn.size, &rettv, (int)args.size,
+ vim_args, &funcexe);
+ if (!try_end(err)) {
+ rv = vim_to_object(&rettv);
+ }
+ tv_clear(&rettv);
+ recursive--;
});
free_vim_args:
@@ -663,31 +668,28 @@ Object nvim_call_dict_function(Object dict, String fn, Array args, Error *err)
typval_T rettv;
bool mustfree = false;
switch (dict.type) {
- case kObjectTypeString: {
- try_start();
- if (eval0((char_u *)dict.data.string.data, &rettv, NULL, true) == FAIL) {
- api_set_error(err, kErrorTypeException,
- "Failed to evaluate dict expression");
- }
- if (try_end(err)) {
- return rv;
- }
- // Evaluation of the string arg created a new dict or increased the
- // refcount of a dict. Not necessary for a RPC dict.
- mustfree = true;
- break;
- }
- case kObjectTypeDictionary: {
- if (!object_to_vim(dict, &rettv, err)) {
- goto end;
- }
- break;
+ case kObjectTypeString:
+ try_start();
+ if (eval0((char_u *)dict.data.string.data, &rettv, NULL, true) == FAIL) {
+ api_set_error(err, kErrorTypeException,
+ "Failed to evaluate dict expression");
}
- default: {
- api_set_error(err, kErrorTypeValidation,
- "dict argument type must be String or Dictionary");
+ if (try_end(err)) {
return rv;
}
+ // Evaluation of the string arg created a new dict or increased the
+ // refcount of a dict. Not necessary for a RPC dict.
+ mustfree = true;
+ break;
+ case kObjectTypeDictionary:
+ if (!object_to_vim(dict, &rettv, err)) {
+ goto end;
+ }
+ break;
+ default:
+ api_set_error(err, kErrorTypeValidation,
+ "dict argument type must be String or Dictionary");
+ return rv;
}
dict_T *self_dict = rettv.vval.v_dict;
if (rettv.v_type != VAR_DICT || !self_dict) {
@@ -1420,8 +1422,7 @@ void nvim_chan_send(Integer chan, String data, Error *err)
/// @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)
+Window nvim_open_win(Buffer buffer, Boolean enter, Dictionary config, Error *err)
FUNC_API_SINCE(6)
FUNC_API_CHECK_TEXTLOCK
{
@@ -1579,7 +1580,7 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Error *err)
bool cancel = false;
if (phase < -1 || phase > 3) {
- api_set_error(err, kErrorTypeValidation, "Invalid phase: %"PRId64, phase);
+ api_set_error(err, kErrorTypeValidation, "Invalid phase: %" PRId64, phase);
return false;
}
Array args = ARRAY_DICT_INIT;
@@ -1643,8 +1644,7 @@ theend:
/// @param after If true insert after cursor (like |p|), or before (like |P|).
/// @param follow If true place cursor at end of inserted text.
/// @param[out] err Error details, if any
-void nvim_put(ArrayOf(String) lines, String type, Boolean after,
- Boolean follow, Error *err)
+void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, Error *err)
FUNC_API_SINCE(6)
FUNC_API_CHECK_TEXTLOCK
{
@@ -1885,8 +1885,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, Dictionary opts, Error *err)
FUNC_API_SINCE(6)
{
modify_keymap(-1, false, mode, lhs, rhs, opts, err);
@@ -1983,10 +1982,8 @@ Array nvim_get_api_info(uint64_t channel_id)
/// .png or .svg format is preferred.
///
/// @param[out] err Error details, if any
-void nvim_set_client_info(uint64_t channel_id, String name,
- Dictionary version, String type,
- Dictionary methods, Dictionary attributes,
- Error *err)
+void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version, String type,
+ Dictionary methods, Dictionary attributes, Error *err)
FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY
{
Dictionary info = ARRAY_DICT_INIT;
@@ -2114,9 +2111,9 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err)
Array args = call.items[1].data.array;
MsgpackRpcRequestHandler handler =
- msgpack_rpc_get_handler_for(name.data,
- name.size,
- &nested_error);
+ msgpack_rpc_get_handler_for(name.data,
+ name.size,
+ &nested_error);
if (ERROR_SET(&nested_error)) {
break;
@@ -2232,26 +2229,26 @@ typedef kvec_withinit_t(ExprASTConvStackItem, 16) ExprASTConvStack;
/// - "svalue": String, value for "SingleQuotedString" and
/// "DoubleQuotedString" nodes.
/// @param[out] err Error details, if any
-Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
- Error *err)
+Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight, Error *err)
FUNC_API_SINCE(4) FUNC_API_FAST
{
int pflags = 0;
for (size_t i = 0 ; i < flags.size ; i++) {
switch (flags.data[i]) {
- case 'm': { pflags |= kExprFlagsMulti; break; }
- case 'E': { pflags |= kExprFlagsDisallowEOC; break; }
- case 'l': { pflags |= kExprFlagsParseLet; break; }
- case NUL: {
- api_set_error(err, kErrorTypeValidation, "Invalid flag: '\\0' (%u)",
- (unsigned)flags.data[i]);
- return (Dictionary)ARRAY_DICT_INIT;
- }
- default: {
- api_set_error(err, kErrorTypeValidation, "Invalid flag: '%c' (%u)",
- flags.data[i], (unsigned)flags.data[i]);
- return (Dictionary)ARRAY_DICT_INIT;
- }
+ case 'm':
+ pflags |= kExprFlagsMulti; break;
+ case 'E':
+ pflags |= kExprFlagsDisallowEOC; break;
+ case 'l':
+ pflags |= kExprFlagsParseLet; break;
+ case NUL:
+ api_set_error(err, kErrorTypeValidation, "Invalid flag: '\\0' (%u)",
+ (unsigned)flags.data[i]);
+ return (Dictionary)ARRAY_DICT_INIT;
+ default:
+ api_set_error(err, kErrorTypeValidation, "Invalid flag: '%c' (%u)",
+ flags.data[i], (unsigned)flags.data[i]);
+ return (Dictionary)ARRAY_DICT_INIT;
}
}
ParserLine parser_lines[] = {
@@ -2267,15 +2264,14 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
kvi_init(colors);
ParserHighlight *const colors_p = (highlight ? &colors : NULL);
ParserState pstate;
- viml_parser_init(
- &pstate, parser_simple_get_line, &plines_p, colors_p);
+ viml_parser_init(&pstate, parser_simple_get_line, &plines_p, colors_p);
ExprAST east = viml_pexpr_parse(&pstate, pflags);
const size_t ret_size = (
- 2 // "ast", "len"
- + (size_t)(east.err.msg != NULL) // "error"
- + (size_t)highlight // "highlight"
- + 0);
+ 2 // "ast", "len"
+ + (size_t)(east.err.msg != NULL) // "error"
+ + (size_t)highlight // "highlight"
+ + 0);
Dictionary ret = {
.items = xmalloc(ret_size * sizeof(ret.items[0])),
.size = 0,
@@ -2362,23 +2358,23 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
} else {
if (cur_item.ret_node_p->type == kObjectTypeNil) {
const size_t ret_node_items_size = (size_t)(
- 3 // "type", "start" and "len"
- + (node->children != NULL) // "children"
- + (node->type == kExprNodeOption
- || node->type == kExprNodePlainIdentifier) // "scope"
- + (node->type == kExprNodeOption
- || node->type == kExprNodePlainIdentifier
- || node->type == kExprNodePlainKey
- || node->type == kExprNodeEnvironment) // "ident"
- + (node->type == kExprNodeRegister) // "name"
- + (3 // "cmp_type", "ccs_strategy", "invert"
- * (node->type == kExprNodeComparison))
- + (node->type == kExprNodeInteger) // "ivalue"
- + (node->type == kExprNodeFloat) // "fvalue"
- + (node->type == kExprNodeDoubleQuotedString
- || node->type == kExprNodeSingleQuotedString) // "svalue"
- + (node->type == kExprNodeAssignment) // "augmentation"
- + 0);
+ 3 // "type", "start" and "len"
+ + (node->children != NULL) // "children"
+ + (node->type == kExprNodeOption
+ || node->type == kExprNodePlainIdentifier) // "scope"
+ + (node->type == kExprNodeOption
+ || node->type == kExprNodePlainIdentifier
+ || node->type == kExprNodePlainKey
+ || node->type == kExprNodeEnvironment) // "ident"
+ + (node->type == kExprNodeRegister) // "name"
+ + (3 // "cmp_type", "ccs_strategy", "invert"
+ * (node->type == kExprNodeComparison))
+ + (node->type == kExprNodeInteger) // "ivalue"
+ + (node->type == kExprNodeFloat) // "fvalue"
+ + (node->type == kExprNodeDoubleQuotedString
+ || node->type == kExprNodeSingleQuotedString) // "svalue"
+ + (node->type == kExprNodeAssignment) // "augmentation"
+ + 0);
Dictionary ret_node = {
.items = xmalloc(ret_node_items_size * sizeof(ret_node.items[0])),
.capacity = ret_node_items_size,
@@ -2432,151 +2428,138 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
.value = INTEGER_OBJ((Integer)node->len),
};
switch (node->type) {
- case kExprNodeDoubleQuotedString:
- case kExprNodeSingleQuotedString: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("svalue"),
- .value = STRING_OBJ(((String) {
- .data = node->data.str.value,
- .size = node->data.str.size,
- })),
- };
- break;
- }
- case kExprNodeOption: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("scope"),
- .value = INTEGER_OBJ(node->data.opt.scope),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.opt.ident,
- node->data.opt.ident_len),
- .size = node->data.opt.ident_len,
- })),
- };
- break;
- }
- case kExprNodePlainIdentifier: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("scope"),
- .value = INTEGER_OBJ(node->data.var.scope),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.var.ident,
- node->data.var.ident_len),
- .size = node->data.var.ident_len,
- })),
- };
- break;
- }
- case kExprNodePlainKey: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.var.ident,
- node->data.var.ident_len),
- .size = node->data.var.ident_len,
- })),
- };
- break;
- }
- case kExprNodeEnvironment: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.env.ident,
- node->data.env.ident_len),
- .size = node->data.env.ident_len,
- })),
- };
- break;
- }
- case kExprNodeRegister: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("name"),
- .value = INTEGER_OBJ(node->data.reg.name),
- };
- break;
- }
- case kExprNodeComparison: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("cmp_type"),
- .value = STRING_OBJ(cstr_to_string(
- eltkn_cmp_type_tab[node->data.cmp.type])),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ccs_strategy"),
- .value = STRING_OBJ(cstr_to_string(
- ccs_tab[node->data.cmp.ccs])),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("invert"),
- .value = BOOLEAN_OBJ(node->data.cmp.inv),
- };
- break;
- }
- case kExprNodeFloat: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("fvalue"),
- .value = FLOAT_OBJ(node->data.flt.value),
- };
- break;
- }
- case kExprNodeInteger: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ivalue"),
- .value = INTEGER_OBJ((Integer)(
- node->data.num.value > API_INTEGER_MAX
+ case kExprNodeDoubleQuotedString:
+ case kExprNodeSingleQuotedString:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("svalue"),
+ .value = STRING_OBJ(((String) {
+ .data = node->data.str.value,
+ .size = node->data.str.size,
+ })),
+ };
+ break;
+ case kExprNodeOption:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("scope"),
+ .value = INTEGER_OBJ(node->data.opt.scope),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.opt.ident,
+ node->data.opt.ident_len),
+ .size = node->data.opt.ident_len,
+ })),
+ };
+ break;
+ case kExprNodePlainIdentifier:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("scope"),
+ .value = INTEGER_OBJ(node->data.var.scope),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.var.ident,
+ node->data.var.ident_len),
+ .size = node->data.var.ident_len,
+ })),
+ };
+ break;
+ case kExprNodePlainKey:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.var.ident,
+ node->data.var.ident_len),
+ .size = node->data.var.ident_len,
+ })),
+ };
+ break;
+ case kExprNodeEnvironment:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.env.ident,
+ node->data.env.ident_len),
+ .size = node->data.env.ident_len,
+ })),
+ };
+ break;
+ case kExprNodeRegister:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("name"),
+ .value = INTEGER_OBJ(node->data.reg.name),
+ };
+ break;
+ case kExprNodeComparison:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("cmp_type"),
+ .value = STRING_OBJ(cstr_to_string(eltkn_cmp_type_tab[node->data.cmp.type])),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ccs_strategy"),
+ .value = STRING_OBJ(cstr_to_string(ccs_tab[node->data.cmp.ccs])),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("invert"),
+ .value = BOOLEAN_OBJ(node->data.cmp.inv),
+ };
+ break;
+ case kExprNodeFloat:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("fvalue"),
+ .value = FLOAT_OBJ(node->data.flt.value),
+ };
+ break;
+ case kExprNodeInteger:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ivalue"),
+ .value = INTEGER_OBJ((Integer)(
+ node->data.num.value > API_INTEGER_MAX
? API_INTEGER_MAX
: (Integer)node->data.num.value)),
- };
- break;
- }
- case kExprNodeAssignment: {
- const ExprAssignmentType asgn_type = node->data.ass.type;
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("augmentation"),
- .value = STRING_OBJ(
- asgn_type == kExprAsgnPlain
+ };
+ break;
+ case kExprNodeAssignment: {
+ const ExprAssignmentType asgn_type = node->data.ass.type;
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("augmentation"),
+ .value = STRING_OBJ(asgn_type == kExprAsgnPlain
? (String)STRING_INIT
: cstr_to_string(expr_asgn_type_tab[asgn_type])),
- };
- break;
- }
- case kExprNodeMissing:
- case kExprNodeOpMissing:
- case kExprNodeTernary:
- case kExprNodeTernaryValue:
- case kExprNodeSubscript:
- case kExprNodeListLiteral:
- case kExprNodeUnaryPlus:
- case kExprNodeBinaryPlus:
- case kExprNodeNested:
- case kExprNodeCall:
- case kExprNodeComplexIdentifier:
- case kExprNodeUnknownFigure:
- case kExprNodeLambda:
- case kExprNodeDictLiteral:
- case kExprNodeCurlyBracesIdentifier:
- case kExprNodeComma:
- case kExprNodeColon:
- case kExprNodeArrow:
- case kExprNodeConcat:
- case kExprNodeConcatOrSubscript:
- case kExprNodeOr:
- case kExprNodeAnd:
- case kExprNodeUnaryMinus:
- case kExprNodeBinaryMinus:
- case kExprNodeNot:
- case kExprNodeMultiplication:
- case kExprNodeDivision:
- case kExprNodeMod: {
- break;
- }
+ };
+ break;
+ }
+ case kExprNodeMissing:
+ case kExprNodeOpMissing:
+ case kExprNodeTernary:
+ case kExprNodeTernaryValue:
+ case kExprNodeSubscript:
+ case kExprNodeListLiteral:
+ case kExprNodeUnaryPlus:
+ case kExprNodeBinaryPlus:
+ case kExprNodeNested:
+ case kExprNodeCall:
+ case kExprNodeComplexIdentifier:
+ case kExprNodeUnknownFigure:
+ case kExprNodeLambda:
+ case kExprNodeDictLiteral:
+ case kExprNodeCurlyBracesIdentifier:
+ case kExprNodeComma:
+ case kExprNodeColon:
+ case kExprNodeArrow:
+ case kExprNodeConcat:
+ case kExprNodeConcatOrSubscript:
+ case kExprNodeOr:
+ case kExprNodeAnd:
+ case kExprNodeUnaryMinus:
+ case kExprNodeBinaryMinus:
+ case kExprNodeNot:
+ case kExprNodeMultiplication:
+ case kExprNodeDivision:
+ case kExprNodeMod:
+ break;
}
assert(cur_item.ret_node_p->data.dictionary.size
== cur_item.ret_node_p->data.dictionary.capacity);
@@ -2806,8 +2789,8 @@ Object nvim_get_proc(Integer pid, Error *err)
/// `insert`.
/// @param opts Optional parameters. Reserved for future use.
/// @param[out] err Error details, if any
-void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish,
- Dictionary opts, Error *err)
+void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish, Dictionary opts,
+ Error *err)
FUNC_API_SINCE(6)
{
if (opts.size > 0) {
@@ -2904,8 +2887,7 @@ void nvim__screenshot(String path)
/// ["win", winid, bufnr, row]
/// - on_end: called at the end of a redraw cycle
/// ["end", tick]
-void nvim_set_decoration_provider(Integer ns_id, DictionaryOf(LuaRef) opts,
- Error *err)
+void nvim_set_decoration_provider(Integer ns_id, DictionaryOf(LuaRef) opts, Error *err)
FUNC_API_SINCE(7) FUNC_API_LUA_ONLY
{
DecorProvider *p = get_decor_provider((NS)ns_id, true);
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c
index 069dfae233..99ba297111 100644
--- a/src/nvim/api/window.c
+++ b/src/nvim/api/window.c
@@ -1,25 +1,25 @@
// 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 <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
-#include <limits.h>
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
-#include "nvim/lua/executor.h"
-#include "nvim/ex_docmd.h"
-#include "nvim/vim.h"
#include "nvim/api/window.h"
#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/cursor.h"
+#include "nvim/ex_docmd.h"
#include "nvim/globals.h"
+#include "nvim/lua/executor.h"
#include "nvim/move.h"
#include "nvim/option.h"
#include "nvim/screen.h"
#include "nvim/syntax.h"
+#include "nvim/vim.h"
#include "nvim/window.h"
/// Gets the current buffer in a window
@@ -222,7 +222,7 @@ Object nvim_win_get_var(Window window, String name, Error *err)
win_T *win = find_window_by_handle(window, err);
if (!win) {
- return (Object) OBJECT_INIT;
+ return (Object)OBJECT_INIT;
}
return dict_get_value(win->w_vars, name, err);
@@ -275,7 +275,7 @@ Object nvim_win_get_option(Window window, String name, Error *err)
win_T *win = find_window_by_handle(window, err);
if (!win) {
- return (Object) OBJECT_INIT;
+ return (Object)OBJECT_INIT;
}
return get_option_from(win, SREQ_WIN, name, err);
@@ -289,8 +289,7 @@ Object nvim_win_get_option(Window window, String name, Error *err)
/// @param name Option name
/// @param value Option value
/// @param[out] err Error details, if any
-void nvim_win_set_option(uint64_t channel_id, Window window,
- String name, Object value, Error *err)
+void nvim_win_set_option(uint64_t channel_id, Window window, String name, Object value, Error *err)
FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -452,8 +451,7 @@ Dictionary nvim_win_get_config(Window window, Error *err)
PUT(rv, "bufpos", ARRAY_OBJ(pos));
}
}
- PUT(rv, "anchor", STRING_OBJ(cstr_to_string(
- float_anchor_str[config->anchor])));
+ 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));
@@ -463,8 +461,7 @@ Dictionary nvim_win_get_config(Window window, Error *err)
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));
+ 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);
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c
index 5c03f55621..c8734c9b9c 100644
--- a/src/nvim/eval/decode.c
+++ b/src/nvim/eval/decode.c
@@ -1,20 +1,19 @@
// 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 <stddef.h>
-
#include <msgpack.h>
+#include <stddef.h>
-#include "nvim/eval/typval.h"
+#include "nvim/ascii.h"
+#include "nvim/charset.h" // vim_str2nr
#include "nvim/eval.h"
#include "nvim/eval/decode.h"
#include "nvim/eval/encode.h"
-#include "nvim/ascii.h"
-#include "nvim/macros.h"
-#include "nvim/message.h"
+#include "nvim/eval/typval.h"
#include "nvim/globals.h"
-#include "nvim/charset.h" // vim_str2nr
#include "nvim/lib/kvec.h"
+#include "nvim/macros.h"
+#include "nvim/message.h"
#include "nvim/vim.h" // OK, FAIL
/// Helper structure for container_struct
@@ -52,8 +51,7 @@ typedef kvec_t(ContainerStackItem) ContainerStack;
/// @param[out] rettv Location where created dictionary will be saved.
/// @param[in] type Type of the dictionary.
/// @param[in] val Value associated with the _VAL key.
-static inline void create_special_dict(typval_T *const rettv,
- const MessagePackType type,
+static inline void create_special_dict(typval_T *const rettv, const MessagePackType type,
typval_T val)
FUNC_ATTR_NONNULL_ALL
{
@@ -97,12 +95,9 @@ static inline void create_special_dict(typval_T *const rettv,
/// value when decoder is restarted, otherwise unused.
///
/// @return OK in case of success, FAIL in case of error.
-static inline int json_decoder_pop(ValuesStackItem obj,
- ValuesStack *const stack,
- ContainerStack *const container_stack,
- const char **const pp,
- bool *const next_map_special,
- bool *const didcomma,
+static inline int json_decoder_pop(ValuesStackItem obj, ValuesStack *const stack,
+ ContainerStack *const container_stack, const char **const pp,
+ bool *const next_map_special, bool *const didcomma,
bool *const didcolon)
FUNC_ATTR_NONNULL_ALL
{
@@ -114,9 +109,9 @@ static inline int json_decoder_pop(ValuesStackItem obj,
const char *val_location = *pp;
if (obj.val.v_type == last_container.container.v_type
// vval.v_list and vval.v_dict should have the same size and offset
- && ((void *) obj.val.vval.v_list
- == (void *) last_container.container.vval.v_list)) {
- (void) kv_pop(*container_stack);
+ && ((void *)obj.val.vval.v_list
+ == (void *)last_container.container.vval.v_list)) {
+ (void)kv_pop(*container_stack);
val_location = last_container.s;
last_container = kv_last(*container_stack);
}
@@ -142,8 +137,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
assert(!(key.is_special_string
|| key.val.vval.v_string == NULL
|| *key.val.vval.v_string == NUL));
- dictitem_T *const obj_di = tv_dict_item_alloc(
- (const char *)key.val.vval.v_string);
+ dictitem_T *const obj_di = tv_dict_item_alloc((const char *)key.val.vval.v_string);
tv_clear(&key.val);
if (tv_dict_add(last_container.container.vval.v_dict, obj_di)
== FAIL) {
@@ -179,9 +173,9 @@ static inline int json_decoder_pop(ValuesStackItem obj,
tv_clear(&obj.val);
// Restart
- (void) kv_pop(*container_stack);
+ (void)kv_pop(*container_stack);
ValuesStackItem last_container_val =
- kv_A(*stack, last_container.stack_index);
+ kv_A(*stack, last_container.stack_index);
while (kv_size(*stack) > last_container.stack_index) {
tv_clear(&(kv_pop(*stack).val));
}
@@ -197,7 +191,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
}
#define LENP(p, e) \
- ((int) ((e) - (p))), (p)
+ ((int)((e) - (p))), (p)
#define OBJ(obj_tv, is_sp_string, didcomma_, didcolon_) \
((ValuesStackItem) { \
.is_special_string = (is_sp_string), \
@@ -229,8 +223,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
///
/// @return [allocated] list which should contain key-value pairs. Return value
/// may be safely ignored.
-list_T *decode_create_map_special_dict(typval_T *const ret_tv,
- const ptrdiff_t len)
+list_T *decode_create_map_special_dict(typval_T *const ret_tv, const ptrdiff_t len)
FUNC_ATTR_NONNULL_ALL
{
list_T *const list = tv_list_alloc(len);
@@ -260,9 +253,8 @@ list_T *decode_create_map_special_dict(typval_T *const ret_tv,
/// will be freed.
///
/// @return Decoded string.
-typval_T decode_string(const char *const s, const size_t len,
- const TriState hasnul, const bool binary,
- const bool s_allocated)
+typval_T decode_string(const char *const s, const size_t len, const TriState hasnul,
+ const bool binary, const bool s_allocated)
FUNC_ATTR_WARN_UNUSED_RESULT
{
assert(s != NULL || len == 0);
@@ -280,10 +272,10 @@ typval_T decode_string(const char *const s, const size_t len,
tv_list_ref(list);
create_special_dict(&tv, kMPString,
((typval_T){
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- }));
+ .v_type = VAR_LIST,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_list = list },
+ }));
const int elw_ret = encode_list_write((void *)list, s, len);
if (s_allocated) {
xfree((void *)s);
@@ -299,7 +291,7 @@ typval_T decode_string(const char *const s, const size_t len,
.v_type = VAR_STRING,
.v_lock = VAR_UNLOCKED,
.vval = { .v_string = (char_u *)(
- (s == NULL || s_allocated) ? (char *)s : xmemdupz(s, len)) },
+ (s == NULL || s_allocated) ? (char *)s : xmemdupz(s, len)) },
};
}
}
@@ -323,11 +315,9 @@ typval_T decode_string(const char *const s, const size_t len,
///
/// @return OK in case of success, FAIL in case of error.
static inline int parse_json_string(const char *const buf, const size_t buf_len,
- const char **const pp,
- ValuesStack *const stack,
+ const char **const pp, ValuesStack *const stack,
ContainerStack *const container_stack,
- bool *const next_map_special,
- bool *const didcomma,
+ bool *const next_map_special, bool *const didcomma,
bool *const didcolon)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
{
@@ -341,55 +331,52 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
p++;
if (p == e) {
emsgf(_("E474: Unfinished escape sequence: %.*s"),
- (int) buf_len, buf);
+ (int)buf_len, buf);
goto parse_json_string_fail;
}
switch (*p) {
- case 'u': {
- if (p + 4 >= e) {
- emsgf(_("E474: Unfinished unicode escape sequence: %.*s"),
- (int) buf_len, buf);
- goto parse_json_string_fail;
- } else if (!ascii_isxdigit(p[1])
- || !ascii_isxdigit(p[2])
- || !ascii_isxdigit(p[3])
- || !ascii_isxdigit(p[4])) {
- emsgf(_("E474: Expected four hex digits after \\u: %.*s"),
- LENP(p - 1, e));
- goto parse_json_string_fail;
- }
- // One UTF-8 character below U+10000 can take up to 3 bytes,
- // above up to 6, but they are encoded using two \u escapes.
- len += 3;
- p += 5;
- break;
- }
- case '\\':
- case '/':
- case '"':
- case 't':
- case 'b':
- case 'n':
- case 'r':
- case 'f': {
- len++;
- p++;
- break;
- }
- default: {
- emsgf(_("E474: Unknown escape sequence: %.*s"), LENP(p - 1, e));
+ case 'u':
+ if (p + 4 >= e) {
+ emsgf(_("E474: Unfinished unicode escape sequence: %.*s"),
+ (int)buf_len, buf);
+ goto parse_json_string_fail;
+ } else if (!ascii_isxdigit(p[1])
+ || !ascii_isxdigit(p[2])
+ || !ascii_isxdigit(p[3])
+ || !ascii_isxdigit(p[4])) {
+ emsgf(_("E474: Expected four hex digits after \\u: %.*s"),
+ LENP(p - 1, e));
goto parse_json_string_fail;
}
+ // One UTF-8 character below U+10000 can take up to 3 bytes,
+ // above up to 6, but they are encoded using two \u escapes.
+ len += 3;
+ p += 5;
+ break;
+ case '\\':
+ case '/':
+ case '"':
+ case 't':
+ case 'b':
+ case 'n':
+ case 'r':
+ case 'f':
+ len++;
+ p++;
+ break;
+ default:
+ emsgf(_("E474: Unknown escape sequence: %.*s"), LENP(p - 1, e));
+ goto parse_json_string_fail;
}
} else {
- uint8_t p_byte = (uint8_t) *p;
+ uint8_t p_byte = (uint8_t)*p;
// unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
if (p_byte < 0x20) {
emsgf(_("E474: ASCII control characters cannot be present "
"inside string: %.*s"), LENP(p, e));
goto parse_json_string_fail;
}
- const int ch = utf_ptr2char((char_u *) p);
+ const int ch = utf_ptr2char((char_u *)p);
// All characters above U+007F are encoded using two or more bytes
// and thus cannot possibly be equal to *p. But utf_ptr2char({0xFF,
// 0}) will return 0xFF, even though 0xFF cannot start any UTF-8
@@ -397,7 +384,7 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
//
// The only exception is U+00C3 which is represented as 0xC3 0x83.
if (ch >= 0x80 && p_byte == ch
- && !(ch == 0xC3 && p + 1 < e && (uint8_t) p[1] == 0x83)) {
+ && !(ch == 0xC3 && p + 1 < e && (uint8_t)p[1] == 0x83)) {
emsgf(_("E474: Only UTF-8 strings allowed: %.*s"), LENP(p, e));
goto parse_json_string_fail;
} else if (ch > 0x10FFFF) {
@@ -405,14 +392,14 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
"are allowed to appear unescaped: %.*s"), LENP(p, e));
goto parse_json_string_fail;
}
- const size_t ch_len = (size_t) utf_char2len(ch);
- assert(ch_len == (size_t) (ch ? utf_ptr2len((char_u *) p) : 1));
+ const size_t ch_len = (size_t)utf_char2len(ch);
+ assert(ch_len == (size_t)(ch ? utf_ptr2len((char_u *)p) : 1));
len += ch_len;
p += ch_len;
}
}
if (p == e || *p != '"') {
- emsgf(_("E474: Expected string end: %.*s"), (int) buf_len, buf);
+ emsgf(_("E474: Expected string end: %.*s"), (int)buf_len, buf);
goto parse_json_string_fail;
}
if (len == 0) {
@@ -429,7 +416,7 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
#define PUT_FST_IN_PAIR(fst_in_pair, str_end) \
do { \
if (fst_in_pair != 0) { \
- str_end += utf_char2bytes(fst_in_pair, (char_u *) str_end); \
+ str_end += utf_char2bytes(fst_in_pair, (char_u *)str_end); \
fst_in_pair = 0; \
} \
} while (0)
@@ -440,56 +427,55 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
if (*t == '\\') {
t++;
switch (*t) {
- case 'u': {
- const char ubuf[] = { t[1], t[2], t[3], t[4] };
- t += 4;
- uvarnumber_T ch;
- vim_str2nr((char_u *)ubuf, NULL, NULL,
- STR2NR_HEX | STR2NR_FORCE, NULL, &ch, 4, true);
- if (ch == 0) {
- hasnul = true;
- }
- if (SURROGATE_HI_START <= ch && ch <= SURROGATE_HI_END) {
- PUT_FST_IN_PAIR(fst_in_pair, str_end);
- fst_in_pair = (int) ch;
- } else if (SURROGATE_LO_START <= ch && ch <= SURROGATE_LO_END
- && fst_in_pair != 0) {
- const int full_char = (
- (int) (ch - SURROGATE_LO_START)
- + ((fst_in_pair - SURROGATE_HI_START) << 10)
- + SURROGATE_FIRST_CHAR);
- str_end += utf_char2bytes(full_char, (char_u *) str_end);
- fst_in_pair = 0;
- } else {
- PUT_FST_IN_PAIR(fst_in_pair, str_end);
- str_end += utf_char2bytes((int) ch, (char_u *) str_end);
- }
- break;
+ case 'u': {
+ const char ubuf[] = { t[1], t[2], t[3], t[4] };
+ t += 4;
+ uvarnumber_T ch;
+ vim_str2nr((char_u *)ubuf, NULL, NULL,
+ STR2NR_HEX | STR2NR_FORCE, NULL, &ch, 4, true);
+ if (ch == 0) {
+ hasnul = true;
}
- case '\\':
- case '/':
- case '"':
- case 't':
- case 'b':
- case 'n':
- case 'r':
- case 'f': {
- static const char escapes[] = {
- ['\\'] = '\\',
- ['/'] = '/',
- ['"'] = '"',
- ['t'] = TAB,
- ['b'] = BS,
- ['n'] = NL,
- ['r'] = CAR,
- ['f'] = FF,
- };
- *str_end++ = escapes[(int) *t];
- break;
- }
- default: {
- abort();
+ if (SURROGATE_HI_START <= ch && ch <= SURROGATE_HI_END) {
+ PUT_FST_IN_PAIR(fst_in_pair, str_end);
+ fst_in_pair = (int)ch;
+ } else if (SURROGATE_LO_START <= ch && ch <= SURROGATE_LO_END
+ && fst_in_pair != 0) {
+ const int full_char = (
+ (int)(ch - SURROGATE_LO_START)
+ + ((fst_in_pair - SURROGATE_HI_START) << 10)
+ + SURROGATE_FIRST_CHAR);
+ str_end += utf_char2bytes(full_char, (char_u *)str_end);
+ fst_in_pair = 0;
+ } else {
+ PUT_FST_IN_PAIR(fst_in_pair, str_end);
+ str_end += utf_char2bytes((int)ch, (char_u *)str_end);
}
+ break;
+ }
+ case '\\':
+ case '/':
+ case '"':
+ case 't':
+ case 'b':
+ case 'n':
+ case 'r':
+ case 'f': {
+ static const char escapes[] = {
+ ['\\'] = '\\',
+ ['/'] = '/',
+ ['"'] = '"',
+ ['t'] = TAB,
+ ['b'] = BS,
+ ['n'] = NL,
+ ['r'] = CAR,
+ ['f'] = FF,
+ };
+ *str_end++ = escapes[(int)*t];
+ break;
+ }
+ default:
+ abort();
}
} else {
*str_end++ = *t;
@@ -498,8 +484,7 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
PUT_FST_IN_PAIR(fst_in_pair, str_end);
#undef PUT_FST_IN_PAIR
*str_end = NUL;
- typval_T obj = decode_string(
- str, (size_t)(str_end - str), hasnul ? kTrue : kFalse, false, true);
+ typval_T obj = decode_string(str, (size_t)(str_end - str), hasnul ? kTrue : kFalse, false, true);
if (obj.v_type == VAR_UNKNOWN) {
goto parse_json_string_fail;
}
@@ -536,11 +521,9 @@ parse_json_string_ret:
///
/// @return OK in case of success, FAIL in case of error.
static inline int parse_json_number(const char *const buf, const size_t buf_len,
- const char **const pp,
- ValuesStack *const stack,
+ const char **const pp, ValuesStack *const stack,
ContainerStack *const container_stack,
- bool *const next_map_special,
- bool *const didcomma,
+ bool *const next_map_special, bool *const didcomma,
bool *const didcolon)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
{
@@ -605,14 +588,14 @@ parse_json_number_check:
.v_type = VAR_NUMBER,
.v_lock = VAR_UNLOCKED,
};
- const size_t exp_num_len = (size_t) (p - s);
+ const size_t exp_num_len = (size_t)(p - s);
if (fracs || exps) {
// Convert floating-point number
const size_t num_len = string2float(s, &tv.vval.v_float);
if (exp_num_len != num_len) {
emsgf(_("E685: internal error: while converting number \"%.*s\" "
"to float string2float consumed %zu bytes in place of %zu"),
- (int) exp_num_len, s, num_len, exp_num_len);
+ (int)exp_num_len, s, num_len, exp_num_len);
}
tv.v_type = VAR_FLOAT;
} else {
@@ -623,7 +606,7 @@ parse_json_number_check:
if ((int)exp_num_len != num_len) {
emsgf(_("E685: internal error: while converting number \"%.*s\" "
"to integer vim_str2nr consumed %i bytes in place of %zu"),
- (int) exp_num_len, s, num_len, exp_num_len);
+ (int)exp_num_len, s, num_len, exp_num_len);
}
tv.vval.v_number = nr;
}
@@ -664,8 +647,7 @@ parse_json_number_ret:
/// @param[out] rettv Location where to save results.
///
/// @return OK in case of success, FAIL otherwise.
-int json_decode_string(const char *const buf, const size_t buf_len,
- typval_T *const rettv)
+int json_decode_string(const char *const buf, const size_t buf_len, typval_T *const rettv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
const char *p = buf;
@@ -688,219 +670,212 @@ int json_decode_string(const char *const buf, const size_t buf_len,
json_decode_string_cycle_start:
assert(*p == '{' || next_map_special == false);
switch (*p) {
- case '}':
- case ']': {
- if (kv_size(container_stack) == 0) {
- emsgf(_("E474: No container to close: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- ContainerStackItem last_container = kv_last(container_stack);
- if (*p == '}' && last_container.container.v_type != VAR_DICT) {
- emsgf(_("E474: Closing list with curly bracket: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (*p == ']' && last_container.container.v_type != VAR_LIST) {
- emsgf(_("E474: Closing dictionary with square bracket: %.*s"),
- LENP(p, e));
- goto json_decode_string_fail;
- } else if (didcomma) {
- emsgf(_("E474: Trailing comma: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (didcolon) {
- emsgf(_("E474: Expected value after colon: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (last_container.stack_index != kv_size(stack) - 1) {
- assert(last_container.stack_index < kv_size(stack) - 1);
- emsgf(_("E474: Expected value: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- if (kv_size(stack) == 1) {
- p++;
- (void) kv_pop(container_stack);
- goto json_decode_string_after_cycle;
- } else {
- if (json_decoder_pop(kv_pop(stack), &stack, &container_stack, &p,
- &next_map_special, &didcomma, &didcolon)
- == FAIL) {
- goto json_decode_string_fail;
- }
- assert(!next_map_special);
- break;
- }
+ case '}':
+ case ']': {
+ if (kv_size(container_stack) == 0) {
+ emsgf(_("E474: No container to close: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
- case ',': {
- if (kv_size(container_stack) == 0) {
- emsgf(_("E474: Comma not inside container: %.*s"), LENP(p, e));
+ ContainerStackItem last_container = kv_last(container_stack);
+ if (*p == '}' && last_container.container.v_type != VAR_DICT) {
+ emsgf(_("E474: Closing list with curly bracket: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (*p == ']' && last_container.container.v_type != VAR_LIST) {
+ emsgf(_("E474: Closing dictionary with square bracket: %.*s"),
+ LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (didcomma) {
+ emsgf(_("E474: Trailing comma: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (didcolon) {
+ emsgf(_("E474: Expected value after colon: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (last_container.stack_index != kv_size(stack) - 1) {
+ assert(last_container.stack_index < kv_size(stack) - 1);
+ emsgf(_("E474: Expected value: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ }
+ if (kv_size(stack) == 1) {
+ p++;
+ (void)kv_pop(container_stack);
+ goto json_decode_string_after_cycle;
+ } else {
+ if (json_decoder_pop(kv_pop(stack), &stack, &container_stack, &p,
+ &next_map_special, &didcomma, &didcolon)
+ == FAIL) {
goto json_decode_string_fail;
}
- ContainerStackItem last_container = kv_last(container_stack);
- if (didcomma) {
- emsgf(_("E474: Duplicate comma: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (didcolon) {
- emsgf(_("E474: Comma after colon: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (last_container.container.v_type == VAR_DICT
- && last_container.stack_index != kv_size(stack) - 1) {
- emsgf(_("E474: Using comma in place of colon: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (last_container.special_val == NULL
+ assert(!next_map_special);
+ break;
+ }
+ }
+ case ',': {
+ if (kv_size(container_stack) == 0) {
+ emsgf(_("E474: Comma not inside container: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ }
+ ContainerStackItem last_container = kv_last(container_stack);
+ if (didcomma) {
+ emsgf(_("E474: Duplicate comma: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (didcolon) {
+ emsgf(_("E474: Comma after colon: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (last_container.container.v_type == VAR_DICT
+ && last_container.stack_index != kv_size(stack) - 1) {
+ emsgf(_("E474: Using comma in place of colon: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (last_container.special_val == NULL
? (last_container.container.v_type == VAR_DICT
? (DICT_LEN(last_container.container.vval.v_dict) == 0)
: (tv_list_len(last_container.container.vval.v_list)
== 0))
- : (tv_list_len(last_container.special_val) == 0)) {
- emsgf(_("E474: Leading comma: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- didcomma = true;
- continue;
+ : (tv_list_len(last_container.special_val) == 0)) {
+ emsgf(_("E474: Leading comma: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
- case ':': {
- if (kv_size(container_stack) == 0) {
- emsgf(_("E474: Colon not inside container: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- ContainerStackItem last_container = kv_last(container_stack);
- if (last_container.container.v_type != VAR_DICT) {
- emsgf(_("E474: Using colon not in dictionary: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (last_container.stack_index != kv_size(stack) - 2) {
- emsgf(_("E474: Unexpected colon: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (didcomma) {
- emsgf(_("E474: Colon after comma: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- } else if (didcolon) {
- emsgf(_("E474: Duplicate colon: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- didcolon = true;
- continue;
+ didcomma = true;
+ continue;
+ }
+ case ':': {
+ if (kv_size(container_stack) == 0) {
+ emsgf(_("E474: Colon not inside container: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
- case ' ':
- case TAB:
- case NL:
- case CAR: {
- continue;
+ ContainerStackItem last_container = kv_last(container_stack);
+ if (last_container.container.v_type != VAR_DICT) {
+ emsgf(_("E474: Using colon not in dictionary: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (last_container.stack_index != kv_size(stack) - 2) {
+ emsgf(_("E474: Unexpected colon: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (didcomma) {
+ emsgf(_("E474: Colon after comma: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
+ } else if (didcolon) {
+ emsgf(_("E474: Duplicate colon: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
- case 'n': {
- if ((p + 3) >= e || strncmp(p + 1, "ull", 3) != 0) {
- emsgf(_("E474: Expected null: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- p += 3;
- POP(((typval_T) {
- .v_type = VAR_SPECIAL,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_special = kSpecialVarNull },
- }), false);
- break;
+ didcolon = true;
+ continue;
+ }
+ case ' ':
+ case TAB:
+ case NL:
+ case CAR:
+ continue;
+ case 'n':
+ if ((p + 3) >= e || strncmp(p + 1, "ull", 3) != 0) {
+ emsgf(_("E474: Expected null: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
- case 't': {
- if ((p + 3) >= e || strncmp(p + 1, "rue", 3) != 0) {
- emsgf(_("E474: Expected true: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- p += 3;
- POP(((typval_T) {
- .v_type = VAR_BOOL,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_bool = kBoolVarTrue },
- }), false);
- break;
+ p += 3;
+ POP(((typval_T) {
+ .v_type = VAR_SPECIAL,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_special = kSpecialVarNull },
+ }), false);
+ break;
+ case 't':
+ if ((p + 3) >= e || strncmp(p + 1, "rue", 3) != 0) {
+ emsgf(_("E474: Expected true: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
- case 'f': {
- if ((p + 4) >= e || strncmp(p + 1, "alse", 4) != 0) {
- emsgf(_("E474: Expected false: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
- p += 4;
- POP(((typval_T) {
- .v_type = VAR_BOOL,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_bool = kBoolVarFalse },
- }), false);
- break;
+ p += 3;
+ POP(((typval_T) {
+ .v_type = VAR_BOOL,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_bool = kBoolVarTrue },
+ }), false);
+ break;
+ case 'f':
+ if ((p + 4) >= e || strncmp(p + 1, "alse", 4) != 0) {
+ emsgf(_("E474: Expected false: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
- case '"': {
- if (parse_json_string(buf, buf_len, &p, &stack, &container_stack,
- &next_map_special, &didcomma, &didcolon)
- == FAIL) {
- // Error message was already given
- goto json_decode_string_fail;
- }
- if (next_map_special) {
- goto json_decode_string_cycle_start;
- }
- break;
+ p += 4;
+ POP(((typval_T) {
+ .v_type = VAR_BOOL,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_bool = kBoolVarFalse },
+ }), false);
+ break;
+ case '"':
+ if (parse_json_string(buf, buf_len, &p, &stack, &container_stack,
+ &next_map_special, &didcomma, &didcolon)
+ == FAIL) {
+ // Error message was already given
+ goto json_decode_string_fail;
}
- case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': {
- if (parse_json_number(buf, buf_len, &p, &stack, &container_stack,
- &next_map_special, &didcomma, &didcolon)
- == FAIL) {
- // Error message was already given
- goto json_decode_string_fail;
- }
- if (next_map_special) {
- goto json_decode_string_cycle_start;
- }
- break;
+ if (next_map_special) {
+ goto json_decode_string_cycle_start;
}
- case '[': {
- list_T *list = tv_list_alloc(kListLenMayKnow);
- tv_list_ref(list);
- typval_T tv = {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- };
- kv_push(container_stack, ((ContainerStackItem) {
+ break;
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (parse_json_number(buf, buf_len, &p, &stack, &container_stack,
+ &next_map_special, &didcomma, &didcolon)
+ == FAIL) {
+ // Error message was already given
+ goto json_decode_string_fail;
+ }
+ if (next_map_special) {
+ goto json_decode_string_cycle_start;
+ }
+ break;
+ case '[': {
+ list_T *list = tv_list_alloc(kListLenMayKnow);
+ tv_list_ref(list);
+ typval_T tv = {
+ .v_type = VAR_LIST,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_list = list },
+ };
+ kv_push(container_stack, ((ContainerStackItem) {
.stack_index = kv_size(stack),
.s = p,
.container = tv,
.special_val = NULL,
}));
- kv_push(stack, OBJ(tv, false, didcomma, didcolon));
- break;
+ kv_push(stack, OBJ(tv, false, didcomma, didcolon));
+ break;
+ }
+ case '{': {
+ typval_T tv;
+ list_T *val_list = NULL;
+ if (next_map_special) {
+ next_map_special = false;
+ val_list = decode_create_map_special_dict(&tv, kListLenMayKnow);
+ } else {
+ dict_T *dict = tv_dict_alloc();
+ dict->dv_refcount++;
+ tv = (typval_T) {
+ .v_type = VAR_DICT,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_dict = dict },
+ };
}
- case '{': {
- typval_T tv;
- list_T *val_list = NULL;
- if (next_map_special) {
- next_map_special = false;
- val_list = decode_create_map_special_dict(&tv, kListLenMayKnow);
- } else {
- dict_T *dict = tv_dict_alloc();
- dict->dv_refcount++;
- tv = (typval_T) {
- .v_type = VAR_DICT,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_dict = dict },
- };
- }
- kv_push(container_stack, ((ContainerStackItem) {
+ kv_push(container_stack, ((ContainerStackItem) {
.stack_index = kv_size(stack),
.s = p,
.container = tv,
.special_val = val_list,
}));
- kv_push(stack, OBJ(tv, false, didcomma, didcolon));
- break;
- }
- default: {
- emsgf(_("E474: Unidentified byte: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
+ kv_push(stack, OBJ(tv, false, didcomma, didcolon));
+ break;
+ }
+ default:
+ emsgf(_("E474: Unidentified byte: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
didcomma = false;
didcolon = false;
@@ -912,23 +887,21 @@ json_decode_string_cycle_start:
json_decode_string_after_cycle:
for (; p < e; p++) {
switch (*p) {
- case NL:
- case ' ':
- case TAB:
- case CAR: {
- break;
- }
- default: {
- emsgf(_("E474: Trailing characters: %.*s"), LENP(p, e));
- goto json_decode_string_fail;
- }
+ case NL:
+ case ' ':
+ case TAB:
+ case CAR:
+ break;
+ default:
+ emsgf(_("E474: Trailing characters: %.*s"), LENP(p, e));
+ goto json_decode_string_fail;
}
}
if (kv_size(stack) == 1 && kv_size(container_stack) == 0) {
*rettv = kv_pop(stack).val;
goto json_decode_string_ret;
}
- emsgf(_("E474: Unexpected end of input: %.*s"), (int) buf_len, buf);
+ emsgf(_("E474: Unexpected end of input: %.*s"), (int)buf_len, buf);
json_decode_string_fail:
ret = FAIL;
while (kv_size(stack)) {
@@ -952,192 +925,183 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (mobj.type) {
- case MSGPACK_OBJECT_NIL: {
+ case MSGPACK_OBJECT_NIL:
+ *rettv = (typval_T) {
+ .v_type = VAR_SPECIAL,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_special = kSpecialVarNull },
+ };
+ break;
+ case MSGPACK_OBJECT_BOOLEAN:
+ *rettv = (typval_T) {
+ .v_type = VAR_BOOL,
+ .v_lock = VAR_UNLOCKED,
+ .vval = {
+ .v_bool = mobj.via.boolean ? kBoolVarTrue : kBoolVarFalse
+ },
+ };
+ break;
+ case MSGPACK_OBJECT_POSITIVE_INTEGER:
+ if (mobj.via.u64 <= VARNUMBER_MAX) {
*rettv = (typval_T) {
- .v_type = VAR_SPECIAL,
+ .v_type = VAR_NUMBER,
.v_lock = VAR_UNLOCKED,
- .vval = { .v_special = kSpecialVarNull },
+ .vval = { .v_number = (varnumber_T)mobj.via.u64 },
};
- break;
+ } else {
+ list_T *const list = tv_list_alloc(4);
+ tv_list_ref(list);
+ create_special_dict(rettv, kMPInteger, ((typval_T) {
+ .v_type = VAR_LIST,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_list = list },
+ }));
+ uint64_t n = mobj.via.u64;
+ tv_list_append_number(list, 1);
+ tv_list_append_number(list, (varnumber_T)((n >> 62) & 0x3));
+ tv_list_append_number(list, (varnumber_T)((n >> 31) & 0x7FFFFFFF));
+ tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
}
- case MSGPACK_OBJECT_BOOLEAN: {
+ break;
+ case MSGPACK_OBJECT_NEGATIVE_INTEGER:
+ if (mobj.via.i64 >= VARNUMBER_MIN) { // -V547
*rettv = (typval_T) {
- .v_type = VAR_BOOL,
+ .v_type = VAR_NUMBER,
.v_lock = VAR_UNLOCKED,
- .vval = {
- .v_bool = mobj.via.boolean ? kBoolVarTrue : kBoolVarFalse
- },
+ .vval = { .v_number = (varnumber_T)mobj.via.i64 },
};
- break;
- }
- case MSGPACK_OBJECT_POSITIVE_INTEGER: {
- if (mobj.via.u64 <= VARNUMBER_MAX) {
- *rettv = (typval_T) {
- .v_type = VAR_NUMBER,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_number = (varnumber_T) mobj.via.u64 },
- };
- } else {
- list_T *const list = tv_list_alloc(4);
- tv_list_ref(list);
- create_special_dict(rettv, kMPInteger, ((typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- }));
- uint64_t n = mobj.via.u64;
- tv_list_append_number(list, 1);
- tv_list_append_number(list, (varnumber_T)((n >> 62) & 0x3));
- tv_list_append_number(list, (varnumber_T)((n >> 31) & 0x7FFFFFFF));
- tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
- }
- break;
- }
- case MSGPACK_OBJECT_NEGATIVE_INTEGER: {
- if (mobj.via.i64 >= VARNUMBER_MIN) { // -V547
- *rettv = (typval_T) {
- .v_type = VAR_NUMBER,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_number = (varnumber_T) mobj.via.i64 },
- };
- } else {
- list_T *const list = tv_list_alloc(4);
- tv_list_ref(list);
- create_special_dict(rettv, kMPInteger, ((typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- }));
- uint64_t n = -((uint64_t)mobj.via.i64);
- tv_list_append_number(list, -1);
- tv_list_append_number(list, (varnumber_T)((n >> 62) & 0x3));
- tv_list_append_number(list, (varnumber_T)((n >> 31) & 0x7FFFFFFF));
- tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
- }
- break;
+ } else {
+ list_T *const list = tv_list_alloc(4);
+ tv_list_ref(list);
+ create_special_dict(rettv, kMPInteger, ((typval_T) {
+ .v_type = VAR_LIST,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_list = list },
+ }));
+ uint64_t n = -((uint64_t)mobj.via.i64);
+ tv_list_append_number(list, -1);
+ tv_list_append_number(list, (varnumber_T)((n >> 62) & 0x3));
+ tv_list_append_number(list, (varnumber_T)((n >> 31) & 0x7FFFFFFF));
+ tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
}
+ break;
#ifdef NVIM_MSGPACK_HAS_FLOAT32
- case MSGPACK_OBJECT_FLOAT32:
- case MSGPACK_OBJECT_FLOAT64:
+ case MSGPACK_OBJECT_FLOAT32:
+ case MSGPACK_OBJECT_FLOAT64:
#else
- case MSGPACK_OBJECT_FLOAT:
+ case MSGPACK_OBJECT_FLOAT:
#endif
- {
- *rettv = (typval_T) {
- .v_type = VAR_FLOAT,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_float = mobj.via.f64 },
- };
- break;
+ *rettv = (typval_T) {
+ .v_type = VAR_FLOAT,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_float = mobj.via.f64 },
+ };
+ break;
+ case MSGPACK_OBJECT_STR:
+ *rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kTrue, false,
+ false);
+ if (rettv->v_type == VAR_UNKNOWN) {
+ return FAIL;
}
- case MSGPACK_OBJECT_STR: {
- *rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kTrue, false,
- false);
- if (rettv->v_type == VAR_UNKNOWN) {
- return FAIL;
- }
- break;
+ break;
+ case MSGPACK_OBJECT_BIN:
+ *rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kNone, true,
+ false);
+ if (rettv->v_type == VAR_UNKNOWN) {
+ return FAIL;
}
- case MSGPACK_OBJECT_BIN: {
- *rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kNone, true,
- false);
- if (rettv->v_type == VAR_UNKNOWN) {
+ break;
+ case MSGPACK_OBJECT_ARRAY: {
+ list_T *const list = tv_list_alloc((ptrdiff_t)mobj.via.array.size);
+ tv_list_ref(list);
+ *rettv = (typval_T) {
+ .v_type = VAR_LIST,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_list = list },
+ };
+ for (size_t i = 0; i < mobj.via.array.size; i++) {
+ // Not populated yet, need to create list item to push.
+ tv_list_append_owned_tv(list, (typval_T) { .v_type = VAR_UNKNOWN });
+ if (msgpack_to_vim(mobj.via.array.ptr[i],
+ TV_LIST_ITEM_TV(tv_list_last(list)))
+ == FAIL) {
return FAIL;
}
- break;
}
- case MSGPACK_OBJECT_ARRAY: {
- list_T *const list = tv_list_alloc((ptrdiff_t)mobj.via.array.size);
- tv_list_ref(list);
- *rettv = (typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- };
- for (size_t i = 0; i < mobj.via.array.size; i++) {
- // Not populated yet, need to create list item to push.
- tv_list_append_owned_tv(list, (typval_T) { .v_type = VAR_UNKNOWN });
- if (msgpack_to_vim(mobj.via.array.ptr[i],
- TV_LIST_ITEM_TV(tv_list_last(list)))
- == FAIL) {
- return FAIL;
- }
+ break;
+ }
+ case MSGPACK_OBJECT_MAP: {
+ for (size_t i = 0; i < mobj.via.map.size; i++) {
+ if (mobj.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR
+ || mobj.via.map.ptr[i].key.via.str.size == 0
+ || memchr(mobj.via.map.ptr[i].key.via.str.ptr, NUL,
+ mobj.via.map.ptr[i].key.via.str.size) != NULL) {
+ goto msgpack_to_vim_generic_map;
}
- break;
}
- case MSGPACK_OBJECT_MAP: {
- for (size_t i = 0; i < mobj.via.map.size; i++) {
- if (mobj.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR
- || mobj.via.map.ptr[i].key.via.str.size == 0
- || memchr(mobj.via.map.ptr[i].key.via.str.ptr, NUL,
- mobj.via.map.ptr[i].key.via.str.size) != NULL) {
- goto msgpack_to_vim_generic_map;
- }
+ dict_T *const dict = tv_dict_alloc();
+ dict->dv_refcount++;
+ *rettv = (typval_T) {
+ .v_type = VAR_DICT,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_dict = dict },
+ };
+ for (size_t i = 0; i < mobj.via.map.size; i++) {
+ dictitem_T *const di = xmallocz(offsetof(dictitem_T, di_key)
+ + mobj.via.map.ptr[i].key.via.str.size);
+ memcpy(&di->di_key[0], mobj.via.map.ptr[i].key.via.str.ptr,
+ mobj.via.map.ptr[i].key.via.str.size);
+ di->di_tv.v_type = VAR_UNKNOWN;
+ if (tv_dict_add(dict, di) == FAIL) {
+ // Duplicate key: fallback to generic map
+ tv_clear(rettv);
+ xfree(di);
+ goto msgpack_to_vim_generic_map;
}
- dict_T *const dict = tv_dict_alloc();
- dict->dv_refcount++;
- *rettv = (typval_T) {
- .v_type = VAR_DICT,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_dict = dict },
- };
- for (size_t i = 0; i < mobj.via.map.size; i++) {
- dictitem_T *const di = xmallocz(offsetof(dictitem_T, di_key)
- + mobj.via.map.ptr[i].key.via.str.size);
- memcpy(&di->di_key[0], mobj.via.map.ptr[i].key.via.str.ptr,
- mobj.via.map.ptr[i].key.via.str.size);
- di->di_tv.v_type = VAR_UNKNOWN;
- if (tv_dict_add(dict, di) == FAIL) {
- // Duplicate key: fallback to generic map
- tv_clear(rettv);
- xfree(di);
- goto msgpack_to_vim_generic_map;
- }
- if (msgpack_to_vim(mobj.via.map.ptr[i].val, &di->di_tv) == FAIL) {
- return FAIL;
- }
+ if (msgpack_to_vim(mobj.via.map.ptr[i].val, &di->di_tv) == FAIL) {
+ return FAIL;
}
- break;
+ }
+ break;
msgpack_to_vim_generic_map: {}
- list_T *const list = decode_create_map_special_dict(
- rettv, (ptrdiff_t)mobj.via.map.size);
- for (size_t i = 0; i < mobj.via.map.size; i++) {
- list_T *const kv_pair = tv_list_alloc(2);
- tv_list_append_list(list, kv_pair);
+ list_T *const list = decode_create_map_special_dict(rettv, (ptrdiff_t)mobj.via.map.size);
+ for (size_t i = 0; i < mobj.via.map.size; i++) {
+ list_T *const kv_pair = tv_list_alloc(2);
+ tv_list_append_list(list, kv_pair);
- typval_T key_tv = { .v_type = VAR_UNKNOWN };
- if (msgpack_to_vim(mobj.via.map.ptr[i].key, &key_tv) == FAIL) {
- tv_clear(&key_tv);
- return FAIL;
- }
- tv_list_append_owned_tv(kv_pair, key_tv);
+ typval_T key_tv = { .v_type = VAR_UNKNOWN };
+ if (msgpack_to_vim(mobj.via.map.ptr[i].key, &key_tv) == FAIL) {
+ tv_clear(&key_tv);
+ return FAIL;
+ }
+ tv_list_append_owned_tv(kv_pair, key_tv);
- typval_T val_tv = { .v_type = VAR_UNKNOWN };
- if (msgpack_to_vim(mobj.via.map.ptr[i].val, &val_tv) == FAIL) {
- tv_clear(&val_tv);
- return FAIL;
- }
- tv_list_append_owned_tv(kv_pair, val_tv);
+ typval_T val_tv = { .v_type = VAR_UNKNOWN };
+ if (msgpack_to_vim(mobj.via.map.ptr[i].val, &val_tv) == FAIL) {
+ tv_clear(&val_tv);
+ return FAIL;
}
- break;
+ tv_list_append_owned_tv(kv_pair, val_tv);
}
- case MSGPACK_OBJECT_EXT: {
- list_T *const list = tv_list_alloc(2);
- tv_list_ref(list);
- tv_list_append_number(list, mobj.via.ext.type);
- list_T *const ext_val_list = tv_list_alloc(kListLenMayKnow);
- tv_list_append_list(list, ext_val_list);
- create_special_dict(rettv, kMPExt, ((typval_T) {
+ break;
+ }
+ case MSGPACK_OBJECT_EXT: {
+ list_T *const list = tv_list_alloc(2);
+ tv_list_ref(list);
+ tv_list_append_number(list, mobj.via.ext.type);
+ list_T *const ext_val_list = tv_list_alloc(kListLenMayKnow);
+ tv_list_append_list(list, ext_val_list);
+ create_special_dict(rettv, kMPExt, ((typval_T) {
.v_type = VAR_LIST,
.v_lock = VAR_UNLOCKED,
.vval = { .v_list = list },
}));
- if (encode_list_write((void *) ext_val_list, mobj.via.ext.ptr,
- mobj.via.ext.size) == -1) {
- return FAIL;
- }
- break;
+ if (encode_list_write((void *)ext_val_list, mobj.via.ext.ptr,
+ mobj.via.ext.size) == -1) {
+ return FAIL;
}
+ break;
+ }
}
return OK;
}
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index b5e50e7ef5..1c0afc89f5 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -7,27 +7,27 @@
///
/// Split out from eval.c.
-#include <msgpack.h>
-#include <inttypes.h>
-#include <stddef.h>
#include <assert.h>
+#include <inttypes.h>
#include <math.h>
+#include <msgpack.h>
+#include <stddef.h>
-#include "nvim/eval/encode.h"
+#include "nvim/ascii.h"
#include "nvim/buffer_defs.h"
+#include "nvim/charset.h" // vim_isprintc()
#include "nvim/eval.h"
+#include "nvim/eval/encode.h"
#include "nvim/eval/typval.h"
+#include "nvim/eval/typval_encode.h"
#include "nvim/garray.h"
-#include "nvim/mbyte.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/macros.h"
#include "nvim/math.h"
-#include "nvim/message.h"
+#include "nvim/mbyte.h"
#include "nvim/memory.h"
-#include "nvim/charset.h" // vim_isprintc()
-#include "nvim/macros.h"
-#include "nvim/ascii.h"
+#include "nvim/message.h"
#include "nvim/vim.h" // For _()
-#include "nvim/lib/kvec.h"
-#include "nvim/eval/typval_encode.h"
#define ga_concat(a, b) ga_concat(a, (char_u *)b)
#define utf_ptr2char(b) utf_ptr2char((char_u *)b)
@@ -62,7 +62,7 @@ int encode_list_write(void *const data, const char *const buf, const size_t len)
if (len == 0) {
return 0;
}
- list_T *const list = (list_T *) data;
+ list_T *const list = (list_T *)data;
const char *const end = buf + len;
const char *line_end = buf;
listitem_T *li = tv_list_last(list);
@@ -74,8 +74,7 @@ int encode_list_write(void *const data, const char *const buf, const size_t len)
const size_t line_length = (size_t)(line_end - buf);
char *str = (char *)TV_LIST_ITEM_TV(li)->vval.v_string;
const size_t li_len = (str == NULL ? 0 : strlen(str));
- TV_LIST_ITEM_TV(li)->vval.v_string = xrealloc(
- str, li_len + line_length + 1);
+ TV_LIST_ITEM_TV(li)->vval.v_string = xrealloc(str, li_len + line_length + 1);
str = (char *)TV_LIST_ITEM_TV(li)->vval.v_string + li_len;
memcpy(str, buf, line_length);
str[line_length] = 0;
@@ -86,7 +85,7 @@ int encode_list_write(void *const data, const char *const buf, const size_t len)
while (line_end < end) {
const char *line_start = line_end;
- line_end = xmemscan(line_start, NL, (size_t) (end - line_start));
+ line_end = xmemscan(line_start, NL, (size_t)(end - line_start));
char *str = NULL;
if (line_end != line_start) {
const size_t line_length = (size_t)(line_end - line_start);
@@ -133,75 +132,70 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
}
MPConvStackVal v = kv_A(*mpstack, i);
switch (v.type) {
- case kMPConvDict: {
- typval_T key_tv = {
- .v_type = VAR_STRING,
- .vval = { .v_string = (v.data.d.hi == NULL
+ case kMPConvDict: {
+ typval_T key_tv = {
+ .v_type = VAR_STRING,
+ .vval = { .v_string = (v.data.d.hi == NULL
? v.data.d.dict->dv_hashtab.ht_array
: (v.data.d.hi - 1))->hi_key },
- };
- char *const key = encode_tv2string(&key_tv, NULL);
- vim_snprintf((char *) IObuff, IOSIZE, key_msg, key);
- xfree(key);
- ga_concat(&msg_ga, IObuff);
- break;
- }
- case kMPConvPairs:
- case kMPConvList: {
- const int idx = (v.data.l.li == tv_list_first(v.data.l.list)
+ };
+ char *const key = encode_tv2string(&key_tv, NULL);
+ vim_snprintf((char *)IObuff, IOSIZE, key_msg, key);
+ xfree(key);
+ ga_concat(&msg_ga, IObuff);
+ break;
+ }
+ case kMPConvPairs:
+ case kMPConvList: {
+ const int idx = (v.data.l.li == tv_list_first(v.data.l.list)
? 0
: (v.data.l.li == NULL
? tv_list_len(v.data.l.list) - 1
- : (int)tv_list_idx_of_item(
- v.data.l.list,
- TV_LIST_ITEM_PREV(v.data.l.list,
- v.data.l.li))));
- const listitem_T *const li = (v.data.l.li == NULL
+ : (int)tv_list_idx_of_item(v.data.l.list,
+ TV_LIST_ITEM_PREV(v.data.l.list,
+ v.data.l.li))));
+ const listitem_T *const li = (v.data.l.li == NULL
? tv_list_last(v.data.l.list)
: TV_LIST_ITEM_PREV(v.data.l.list,
v.data.l.li));
- if (v.type == kMPConvList
- || li == NULL
- || (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);
- } else {
- assert(li != NULL);
- listitem_T *const first_item =
- tv_list_first(TV_LIST_ITEM_TV(li)->vval.v_list);
- assert(first_item != NULL);
- typval_T key_tv = *TV_LIST_ITEM_TV(first_item);
- 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);
- }
- break;
+ if (v.type == kMPConvList
+ || li == NULL
+ || (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);
+ } else {
+ assert(li != NULL);
+ listitem_T *const first_item =
+ tv_list_first(TV_LIST_ITEM_TV(li)->vval.v_list);
+ assert(first_item != NULL);
+ typval_T key_tv = *TV_LIST_ITEM_TV(first_item);
+ 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);
}
- case kMPConvPartial: {
- switch (v.data.p.stage) {
- case kMPConvPartialArgs: {
- abort();
- break;
- }
- case kMPConvPartialSelf: {
- ga_concat(&msg_ga, partial_arg_msg);
- break;
- }
- case kMPConvPartialEnd: {
- ga_concat(&msg_ga, partial_self_msg);
- break;
- }
- }
+ break;
+ }
+ case kMPConvPartial:
+ switch (v.data.p.stage) {
+ case kMPConvPartialArgs:
+ abort();
break;
- }
- 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);
+ case kMPConvPartialSelf:
+ ga_concat(&msg_ga, partial_arg_msg);
+ break;
+ case kMPConvPartialEnd:
+ ga_concat(&msg_ga, partial_self_msg);
break;
}
+ break;
+ 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);
+ break;
+ }
}
}
emsgf(msg, _(objname), (kv_size(*mpstack) == 0
@@ -219,8 +213,7 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
/// zero.
///
/// @return true in case of success, false in case of failure.
-bool encode_vim_list_to_buf(const list_T *const list, size_t *const ret_len,
- char **const ret_buf)
+bool encode_vim_list_to_buf(const list_T *const list, size_t *const ret_len, char **const ret_buf)
FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT
{
size_t len = 0;
@@ -264,8 +257,8 @@ bool encode_vim_list_to_buf(const list_T *const list, size_t *const ret_len,
/// @return OK when reading was finished, FAIL in case of error (i.e. list item
/// was not a string), NOTDONE if reading was successful, but there are
/// more bytes to read.
-int encode_read_from_list(ListReaderState *const state, char *const buf,
- const size_t nbuf, size_t *const read_bytes)
+int encode_read_from_list(ListReaderState *const state, char *const buf, const size_t nbuf,
+ size_t *const read_bytes)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
char *const buf_end = buf + nbuf;
@@ -276,13 +269,13 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
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++]);
+ TV_LIST_ITEM_TV(state->li)->vval.v_string[state->offset++]);
*p++ = (char)((char)ch == (char)NL ? (char)NUL : (char)ch);
}
if (p < buf_end) {
state->li = TV_LIST_ITEM_NEXT(state->list, state->li);
if (state->li == NULL) {
- *read_bytes = (size_t) (p - buf);
+ *read_bytes = (size_t)(p - buf);
return OK;
}
*p++ = NL;
@@ -304,181 +297,181 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
}
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
- do { \
- const char *const buf_ = (const char *) buf; \
- if (buf == NULL) { \
- ga_concat(gap, "''"); \
- } else { \
- const size_t len_ = (len); \
- ga_grow(gap, (int) (2 + len_ + memcnt(buf_, '\'', len_))); \
- ga_append(gap, '\''); \
- for (size_t i_ = 0; i_ < len_; i_++) { \
- if (buf_[i_] == '\'') { \
- ga_append(gap, '\''); \
- } \
- ga_append(gap, buf_[i_]); \
+ do { \
+ const char *const buf_ = (const char *)buf; \
+ if (buf == NULL) { \
+ ga_concat(gap, "''"); \
+ } else { \
+ const size_t len_ = (len); \
+ ga_grow(gap, (int)(2 + len_ + memcnt(buf_, '\'', len_))); \
+ ga_append(gap, '\''); \
+ for (size_t i_ = 0; i_ < len_; i_++) { \
+ if (buf_[i_] == '\'') { \
+ ga_append(gap, '\''); \
} \
- ga_append(gap, '\''); \
+ ga_append(gap, buf_[i_]); \
} \
- } while (0)
+ ga_append(gap, '\''); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len) \
- TYPVAL_ENCODE_CONV_STRING(tv, buf, len)
+ TYPVAL_ENCODE_CONV_STRING(tv, buf, len)
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type)
#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \
- do { \
- const blob_T *const blob_ = (blob); \
- const int len_ = (len); \
- if (len_ == 0) { \
- ga_concat(gap, "0z"); \
- } else { \
- /* Allocate space for "0z", the two hex chars per byte, and a */ \
- /* "." separator after every eight hex chars. */ \
- /* Example: "0z00112233.44556677.8899" */ \
- ga_grow(gap, 2 + 2 * len_ + (len_ - 1) / 4); \
- ga_concat(gap, "0z"); \
- char numbuf[NUMBUFLEN]; \
- for (int i_ = 0; i_ < len_; i_++) { \
- if (i_ > 0 && (i_ & 3) == 0) { \
- ga_append(gap, '.'); \
- } \
- vim_snprintf((char *)numbuf, ARRAY_SIZE(numbuf), "%02X", \
- (int)tv_blob_get(blob_, i_)); \
- ga_concat(gap, numbuf); \
+ do { \
+ const blob_T *const blob_ = (blob); \
+ const int len_ = (len); \
+ if (len_ == 0) { \
+ ga_concat(gap, "0z"); \
+ } else { \
+ /* Allocate space for "0z", the two hex chars per byte, and a */ \
+ /* "." separator after every eight hex chars. */ \
+ /* Example: "0z00112233.44556677.8899" */ \
+ ga_grow(gap, 2 + 2 * len_ + (len_ - 1) / 4); \
+ ga_concat(gap, "0z"); \
+ char numbuf[NUMBUFLEN]; \
+ for (int i_ = 0; i_ < len_; i_++) { \
+ if (i_ > 0 && (i_ & 3) == 0) { \
+ ga_append(gap, '.'); \
} \
+ vim_snprintf((char *)numbuf, ARRAY_SIZE(numbuf), "%02X", \
+ (int)tv_blob_get(blob_, i_)); \
+ ga_concat(gap, numbuf); \
} \
- } while (0)
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
- do { \
- char numbuf[NUMBUFLEN]; \
- vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%" PRId64, (int64_t) (num)); \
- ga_concat(gap, numbuf); \
- } while (0)
+ do { \
+ char numbuf[NUMBUFLEN]; \
+ vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%" PRId64, (int64_t)(num)); \
+ ga_concat(gap, numbuf); \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
- do { \
- const float_T flt_ = (flt); \
- switch (xfpclassify(flt_)) { \
- case FP_NAN: { \
- ga_concat(gap, (char_u *) "str2float('nan')"); \
- break; \
- } \
- case FP_INFINITE: { \
- if (flt_ < 0) { \
- ga_append(gap, '-'); \
- } \
- ga_concat(gap, (char_u *) "str2float('inf')"); \
- break; \
- } \
- default: { \
- char numbuf[NUMBUFLEN]; \
- vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \
- ga_concat(gap, (char_u *) numbuf); \
- } \
+ do { \
+ const float_T flt_ = (flt); \
+ switch (xfpclassify(flt_)) { \
+ case FP_NAN: { \
+ ga_concat(gap, (char_u *)"str2float('nan')"); \
+ break; \
+ } \
+ case FP_INFINITE: { \
+ if (flt_ < 0) { \
+ ga_append(gap, '-'); \
} \
- } while (0)
+ ga_concat(gap, (char_u *)"str2float('inf')"); \
+ break; \
+ } \
+ default: { \
+ char numbuf[NUMBUFLEN]; \
+ vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \
+ ga_concat(gap, (char_u *)numbuf); \
+ } \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
- do { \
- const char *const fun_ = (const char *)(fun); \
- if (fun_ == NULL) { \
- internal_error("string(): NULL function name"); \
- ga_concat(gap, "function(NULL"); \
- } else { \
- ga_concat(gap, "function("); \
- TYPVAL_ENCODE_CONV_STRING(tv, fun_, strlen(fun_)); \
- }\
- } while (0)
+ do { \
+ const char *const fun_ = (const char *)(fun); \
+ if (fun_ == NULL) { \
+ internal_error("string(): NULL function name"); \
+ ga_concat(gap, "function(NULL"); \
+ } else { \
+ ga_concat(gap, "function("); \
+ TYPVAL_ENCODE_CONV_STRING(tv, fun_, strlen(fun_)); \
+ }\
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len) \
- do { \
- if (len != 0) { \
- ga_concat(gap, ", "); \
- } \
- } while (0)
+ do { \
+ if (len != 0) { \
+ ga_concat(gap, ", "); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len) \
- do { \
- if ((ptrdiff_t)len != -1) { \
- ga_concat(gap, ", "); \
- } \
- } while (0)
+ do { \
+ if ((ptrdiff_t)len != -1) { \
+ ga_concat(gap, ", "); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_END(tv) \
- ga_append(gap, ')')
+ ga_append(gap, ')')
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
- ga_concat(gap, "[]")
+ ga_concat(gap, "[]")
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
- ga_append(gap, '[')
+ ga_append(gap, '[')
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
- ga_concat(gap, "{}")
+ ga_concat(gap, "{}")
#define TYPVAL_ENCODE_CONV_NIL(tv) \
- ga_concat(gap, "v:null")
+ ga_concat(gap, "v:null")
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
- ga_concat(gap, ((num)? "v:true": "v:false"))
+ ga_concat(gap, ((num)? "v:true": "v:false"))
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num)
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
- ga_append(gap, '{')
+ ga_append(gap, '{')
#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv)
#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
- ga_append(gap, '}')
+ ga_append(gap, '}')
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict) \
- ga_concat(gap, ": ")
+ ga_concat(gap, ": ")
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict) \
- ga_concat(gap, ", ")
+ ga_concat(gap, ", ")
#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, key)
#define TYPVAL_ENCODE_CONV_LIST_END(tv) \
- ga_append(gap, ']')
+ ga_append(gap, ']')
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv) \
- TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, NULL)
+ TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, NULL)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
- do { \
- if (!did_echo_string_emsg) { \
- /* Only give this message once for a recursive call to avoid */ \
- /* flooding the user with errors. */ \
- did_echo_string_emsg = true; \
- EMSG(_("E724: unable to correctly dump variable " \
- "with self-referencing container")); \
- } \
- char ebuf[NUMBUFLEN + 7]; \
- size_t backref = 0; \
- for (; backref < kv_size(*mpstack); backref++) { \
- const MPConvStackVal mpval = kv_A(*mpstack, backref); \
- if (mpval.type == conv_type) { \
- if (conv_type == kMPConvDict) { \
- if ((void *) mpval.data.d.dict == (void *) (val)) { \
- break; \
- } \
- } else if (conv_type == kMPConvList) { \
- if ((void *) mpval.data.l.list == (void *) (val)) { \
- break; \
- } \
+ do { \
+ if (!did_echo_string_emsg) { \
+ /* Only give this message once for a recursive call to avoid */ \
+ /* flooding the user with errors. */ \
+ did_echo_string_emsg = true; \
+ EMSG(_("E724: unable to correctly dump variable " \
+ "with self-referencing container")); \
+ } \
+ char ebuf[NUMBUFLEN + 7]; \
+ size_t backref = 0; \
+ for (; backref < kv_size(*mpstack); backref++) { \
+ const MPConvStackVal mpval = kv_A(*mpstack, backref); \
+ if (mpval.type == conv_type) { \
+ if (conv_type == kMPConvDict) { \
+ if ((void *)mpval.data.d.dict == (void *)(val)) { \
+ break; \
+ } \
+ } else if (conv_type == kMPConvList) { \
+ if ((void *)mpval.data.l.list == (void *)(val)) { \
+ break; \
} \
} \
} \
- vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "{E724@%zu}", backref); \
- ga_concat(gap, &ebuf[0]); \
- } while (0)
+ } \
+ vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "{E724@%zu}", backref); \
+ ga_concat(gap, &ebuf[0]); \
+ } while (0)
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
@@ -494,31 +487,31 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
#undef TYPVAL_ENCODE_CONV_RECURSE
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
- do { \
- char ebuf[NUMBUFLEN + 7]; \
- size_t backref = 0; \
- for (; backref < kv_size(*mpstack); backref++) { \
- const MPConvStackVal mpval = kv_A(*mpstack, backref); \
- if (mpval.type == conv_type) { \
- if (conv_type == kMPConvDict) { \
- if ((void *) mpval.data.d.dict == (void *) val) { \
- break; \
- } \
- } else if (conv_type == kMPConvList) { \
- if ((void *) mpval.data.l.list == (void *) val) { \
- break; \
- } \
+ do { \
+ char ebuf[NUMBUFLEN + 7]; \
+ size_t backref = 0; \
+ for (; backref < kv_size(*mpstack); backref++) { \
+ const MPConvStackVal mpval = kv_A(*mpstack, backref); \
+ if (mpval.type == conv_type) { \
+ if (conv_type == kMPConvDict) { \
+ if ((void *)mpval.data.d.dict == (void *)val) { \
+ break; \
+ } \
+ } else if (conv_type == kMPConvList) { \
+ if ((void *)mpval.data.l.list == (void *)val) { \
+ break; \
} \
} \
} \
- if (conv_type == kMPConvDict) { \
- vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "{...@%zu}", backref); \
- } else { \
- vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "[...@%zu]", backref); \
- } \
- ga_concat(gap, &ebuf[0]); \
- return OK; \
- } while (0)
+ } \
+ if (conv_type == kMPConvDict) { \
+ vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "{...@%zu}", backref); \
+ } else { \
+ vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "[...@%zu]", backref); \
+ } \
+ ga_concat(gap, &ebuf[0]); \
+ return OK; \
+ } while (0)
#define TYPVAL_ENCODE_SCOPE
#define TYPVAL_ENCODE_NAME echo
@@ -532,56 +525,56 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
#undef TYPVAL_ENCODE_CONV_RECURSE
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
- do { \
- if (!did_echo_string_emsg) { \
- /* Only give this message once for a recursive call to avoid */ \
- /* flooding the user with errors. */ \
- did_echo_string_emsg = true; \
- EMSG(_("E724: unable to correctly dump variable " \
- "with self-referencing container")); \
- } \
- } while (0)
+ do { \
+ if (!did_echo_string_emsg) { \
+ /* Only give this message once for a recursive call to avoid */ \
+ /* flooding the user with errors. */ \
+ did_echo_string_emsg = true; \
+ EMSG(_("E724: unable to correctly dump variable " \
+ "with self-referencing container")); \
+ } \
+ } while (0)
#undef TYPVAL_ENCODE_ALLOW_SPECIALS
#define TYPVAL_ENCODE_ALLOW_SPECIALS true
#undef TYPVAL_ENCODE_CONV_NIL
#define TYPVAL_ENCODE_CONV_NIL(tv) \
- ga_concat(gap, "null")
+ ga_concat(gap, "null")
#undef TYPVAL_ENCODE_CONV_BOOL
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
- ga_concat(gap, ((num)? "true": "false"))
+ ga_concat(gap, ((num)? "true": "false"))
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num) \
- do { \
- char numbuf[NUMBUFLEN]; \
- vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%" PRIu64, (num)); \
- ga_concat(gap, numbuf); \
- } while (0)
+ do { \
+ char numbuf[NUMBUFLEN]; \
+ vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%" PRIu64, (num)); \
+ ga_concat(gap, numbuf); \
+ } while (0)
#undef TYPVAL_ENCODE_CONV_FLOAT
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
- do { \
- const float_T flt_ = (flt); \
- switch (xfpclassify(flt_)) { \
- case FP_NAN: { \
- EMSG(_("E474: Unable to represent NaN value in JSON")); \
- return FAIL; \
- } \
- case FP_INFINITE: { \
- EMSG(_("E474: Unable to represent infinity in JSON")); \
- return FAIL; \
- } \
- default: { \
- char numbuf[NUMBUFLEN]; \
- vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \
- ga_concat(gap, (char_u *) numbuf); \
- break; \
- } \
- } \
- } while (0)
+ do { \
+ const float_T flt_ = (flt); \
+ switch (xfpclassify(flt_)) { \
+ case FP_NAN: { \
+ EMSG(_("E474: Unable to represent NaN value in JSON")); \
+ return FAIL; \
+ } \
+ case FP_INFINITE: { \
+ EMSG(_("E474: Unable to represent infinity in JSON")); \
+ return FAIL; \
+ } \
+ default: { \
+ char numbuf[NUMBUFLEN]; \
+ vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \
+ ga_concat(gap, (char_u *)numbuf); \
+ break; \
+ } \
+ } \
+ } while (0)
/// Escape sequences used in JSON
static const char escapes[][3] = {
@@ -603,8 +596,7 @@ static const char xdigits[] = "0123456789ABCDEF";
/// @param[in] len Converted string length.
///
/// @return OK in case of success, FAIL otherwise.
-static inline int convert_to_json_string(garray_T *const gap,
- const char *const buf,
+static inline int convert_to_json_string(garray_T *const gap, const char *const buf,
const size_t len)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_ALWAYS_INLINE
{
@@ -622,49 +614,47 @@ static inline int convert_to_json_string(garray_T *const gap,
// This is done to make resulting values displayable on screen also not from
// Neovim.
#define ENCODE_RAW(ch) \
- (ch >= 0x20 && utf_printable(ch))
+ (ch >= 0x20 && utf_printable(ch))
for (size_t i = 0; i < utf_len;) {
const int ch = utf_ptr2char(utf_buf + i);
const size_t shift = (ch == 0? 1: utf_ptr2len(utf_buf + i));
assert(shift > 0);
i += shift;
switch (ch) {
- case BS:
- case TAB:
- case NL:
- case FF:
- case CAR:
- case '"':
- case '\\': {
- str_len += 2;
- break;
- }
- default: {
- if (ch > 0x7F && shift == 1) {
- emsgf(_("E474: String \"%.*s\" contains byte that does not start "
- "any UTF-8 character"),
- (int)(utf_len - (i - shift)), utf_buf + i - shift);
- xfree(tofree);
- return FAIL;
- } else if ((SURROGATE_HI_START <= ch && ch <= SURROGATE_HI_END)
- || (SURROGATE_LO_START <= ch && ch <= SURROGATE_LO_END)) {
- emsgf(_("E474: UTF-8 string contains code point which belongs "
- "to a surrogate pair: %.*s"),
- (int)(utf_len - (i - shift)), utf_buf + i - shift);
- xfree(tofree);
- return FAIL;
- } else if (ENCODE_RAW(ch)) {
- str_len += shift;
- } else {
- str_len += ((sizeof("\\u1234") - 1)
- * (size_t) (1 + (ch >= SURROGATE_FIRST_CHAR)));
- }
- break;
+ case BS:
+ case TAB:
+ case NL:
+ case FF:
+ case CAR:
+ case '"':
+ case '\\':
+ str_len += 2;
+ break;
+ default:
+ if (ch > 0x7F && shift == 1) {
+ emsgf(_("E474: String \"%.*s\" contains byte that does not start "
+ "any UTF-8 character"),
+ (int)(utf_len - (i - shift)), utf_buf + i - shift);
+ xfree(tofree);
+ return FAIL;
+ } else if ((SURROGATE_HI_START <= ch && ch <= SURROGATE_HI_END)
+ || (SURROGATE_LO_START <= ch && ch <= SURROGATE_LO_END)) {
+ emsgf(_("E474: UTF-8 string contains code point which belongs "
+ "to a surrogate pair: %.*s"),
+ (int)(utf_len - (i - shift)), utf_buf + i - shift);
+ xfree(tofree);
+ return FAIL;
+ } else if (ENCODE_RAW(ch)) {
+ str_len += shift;
+ } else {
+ str_len += ((sizeof("\\u1234") - 1)
+ * (size_t)(1 + (ch >= SURROGATE_FIRST_CHAR)));
}
+ break;
}
}
ga_append(gap, '"');
- ga_grow(gap, (int) str_len);
+ ga_grow(gap, (int)str_len);
for (size_t i = 0; i < utf_len;) {
const int ch = utf_ptr2char(utf_buf + i);
const size_t shift = (ch == 0? 1: utf_char2len(ch));
@@ -672,46 +662,44 @@ static inline int convert_to_json_string(garray_T *const gap,
// Is false on invalid unicode, but this should already be handled.
assert(ch == 0 || shift == utf_ptr2len(utf_buf + i));
switch (ch) {
- case BS:
- case TAB:
- case NL:
- case FF:
- case CAR:
- case '"':
- case '\\': {
- ga_concat_len(gap, escapes[ch], 2);
- break;
- }
- default: {
- if (ENCODE_RAW(ch)) {
- ga_concat_len(gap, utf_buf + i, shift);
- } else if (ch < SURROGATE_FIRST_CHAR) {
- ga_concat_len(gap, ((const char[]) {
- '\\', 'u',
- xdigits[(ch >> (4 * 3)) & 0xF],
- xdigits[(ch >> (4 * 2)) & 0xF],
- xdigits[(ch >> (4 * 1)) & 0xF],
- xdigits[(ch >> (4 * 0)) & 0xF],
- }), sizeof("\\u1234") - 1);
- } else {
- const int tmp = ch - SURROGATE_FIRST_CHAR;
- const int hi = SURROGATE_HI_START + ((tmp >> 10) & ((1 << 10) - 1));
- const int lo = SURROGATE_LO_END + ((tmp >> 0) & ((1 << 10) - 1));
- ga_concat_len(gap, ((const char[]) {
- '\\', 'u',
- xdigits[(hi >> (4 * 3)) & 0xF],
- xdigits[(hi >> (4 * 2)) & 0xF],
- xdigits[(hi >> (4 * 1)) & 0xF],
- xdigits[(hi >> (4 * 0)) & 0xF],
- '\\', 'u',
- xdigits[(lo >> (4 * 3)) & 0xF],
- xdigits[(lo >> (4 * 2)) & 0xF],
- xdigits[(lo >> (4 * 1)) & 0xF],
- xdigits[(lo >> (4 * 0)) & 0xF],
- }), (sizeof("\\u1234") - 1) * 2);
- }
- break;
+ case BS:
+ case TAB:
+ case NL:
+ case FF:
+ case CAR:
+ case '"':
+ case '\\':
+ ga_concat_len(gap, escapes[ch], 2);
+ break;
+ default:
+ if (ENCODE_RAW(ch)) {
+ ga_concat_len(gap, utf_buf + i, shift);
+ } else if (ch < SURROGATE_FIRST_CHAR) {
+ ga_concat_len(gap, ((const char[]) {
+ '\\', 'u',
+ xdigits[(ch >> (4 * 3)) & 0xF],
+ xdigits[(ch >> (4 * 2)) & 0xF],
+ xdigits[(ch >> (4 * 1)) & 0xF],
+ xdigits[(ch >> (4 * 0)) & 0xF],
+ }), sizeof("\\u1234") - 1);
+ } else {
+ const int tmp = ch - SURROGATE_FIRST_CHAR;
+ const int hi = SURROGATE_HI_START + ((tmp >> 10) & ((1 << 10) - 1));
+ const int lo = SURROGATE_LO_END + ((tmp >> 0) & ((1 << 10) - 1));
+ ga_concat_len(gap, ((const char[]) {
+ '\\', 'u',
+ xdigits[(hi >> (4 * 3)) & 0xF],
+ xdigits[(hi >> (4 * 2)) & 0xF],
+ xdigits[(hi >> (4 * 1)) & 0xF],
+ xdigits[(hi >> (4 * 0)) & 0xF],
+ '\\', 'u',
+ xdigits[(lo >> (4 * 3)) & 0xF],
+ xdigits[(lo >> (4 * 2)) & 0xF],
+ xdigits[(lo >> (4 * 1)) & 0xF],
+ xdigits[(lo >> (4 * 0)) & 0xF],
+ }), (sizeof("\\u1234") - 1) * 2);
}
+ break;
}
i += shift;
}
@@ -723,47 +711,47 @@ static inline int convert_to_json_string(garray_T *const gap,
#undef TYPVAL_ENCODE_CONV_STRING
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
- do { \
- if (convert_to_json_string(gap, (const char *) (buf), (len)) != OK) { \
- return FAIL; \
- } \
- } while (0)
+ do { \
+ if (convert_to_json_string(gap, (const char *)(buf), (len)) != OK) { \
+ return FAIL; \
+ } \
+ } while (0)
#undef TYPVAL_ENCODE_CONV_EXT_STRING
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) \
- do { \
- xfree(buf); \
- EMSG(_("E474: Unable to convert EXT string to JSON")); \
- return FAIL; \
- } while (0)
+ do { \
+ xfree(buf); \
+ EMSG(_("E474: Unable to convert EXT string to JSON")); \
+ return FAIL; \
+ } while (0)
#undef TYPVAL_ENCODE_CONV_BLOB
#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \
- do { \
- const blob_T *const blob_ = (blob); \
- const int len_ = (len); \
- if (len_ == 0) { \
- ga_concat(gap, "[]"); \
- } else { \
- ga_append(gap, '['); \
- char numbuf[NUMBUFLEN]; \
- for (int i_ = 0; i_ < len_; i_++) { \
- if (i_ > 0) { \
- ga_concat(gap, ", "); \
- } \
- vim_snprintf((char *)numbuf, ARRAY_SIZE(numbuf), "%d", \
- (int)tv_blob_get(blob_, i_)); \
- ga_concat(gap, numbuf); \
+ do { \
+ const blob_T *const blob_ = (blob); \
+ const int len_ = (len); \
+ if (len_ == 0) { \
+ ga_concat(gap, "[]"); \
+ } else { \
+ ga_append(gap, '['); \
+ char numbuf[NUMBUFLEN]; \
+ for (int i_ = 0; i_ < len_; i_++) { \
+ if (i_ > 0) { \
+ ga_concat(gap, ", "); \
} \
- ga_append(gap, ']'); \
+ vim_snprintf((char *)numbuf, ARRAY_SIZE(numbuf), "%d", \
+ (int)tv_blob_get(blob_, i_)); \
+ ga_concat(gap, numbuf); \
} \
- } while (0)
+ ga_append(gap, ']'); \
+ } \
+ } while (0)
#undef TYPVAL_ENCODE_CONV_FUNC_START
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
- return conv_error(_("E474: Error while dumping %s, %s: " \
- "attempt to dump function reference"), \
- mpstack, objname)
+ return conv_error(_("E474: Error while dumping %s, %s: " \
+ "attempt to dump function reference"), \
+ mpstack, objname)
/// Check whether given key can be used in json_encode()
///
@@ -804,12 +792,12 @@ bool encode_check_json_key(const typval_T *const tv)
#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, key) \
- do { \
- if (!encode_check_json_key(&key)) { \
- EMSG(_("E474: Invalid key in special dictionary")); \
- goto label; \
- } \
- } while (0)
+ do { \
+ if (!encode_check_json_key(&key)) { \
+ EMSG(_("E474: Invalid key in special dictionary")); \
+ goto label; \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_SCOPE static
#define TYPVAL_ENCODE_NAME json
@@ -867,10 +855,10 @@ char *encode_tv2string(typval_T *tv, size_t *len)
assert(evs_ret == OK);
did_echo_string_emsg = false;
if (len != NULL) {
- *len = (size_t) ga.ga_len;
+ *len = (size_t)ga.ga_len;
}
ga_append(&ga, '\0');
- return (char *) ga.ga_data;
+ return (char *)ga.ga_data;
}
/// Return a string with the string representation of a variable.
@@ -895,10 +883,10 @@ char *encode_tv2echo(typval_T *tv, size_t *len)
assert(eve_ret == OK);
}
if (len != NULL) {
- *len = (size_t) ga.ga_len;
+ *len = (size_t)ga.ga_len;
}
ga_append(&ga, '\0');
- return (char *) ga.ga_data;
+ return (char *)ga.ga_data;
}
/// Return a string with the string representation of a variable.
@@ -927,90 +915,90 @@ char *encode_tv2json(typval_T *tv, size_t *len)
}
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
- do { \
- if (buf == NULL) { \
- msgpack_pack_bin(packer, 0); \
- } else { \
- const size_t len_ = (len); \
- msgpack_pack_bin(packer, len_); \
- msgpack_pack_bin_body(packer, buf, len_); \
- } \
- } while (0)
+ do { \
+ if (buf == NULL) { \
+ msgpack_pack_bin(packer, 0); \
+ } else { \
+ const size_t len_ = (len); \
+ msgpack_pack_bin(packer, len_); \
+ msgpack_pack_bin_body(packer, buf, len_); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len) \
- do { \
- if (buf == NULL) { \
- msgpack_pack_str(packer, 0); \
- } else { \
- const size_t len_ = (len); \
- msgpack_pack_str(packer, len_); \
- msgpack_pack_str_body(packer, buf, len_); \
- } \
- } while (0)
+ do { \
+ if (buf == NULL) { \
+ msgpack_pack_str(packer, 0); \
+ } else { \
+ const size_t len_ = (len); \
+ msgpack_pack_str(packer, len_); \
+ msgpack_pack_str_body(packer, buf, len_); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) \
- do { \
- if (buf == NULL) { \
- msgpack_pack_ext(packer, 0, (int8_t) type); \
- } else { \
- const size_t len_ = (len); \
- msgpack_pack_ext(packer, len_, (int8_t) type); \
- msgpack_pack_ext_body(packer, buf, len_); \
- } \
- } while (0)
+ do { \
+ if (buf == NULL) { \
+ msgpack_pack_ext(packer, 0, (int8_t)type); \
+ } else { \
+ const size_t len_ = (len); \
+ msgpack_pack_ext(packer, len_, (int8_t)type); \
+ msgpack_pack_ext_body(packer, buf, len_); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \
- do { \
- const size_t len_ = (size_t)(len); \
- msgpack_pack_bin(packer, len_); \
- if (len_ > 0) { \
- msgpack_pack_bin_body(packer, (blob)->bv_ga.ga_data, len_); \
- } \
- } while (0)
+ do { \
+ const size_t len_ = (size_t)(len); \
+ msgpack_pack_bin(packer, len_); \
+ if (len_ > 0) { \
+ msgpack_pack_bin_body(packer, (blob)->bv_ga.ga_data, len_); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
- msgpack_pack_int64(packer, (int64_t)(num))
+ msgpack_pack_int64(packer, (int64_t)(num))
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
- msgpack_pack_double(packer, (double)(flt))
+ msgpack_pack_double(packer, (double)(flt))
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
- return conv_error(_("E5004: Error while dumping %s, %s: " \
- "attempt to dump function reference"), \
- mpstack, objname)
+ return conv_error(_("E5004: Error while dumping %s, %s: " \
+ "attempt to dump function reference"), \
+ mpstack, objname)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_END(tv)
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
- msgpack_pack_array(packer, 0)
+ msgpack_pack_array(packer, 0)
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
- msgpack_pack_array(packer, (size_t)(len))
+ msgpack_pack_array(packer, (size_t)(len))
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
- msgpack_pack_map(packer, 0)
+ msgpack_pack_map(packer, 0)
#define TYPVAL_ENCODE_CONV_NIL(tv) \
- msgpack_pack_nil(packer)
+ msgpack_pack_nil(packer)
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
- do { \
- if (num) { \
- msgpack_pack_true(packer); \
- } else { \
- msgpack_pack_false(packer); \
- } \
- } while (0)
+ do { \
+ if (num) { \
+ msgpack_pack_true(packer); \
+ } else { \
+ msgpack_pack_false(packer); \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num) \
- msgpack_pack_uint64(packer, (num))
+ msgpack_pack_uint64(packer, (num))
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
- msgpack_pack_map(packer, (size_t)(len))
+ msgpack_pack_map(packer, (size_t)(len))
#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv)
@@ -1027,9 +1015,9 @@ char *encode_tv2json(typval_T *tv, size_t *len)
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
- return conv_error(_("E5005: Unable to dump %s: " \
- "container references itself in %s"), \
- mpstack, objname)
+ return conv_error(_("E5005: Unable to dump %s: " \
+ "container references itself in %s"), \
+ mpstack, objname)
#define TYPVAL_ENCODE_ALLOW_SPECIALS true
diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c
index 5ced2a0535..8eceda84cf 100644
--- a/src/nvim/eval/executor.c
+++ b/src/nvim/eval/executor.c
@@ -1,12 +1,12 @@
// 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/eval/typval.h"
-#include "nvim/eval/executor.h"
#include "nvim/eval.h"
+#include "nvim/eval/executor.h"
+#include "nvim/eval/typval.h"
+#include "nvim/globals.h"
#include "nvim/message.h"
#include "nvim/vim.h"
-#include "nvim/globals.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/executor.c.generated.h"
@@ -23,117 +23,124 @@ char *e_listidx = N_("E684: list index out of range: %" PRId64);
/// @param[in] op Used operator.
///
/// @return OK or FAIL.
-int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
- const char *const op)
+int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2, const char *const op)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NO_SANITIZE_UNDEFINED
{
// Can't do anything with a Funcref, a Dict or special value on the right.
if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT
&& tv2->v_type != VAR_BOOL && tv2->v_type != VAR_SPECIAL) {
switch (tv1->v_type) {
- case VAR_DICT:
- case VAR_FUNC:
- case VAR_PARTIAL:
- case VAR_BOOL:
- case VAR_SPECIAL: {
+ case VAR_DICT:
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ break;
+ case VAR_BLOB:
+ if (*op != '+' || tv2->v_type != VAR_BLOB) {
break;
}
- case VAR_BLOB: {
- if (*op != '+' || tv2->v_type != VAR_BLOB) {
- break;
- }
- // Blob += Blob
- if (tv1->vval.v_blob != NULL && tv2->vval.v_blob != NULL) {
- blob_T *const b1 = tv1->vval.v_blob;
- blob_T *const b2 = tv2->vval.v_blob;
- for (int i = 0; i < tv_blob_len(b2); i++) {
- ga_append(&b1->bv_ga, (char)tv_blob_get(b2, i));
- }
- }
- return OK;
- }
- case VAR_LIST: {
- if (*op != '+' || tv2->v_type != VAR_LIST) {
- break;
- }
- // List += List
- if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) {
- tv_list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
+ // Blob += Blob
+ if (tv1->vval.v_blob != NULL && tv2->vval.v_blob != NULL) {
+ blob_T *const b1 = tv1->vval.v_blob;
+ blob_T *const b2 = tv2->vval.v_blob;
+ for (int i = 0; i < tv_blob_len(b2); i++) {
+ ga_append(&b1->bv_ga, (char)tv_blob_get(b2, i));
}
- return OK;
}
- case VAR_NUMBER:
- case VAR_STRING: {
- if (tv2->v_type == VAR_LIST) {
- break;
- }
- if (vim_strchr((char_u *)"+-*/%", *op) != NULL) {
- // nr += nr or nr -= nr, nr *= nr, nr /= nr, nr %= nr
- varnumber_T n = tv_get_number(tv1);
- if (tv2->v_type == VAR_FLOAT) {
- float_T f = (float_T)n;
+ return OK;
+ case VAR_LIST:
+ if (*op != '+' || tv2->v_type != VAR_LIST) {
+ break;
+ }
+ // List += List
+ if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) {
+ tv_list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
+ }
+ return OK;
+ case VAR_NUMBER:
+ case VAR_STRING:
+ if (tv2->v_type == VAR_LIST) {
+ break;
+ }
+ if (vim_strchr((char_u *)"+-*/%", *op) != NULL) {
+ // nr += nr or nr -= nr, nr *= nr, nr /= nr, nr %= nr
+ varnumber_T n = tv_get_number(tv1);
+ if (tv2->v_type == VAR_FLOAT) {
+ float_T f = (float_T)n;
- if (*op == '%') {
- break;
- }
- switch (*op) {
- case '+': f += tv2->vval.v_float; break;
- case '-': f -= tv2->vval.v_float; break;
- case '*': f *= tv2->vval.v_float; break;
- case '/': f /= tv2->vval.v_float; break;
- }
- tv_clear(tv1);
- tv1->v_type = VAR_FLOAT;
- tv1->vval.v_float = f;
- } else {
- switch (*op) {
- case '+': n += tv_get_number(tv2); break;
- case '-': n -= tv_get_number(tv2); break;
- case '*': n *= tv_get_number(tv2); break;
- case '/': n = num_divide(n, tv_get_number(tv2)); break;
- case '%': n = num_modulus(n, tv_get_number(tv2)); break;
- }
- tv_clear(tv1);
- tv1->v_type = VAR_NUMBER;
- tv1->vval.v_number = n;
+ if (*op == '%') {
+ break;
+ }
+ switch (*op) {
+ case '+':
+ f += tv2->vval.v_float; break;
+ case '-':
+ f -= tv2->vval.v_float; break;
+ case '*':
+ f *= tv2->vval.v_float; break;
+ case '/':
+ f /= tv2->vval.v_float; break;
}
+ tv_clear(tv1);
+ tv1->v_type = VAR_FLOAT;
+ tv1->vval.v_float = f;
} else {
- // str .= str
- if (tv2->v_type == VAR_FLOAT) {
- break;
+ switch (*op) {
+ case '+':
+ n += tv_get_number(tv2); break;
+ case '-':
+ n -= tv_get_number(tv2); break;
+ case '*':
+ n *= tv_get_number(tv2); break;
+ case '/':
+ n = num_divide(n, tv_get_number(tv2)); break;
+ case '%':
+ n = num_modulus(n, tv_get_number(tv2)); break;
}
- const char *tvs = tv_get_string(tv1);
- char numbuf[NUMBUFLEN];
- char *const s = (char *)concat_str(
- (const char_u *)tvs, (const char_u *)tv_get_string_buf(tv2,
- numbuf));
tv_clear(tv1);
- tv1->v_type = VAR_STRING;
- tv1->vval.v_string = (char_u *)s;
+ tv1->v_type = VAR_NUMBER;
+ tv1->vval.v_number = n;
}
- return OK;
- }
- case VAR_FLOAT: {
- if (*op == '%' || *op == '.'
- || (tv2->v_type != VAR_FLOAT
- && tv2->v_type != VAR_NUMBER
- && tv2->v_type != VAR_STRING)) {
+ } else {
+ // str .= str
+ if (tv2->v_type == VAR_FLOAT) {
break;
}
- const float_T f = (tv2->v_type == VAR_FLOAT
+ const char *tvs = tv_get_string(tv1);
+ char numbuf[NUMBUFLEN];
+ char *const s =
+ (char *)concat_str((const char_u *)tvs, (const char_u *)tv_get_string_buf(tv2,
+ numbuf));
+ tv_clear(tv1);
+ tv1->v_type = VAR_STRING;
+ tv1->vval.v_string = (char_u *)s;
+ }
+ return OK;
+ case VAR_FLOAT: {
+ if (*op == '%' || *op == '.'
+ || (tv2->v_type != VAR_FLOAT
+ && tv2->v_type != VAR_NUMBER
+ && tv2->v_type != VAR_STRING)) {
+ break;
+ }
+ const float_T f = (tv2->v_type == VAR_FLOAT
? tv2->vval.v_float
: (float_T)tv_get_number(tv2));
- switch (*op) {
- case '+': tv1->vval.v_float += f; break;
- case '-': tv1->vval.v_float -= f; break;
- case '*': tv1->vval.v_float *= f; break;
- case '/': tv1->vval.v_float /= f; break;
- }
- return OK;
- }
- case VAR_UNKNOWN: {
- abort();
+ switch (*op) {
+ case '+':
+ tv1->vval.v_float += f; break;
+ case '-':
+ tv1->vval.v_float -= f; break;
+ case '*':
+ tv1->vval.v_float *= f; break;
+ case '/':
+ tv1->vval.v_float /= f; break;
}
+ return OK;
+ }
+ case VAR_UNKNOWN:
+ abort();
}
}
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 821a2c8e8e..35ebd0f3f8 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -115,8 +115,9 @@ char_u *get_function_name(expand_T *xp, int idx)
static int intidx = -1;
char_u *name;
- if (idx == 0)
+ if (idx == 0) {
intidx = -1;
+ }
if (intidx < 0) {
name = get_user_func_name(xp, idx);
if (name != NULL) {
@@ -155,12 +156,14 @@ char_u *get_expr_name(expand_T *xp, int idx)
static int intidx = -1;
char_u *name;
- if (idx == 0)
+ if (idx == 0) {
intidx = -1;
+ }
if (intidx < 0) {
name = get_function_name(xp, idx);
- if (name != NULL)
+ if (name != NULL) {
return name;
+ }
}
return get_user_var_name(xp, ++intidx);
}
@@ -177,8 +180,8 @@ const VimLFuncDef *find_internal_func(const char *const name)
return find_internal_func_gperf(name, len);
}
-int call_internal_func(const char_u *const fname, const int argcount,
- typval_T *const argvars, typval_T *const rettv)
+int call_internal_func(const char_u *const fname, const int argcount, typval_T *const argvars,
+ typval_T *const rettv)
FUNC_ATTR_NONNULL_ALL
{
const VimLFuncDef *const fdef = find_internal_func((const char *)fname);
@@ -195,9 +198,8 @@ int call_internal_func(const char_u *const fname, const int argcount,
}
/// Invoke a method for base->method().
-int call_internal_method(const char_u *const fname, const int argcount,
- typval_T *const argvars, typval_T *const rettv,
- typval_T *const basetv)
+int call_internal_method(const char_u *const fname, const int argcount, typval_T *const argvars,
+ typval_T *const rettv, typval_T *const basetv)
FUNC_ATTR_NONNULL_ALL
{
const VimLFuncDef *const fdef = find_internal_func((const char *)fname);
@@ -213,7 +215,7 @@ int call_internal_method(const char_u *const fname, const int argcount,
typval_T argv[MAX_FUNC_ARGS + 1];
const ptrdiff_t base_index
- = fdef->base_arg == BASE_LAST ? argcount : fdef->base_arg - 1;
+ = fdef->base_arg == BASE_LAST ? argcount : fdef->base_arg - 1;
memcpy(argv, argvars, base_index * sizeof(typval_T));
argv[base_index] = *basetv;
memcpy(argv + base_index + 1, argvars + base_index,
@@ -444,8 +446,7 @@ static void f_argv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string = NULL;
int idx = tv_get_number_chk(&argvars[0], NULL);
if (arglist != NULL && idx >= 0 && idx < argcount) {
- rettv->vval.v_string = (char_u *)xstrdup(
- (const char *)alist_name(&arglist[idx]));
+ rettv->vval.v_string = (char_u *)xstrdup((const char *)alist_name(&arglist[idx]));
} else if (idx == -1) {
get_arglist_as_rettv(arglist, argcount, rettv);
}
@@ -487,13 +488,13 @@ static void f_assert_notequal(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// "assert_report(msg)
static void f_assert_report(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- garray_T ga;
+ garray_T ga;
- prepare_assert_error(&ga);
- ga_concat(&ga, (const char_u *)tv_get_string(&argvars[0]));
- assert_error(&ga);
- ga_clear(&ga);
- rettv->vval.v_number = 1;
+ prepare_assert_error(&ga);
+ ga_concat(&ga, (const char_u *)tv_get_string(&argvars[0]));
+ assert_error(&ga);
+ ga_clear(&ga);
+ rettv->vval.v_number = 1;
}
/// "assert_exception(string[, msg])" function
@@ -577,11 +578,11 @@ static void f_browsedir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static buf_T *find_buffer(typval_T *avar)
{
- buf_T *buf = NULL;
+ buf_T *buf = NULL;
- if (avar->v_type == VAR_NUMBER)
+ if (avar->v_type == VAR_NUMBER) {
buf = buflist_findnr((int)avar->vval.v_number);
- else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) {
+ } else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) {
buf = buflist_findname_exp(avar->vval.v_string);
if (buf == NULL) {
/* No full path name match, try a match with a URL or a "nofile"
@@ -622,7 +623,7 @@ static void f_bufexists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_buflisted(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
+ buf_T *buf;
buf = find_buffer(&argvars[0]);
rettv->vval.v_number = (buf != NULL && buf->b_p_bl);
@@ -648,7 +649,7 @@ static void f_bufload(typval_T *argvars, typval_T *unused, FunPtr fptr)
*/
static void f_bufloaded(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
+ buf_T *buf;
buf = find_buffer(&argvars[0]);
rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL);
@@ -750,19 +751,23 @@ static void f_bufwinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
buf_T *tv_get_buf(typval_T *tv, int curtab_only)
{
- char_u *name = tv->vval.v_string;
+ char_u *name = tv->vval.v_string;
int save_magic;
- char_u *save_cpo;
- buf_T *buf;
+ char_u *save_cpo;
+ buf_T *buf;
- if (tv->v_type == VAR_NUMBER)
+ if (tv->v_type == VAR_NUMBER) {
return buflist_findnr((int)tv->vval.v_number);
- if (tv->v_type != VAR_STRING)
+ }
+ if (tv->v_type != VAR_STRING) {
return NULL;
- if (name == NULL || *name == NUL)
+ }
+ if (name == NULL || *name == NUL) {
return curbuf;
- if (name[0] == '$' && name[1] == NUL)
+ }
+ if (name[0] == '$' && name[1] == NUL) {
return lastbuf;
+ }
// Ignore 'magic' and 'cpoptions' here to make scripts portable
save_magic = p_magic;
@@ -876,9 +881,9 @@ static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
bool owned = false;
- char_u *func;
- partial_T *partial = NULL;
- dict_T *selfdict = NULL;
+ char_u *func;
+ partial_T *partial = NULL;
+ dict_T *selfdict = NULL;
if (argvars[0].v_type == VAR_FUNC) {
func = argvars[0].vval.v_string;
} else if (argvars[0].v_type == VAR_PARTIAL) {
@@ -928,7 +933,7 @@ static void f_chanclose(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (argvars[0].v_type != VAR_NUMBER || (argvars[1].v_type != VAR_STRING
- && argvars[1].v_type != VAR_UNKNOWN)) {
+ && argvars[1].v_type != VAR_UNKNOWN)) {
EMSG(_(e_invarg));
return;
}
@@ -1008,8 +1013,7 @@ static void f_char2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
- rettv->vval.v_number = utf_ptr2char(
- (const char_u *)tv_get_string(&argvars[0]));
+ rettv->vval.v_number = utf_ptr2char((const char_u *)tv_get_string(&argvars[0]));
}
// "charidx()" function
@@ -1072,8 +1076,9 @@ static void f_cindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
curwin->w_cursor.lnum = lnum;
rettv->vval.v_number = get_c_indent();
curwin->w_cursor = pos;
- } else
+ } else {
rettv->vval.v_number = -1;
+ }
}
static win_T * get_optional_window(typval_T *argvars, int idx)
@@ -1108,7 +1113,7 @@ static void f_clearmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_col(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
colnr_T col = 0;
- pos_T *fp;
+ pos_T *fp;
int fnum = curbuf->b_fnum;
fp = var2fpos(&argvars[0], FALSE, &fnum);
@@ -1125,7 +1130,7 @@ static void f_col(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// col(".") when the cursor is on the NUL at the end of the line
// because of "coladd" can be seen as an extra column.
if (virtual_active() && fp == &curwin->w_cursor) {
- char_u *p = get_cursor_pos_ptr();
+ char_u *p = get_cursor_pos_ptr();
if (curwin->w_cursor.coladd
>= (colnr_T)win_chartabsize(curwin, p,
@@ -1133,8 +1138,9 @@ static void f_col(typval_T *argvars, typval_T *rettv, FunPtr fptr)
- curwin->w_cursor.coladd))) {
int l;
- if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL)
+ if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) {
col += l;
+ }
}
}
}
@@ -1240,11 +1246,16 @@ static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
error = true;
} else {
switch (TOUPPER_ASC(*typestr)) {
- case 'E': type = VIM_ERROR; break;
- case 'Q': type = VIM_QUESTION; break;
- case 'I': type = VIM_INFO; break;
- case 'W': type = VIM_WARNING; break;
- case 'G': type = VIM_GENERIC; break;
+ case 'E':
+ type = VIM_ERROR; break;
+ case 'Q':
+ type = VIM_QUESTION; break;
+ case 'I':
+ type = VIM_INFO; break;
+ case 'W':
+ type = VIM_WARNING; break;
+ case 'G':
+ type = VIM_GENERIC; break;
}
}
}
@@ -1256,8 +1267,8 @@ static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (!error) {
- rettv->vval.v_number = do_dialog(
- type, NULL, (char_u *)message, (char_u *)buttons, def, NULL, false);
+ rettv->vval.v_number = do_dialog(type, NULL, (char_u *)message, (char_u *)buttons, def, NULL,
+ false);
}
}
@@ -1307,8 +1318,8 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
} else if (argvars[0].v_type == VAR_LIST) {
- listitem_T *li;
- list_T *l;
+ listitem_T *li;
+ list_T *l;
long idx;
if ((l = argvars[0].vval.v_list) != NULL) {
@@ -1323,8 +1334,9 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
}
- if (error)
+ if (error) {
li = NULL;
+ }
}
for (; li != NULL; li = TV_LIST_ITEM_NEXT(l, li)) {
@@ -1335,8 +1347,8 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
} else if (argvars[0].v_type == VAR_DICT) {
int todo;
- dict_T *d;
- hashitem_T *hi;
+ dict_T *d;
+ hashitem_T *hi;
if ((d = argvars[0].vval.v_dict) != NULL) {
if (argvars[2].v_type != VAR_UNKNOWN) {
@@ -1855,57 +1867,45 @@ static void f_empty(typval_T *argvars, typval_T *rettv, FunPtr fptr)
bool n = true;
switch (argvars[0].v_type) {
- case VAR_STRING:
- case VAR_FUNC: {
- n = argvars[0].vval.v_string == NULL
- || *argvars[0].vval.v_string == NUL;
- break;
- }
- case VAR_PARTIAL: {
+ case VAR_STRING:
+ case VAR_FUNC:
+ n = argvars[0].vval.v_string == NULL
+ || *argvars[0].vval.v_string == NUL;
+ break;
+ case VAR_PARTIAL:
+ n = false;
+ break;
+ case VAR_NUMBER:
+ n = argvars[0].vval.v_number == 0;
+ break;
+ case VAR_FLOAT:
+ n = argvars[0].vval.v_float == 0.0;
+ break;
+ case VAR_LIST:
+ n = (tv_list_len(argvars[0].vval.v_list) == 0);
+ break;
+ case VAR_DICT:
+ n = (tv_dict_len(argvars[0].vval.v_dict) == 0);
+ break;
+ case VAR_BOOL:
+ switch (argvars[0].vval.v_bool) {
+ case kBoolVarTrue:
n = false;
break;
- }
- case VAR_NUMBER: {
- n = argvars[0].vval.v_number == 0;
- break;
- }
- case VAR_FLOAT: {
- n = argvars[0].vval.v_float == 0.0;
- break;
- }
- case VAR_LIST: {
- n = (tv_list_len(argvars[0].vval.v_list) == 0);
- break;
- }
- case VAR_DICT: {
- n = (tv_dict_len(argvars[0].vval.v_dict) == 0);
- break;
- }
- case VAR_BOOL: {
- switch (argvars[0].vval.v_bool) {
- case kBoolVarTrue: {
- n = false;
- break;
- }
- case kBoolVarFalse: {
- n = true;
- break;
- }
- }
- break;
- }
- case VAR_SPECIAL: {
- n = argvars[0].vval.v_special == kSpecialVarNull;
- break;
- }
- case VAR_BLOB: {
- n = (tv_blob_len(argvars[0].vval.v_blob) == 0);
- break;
- }
- case VAR_UNKNOWN: {
- internal_error("f_empty(UNKNOWN)");
+ case kBoolVarFalse:
+ n = true;
break;
}
+ break;
+ case VAR_SPECIAL:
+ n = argvars[0].vval.v_special == kSpecialVarNull;
+ break;
+ case VAR_BLOB:
+ n = (tv_blob_len(argvars[0].vval.v_blob) == 0);
+ break;
+ case VAR_UNKNOWN:
+ internal_error("f_empty(UNKNOWN)");
+ break;
}
rettv->vval.v_number = n;
@@ -1965,9 +1965,8 @@ static void f_escape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char buf[NUMBUFLEN];
- rettv->vval.v_string = vim_strsave_escaped(
- (const char_u *)tv_get_string(&argvars[0]),
- (const char_u *)tv_get_string_buf(&argvars[1], buf));
+ rettv->vval.v_string = vim_strsave_escaped((const char_u *)tv_get_string(&argvars[0]),
+ (const char_u *)tv_get_string_buf(&argvars[1], buf));
rettv->v_type = VAR_STRING;
}
@@ -2048,8 +2047,7 @@ static char_u *get_list_line(int c, void *cookie, int indent, bool do_concat)
return (char_u *)(s == NULL ? NULL : xstrdup(s));
}
-static void execute_common(typval_T *argvars, typval_T *rettv, FunPtr fptr,
- int arg_off)
+static void execute_common(typval_T *argvars, typval_T *rettv, FunPtr fptr, int arg_off)
{
const int save_msg_silent = msg_silent;
const int save_emsg_silent = emsg_silent;
@@ -2155,7 +2153,7 @@ static void f_win_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// Update the status line if the cursor moved.
if (win_valid(wp) && !equalpos(curpos, wp->w_cursor)) {
- wp->w_redr_status = true;
+ wp->w_redr_status = true;
}
}
}
@@ -2223,7 +2221,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
size_t len;
- char_u *errormsg;
+ char_u *errormsg;
int options = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND;
expand_T xpc;
bool error = false;
@@ -2522,8 +2520,9 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
if (*fname != NUL && !error) {
do {
- if (rettv->v_type == VAR_STRING || rettv->v_type == VAR_LIST)
+ if (rettv->v_type == VAR_STRING || rettv->v_type == VAR_LIST) {
xfree(fresult);
+ }
fresult = find_file_in_path_option(first ? (char_u *)fname : NULL,
first ? strlen(fname) : 0,
0, first, path,
@@ -2539,8 +2538,9 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
} while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL);
}
- if (rettv->v_type == VAR_STRING)
+ if (rettv->v_type == VAR_STRING) {
rettv->vval.v_string = fresult;
+ }
}
@@ -2607,8 +2607,7 @@ static void f_fmod(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_fnameescape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_string = (char_u *)vim_strsave_fnameescape(
- tv_get_string(&argvars[0]), false);
+ rettv->vval.v_string = (char_u *)vim_strsave_fnameescape(tv_get_string(&argvars[0]), false);
rettv->v_type = VAR_STRING;
}
@@ -2698,12 +2697,12 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T foldstart;
linenr_T foldend;
- char_u *dashes;
+ char_u *dashes;
linenr_T lnum;
- char_u *s;
- char_u *r;
+ char_u *s;
+ char_u *r;
int len;
- char *txt;
+ char *txt;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
@@ -2726,8 +2725,9 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
s = skipwhite(s + 2);
if (*skipwhite(s) == NUL && lnum + 1 < foldend) {
s = skipwhite(ml_get(lnum + 1));
- if (*s == '*')
+ if (*s == '*') {
s = skipwhite(s + 1);
+ }
}
}
unsigned long count = (unsigned long)(foldend - foldstart + 1);
@@ -2750,7 +2750,7 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *text;
+ char_u *text;
char_u buf[FOLD_TEXT_LEN];
static bool entered = false;
@@ -2812,11 +2812,11 @@ static void f_garbagecollect(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- listitem_T *li;
- list_T *l;
- dictitem_T *di;
- dict_T *d;
- typval_T *tv = NULL;
+ listitem_T *li;
+ list_T *l;
+ dictitem_T *di;
+ dict_T *d;
+ typval_T *tv = NULL;
bool what_is_dict = false;
if (argvars[0].v_type == VAR_BLOB) {
@@ -2975,11 +2975,7 @@ static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
* buffer.
* If 'retlist' is TRUE, then the lines are returned as a Vim List.
*/
-static void get_buffer_lines(buf_T *buf,
- linenr_T start,
- linenr_T end,
- int retlist,
- typval_T *rettv)
+static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)
{
rettv->v_type = (retlist ? VAR_LIST : VAR_STRING);
rettv->vval.v_string = NULL;
@@ -3201,7 +3197,7 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
int col = mouse_col;
int grid = mouse_grid;
linenr_T lnum;
- win_T *wp;
+ win_T *wp;
int winnr = 1;
if (row >= 0 && col >= 0) {
@@ -3212,8 +3208,9 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
return;
}
(void)mouse_comp_pos(win, &row, &col, &lnum);
- for (wp = firstwin; wp != win; wp = wp->w_next)
+ for (wp = firstwin; wp != win; wp = wp->w_next) {
++winnr;
+ }
set_vim_var_nr(VV_MOUSE_WIN, winnr);
set_vim_var_nr(VV_MOUSE_WINID, wp->handle);
set_vim_var_nr(VV_MOUSE_LNUM, lnum);
@@ -3312,11 +3309,11 @@ static void f_getcmdwintype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// "getcompletion()" function
static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *pat;
+ char_u *pat;
expand_T xpc;
bool filtered = false;
int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH
- | WILD_NO_BEEP;
+ | WILD_NO_BEEP;
if (argvars[1].v_type != VAR_STRING) {
EMSG2(_(e_invarg2), "type must be a string");
@@ -3410,7 +3407,7 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
char_u *from = NULL; // The original string to copy
tabpage_T *tp = curtab; // The tabpage to look at.
- win_T *win = curwin; // The window to look at.
+ win_T *win = curwin; // The window to look at.
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
@@ -3473,29 +3470,29 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
cwd = xmalloc(MAXPATHL);
switch (scope) {
- case kCdScopeWindow:
- assert(win);
- from = win->w_localdir;
- if (from) {
- break;
- }
- FALLTHROUGH;
- case kCdScopeTab:
- assert(tp);
- from = tp->tp_localdir;
- if (from) {
- break;
- }
- FALLTHROUGH;
- case kCdScopeGlobal:
- if (globaldir) { // `globaldir` is not always set.
- from = globaldir;
- } else if (os_dirname(cwd, MAXPATHL) == FAIL) { // Get the OS CWD.
- from = (char_u *)""; // Return empty string on failure.
- }
+ case kCdScopeWindow:
+ assert(win);
+ from = win->w_localdir;
+ if (from) {
+ break;
+ }
+ FALLTHROUGH;
+ case kCdScopeTab:
+ assert(tp);
+ from = tp->tp_localdir;
+ if (from) {
break;
- case kCdScopeInvalid: // We should never get here
- abort();
+ }
+ FALLTHROUGH;
+ case kCdScopeGlobal:
+ if (globaldir) { // `globaldir` is not always set.
+ from = globaldir;
+ } else if (os_dirname(cwd, MAXPATHL) == FAIL) { // Get the OS CWD.
+ from = (char_u *)""; // Return empty string on failure.
+ }
+ break;
+ case kCdScopeInvalid: // We should never get here
+ abort();
}
if (from) {
@@ -3588,8 +3585,8 @@ static void f_getftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_getftype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *type = NULL;
- char *t;
+ char_u *type = NULL;
+ char *t;
const char *fname = tv_get_string(&argvars[0]);
@@ -3716,7 +3713,7 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (cur->match.regprog == NULL) {
// match added with matchaddpos()
for (i = 0; i < MAXPOSMATCH; i++) {
- llpos_T *llpos;
+ llpos_T *llpos;
char buf[30]; // use 30 to avoid compiler warning
llpos = &cur->pos.pos[i];
@@ -3777,12 +3774,10 @@ static void getpos_both(typval_T *argvars, typval_T *rettv, bool getcurpos)
tv_list_append_number(l, ((fp != NULL)
? (varnumber_T)fp->lnum
: (varnumber_T)0));
- tv_list_append_number(
- l, ((fp != NULL)
+ tv_list_append_number(l, ((fp != NULL)
? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
- : (varnumber_T)0));
- tv_list_append_number(
- l, (fp != NULL) ? (varnumber_T)fp->coladd : (varnumber_T)0);
+ : (varnumber_T)0));
+ tv_list_append_number(l, (fp != NULL) ? (varnumber_T)fp->coladd : (varnumber_T)0);
if (getcurpos) {
const int save_set_curswant = curwin->w_set_curswant;
const colnr_T save_curswant = curwin->w_curswant;
@@ -3987,18 +3982,18 @@ static void f_gettabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// "gettagstack()" function
static void f_gettagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- win_T *wp = curwin; // default is current window
+ win_T *wp = curwin; // default is current window
- tv_dict_alloc_ret(rettv);
+ tv_dict_alloc_ret(rettv);
- if (argvars[0].v_type != VAR_UNKNOWN) {
- wp = find_win_by_nr_or_id(&argvars[0]);
- if (wp == NULL) {
- return;
- }
+ if (argvars[0].v_type != VAR_UNKNOWN) {
+ wp = find_win_by_nr_or_id(&argvars[0]);
+ if (wp == NULL) {
+ return;
}
+ }
- get_tagstack(wp, rettv->vval.v_dict);
+ get_tagstack(wp, rettv->vval.v_dict);
}
/// "getwininfo()" function
@@ -4116,12 +4111,11 @@ static void f_win_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
//
// Move the window wp into a new split of targetwin in a given direction
//
-static void win_move_into_split(win_T *wp, win_T *targetwin,
- int size, int flags)
+static void win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags)
{
int dir;
int height = wp->w_height;
- win_T *oldwin = curwin;
+ win_T *oldwin = curwin;
if (wp == targetwin) {
return;
@@ -4157,8 +4151,8 @@ static void win_move_into_split(win_T *wp, win_T *targetwin,
// "win_splitmove()" function
static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- win_T *wp;
- win_T *targetwin;
+ win_T *wp;
+ win_T *targetwin;
int flags = 0, size = 0;
wp = find_win_by_nr_or_id(&argvars[0]);
@@ -4173,8 +4167,8 @@ static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (argvars[2].v_type != VAR_UNKNOWN) {
- dict_T *d;
- dictitem_T *di;
+ dict_T *d;
+ dictitem_T *di;
if (argvars[2].v_type != VAR_DICT || argvars[2].vval.v_dict == NULL) {
EMSG(_(e_invarg));
@@ -4253,11 +4247,12 @@ static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (!error) {
ExpandInit(&xpc);
xpc.xp_context = EXPAND_FILES;
- if (p_wic)
+ if (p_wic) {
options += WILD_ICASE;
+ }
if (rettv->v_type == VAR_STRING) {
- rettv->vval.v_string = ExpandOne(
- &xpc, (char_u *)tv_get_string(&argvars[0]), NULL, options, WILD_ALL);
+ rettv->vval.v_string = ExpandOne(&xpc, (char_u *)tv_get_string(
+ &argvars[0]), NULL, options, WILD_ALL);
} else {
ExpandOne(&xpc, (char_u *)tv_get_string(&argvars[0]), NULL, options,
WILD_ALL_KEEP);
@@ -4268,8 +4263,9 @@ static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
ExpandCleanup(&xpc);
}
- } else
+ } else {
rettv->vval.v_string = NULL;
+ }
}
/// "globpath()" function
@@ -4529,8 +4525,9 @@ static void f_has_key(typval_T *argvars, typval_T *rettv, FunPtr fptr)
EMSG(_(e_dictreq));
return;
}
- if (argvars[0].vval.v_dict == NULL)
+ if (argvars[0].vval.v_dict == NULL) {
return;
+ }
rettv->vval.v_number = tv_dict_find(argvars[0].vval.v_dict,
tv_get_string(&argvars[1]),
@@ -4561,7 +4558,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
};
tabpage_T *tp = curtab; // The tabpage to look at.
- win_T *win = curwin; // The window to look at.
+ win_T *win = curwin; // The window to look at.
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
@@ -4620,20 +4617,20 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
switch (scope) {
- case kCdScopeWindow:
- assert(win);
- rettv->vval.v_number = win->w_localdir ? 1 : 0;
- break;
- case kCdScopeTab:
- assert(tp);
- rettv->vval.v_number = tp->tp_localdir ? 1 : 0;
- break;
- case kCdScopeGlobal:
- // The global scope never has a local directory
- break;
- case kCdScopeInvalid:
- // We should never get here
- abort();
+ case kCdScopeWindow:
+ assert(win);
+ rettv->vval.v_number = win->w_localdir ? 1 : 0;
+ break;
+ case kCdScopeTab:
+ assert(tp);
+ rettv->vval.v_number = tp->tp_localdir ? 1 : 0;
+ break;
+ case kCdScopeGlobal:
+ // The global scope never has a local directory
+ break;
+ case kCdScopeInvalid:
+ // We should never get here
+ abort();
}
}
@@ -4756,8 +4753,7 @@ static void f_histnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = syn_name2id(
- (const char_u *)tv_get_string(&argvars[0]));
+ rettv->vval.v_number = syn_name2id((const char_u *)tv_get_string(&argvars[0]));
}
/*
@@ -4765,8 +4761,7 @@ static void f_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_hlexists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = highlight_exists(
- (const char_u *)tv_get_string(&argvars[0]));
+ rettv->vval.v_number = highlight_exists((const char_u *)tv_get_string(&argvars[0]));
}
/*
@@ -4793,11 +4788,9 @@ static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
const char *const str = tv_get_string(&argvars[0]);
char buf1[NUMBUFLEN];
- char_u *const from = enc_canonize(enc_skip(
- (char_u *)tv_get_string_buf(&argvars[1], buf1)));
+ char_u *const from = enc_canonize(enc_skip((char_u *)tv_get_string_buf(&argvars[1], buf1)));
char buf2[NUMBUFLEN];
- char_u *const to = enc_canonize(enc_skip(
- (char_u *)tv_get_string_buf(&argvars[2], buf2)));
+ char_u *const to = enc_canonize(enc_skip((char_u *)tv_get_string_buf(&argvars[2], buf2)));
vimconv.vc_type = CONV_NONE;
convert_setup(&vimconv, from, to);
@@ -5062,8 +5055,7 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// "interrupt()" function
-static void f_interrupt(typval_T *argvars FUNC_ATTR_UNUSED,
- typval_T *rettv FUNC_ATTR_UNUSED,
+static void f_interrupt(typval_T *argvars FUNC_ATTR_UNUSED, typval_T *rettv FUNC_ATTR_UNUSED,
FunPtr fptr FUNC_ATTR_UNUSED)
{
got_int = true;
@@ -5091,7 +5083,7 @@ static void f_isdirectory(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
lval_T lv;
- dictitem_T *di;
+ dictitem_T *di;
rettv->vval.v_number = -1;
const char_u *const end = get_lval((char_u *)tv_get_string(&argvars[0]),
@@ -5143,7 +5135,7 @@ static void f_isinf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_isnan(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT
- && xisnan(argvars[0].vval.v_float);
+ && xisnan(argvars[0].vval.v_float);
}
/// "id()" function
@@ -5251,9 +5243,7 @@ static const char *required_env_vars[] = {
NULL
};
-static dict_T *create_environment(const dictitem_T *job_env,
- const bool clear_env,
- const bool pty,
+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();
@@ -5502,7 +5492,7 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
if (argvars[0].v_type != VAR_LIST || (argvars[1].v_type != VAR_NUMBER
- && argvars[1].v_type != VAR_UNKNOWN)) {
+ && argvars[1].v_type != VAR_UNKNOWN)) {
EMSG(_(e_invarg));
return;
}
@@ -5688,33 +5678,27 @@ static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_len(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
switch (argvars[0].v_type) {
- case VAR_STRING:
- case VAR_NUMBER: {
- rettv->vval.v_number = (varnumber_T)strlen(
- tv_get_string(&argvars[0]));
- break;
- }
- case VAR_BLOB: {
- rettv->vval.v_number = tv_blob_len(argvars[0].vval.v_blob);
- break;
- }
- case VAR_LIST: {
- rettv->vval.v_number = tv_list_len(argvars[0].vval.v_list);
- break;
- }
- case VAR_DICT: {
- rettv->vval.v_number = tv_dict_len(argvars[0].vval.v_dict);
- break;
- }
- case VAR_UNKNOWN:
- case VAR_BOOL:
- case VAR_SPECIAL:
- case VAR_FLOAT:
- case VAR_PARTIAL:
- case VAR_FUNC: {
- EMSG(_("E701: Invalid type for len()"));
- break;
- }
+ case VAR_STRING:
+ case VAR_NUMBER:
+ rettv->vval.v_number = (varnumber_T)strlen(tv_get_string(&argvars[0]));
+ break;
+ case VAR_BLOB:
+ rettv->vval.v_number = tv_blob_len(argvars[0].vval.v_blob);
+ break;
+ case VAR_LIST:
+ rettv->vval.v_number = tv_list_len(argvars[0].vval.v_list);
+ break;
+ case VAR_DICT:
+ rettv->vval.v_number = tv_dict_len(argvars[0].vval.v_dict);
+ break;
+ case VAR_UNKNOWN:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ case VAR_FLOAT:
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ EMSG(_("E701: Invalid type for len()"));
+ break;
}
}
@@ -5759,7 +5743,7 @@ static void libcall_common(typval_T *argvars, typval_T *rettv, int out_type)
}
if (out_type == VAR_NUMBER) {
- rettv->vval.v_number = (varnumber_T)int_out;
+ rettv->vval.v_number = (varnumber_T)int_out;
}
}
@@ -5889,7 +5873,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
int mode;
int abbr = FALSE;
int get_dict = FALSE;
- mapblock_T *mp;
+ mapblock_T *mp;
int buffer_local;
// Return empty string for failure.
@@ -5931,11 +5915,9 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
if (*rhs == NUL) {
rettv->vval.v_string = vim_strsave((char_u *)"<Nop>");
} else {
- rettv->vval.v_string = (char_u *)str2special_save(
- (char *)rhs, false, false);
+ rettv->vval.v_string = (char_u *)str2special_save((char *)rhs, false, false);
}
}
-
} else {
tv_dict_alloc_ret(rettv);
if (rhs != NULL) {
@@ -5985,19 +5967,19 @@ static void f_mapcheck(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void find_some_match(typval_T *const argvars, typval_T *const rettv,
const SomeMatchType type)
{
- char_u *str = NULL;
+ char_u *str = NULL;
long len = 0;
- char_u *expr = NULL;
+ char_u *expr = NULL;
regmatch_T regmatch;
- char_u *save_cpo;
+ char_u *save_cpo;
long start = 0;
long nth = 1;
colnr_T startcol = 0;
bool match = false;
- list_T *l = NULL;
- listitem_T *li = NULL;
+ list_T *l = NULL;
+ listitem_T *li = NULL;
long idx = 0;
- char_u *tofree = NULL;
+ char_u *tofree = NULL;
// Make 'cpoptions' empty, the 'l' flag should not be used here.
save_cpo = p_cpo;
@@ -6005,30 +5987,26 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
rettv->vval.v_number = -1;
switch (type) {
- // matchlist(): return empty list when there are no matches.
- case kSomeMatchList: {
- tv_list_alloc_ret(rettv, kListLenMayKnow);
- break;
- }
- // matchstrpos(): return ["", -1, -1, -1]
- case kSomeMatchStrPos: {
- tv_list_alloc_ret(rettv, 4);
- tv_list_append_string(rettv->vval.v_list, "", 0);
- tv_list_append_number(rettv->vval.v_list, -1);
- tv_list_append_number(rettv->vval.v_list, -1);
- tv_list_append_number(rettv->vval.v_list, -1);
- break;
- }
- case kSomeMatchStr: {
- rettv->v_type = VAR_STRING;
- rettv->vval.v_string = NULL;
- break;
- }
- case kSomeMatch:
- case kSomeMatchEnd: {
- // Do nothing: zero is default.
- break;
- }
+ // matchlist(): return empty list when there are no matches.
+ case kSomeMatchList:
+ tv_list_alloc_ret(rettv, kListLenMayKnow);
+ break;
+ // matchstrpos(): return ["", -1, -1, -1]
+ case kSomeMatchStrPos:
+ tv_list_alloc_ret(rettv, 4);
+ tv_list_append_string(rettv->vval.v_list, "", 0);
+ tv_list_append_number(rettv->vval.v_list, -1);
+ tv_list_append_number(rettv->vval.v_list, -1);
+ tv_list_append_number(rettv->vval.v_list, -1);
+ break;
+ case kSomeMatchStr:
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+ break;
+ case kSomeMatch:
+ case kSomeMatchEnd:
+ // Do nothing: zero is default.
+ break;
}
if (argvars[0].v_type == VAR_LIST) {
@@ -6061,10 +6039,12 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
}
li = tv_list_find(l, idx);
} else {
- if (start < 0)
+ if (start < 0) {
start = 0;
- if (start > len)
+ }
+ if (start > len) {
goto theend;
+ }
// When "count" argument is there ignore matches before "start",
// otherwise skip part of the string. Differs when pattern is "^"
// or "\<".
@@ -6104,10 +6084,12 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
match = vim_regexec_nl(&regmatch, str, (colnr_T)startcol);
- if (match && --nth <= 0)
+ if (match && --nth <= 0) {
break;
- if (l == NULL && !match)
+ }
+ if (l == NULL && !match) {
break;
+ }
// Advance to just after the match.
if (l != NULL) {
@@ -6117,74 +6099,70 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
startcol = (colnr_T)(regmatch.startp[0]
+ (*mb_ptr2len)(regmatch.startp[0]) - str);
if (startcol > (colnr_T)len || str + startcol <= regmatch.startp[0]) {
- match = false;
- break;
+ match = false;
+ break;
}
}
}
if (match) {
switch (type) {
- case kSomeMatchStrPos: {
- list_T *const ret_l = rettv->vval.v_list;
- listitem_T *li1 = tv_list_first(ret_l);
- listitem_T *li2 = TV_LIST_ITEM_NEXT(ret_l, li1);
- listitem_T *li3 = TV_LIST_ITEM_NEXT(ret_l, li2);
- listitem_T *li4 = TV_LIST_ITEM_NEXT(ret_l, li3);
- xfree(TV_LIST_ITEM_TV(li1)->vval.v_string);
-
- const size_t rd = (size_t)(regmatch.endp[0] - regmatch.startp[0]);
- TV_LIST_ITEM_TV(li1)->vval.v_string = xmemdupz(
- (const char *)regmatch.startp[0], rd);
- TV_LIST_ITEM_TV(li3)->vval.v_number = (varnumber_T)(
- regmatch.startp[0] - expr);
- TV_LIST_ITEM_TV(li4)->vval.v_number = (varnumber_T)(
- regmatch.endp[0] - expr);
- if (l != NULL) {
- TV_LIST_ITEM_TV(li2)->vval.v_number = (varnumber_T)idx;
- }
- break;
- }
- case kSomeMatchList: {
- // Return list with matched string and submatches.
- for (int i = 0; i < NSUBEXP; i++) {
- if (regmatch.endp[i] == NULL) {
- tv_list_append_string(rettv->vval.v_list, NULL, 0);
- } else {
- tv_list_append_string(rettv->vval.v_list,
- (const char *)regmatch.startp[i],
- (regmatch.endp[i] - regmatch.startp[i]));
- }
- }
- break;
+ case kSomeMatchStrPos: {
+ list_T *const ret_l = rettv->vval.v_list;
+ listitem_T *li1 = tv_list_first(ret_l);
+ listitem_T *li2 = TV_LIST_ITEM_NEXT(ret_l, li1);
+ listitem_T *li3 = TV_LIST_ITEM_NEXT(ret_l, li2);
+ listitem_T *li4 = TV_LIST_ITEM_NEXT(ret_l, li3);
+ xfree(TV_LIST_ITEM_TV(li1)->vval.v_string);
+
+ const size_t rd = (size_t)(regmatch.endp[0] - regmatch.startp[0]);
+ TV_LIST_ITEM_TV(li1)->vval.v_string = xmemdupz((const char *)regmatch.startp[0], rd);
+ TV_LIST_ITEM_TV(li3)->vval.v_number = (varnumber_T)(
+ regmatch.startp[0] - expr);
+ TV_LIST_ITEM_TV(li4)->vval.v_number = (varnumber_T)(
+ regmatch.endp[0] - expr);
+ if (l != NULL) {
+ TV_LIST_ITEM_TV(li2)->vval.v_number = (varnumber_T)idx;
}
- case kSomeMatchStr: {
- // Return matched string.
- if (l != NULL) {
- tv_copy(TV_LIST_ITEM_TV(li), rettv);
+ break;
+ }
+ case kSomeMatchList:
+ // Return list with matched string and submatches.
+ for (int i = 0; i < NSUBEXP; i++) {
+ if (regmatch.endp[i] == NULL) {
+ tv_list_append_string(rettv->vval.v_list, NULL, 0);
} else {
- rettv->vval.v_string = (char_u *)xmemdupz(
- (const char *)regmatch.startp[0],
- (size_t)(regmatch.endp[0] - regmatch.startp[0]));
+ tv_list_append_string(rettv->vval.v_list,
+ (const char *)regmatch.startp[i],
+ (regmatch.endp[i] - regmatch.startp[i]));
}
- break;
}
- case kSomeMatch:
- case kSomeMatchEnd: {
- if (l != NULL) {
- rettv->vval.v_number = idx;
+ break;
+ case kSomeMatchStr:
+ // Return matched string.
+ if (l != NULL) {
+ tv_copy(TV_LIST_ITEM_TV(li), rettv);
+ } else {
+ rettv->vval.v_string = (char_u *)xmemdupz((const char *)regmatch.startp[0],
+ (size_t)(regmatch.endp[0] -
+ regmatch.startp[0]));
+ }
+ break;
+ case kSomeMatch:
+ case kSomeMatchEnd:
+ if (l != NULL) {
+ rettv->vval.v_number = idx;
+ } else {
+ if (type == kSomeMatch) {
+ rettv->vval.v_number =
+ (varnumber_T)(regmatch.startp[0] - str);
} else {
- if (type == kSomeMatch) {
- rettv->vval.v_number =
- (varnumber_T)(regmatch.startp[0] - str);
- } else {
- rettv->vval.v_number =
- (varnumber_T)(regmatch.endp[0] - str);
- }
- rettv->vval.v_number += (varnumber_T)(str - expr);
+ rettv->vval.v_number =
+ (varnumber_T)(regmatch.endp[0] - str);
}
- break;
+ rettv->vval.v_number += (varnumber_T)(str - expr);
}
+ break;
}
}
vim_regfree(regmatch.regprog);
@@ -6333,7 +6311,7 @@ static void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_matchdelete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- win_T *win = get_optional_window(argvars, 1);
+ win_T *win = get_optional_window(argvars, 1);
if (win == NULL) {
rettv->vval.v_number = -1;
} else {
@@ -6381,8 +6359,7 @@ static void f_matchstrpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// vval.v_number, type is not touched. Returns zero for
/// empty lists/dictionaries.
/// @param[in] domax Determines whether maximal or minimal value is desired.
-static void max_min(const typval_T *const tv, typval_T *const rettv,
- const bool domax)
+static void max_min(const typval_T *const tv, typval_T *const rettv, const bool domax)
FUNC_ATTR_NONNULL_ALL
{
bool error = false;
@@ -6532,41 +6509,38 @@ static void f_msgpackdump(typval_T *argvars, typval_T *rettv, FunPtr fptr)
msgpack_packer_free(packer);
}
-static int msgpackparse_convert_item(const msgpack_object data,
- const msgpack_unpack_return result,
- list_T *const ret_list,
- const bool fail_if_incomplete)
+static int msgpackparse_convert_item(const msgpack_object data, const msgpack_unpack_return result,
+ list_T *const ret_list, const bool fail_if_incomplete)
FUNC_ATTR_NONNULL_ALL
{
switch (result) {
- case MSGPACK_UNPACK_PARSE_ERROR:
- EMSG2(_(e_invarg2), "Failed to parse msgpack string");
+ case MSGPACK_UNPACK_PARSE_ERROR:
+ EMSG2(_(e_invarg2), "Failed to parse msgpack string");
+ return FAIL;
+ case MSGPACK_UNPACK_NOMEM_ERROR:
+ EMSG(_(e_outofmem));
+ return FAIL;
+ case MSGPACK_UNPACK_CONTINUE:
+ if (fail_if_incomplete) {
+ EMSG2(_(e_invarg2), "Incomplete msgpack string");
return FAIL;
- case MSGPACK_UNPACK_NOMEM_ERROR:
- EMSG(_(e_outofmem));
+ }
+ return NOTDONE;
+ case MSGPACK_UNPACK_SUCCESS: {
+ typval_T tv = { .v_type = VAR_UNKNOWN };
+ if (msgpack_to_vim(data, &tv) == FAIL) {
+ EMSG2(_(e_invarg2), "Failed to convert msgpack string");
return FAIL;
- case MSGPACK_UNPACK_CONTINUE:
- if (fail_if_incomplete) {
- EMSG2(_(e_invarg2), "Incomplete msgpack string");
- return FAIL;
- }
- return NOTDONE;
- case MSGPACK_UNPACK_SUCCESS: {
- typval_T tv = { .v_type = VAR_UNKNOWN };
- if (msgpack_to_vim(data, &tv) == FAIL) {
- EMSG2(_(e_invarg2), "Failed to convert msgpack string");
- return FAIL;
- }
- tv_list_append_owned_tv(ret_list, tv);
- return OK;
}
- default:
- abort();
+ tv_list_append_owned_tv(ret_list, tv);
+ return OK;
+ }
+ default:
+ abort();
}
}
-static void msgpackparse_unpack_list(const list_T *const list,
- list_T *const ret_list)
+static void msgpackparse_unpack_list(const list_T *const list, list_T *const ret_list)
FUNC_ATTR_NONNULL_ARG(2)
{
if (tv_list_len(list) == 0) {
@@ -6590,8 +6564,8 @@ static void msgpackparse_unpack_list(const list_T *const list,
goto end;
}
size_t read_bytes;
- const int rlret = encode_read_from_list(
- &lrstate, msgpack_unpacker_buffer(unpacker), IOSIZE, &read_bytes);
+ const int rlret = encode_read_from_list(&lrstate, msgpack_unpacker_buffer(
+ unpacker), IOSIZE, &read_bytes);
if (rlret == FAIL) {
EMSG2(_(e_invarg2), "List item is not a string");
goto end;
@@ -6602,7 +6576,7 @@ static void msgpackparse_unpack_list(const list_T *const list,
}
while (unpacker->off < unpacker->used) {
const msgpack_unpack_return result
- = msgpack_unpacker_next(unpacker, &unpacked);
+ = msgpack_unpacker_next(unpacker, &unpacked);
const int conv_result = msgpackparse_convert_item(unpacked.data, result,
ret_list, rlret == OK);
if (conv_result == NOTDONE) {
@@ -6621,8 +6595,7 @@ end:
msgpack_unpacked_destroy(&unpacked);
}
-static void msgpackparse_unpack_blob(const blob_T *const blob,
- list_T *const ret_list)
+static void msgpackparse_unpack_blob(const blob_T *const blob, list_T *const ret_list)
FUNC_ATTR_NONNULL_ARG(2)
{
const int len = tv_blob_len(blob);
@@ -6633,7 +6606,7 @@ static void msgpackparse_unpack_blob(const blob_T *const blob,
msgpack_unpacked_init(&unpacked);
for (size_t offset = 0; offset < (size_t)len;) {
const msgpack_unpack_return result
- = msgpack_unpack_next(&unpacked, blob->bv_ga.ga_data, len, &offset);
+ = msgpack_unpack_next(&unpacked, blob->bv_ga.ga_data, len, &offset);
if (msgpackparse_convert_item(unpacked.data, result, ret_list, true)
!= OK) {
break;
@@ -6791,53 +6764,51 @@ static void f_printf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// "prompt_setcallback({buffer}, {callback})" function
-static void f_prompt_setcallback(typval_T *argvars,
- typval_T *rettv, FunPtr fptr)
+static void f_prompt_setcallback(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
- Callback prompt_callback = { .type = kCallbackNone };
+ buf_T *buf;
+ Callback prompt_callback = { .type = kCallbackNone };
- if (check_secure()) {
- return;
- }
- buf = tv_get_buf(&argvars[0], false);
- if (buf == NULL) {
- return;
- }
+ if (check_secure()) {
+ return;
+ }
+ buf = tv_get_buf(&argvars[0], false);
+ if (buf == NULL) {
+ return;
+ }
- if (argvars[1].v_type != VAR_STRING || *argvars[1].vval.v_string != NUL) {
- if (!callback_from_typval(&prompt_callback, &argvars[1])) {
- return;
- }
+ if (argvars[1].v_type != VAR_STRING || *argvars[1].vval.v_string != NUL) {
+ if (!callback_from_typval(&prompt_callback, &argvars[1])) {
+ return;
}
+ }
- callback_free(&buf->b_prompt_callback);
- buf->b_prompt_callback = prompt_callback;
+ callback_free(&buf->b_prompt_callback);
+ buf->b_prompt_callback = prompt_callback;
}
// "prompt_setinterrupt({buffer}, {callback})" function
-static void f_prompt_setinterrupt(typval_T *argvars,
- typval_T *rettv, FunPtr fptr)
+static void f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
- Callback interrupt_callback = { .type = kCallbackNone };
+ buf_T *buf;
+ Callback interrupt_callback = { .type = kCallbackNone };
- if (check_secure()) {
- return;
- }
- buf = tv_get_buf(&argvars[0], false);
- if (buf == NULL) {
- return;
- }
+ if (check_secure()) {
+ return;
+ }
+ buf = tv_get_buf(&argvars[0], false);
+ if (buf == NULL) {
+ return;
+ }
- if (argvars[1].v_type != VAR_STRING || *argvars[1].vval.v_string != NUL) {
- if (!callback_from_typval(&interrupt_callback, &argvars[1])) {
- return;
- }
+ if (argvars[1].v_type != VAR_STRING || *argvars[1].vval.v_string != NUL) {
+ if (!callback_from_typval(&interrupt_callback, &argvars[1])) {
+ return;
}
+ }
- callback_free(&buf->b_prompt_interrupt);
- buf->b_prompt_interrupt= interrupt_callback;
+ callback_free(&buf->b_prompt_interrupt);
+ buf->b_prompt_interrupt= interrupt_callback;
}
/// "prompt_getprompt({buffer})" function
@@ -6861,23 +6832,22 @@ void f_prompt_getprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// "prompt_setprompt({buffer}, {text})" function
-static void f_prompt_setprompt(typval_T *argvars,
- typval_T *rettv, FunPtr fptr)
+static void f_prompt_setprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
- const char_u *text;
+ buf_T *buf;
+ const char_u *text;
- if (check_secure()) {
- return;
- }
- buf = tv_get_buf(&argvars[0], false);
- if (buf == NULL) {
- return;
- }
+ if (check_secure()) {
+ return;
+ }
+ buf = tv_get_buf(&argvars[0], false);
+ if (buf == NULL) {
+ return;
+ }
- text = (const char_u *)tv_get_string(&argvars[1]);
- xfree(buf->b_prompt_text);
- buf->b_prompt_text = vim_strsave(text);
+ text = (const char_u *)tv_get_string(&argvars[1]);
+ xfree(buf->b_prompt_text);
+ buf->b_prompt_text = vim_strsave(text);
}
// "pum_getpos()" function
@@ -6892,8 +6862,9 @@ static void f_pum_getpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_pumvisible(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- if (pum_visible())
+ if (pum_visible()) {
rettv->vval.v_number = 1;
+ }
}
/*
@@ -7068,11 +7039,11 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool binary = false;
bool blob = false;
- FILE *fd;
+ FILE *fd;
char_u buf[(IOSIZE/256) * 256]; // rounded to avoid odd + 1
int io_size = sizeof(buf);
int readlen; // size of last fread()
- char_u *prev = NULL; // previously read bytes, if any
+ char_u *prev = NULL; // previously read bytes, if any
long prevlen = 0; // length of data in prev
long prevsize = 0; // size of prev buffer
long maxline = MAXLNUM;
@@ -7129,7 +7100,7 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
p < buf + readlen || (readlen <= 0 && (prevlen > 0 || binary));
p++) {
if (*p == '\n' || readlen <= 0) {
- char_u *s = NULL;
+ char_u *s = NULL;
size_t len = p - start;
// Finished a line. Remove CRs before NL.
@@ -7179,16 +7150,17 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
} else if (*p == NUL) {
*p = '\n';
- // Check for utf8 "bom"; U+FEFF is encoded as EF BB BF. Do this
- // when finding the BF and check the previous two bytes.
+ // Check for utf8 "bom"; U+FEFF is encoded as EF BB BF. Do this
+ // when finding the BF and check the previous two bytes.
} else if (*p == 0xbf && !binary) {
// Find the two bytes before the 0xbf. If p is at buf, or buf + 1,
// these may be in the "prev" string.
char_u back1 = p >= buf + 1 ? p[-1]
- : prevlen >= 1 ? prev[prevlen - 1] : NUL;
+ : prevlen >= 1 ? prev[prevlen - 1] : NUL;
char_u back2 = p >= buf + 2 ? p[-2]
- : p == buf + 1 && prevlen >= 1 ? prev[prevlen - 1]
- : prevlen >= 2 ? prev[prevlen - 2] : NUL;
+ : p == buf + 1 && prevlen >= 1 ? prev[prevlen - 1]
+ : prevlen >=
+ 2 ? prev[prevlen - 2] : NUL;
if (back2 == 0xef && back1 == 0xbb) {
char_u *dest = p - 2;
@@ -7206,8 +7178,9 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// adjust_prevlen must be 1 or 2.
dest = buf;
}
- if (readlen > p - buf + 1)
+ if (readlen > p - buf + 1) {
memmove(dest, p + 1, readlen - (p - buf) - 1);
+ }
readlen -= 3 - adjust_prevlen;
prevlen -= adjust_prevlen;
p = dest - 1;
@@ -7226,9 +7199,9 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
* fragment of a line, so the first allocation is made
* small, to avoid repeatedly 'allocing' large and
* 'reallocing' small. */
- if (prevsize == 0)
+ if (prevsize == 0) {
prevsize = (long)(p - start);
- else {
+ } else {
long grow50pc = (prevsize * 3) / 2;
long growmin = (long)((p - start) * 2 + prevlen);
prevsize = grow50pc > growmin ? grow50pc : growmin;
@@ -7328,7 +7301,7 @@ static void f_reltime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// results, if varnumber_T or proftime_T change, the union cast will need
// to be revised.
STATIC_ASSERT(sizeof(u.prof) == sizeof(u) && sizeof(u.split) == sizeof(u),
- "type punning will produce incorrect results on this platform");
+ "type punning will produce incorrect results on this platform");
tv_list_alloc_ret(rettv, 2);
tv_list_append_number(rettv->vval.v_list, u.split.high);
@@ -7353,13 +7326,13 @@ static void f_reltimestr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- list_T *l;
- listitem_T *item, *item2;
- listitem_T *li;
+ list_T *l;
+ listitem_T *item, *item2;
+ listitem_T *li;
long idx;
long end;
- dict_T *d;
- dictitem_T *di;
+ dict_T *d;
+ dictitem_T *di;
const char *const arg_errmsg = N_("remove() argument");
if (argvars[0].v_type == VAR_DICT) {
@@ -7493,9 +7466,8 @@ static void f_rename(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = -1;
} else {
char buf[NUMBUFLEN];
- rettv->vval.v_number = vim_rename(
- (const char_u *)tv_get_string(&argvars[0]),
- (const char_u *)tv_get_string_buf(&argvars[1], buf));
+ rettv->vval.v_number = vim_rename((const char_u *)tv_get_string(&argvars[0]),
+ (const char_u *)tv_get_string_buf(&argvars[1], buf));
}
}
@@ -7763,30 +7735,40 @@ static int get_search_arg(typval_T *varp, int *flagsp)
}
while (*flags != NUL) {
switch (*flags) {
- case 'b': dir = BACKWARD; break;
- case 'w': p_ws = true; break;
- case 'W': p_ws = false; break;
- default: {
- mask = 0;
- if (flagsp != NULL) {
- switch (*flags) {
- case 'c': mask = SP_START; break;
- case 'e': mask = SP_END; break;
- case 'm': mask = SP_RETCOUNT; break;
- case 'n': mask = SP_NOMOVE; break;
- case 'p': mask = SP_SUBPAT; break;
- case 'r': mask = SP_REPEAT; break;
- case 's': mask = SP_SETPCMARK; break;
- case 'z': mask = SP_COLUMN; break;
- }
- }
- if (mask == 0) {
- emsgf(_(e_invarg2), flags);
- dir = 0;
- } else {
- *flagsp |= mask;
+ case 'b':
+ dir = BACKWARD; break;
+ case 'w':
+ p_ws = true; break;
+ case 'W':
+ p_ws = false; break;
+ default:
+ mask = 0;
+ if (flagsp != NULL) {
+ switch (*flags) {
+ case 'c':
+ mask = SP_START; break;
+ case 'e':
+ mask = SP_END; break;
+ case 'm':
+ mask = SP_RETCOUNT; break;
+ case 'n':
+ mask = SP_NOMOVE; break;
+ case 'p':
+ mask = SP_SUBPAT; break;
+ case 'r':
+ mask = SP_REPEAT; break;
+ case 's':
+ mask = SP_SETPCMARK; break;
+ case 'z':
+ mask = SP_COLUMN; break;
}
}
+ if (mask == 0) {
+ emsgf(_(e_invarg2), flags);
+ dir = 0;
+ } else {
+ *flagsp |= mask;
+ }
}
if (dir == 0) {
break;
@@ -7865,12 +7847,14 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
subpatnum = searchit(curwin, curbuf, &pos, NULL, dir, (char_u *)pat, 1,
options, RE_SEARCH, &sia);
if (subpatnum != FAIL) {
- if (flags & SP_SUBPAT)
+ if (flags & SP_SUBPAT) {
retval = subpatnum;
- else
+ } else {
retval = pos.lnum;
- if (flags & SP_SETPCMARK)
+ }
+ if (flags & SP_SETPCMARK) {
setpcmark();
+ }
curwin->w_cursor = pos;
if (match_pos != NULL) {
// Store the match cursor position
@@ -8008,10 +7992,10 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
msg_ext_set_kind("rpc_error");
if (name) {
- emsgf_multiline("Error invoking '%s' on channel %"PRIu64" (%s):\n%s",
+ emsgf_multiline("Error invoking '%s' on channel %" PRIu64 " (%s):\n%s",
method, chan_id, name, err.msg);
} else {
- emsgf_multiline("Error invoking '%s' on channel %"PRIu64":\n%s",
+ emsgf_multiline("Error invoking '%s' on channel %" PRIu64 ":\n%s",
method, chan_id, err.msg);
}
@@ -8313,9 +8297,8 @@ static int searchpair_cmn(typval_T *argvars, pos_T *match_pos)
}
}
- retval = do_searchpair(
- spat, mpat, epat, dir, skip,
- flags, match_pos, lnum_stop, time_limit);
+ retval = do_searchpair(spat, mpat, epat, dir, skip,
+ flags, match_pos, lnum_stop, time_limit);
theend:
p_ws = save_p_ws;
@@ -8356,22 +8339,19 @@ static void f_searchpairpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
* 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
-)
+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
+ )
FUNC_ATTR_NONNULL_ARG(1, 2, 3)
{
- char_u *save_cpo;
- char_u *pat, *pat2 = NULL, *pat3 = NULL;
+ char_u *save_cpo;
+ char_u *pat, *pat2 = NULL, *pat3 = NULL;
long retval = 0;
pos_T pos;
pos_T firstpos;
@@ -8433,8 +8413,9 @@ do_searchpair(
break;
}
- if (firstpos.lnum == 0)
+ if (firstpos.lnum == 0) {
firstpos = pos;
+ }
if (equalpos(pos, foundpos)) {
// Found the same position again. Can happen with a pattern that
// has "\zs" at the end and searching backwards. Advance one
@@ -8463,8 +8444,9 @@ do_searchpair(
retval = -1;
break;
}
- if (r)
+ if (r) {
continue;
+ }
}
if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) {
@@ -8491,8 +8473,9 @@ do_searchpair(
setpcmark();
}
curwin->w_cursor = pos;
- if (!(flags & SP_REPEAT))
+ if (!(flags & SP_REPEAT)) {
break;
+ }
nest = 1; // search for next unmatched
}
}
@@ -8624,16 +8607,16 @@ static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// "setbufline()" function
static void f_setbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
- buf_T *buf;
+ linenr_T lnum;
+ buf_T *buf;
- buf = tv_get_buf(&argvars[0], false);
- if (buf == NULL) {
- rettv->vval.v_number = 1; // FAIL
- } else {
- lnum = tv_get_lnum_buf(&argvars[1], buf);
- set_buffer_lines(buf, lnum, false, &argvars[2], rettv);
- }
+ buf = tv_get_buf(&argvars[0], false);
+ if (buf == NULL) {
+ rettv->vval.v_number = 1; // FAIL
+ } else {
+ lnum = tv_get_lnum_buf(&argvars[1], buf);
+ set_buffer_lines(buf, lnum, false, &argvars[2], rettv);
+ }
}
/*
@@ -8684,8 +8667,8 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- dict_T *d;
- dictitem_T *di;
+ dict_T *d;
+ dictitem_T *di;
if (argvars[0].v_type != VAR_DICT) {
EMSG(_(e_dictreq));
@@ -8865,7 +8848,7 @@ skip_args:
*/
static void f_setloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- win_T *win;
+ win_T *win;
rettv->vval.v_number = -1;
@@ -9005,7 +8988,7 @@ static void f_setpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
check_cursor();
rettv->vval.v_number = 0;
- } else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) {
+ } else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) {
// set mark
if (setmark_pos((uint8_t)name[1], &pos, fnum) == OK) {
rettv->vval.v_number = 0;
@@ -9057,31 +9040,31 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
for (; *stropt != NUL; stropt++) {
switch (*stropt) {
- case 'a': 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;
+ case 'a':
+ 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;
}
}
}
@@ -9135,7 +9118,8 @@ free_lstval:
if (set_unnamed) {
// Discard the result. We already handle the error case.
- if (op_reg_set_previous(regname)) { }
+ if (op_reg_set_previous(regname)) {
+ }
}
}
@@ -9183,54 +9167,54 @@ static void f_settabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// "settagstack()" function
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';
+ static char *e_invact2 = N_("E962: Invalid action: '%s'");
+ win_T *wp;
+ dict_T *d;
+ int action = 'r';
- rettv->vval.v_number = -1;
+ rettv->vval.v_number = -1;
- // first argument: window number or id
- wp = find_win_by_nr_or_id(&argvars[0]);
- if (wp == NULL) {
- return;
- }
+ // first argument: window number or id
+ wp = find_win_by_nr_or_id(&argvars[0]);
+ if (wp == NULL) {
+ return;
+ }
- // second argument: dict with items to set in the tag stack
- if (argvars[1].v_type != VAR_DICT) {
- EMSG(_(e_dictreq));
- return;
- }
- d = argvars[1].vval.v_dict;
- if (d == NULL) {
+ // second argument: dict with items to set in the tag stack
+ if (argvars[1].v_type != VAR_DICT) {
+ EMSG(_(e_dictreq));
+ return;
+ }
+ d = argvars[1].vval.v_dict;
+ if (d == NULL) {
+ return;
+ }
+
+ // third argument: action - 'a' for append and 'r' for replace.
+ // default is to replace the stack.
+ if (argvars[2].v_type == VAR_UNKNOWN) {
+ action = 'r';
+ } else if (argvars[2].v_type == VAR_STRING) {
+ const char *actstr;
+ actstr = tv_get_string_chk(&argvars[2]);
+ if (actstr == NULL) {
return;
}
-
- // third argument: action - 'a' for append and 'r' for replace.
- // default is to replace the stack.
- if (argvars[2].v_type == VAR_UNKNOWN) {
- action = 'r';
- } else if (argvars[2].v_type == VAR_STRING) {
- const char *actstr;
- actstr = tv_get_string_chk(&argvars[2]);
- if (actstr == NULL) {
- return;
- }
- if ((*actstr == 'r' || *actstr == 'a' || *actstr == 't')
- && actstr[1] == NUL) {
- action = *actstr;
- } else {
- EMSG2(_(e_invact2), actstr);
- return;
- }
+ if ((*actstr == 'r' || *actstr == 'a' || *actstr == 't')
+ && actstr[1] == NUL) {
+ action = *actstr;
} else {
- EMSG(_(e_stringreq));
- return;
+ EMSG2(_(e_invact2), actstr);
+ return;
}
+ } else {
+ EMSG(_(e_stringreq));
+ return;
+ }
- if (set_tagstack(wp, d, action) == OK) {
- rettv->vval.v_number = 0;
- }
+ if (set_tagstack(wp, d, action) == OK) {
+ rettv->vval.v_number = 0;
+ }
}
/*
@@ -9245,7 +9229,7 @@ static void f_setwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_sha256(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *p = tv_get_string(&argvars[0]);
- const char *hash = sha256_bytes((const uint8_t *)p, strlen(p) , NULL, 0);
+ const char *hash = sha256_bytes((const uint8_t *)p, strlen(p), NULL, 0);
// make a copy of the hash (sha256_bytes returns a static buffer)
rettv->vval.v_string = (char_u *)xstrdup(hash);
@@ -9259,8 +9243,8 @@ static void f_shellescape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const bool do_special = non_zero_arg(&argvars[1]);
- rettv->vval.v_string = vim_strsave_shellescape(
- (const char_u *)tv_get_string(&argvars[0]), do_special, do_special);
+ rettv->vval.v_string = vim_strsave_shellescape((const char_u *)tv_get_string(
+ &argvars[0]), do_special, do_special);
rettv->v_type = VAR_STRING;
}
@@ -9310,8 +9294,9 @@ static void f_sign_define(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- rettv->vval.v_number = sign_define_from_dict(
- name, argvars[1].v_type == VAR_DICT ? argvars[1].vval.v_dict : NULL);
+ rettv->vval.v_number = sign_define_from_dict(name,
+ argvars[1].v_type ==
+ VAR_DICT ? argvars[1].vval.v_dict : NULL);
}
/// "sign_getdefined()" function
@@ -9443,8 +9428,8 @@ static void f_sign_place(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- rettv->vval.v_number = sign_place_from_dict(
- &argvars[0], &argvars[1], &argvars[2], &argvars[3], dict);
+ rettv->vval.v_number = sign_place_from_dict(&argvars[0], &argvars[1], &argvars[2], &argvars[3],
+ dict);
}
/// "sign_placelist()" function. Place multiple signs.
@@ -9463,8 +9448,7 @@ static void f_sign_placelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
TV_LIST_ITER_CONST(argvars[0].vval.v_list, li, {
sign_id = -1;
if (TV_LIST_ITEM_TV(li)->v_type == VAR_DICT) {
- sign_id = sign_place_from_dict(
- NULL, NULL, NULL, NULL, TV_LIST_ITEM_TV(li)->vval.v_dict);
+ sign_id = sign_place_from_dict(NULL, NULL, NULL, NULL, TV_LIST_ITEM_TV(li)->vval.v_dict);
} else {
EMSG(_(e_dictreq));
}
@@ -9800,7 +9784,7 @@ static int item_compare2_not_keeping_zero(const void *s1, const void *s2)
*/
static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
{
- ListSortItem *ptrs;
+ ListSortItem *ptrs;
long len;
long i;
@@ -9987,7 +9971,7 @@ static void f_uniq(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// "reltimefloat()" function
-static void f_reltimefloat(typval_T *argvars , typval_T *rettv, FunPtr fptr)
+static void f_reltimefloat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
FUNC_ATTR_NONNULL_ALL
{
proftime_T tm;
@@ -10062,10 +10046,12 @@ static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_list_append_string(rettv->vval.v_list, word, len);
tv_list_append_string(rettv->vval.v_list,
(attr == HLF_SPB ? "bad"
- : attr == HLF_SPR ? "rare"
- : attr == HLF_SPL ? "local"
- : attr == HLF_SPC ? "caps"
- : NULL), -1);
+ : attr == HLF_SPR ? "rare"
+ : attr == HLF_SPL ? "local"
+ : attr ==
+ HLF_SPC ? "caps"
+ :
+ NULL), -1);
}
/*
@@ -10122,7 +10108,7 @@ f_spellsuggest_return:
static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *save_cpo;
+ char_u *save_cpo;
int match;
colnr_T col = 0;
bool keepempty = false;
@@ -10278,18 +10264,15 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
p = skipwhite(p + 1);
}
switch (base) {
- case 2: {
- what |= STR2NR_BIN | STR2NR_FORCE;
- break;
- }
- case 8: {
- what |= STR2NR_OCT | STR2NR_OOCT | STR2NR_FORCE;
- break;
- }
- case 16: {
- what |= STR2NR_HEX | STR2NR_FORCE;
- break;
- }
+ case 2:
+ what |= STR2NR_BIN | STR2NR_FORCE;
+ break;
+ case 8:
+ what |= STR2NR_OCT | STR2NR_OOCT | STR2NR_FORCE;
+ break;
+ case 16:
+ what |= STR2NR_HEX | STR2NR_FORCE;
+ break;
}
vim_str2nr(p, NULL, NULL, what, &n, NULL, 0, false);
// Text after the number is silently ignored.
@@ -10323,7 +10306,7 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)"));
} else {
vimconv_T conv;
- char_u *enc;
+ char_u *enc;
conv.vc_type = CONV_NONE;
enc = enc_locale();
@@ -10799,53 +10782,46 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
const char *p = NULL;
switch (TOLOWER_ASC(what[0])) {
- case 'b': {
- if (TOLOWER_ASC(what[1]) == 'g') { // bg[#]
- p = highlight_color(id, what, modec);
- } else { // bold
- p = highlight_has_attr(id, HL_BOLD, modec);
- }
- break;
- }
- case 'f': { // fg[#] or font
+ case 'b':
+ if (TOLOWER_ASC(what[1]) == 'g') { // bg[#]
p = highlight_color(id, what, modec);
- break;
- }
- case 'i': {
- if (TOLOWER_ASC(what[1]) == 'n') { // inverse
- p = highlight_has_attr(id, HL_INVERSE, modec);
- } else { // italic
- p = highlight_has_attr(id, HL_ITALIC, modec);
- }
- break;
- }
- case 'n': { // name
- p = get_highlight_name_ext(NULL, id - 1, false);
- break;
+ } else { // bold
+ p = highlight_has_attr(id, HL_BOLD, modec);
}
- case 'r': { // reverse
+ break;
+ case 'f': // fg[#] or font
+ p = highlight_color(id, what, modec);
+ break;
+ case 'i':
+ if (TOLOWER_ASC(what[1]) == 'n') { // inverse
p = highlight_has_attr(id, HL_INVERSE, modec);
- break;
+ } else { // italic
+ p = highlight_has_attr(id, HL_ITALIC, modec);
}
- case 's': {
- if (TOLOWER_ASC(what[1]) == 'p') { // sp[#]
- p = highlight_color(id, what, modec);
- } else if (TOLOWER_ASC(what[1]) == 't'
- && TOLOWER_ASC(what[2]) == 'r') { // strikethrough
- p = highlight_has_attr(id, HL_STRIKETHROUGH, modec);
- } else { // standout
- p = highlight_has_attr(id, HL_STANDOUT, modec);
- }
- break;
+ break;
+ case 'n': // name
+ p = get_highlight_name_ext(NULL, id - 1, false);
+ break;
+ case 'r': // reverse
+ p = highlight_has_attr(id, HL_INVERSE, modec);
+ break;
+ case 's':
+ if (TOLOWER_ASC(what[1]) == 'p') { // sp[#]
+ p = highlight_color(id, what, modec);
+ } else if (TOLOWER_ASC(what[1]) == 't'
+ && TOLOWER_ASC(what[2]) == 'r') { // strikethrough
+ p = highlight_has_attr(id, HL_STRIKETHROUGH, modec);
+ } else { // standout
+ p = highlight_has_attr(id, HL_STANDOUT, modec);
}
- case 'u': {
- if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') { // underline
- p = highlight_has_attr(id, HL_UNDERLINE, modec);
- } else { // undercurl
- p = highlight_has_attr(id, HL_UNDERCURL, modec);
- }
- break;
+ break;
+ case 'u':
+ if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') { // underline
+ p = highlight_has_attr(id, HL_UNDERLINE, modec);
+ } else { // undercurl
+ p = highlight_has_attr(id, HL_UNDERCURL, modec);
}
+ break;
}
rettv->v_type = VAR_STRING;
@@ -10955,7 +10931,7 @@ static void f_systemlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- win_T *wp = NULL;
+ win_T *wp = NULL;
if (argvars[0].v_type == VAR_UNKNOWN) {
wp = firstwin;
@@ -11008,9 +10984,9 @@ static void f_tabpagenr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static int get_winnr(tabpage_T *tp, typval_T *argvar)
{
- win_T *twin;
+ win_T *twin;
int nr = 1;
- win_T *wp;
+ win_T *wp;
twin = (tp == curtab) ? curwin : tp->tp_curwin;
if (argvar->v_type != VAR_UNKNOWN) {
@@ -11056,7 +11032,7 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar)
}
}
- if (nr > 0)
+ if (nr > 0) {
for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
wp != twin; wp = wp->w_next) {
if (wp == NULL) {
@@ -11066,6 +11042,7 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar)
}
++nr;
}
+ }
return nr;
}
@@ -11248,8 +11225,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// "test_garbagecollect_now()" function
-static void f_test_garbagecollect_now(typval_T *argvars,
- typval_T *rettv, FunPtr fptr)
+static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
// This is dangerous, any Lists and Dicts used internally may be freed
// while still in use.
@@ -11257,9 +11233,7 @@ static void f_test_garbagecollect_now(typval_T *argvars,
}
// "test_write_list_log()" function
-static void f_test_write_list_log(typval_T *const argvars,
- typval_T *const rettv,
- FunPtr fptr)
+static void f_test_write_list_log(typval_T *const argvars, typval_T *const rettv, FunPtr fptr)
{
const char *const fname = tv_get_string_chk(&argvars[0]);
if (fname == NULL) {
@@ -11334,24 +11308,24 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
rettv->vval.v_number =
- timer_start(tv_get_number(&argvars[0]), repeat, &callback);
+ timer_start(tv_get_number(&argvars[0]), repeat, &callback);
}
// "timer_stop(timerid)" function
static void f_timer_stop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- if (argvars[0].v_type != VAR_NUMBER) {
- EMSG(_(e_number_exp));
- return;
- }
+ if (argvars[0].v_type != VAR_NUMBER) {
+ EMSG(_(e_number_exp));
+ return;
+ }
- timer_T *timer = find_timer_by_nr(tv_get_number(&argvars[0]));
- if (timer == NULL) {
- return;
- }
+ timer_T *timer = find_timer_by_nr(tv_get_number(&argvars[0]));
+ if (timer == NULL) {
+ return;
+ }
- timer_stop(timer);
+ timer_stop(timer);
}
static void f_timer_stopall(typval_T *argvars, typval_T *unused, FunPtr fptr)
@@ -11552,20 +11526,28 @@ static void f_type(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int n = -1;
switch (argvars[0].v_type) {
- case VAR_NUMBER: n = VAR_TYPE_NUMBER; break;
- case VAR_STRING: n = VAR_TYPE_STRING; break;
- case VAR_PARTIAL:
- case VAR_FUNC: n = VAR_TYPE_FUNC; break;
- case VAR_LIST: n = VAR_TYPE_LIST; break;
- case VAR_DICT: n = VAR_TYPE_DICT; break;
- case VAR_FLOAT: n = VAR_TYPE_FLOAT; break;
- case VAR_BOOL: n = VAR_TYPE_BOOL; break;
- case VAR_SPECIAL: n = VAR_TYPE_SPECIAL; break;
- case VAR_BLOB: n = VAR_TYPE_BLOB; break;
- case VAR_UNKNOWN: {
- internal_error("f_type(UNKNOWN)");
- break;
- }
+ case VAR_NUMBER:
+ n = VAR_TYPE_NUMBER; break;
+ case VAR_STRING:
+ n = VAR_TYPE_STRING; break;
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ n = VAR_TYPE_FUNC; break;
+ case VAR_LIST:
+ n = VAR_TYPE_LIST; break;
+ case VAR_DICT:
+ n = VAR_TYPE_DICT; break;
+ case VAR_FLOAT:
+ n = VAR_TYPE_FLOAT; break;
+ case VAR_BOOL:
+ n = VAR_TYPE_BOOL; break;
+ case VAR_SPECIAL:
+ n = VAR_TYPE_SPECIAL; break;
+ case VAR_BLOB:
+ n = VAR_TYPE_BLOB; break;
+ case VAR_UNKNOWN:
+ internal_error("f_type(UNKNOWN)");
+ break;
}
rettv->vval.v_number = n;
}
@@ -11625,7 +11607,7 @@ static void f_values(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_virtcol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
colnr_T vcol = 0;
- pos_T *fp;
+ pos_T *fp;
int fnum = curbuf->b_fnum;
fp = var2fpos(&argvars[0], FALSE, &fnum);
@@ -11876,10 +11858,12 @@ static void f_winrestview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
win_new_width(curwin, curwin->w_width);
changed_window_setting();
- if (curwin->w_topline <= 0)
+ if (curwin->w_topline <= 0) {
curwin->w_topline = 1;
- 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;
+ }
check_topfill(curwin, true);
}
}
@@ -11889,7 +11873,7 @@ static void f_winrestview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_winsaveview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- dict_T *dict;
+ dict_T *dict;
tv_dict_alloc_ret(rettv);
dict = rettv->vval.v_dict;
@@ -11962,15 +11946,18 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
for (const char *p = flags; *p; p++) {
switch (*p) {
- case 'b': { binary = true; break; }
- case 'a': { append = true; break; }
- case 's': { do_fsync = true; break; }
- case 'S': { do_fsync = false; break; }
- default: {
- // Using %s, p and not %c, *p to preserve multibyte characters
- emsgf(_("E5060: Unknown flag: %s"), p);
- return;
- }
+ case 'b':
+ binary = true; break;
+ case 'a':
+ append = true; break;
+ case 's':
+ do_fsync = true; break;
+ case 'S':
+ do_fsync = false; break;
+ default:
+ // Using %s, p and not %c, *p to preserve multibyte characters
+ emsgf(_("E5060: Unknown flag: %s"), p);
+ return;
}
}
}
diff --git a/src/nvim/eval/gc.c b/src/nvim/eval/gc.c
index 2bbf78d827..633e6abacf 100644
--- a/src/nvim/eval/gc.c
+++ b/src/nvim/eval/gc.c
@@ -1,8 +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
-#include "nvim/eval/typval.h"
#include "nvim/eval/gc.h"
+#include "nvim/eval/typval.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/gc.c.generated.h"
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index 381d70ea1b..3bc4ec9381 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -1,36 +1,36 @@
// 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 <assert.h>
+#include <stdbool.h>
#include <stddef.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <assert.h>
-#include <stdbool.h>
-#include "nvim/lib/queue.h"
-#include "nvim/eval/typval.h"
-#include "nvim/eval/gc.h"
-#include "nvim/eval/executor.h"
+#include "nvim/ascii.h"
+#include "nvim/assert.h"
+#include "nvim/charset.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/typval_encode.h"
-#include "nvim/eval.h"
#include "nvim/eval/userfunc.h"
-#include "nvim/lua/executor.h"
-#include "nvim/types.h"
-#include "nvim/assert.h"
-#include "nvim/memory.h"
-#include "nvim/globals.h"
-#include "nvim/hashtab.h"
-#include "nvim/vim.h"
-#include "nvim/ascii.h"
-#include "nvim/pos.h"
-#include "nvim/charset.h"
#include "nvim/garray.h"
#include "nvim/gettext.h"
+#include "nvim/globals.h"
+#include "nvim/hashtab.h"
+#include "nvim/lib/queue.h"
+#include "nvim/lua/executor.h"
#include "nvim/macros.h"
#include "nvim/mbyte.h"
+#include "nvim/memory.h"
#include "nvim/message.h"
+#include "nvim/pos.h"
+#include "nvim/types.h"
+#include "nvim/vim.h"
// TODO(ZyX-I): Move line_breakcheck out of misc1
#include "nvim/misc1.h" // For line_breakcheck
#include "nvim/os/fileio.h"
@@ -71,11 +71,11 @@ void list_write_log(const char *const fname)
char buf[10 + 1 + ((16 + 3) * 3) + (8 + 2) + 2];
// act : hex " c:" len "[]" "\n\0"
const ListLogEntry entry = chunk->entries[i];
- const size_t snp_len = (size_t)snprintf(
- buf, sizeof(buf),
- "%-10.10s: l:%016" PRIxPTR "[%08d] 1:%016" PRIxPTR " 2:%016" PRIxPTR
- "\n",
- entry.action, entry.l, entry.len, entry.li1, entry.li2);
+ const size_t snp_len = (size_t)snprintf(buf, sizeof(buf),
+ "%-10.10s: l:%016" PRIxPTR "[%08d] 1:%016" PRIxPTR " 2:%016" PRIxPTR
+ "\n",
+ entry.action, entry.l, entry.len, entry.li1,
+ entry.li2);
assert(snp_len + 1 == sizeof(buf));
const ptrdiff_t fw_ret = file_write(&fp, buf, snp_len);
if (fw_ret != (ptrdiff_t)snp_len) {
@@ -343,8 +343,7 @@ void tv_list_unref(list_T *const l)
/// @param[out] l List to remove from.
/// @param[in] item First item to remove.
/// @param[in] item2 Last item to remove.
-void tv_list_drop_items(list_T *const l, listitem_T *const item,
- listitem_T *const item2)
+void tv_list_drop_items(list_T *const l, listitem_T *const item, listitem_T *const item2)
FUNC_ATTR_NONNULL_ALL
{
list_log(l, item, item2, "drop");
@@ -369,8 +368,7 @@ void tv_list_drop_items(list_T *const l, listitem_T *const item,
}
/// Like tv_list_drop_items, but also frees all removed items
-void tv_list_remove_items(list_T *const l, listitem_T *const item,
- listitem_T *const item2)
+void tv_list_remove_items(list_T *const l, listitem_T *const item, listitem_T *const item2)
FUNC_ATTR_NONNULL_ALL
{
list_log(l, item, item2, "remove");
@@ -393,9 +391,8 @@ void tv_list_remove_items(list_T *const l, listitem_T *const item,
/// @param[in] item2 Last item to move.
/// @param[out] tgt_l List to move to.
/// @param[in] cnt Number of items moved.
-void tv_list_move_items(list_T *const l, listitem_T *const item,
- listitem_T *const item2, list_T *const tgt_l,
- const int cnt)
+void tv_list_move_items(list_T *const l, listitem_T *const item, listitem_T *const item2,
+ list_T *const tgt_l, const int cnt)
FUNC_ATTR_NONNULL_ALL
{
list_log(l, item, item2, "move");
@@ -418,8 +415,7 @@ void tv_list_move_items(list_T *const l, listitem_T *const item,
/// @param[in,out] ni Item to insert.
/// @param[in] item Item to insert before. If NULL, inserts at the end of the
/// list.
-void tv_list_insert(list_T *const l, listitem_T *const ni,
- listitem_T *const item)
+void tv_list_insert(list_T *const l, listitem_T *const ni, listitem_T *const item)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
if (item == NULL) {
@@ -449,8 +445,7 @@ void tv_list_insert(list_T *const l, listitem_T *const ni,
/// allocated listitem_T and inserted.
/// @param[in] item Item to insert before. If NULL, inserts at the end of the
/// list.
-void tv_list_insert_tv(list_T *const l, typval_T *const tv,
- listitem_T *const item)
+void tv_list_insert_tv(list_T *const l, typval_T *const tv, listitem_T *const item)
{
listitem_T *const ni = tv_list_item_alloc();
@@ -544,8 +539,7 @@ void tv_list_append_dict(list_T *const l, dict_T *const dict)
/// @param[in] len Length of the appended string. May be -1, in this
/// case string is considered to be usual zero-terminated
/// string or NULL “empty” string.
-void tv_list_append_string(list_T *const l, const char *const str,
- const ssize_t len)
+void tv_list_append_string(list_T *const l, const char *const str, const ssize_t len)
FUNC_ATTR_NONNULL_ARG(1)
{
tv_list_append_owned_tv(l, (typval_T) {
@@ -601,8 +595,8 @@ void tv_list_append_number(list_T *const l, const varnumber_T n)
///
/// @return Copied list. May be NULL in case original list is NULL or some
/// failure happens. The refcount of the new list is set to 1.
-list_T *tv_list_copy(const vimconv_T *const conv, list_T *const orig,
- const bool deep, const int copyID)
+list_T *tv_list_copy(const vimconv_T *const conv, list_T *const orig, const bool deep,
+ const int copyID)
FUNC_ATTR_WARN_UNUSED_RESULT
{
if (orig == NULL) {
@@ -697,8 +691,7 @@ int tv_list_flatten(list_T *list, long maxdepth)
/// @param[out] l1 List to extend.
/// @param[in] l2 List to extend with.
/// @param[in] bef If not NULL, extends before this item.
-void tv_list_extend(list_T *const l1, list_T *const l2,
- listitem_T *const bef)
+void tv_list_extend(list_T *const l1, list_T *const l2, listitem_T *const bef)
FUNC_ATTR_NONNULL_ARG(1)
{
int todo = tv_list_len(l2);
@@ -758,8 +751,8 @@ typedef struct {
/// @param[in] join_gap Garray to keep each list item string.
///
/// @return OK in case of success, FAIL otherwise.
-static int list_join_inner(garray_T *const gap, list_T *const l,
- const char *const sep, garray_T *const join_gap)
+static int list_join_inner(garray_T *const gap, list_T *const l, const char *const sep,
+ garray_T *const join_gap)
FUNC_ATTR_NONNULL_ALL
{
size_t sumlen = 0;
@@ -844,8 +837,7 @@ int tv_list_join(garray_T *const gap, list_T *const l, const char *const sep)
/// @param[in] recursive True when used recursively.
///
/// @return True if lists are equal, false otherwise.
-bool tv_list_equal(list_T *const l1, list_T *const l2, const bool ic,
- const bool recursive)
+bool tv_list_equal(list_T *const l1, list_T *const l2, const bool ic, const bool recursive)
FUNC_ATTR_WARN_UNUSED_RESULT
{
if (l1 == l2) {
@@ -915,8 +907,7 @@ void tv_list_reverse(list_T *const l)
/// true list will not be modified. Must be initialized to false
/// by the caller.
void tv_list_item_sort(list_T *const l, ListSortItem *const ptrs,
- const ListSorter item_compare_func,
- bool *errp)
+ const ListSorter item_compare_func, bool *errp)
FUNC_ATTR_NONNULL_ARG(3, 4)
{
const int len = tv_list_len(l);
@@ -968,7 +959,7 @@ listitem_T *tv_list_find(list_T *const l, int n)
}
int idx;
- listitem_T *item;
+ listitem_T *item;
// When there is a cached index may start search from there.
if (l->lv_idx_item != NULL) {
@@ -1127,17 +1118,14 @@ bool tv_callback_equal(const Callback *cb1, const Callback *cb2)
return false;
}
switch (cb1->type) {
- case kCallbackFuncref: {
- return STRCMP(cb1->data.funcref, cb2->data.funcref) == 0;
- }
- case kCallbackPartial: {
- // FIXME: this is inconsistent with tv_equal but is needed for precision
- // maybe change dictwatcheradd to return a watcher id instead?
- return cb1->data.partial == cb2->data.partial;
- }
- case kCallbackNone: {
- return true;
- }
+ case kCallbackFuncref:
+ return STRCMP(cb1->data.funcref, cb2->data.funcref) == 0;
+ case kCallbackPartial:
+ // FIXME: this is inconsistent with tv_equal but is needed for precision
+ // maybe change dictwatcheradd to return a watcher id instead?
+ return cb1->data.partial == cb2->data.partial;
+ case kCallbackNone:
+ return true;
}
abort();
return false;
@@ -1148,18 +1136,15 @@ void callback_free(Callback *callback)
FUNC_ATTR_NONNULL_ALL
{
switch (callback->type) {
- case kCallbackFuncref: {
- func_unref(callback->data.funcref);
- xfree(callback->data.funcref);
- break;
- }
- case kCallbackPartial: {
- partial_unref(callback->data.partial);
- break;
- }
- case kCallbackNone: {
- break;
- }
+ case kCallbackFuncref:
+ func_unref(callback->data.funcref);
+ xfree(callback->data.funcref);
+ break;
+ case kCallbackPartial:
+ partial_unref(callback->data.partial);
+ break;
+ case kCallbackNone:
+ break;
}
callback->type = kCallbackNone;
callback->data.funcref = NULL;
@@ -1170,20 +1155,20 @@ void callback_put(Callback *cb, typval_T *tv)
FUNC_ATTR_NONNULL_ALL
{
switch (cb->type) {
- case kCallbackPartial:
- tv->v_type = VAR_PARTIAL;
- tv->vval.v_partial = cb->data.partial;
- cb->data.partial->pt_refcount++;
- break;
- case kCallbackFuncref:
- tv->v_type = VAR_FUNC;
- tv->vval.v_string = vim_strsave(cb->data.funcref);
- func_ref(cb->data.funcref);
- break;
- default:
- tv->v_type = VAR_SPECIAL;
- tv->vval.v_special = kSpecialVarNull;
- break;
+ case kCallbackPartial:
+ tv->v_type = VAR_PARTIAL;
+ tv->vval.v_partial = cb->data.partial;
+ cb->data.partial->pt_refcount++;
+ break;
+ case kCallbackFuncref:
+ tv->v_type = VAR_FUNC;
+ tv->vval.v_string = vim_strsave(cb->data.funcref);
+ func_ref(cb->data.funcref);
+ break;
+ default:
+ tv->v_type = VAR_SPECIAL;
+ tv->vval.v_special = kSpecialVarNull;
+ break;
}
}
@@ -1193,17 +1178,17 @@ void callback_copy(Callback *dest, Callback *src)
{
dest->type = src->type;
switch (src->type) {
- case kCallbackPartial:
- dest->data.partial = src->data.partial;
- dest->data.partial->pt_refcount++;
- break;
- case kCallbackFuncref:
- dest->data.funcref = vim_strsave(src->data.funcref);
- func_ref(src->data.funcref);
- break;
- default:
- dest->data.funcref = NULL;
- break;
+ case kCallbackPartial:
+ dest->data.partial = src->data.partial;
+ dest->data.partial->pt_refcount++;
+ break;
+ case kCallbackFuncref:
+ dest->data.funcref = vim_strsave(src->data.funcref);
+ func_ref(src->data.funcref);
+ break;
+ default:
+ dest->data.funcref = NULL;
+ break;
}
}
@@ -1216,8 +1201,7 @@ void callback_copy(Callback *dest, Callback *src)
///
/// @return True on success, false if relevant watcher was not found.
bool tv_dict_watcher_remove(dict_T *const dict, const char *const key_pattern,
- const size_t key_pattern_len,
- Callback callback)
+ const size_t key_pattern_len, Callback callback)
FUNC_ATTR_NONNULL_ARG(2)
{
if (dict == NULL) {
@@ -1280,8 +1264,8 @@ static bool tv_dict_watcher_matches(DictWatcher *watcher, const char *const key)
/// @param[in] key Key which was modified.
/// @param[in] newtv New key value.
/// @param[in] oldtv Old key value.
-void tv_dict_watcher_notify(dict_T *const dict, const char *const key,
- typval_T *const newtv, typval_T *const oldtv)
+void tv_dict_watcher_notify(dict_T *const dict, const char *const key, typval_T *const newtv,
+ typval_T *const oldtv)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
typval_T argv[3];
@@ -1540,8 +1524,7 @@ void tv_dict_unref(dict_T *const d)
/// @param[in] len Key length. If negative, then strlen(key) is used.
///
/// @return found item or NULL if nothing was found.
-dictitem_T *tv_dict_find(const dict_T *const d, const char *const key,
- const ptrdiff_t len)
+dictitem_T *tv_dict_find(const dict_T *const d, const char *const key, const ptrdiff_t len)
FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (d == NULL) {
@@ -1628,8 +1611,7 @@ char **tv_dict_to_env(dict_T *denv)
/// @return NULL if key does not exist, empty string in case of type error,
/// string item value otherwise. If returned value is not NULL, it may
/// be allocated depending on `save` argument.
-char *tv_dict_get_string(const dict_T *const d, const char *const key,
- const bool save)
+char *tv_dict_get_string(const dict_T *const d, const char *const key, const bool save)
FUNC_ATTR_WARN_UNUSED_RESULT
{
static char numbuf[NUMBUFLEN];
@@ -1649,8 +1631,7 @@ char *tv_dict_get_string(const dict_T *const d, const char *const key,
///
/// @return NULL if key does not exist, empty string in case of type error,
/// string item value otherwise.
-const char *tv_dict_get_string_buf(const dict_T *const d, const char *const key,
- char *const numbuf)
+const char *tv_dict_get_string_buf(const dict_T *const d, const char *const key, char *const numbuf)
FUNC_ATTR_WARN_UNUSED_RESULT
{
const dictitem_T *const di = tv_dict_find(d, key, -1);
@@ -1672,10 +1653,8 @@ const char *tv_dict_get_string_buf(const dict_T *const d, const char *const key,
/// @return `def` when key does not exist,
/// NULL in case of type error,
/// string item value in case of success.
-const char *tv_dict_get_string_buf_chk(const dict_T *const d,
- const char *const key,
- const ptrdiff_t key_len,
- char *const numbuf,
+const char *tv_dict_get_string_buf_chk(const dict_T *const d, const char *const key,
+ const ptrdiff_t key_len, char *const numbuf,
const char *const def)
FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -1695,8 +1674,7 @@ const char *tv_dict_get_string_buf_chk(const dict_T *const d,
/// will be left.
///
/// @return true/false on success/failure.
-bool tv_dict_get_callback(dict_T *const d,
- const char *const key, const ptrdiff_t key_len,
+bool tv_dict_get_callback(dict_T *const d, const char *const key, const ptrdiff_t key_len,
Callback *const result)
FUNC_ATTR_NONNULL_ARG(2, 4) FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -1743,8 +1721,8 @@ int tv_dict_add(dict_T *const d, dictitem_T *const item)
/// @param list List to add. Will have reference count incremented.
///
/// @return OK in case of success, FAIL when key already exists.
-int tv_dict_add_list(dict_T *const d, const char *const key,
- const size_t key_len, list_T *const list)
+int tv_dict_add_list(dict_T *const d, const char *const key, const size_t key_len,
+ list_T *const list)
FUNC_ATTR_NONNULL_ALL
{
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
@@ -1766,15 +1744,14 @@ int tv_dict_add_list(dict_T *const d, const char *const key,
/// @param[in] key_len Key length.
///
/// @return FAIL if out of memory or key already exists.
-int tv_dict_add_tv(dict_T *d, const char *key, const size_t key_len,
- typval_T *tv)
+int tv_dict_add_tv(dict_T *d, const char *key, const size_t key_len, typval_T *tv)
{
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
tv_copy(tv, &item->di_tv);
if (tv_dict_add(d, item) == FAIL) {
- tv_dict_item_free(item);
- return FAIL;
+ tv_dict_item_free(item);
+ return FAIL;
}
return OK;
}
@@ -1787,8 +1764,8 @@ int tv_dict_add_tv(dict_T *d, const char *key, const size_t key_len,
/// @param dict Dictionary to add. Will have reference count incremented.
///
/// @return OK in case of success, FAIL when key already exists.
-int tv_dict_add_dict(dict_T *const d, const char *const key,
- const size_t key_len, dict_T *const dict)
+int tv_dict_add_dict(dict_T *const d, const char *const key, const size_t key_len,
+ dict_T *const dict)
FUNC_ATTR_NONNULL_ALL
{
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
@@ -1811,8 +1788,8 @@ int tv_dict_add_dict(dict_T *const d, const char *const key,
/// @param[in] nr Number to add.
///
/// @return OK in case of success, FAIL when key already exists.
-int tv_dict_add_nr(dict_T *const d, const char *const key,
- const size_t key_len, const varnumber_T nr)
+int tv_dict_add_nr(dict_T *const d, const char *const key, const size_t key_len,
+ const varnumber_T nr)
{
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
@@ -1833,8 +1810,8 @@ int tv_dict_add_nr(dict_T *const d, const char *const key,
/// @param[in] nr Floating point number to add.
///
/// @return OK in case of success, FAIL when key already exists.
-int tv_dict_add_float(dict_T *const d, const char *const key,
- const size_t key_len, const float_T nr)
+int tv_dict_add_float(dict_T *const d, const char *const key, const size_t key_len,
+ const float_T nr)
{
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
@@ -1855,8 +1832,7 @@ int tv_dict_add_float(dict_T *const d, const char *const key,
/// @param[in] val BoolVarValue to add.
///
/// @return OK in case of success, FAIL when key already exists.
-int tv_dict_add_bool(dict_T *const d, const char *const key,
- const size_t key_len, BoolVarValue val)
+int tv_dict_add_bool(dict_T *const d, const char *const key, const size_t key_len, BoolVarValue val)
{
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
@@ -1872,8 +1848,7 @@ int tv_dict_add_bool(dict_T *const d, const char *const key,
/// Add a string entry to dictionary
///
/// @see tv_dict_add_allocated_str
-int tv_dict_add_str(dict_T *const d,
- const char *const key, const size_t key_len,
+int tv_dict_add_str(dict_T *const d, const char *const key, const size_t key_len,
const char *const val)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
@@ -1889,8 +1864,7 @@ int tv_dict_add_str(dict_T *const d,
/// @param[in] len Use this many bytes from `val`, or -1 for whole string.
///
/// @return OK in case of success, FAIL when key already exists.
-int tv_dict_add_str_len(dict_T *const d,
- const char *const key, const size_t key_len,
+int tv_dict_add_str_len(dict_T *const d, const char *const key, const size_t key_len,
const char *const val, int len)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
@@ -1914,8 +1888,7 @@ int tv_dict_add_str_len(dict_T *const d,
/// @param[in] val String to add.
///
/// @return OK in case of success, FAIL when key already exists.
-int tv_dict_add_allocated_str(dict_T *const d,
- const char *const key, const size_t key_len,
+int tv_dict_add_allocated_str(dict_T *const d, const char *const key, const size_t key_len,
char *const val)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
@@ -1958,8 +1931,7 @@ void tv_dict_clear(dict_T *const d)
/// e*, including "error": duplicate key gives an error.
/// f*, including "force": duplicate d2 keys override d1.
/// other, including "keep": duplicate d2 keys ignored.
-void tv_dict_extend(dict_T *const d1, dict_T *const d2,
- const char *const action)
+void tv_dict_extend(dict_T *const d1, dict_T *const d2, const char *const action)
FUNC_ATTR_NONNULL_ALL
{
const bool watched = tv_dict_is_watched(d1);
@@ -2021,8 +1993,7 @@ void tv_dict_extend(dict_T *const d1, dict_T *const d2,
/// @param[in] d2 Second dictionary.
/// @param[in] ic True if case is to be ignored.
/// @param[in] recursive True when used recursively.
-bool tv_dict_equal(dict_T *const d1, dict_T *const d2,
- const bool ic, const bool recursive)
+bool tv_dict_equal(dict_T *const d1, dict_T *const d2, const bool ic, const bool recursive)
FUNC_ATTR_WARN_UNUSED_RESULT
{
if (d1 == d2) {
@@ -2057,9 +2028,7 @@ bool tv_dict_equal(dict_T *const d1, dict_T *const d2,
/// @return Copied dictionary. May be NULL in case original dictionary is NULL
/// or some failure happens. The refcount of the new dictionary is set
/// to 1.
-dict_T *tv_dict_copy(const vimconv_T *const conv,
- dict_T *const orig,
- const bool deep,
+dict_T *tv_dict_copy(const vimconv_T *const conv, dict_T *const orig, const bool deep,
const int copyID)
{
if (orig == NULL) {
@@ -2271,7 +2240,7 @@ void tv_blob_copy(typval_T *const from, typval_T *const to)
if (len > 0) {
to->vval.v_blob->bv_ga.ga_data
- = xmemdup(from->vval.v_blob->bv_ga.ga_data, (size_t)len);
+ = xmemdup(from->vval.v_blob->bv_ga.ga_data, (size_t)len);
}
to->vval.v_blob->bv_ga.ga_len = len;
to->vval.v_blob->bv_ga.ga_maxlen = len;
@@ -2282,52 +2251,51 @@ void tv_blob_copy(typval_T *const from, typval_T *const to)
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
#define TYPVAL_ENCODE_CONV_NIL(tv) \
- do { \
- tv->vval.v_special = kSpecialVarNull; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
+ do { \
+ tv->vval.v_special = kSpecialVarNull; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
- do { \
- tv->vval.v_bool = kBoolVarFalse; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
+ do { \
+ tv->vval.v_bool = kBoolVarFalse; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
- do { \
- (void)num; \
- tv->vval.v_number = 0; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
+ do { \
+ (void)num; \
+ tv->vval.v_number = 0; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num)
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
- do { \
- tv->vval.v_float = 0; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
+ do { \
+ tv->vval.v_float = 0; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
- do { \
- xfree(buf); \
- tv->vval.v_string = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
+ do { \
+ xfree(buf); \
+ tv->vval.v_string = NULL; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len)
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type)
#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \
- do { \
- tv_blob_unref(tv->vval.v_blob); \
- tv->vval.v_blob = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-static inline int _nothing_conv_func_start(typval_T *const tv,
- char_u *const fun)
+ do { \
+ tv_blob_unref(tv->vval.v_blob); \
+ tv->vval.v_blob = NULL; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
+
+static inline int _nothing_conv_func_start(typval_T *const tv, char_u *const fun)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(1)
{
tv->v_lock = VAR_UNLOCKED;
@@ -2348,11 +2316,11 @@ static inline int _nothing_conv_func_start(typval_T *const tv,
return NOTDONE;
}
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
- do { \
- if (_nothing_conv_func_start(tv, fun) != NOTDONE) { \
- return OK; \
- } \
- } while (0)
+ do { \
+ if (_nothing_conv_func_start(tv, fun) != NOTDONE) { \
+ return OK; \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
@@ -2380,14 +2348,13 @@ static inline void _nothing_conv_func_end(typval_T *const tv, const int copyID)
#define TYPVAL_ENCODE_CONV_FUNC_END(tv) _nothing_conv_func_end(tv, copyID)
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
- do { \
- tv_list_unref(tv->vval.v_list); \
- tv->vval.v_list = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-static inline void _nothing_conv_empty_dict(typval_T *const tv,
- dict_T **const dictp)
+ do { \
+ tv_list_unref(tv->vval.v_list); \
+ tv->vval.v_list = NULL; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
+
+static inline void _nothing_conv_empty_dict(typval_T *const tv, dict_T **const dictp)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(2)
{
tv_dict_unref(*dictp);
@@ -2397,13 +2364,13 @@ static inline void _nothing_conv_empty_dict(typval_T *const tv,
}
}
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
- do { \
- assert((void *)&dict != (void *)&TYPVAL_ENCODE_NODICT_VAR); \
- _nothing_conv_empty_dict(tv, ((dict_T **)&dict)); \
- } while (0)
+ do { \
+ assert((void *)&dict != (void *)&TYPVAL_ENCODE_NODICT_VAR); \
+ _nothing_conv_empty_dict(tv, ((dict_T **)&dict)); \
+ } while (0)
-static inline int _nothing_conv_real_list_after_start(
- typval_T *const tv, MPConvStackVal *const mpsv)
+static inline int _nothing_conv_real_list_after_start(typval_T *const tv,
+ MPConvStackVal *const mpsv)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
{
assert(tv != NULL);
@@ -2419,11 +2386,11 @@ static inline int _nothing_conv_real_list_after_start(
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len)
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv) \
- do { \
- if (_nothing_conv_real_list_after_start(tv, &mpsv) != NOTDONE) { \
- goto typval_encode_stop_converting_one_item; \
- } \
- } while (0)
+ do { \
+ if (_nothing_conv_real_list_after_start(tv, &mpsv) != NOTDONE) { \
+ goto typval_encode_stop_converting_one_item; \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv)
@@ -2440,9 +2407,9 @@ static inline void _nothing_conv_list_end(typval_T *const tv)
}
#define TYPVAL_ENCODE_CONV_LIST_END(tv) _nothing_conv_list_end(tv)
-static inline int _nothing_conv_real_dict_after_start(
- typval_T *const tv, dict_T **const dictp, const void *const nodictvar,
- MPConvStackVal *const mpsv)
+static inline int _nothing_conv_real_dict_after_start(typval_T *const tv, dict_T **const dictp,
+ const void *const nodictvar,
+ MPConvStackVal *const mpsv)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (tv != NULL) {
@@ -2459,20 +2426,18 @@ static inline int _nothing_conv_real_dict_after_start(
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len)
#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv) \
- do { \
- if (_nothing_conv_real_dict_after_start( \
- tv, (dict_T **)&dict, (void *)&TYPVAL_ENCODE_NODICT_VAR, \
- &mpsv) != NOTDONE) { \
- goto typval_encode_stop_converting_one_item; \
- } \
- } while (0)
+ do { \
+ if (_nothing_conv_real_dict_after_start(tv, (dict_T **)&dict, (void *)&TYPVAL_ENCODE_NODICT_VAR, \
+ &mpsv) != NOTDONE) { \
+ goto typval_encode_stop_converting_one_item; \
+ } \
+ } while (0)
#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(tv, dict)
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict)
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict)
-static inline void _nothing_conv_dict_end(typval_T *const tv,
- dict_T **const dictp,
+static inline void _nothing_conv_dict_end(typval_T *const tv, dict_T **const dictp,
const void *const nodictvar)
FUNC_ATTR_ALWAYS_INLINE
{
@@ -2482,8 +2447,8 @@ static inline void _nothing_conv_dict_end(typval_T *const tv,
}
}
#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
- _nothing_conv_dict_end(tv, (dict_T **)&dict, \
- (void *)&TYPVAL_ENCODE_NODICT_VAR)
+ _nothing_conv_dict_end(tv, (dict_T **)&dict, \
+ (void *)&TYPVAL_ENCODE_NODICT_VAR)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type)
@@ -2554,37 +2519,30 @@ void tv_free(typval_T *tv)
{
if (tv != NULL) {
switch (tv->v_type) {
- case VAR_PARTIAL: {
- partial_unref(tv->vval.v_partial);
- break;
- }
- case VAR_FUNC: {
- func_unref(tv->vval.v_string);
- FALLTHROUGH;
- }
- case VAR_STRING: {
- xfree(tv->vval.v_string);
- break;
- }
- case VAR_BLOB: {
- tv_blob_unref(tv->vval.v_blob);
- break;
- }
- case VAR_LIST: {
- tv_list_unref(tv->vval.v_list);
- break;
- }
- case VAR_DICT: {
- tv_dict_unref(tv->vval.v_dict);
- break;
- }
- case VAR_BOOL:
- case VAR_SPECIAL:
- case VAR_NUMBER:
- case VAR_FLOAT:
- case VAR_UNKNOWN: {
- break;
- }
+ case VAR_PARTIAL:
+ partial_unref(tv->vval.v_partial);
+ break;
+ case VAR_FUNC:
+ func_unref(tv->vval.v_string);
+ FALLTHROUGH;
+ case VAR_STRING:
+ xfree(tv->vval.v_string);
+ break;
+ case VAR_BLOB:
+ tv_blob_unref(tv->vval.v_blob);
+ break;
+ case VAR_LIST:
+ tv_list_unref(tv->vval.v_list);
+ break;
+ case VAR_DICT:
+ tv_dict_unref(tv->vval.v_dict);
+ break;
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ case VAR_NUMBER:
+ case VAR_FLOAT:
+ case VAR_UNKNOWN:
+ break;
}
xfree(tv);
}
@@ -2608,48 +2566,41 @@ void tv_copy(const typval_T *const from, typval_T *const to)
to->v_lock = VAR_UNLOCKED;
memmove(&to->vval, &from->vval, sizeof(to->vval));
switch (from->v_type) {
- case VAR_NUMBER:
- case VAR_FLOAT:
- case VAR_BOOL:
- case VAR_SPECIAL: {
- break;
- }
- case VAR_STRING:
- case VAR_FUNC: {
- if (from->vval.v_string != NULL) {
- to->vval.v_string = vim_strsave(from->vval.v_string);
- if (from->v_type == VAR_FUNC) {
- func_ref(to->vval.v_string);
- }
+ case VAR_NUMBER:
+ case VAR_FLOAT:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ break;
+ case VAR_STRING:
+ case VAR_FUNC:
+ if (from->vval.v_string != NULL) {
+ to->vval.v_string = vim_strsave(from->vval.v_string);
+ if (from->v_type == VAR_FUNC) {
+ func_ref(to->vval.v_string);
}
- break;
}
- case VAR_PARTIAL: {
- if (to->vval.v_partial != NULL) {
- to->vval.v_partial->pt_refcount++;
- }
- break;
+ break;
+ case VAR_PARTIAL:
+ if (to->vval.v_partial != NULL) {
+ to->vval.v_partial->pt_refcount++;
}
- case VAR_BLOB: {
- if (from->vval.v_blob != NULL) {
- to->vval.v_blob->bv_refcount++;
- }
- break;
+ break;
+ case VAR_BLOB:
+ if (from->vval.v_blob != NULL) {
+ to->vval.v_blob->bv_refcount++;
}
- case VAR_LIST: {
- tv_list_ref(to->vval.v_list);
- break;
- }
- case VAR_DICT: {
- if (from->vval.v_dict != NULL) {
- to->vval.v_dict->dv_refcount++;
- }
- break;
- }
- case VAR_UNKNOWN: {
- emsgf(_(e_intern2), "tv_copy(UNKNOWN)");
- break;
+ break;
+ case VAR_LIST:
+ tv_list_ref(to->vval.v_list);
+ break;
+ case VAR_DICT:
+ if (from->vval.v_dict != NULL) {
+ to->vval.v_dict->dv_refcount++;
}
+ break;
+ case VAR_UNKNOWN:
+ emsgf(_(e_intern2), "tv_copy(UNKNOWN)");
+ break;
}
}
@@ -2662,8 +2613,7 @@ void tv_copy(const typval_T *const from, typval_T *const to)
/// @param[in] lock True if it is needed to lock an item, false to unlock.
/// @param[in] check_refcount If true, do not lock a list or dict with a
/// reference count larger than 1.
-void tv_item_lock(typval_T *const tv, const int deep, const bool lock,
- const bool check_refcount)
+void tv_item_lock(typval_T *const tv, const int deep, const bool lock, const bool check_refcount)
FUNC_ATTR_NONNULL_ALL
{
// TODO(ZyX-I): Make this not recursive
@@ -2690,51 +2640,49 @@ void tv_item_lock(typval_T *const tv, const int deep, const bool lock,
CHANGE_LOCK(lock, tv->v_lock);
switch (tv->v_type) {
- case VAR_BLOB: {
- blob_T *const b = tv->vval.v_blob;
- if (b != NULL && !(check_refcount && b->bv_refcount > 1)) {
- CHANGE_LOCK(lock, b->bv_lock);
- }
- break;
- }
- case VAR_LIST: {
- list_T *const l = tv->vval.v_list;
- if (l != NULL && !(check_refcount && l->lv_refcount > 1)) {
- CHANGE_LOCK(lock, l->lv_lock);
- if (deep < 0 || deep > 1) {
- // Recursive: lock/unlock the items the List contains.
- TV_LIST_ITER(l, li, {
+ case VAR_BLOB: {
+ blob_T *const b = tv->vval.v_blob;
+ if (b != NULL && !(check_refcount && b->bv_refcount > 1)) {
+ CHANGE_LOCK(lock, b->bv_lock);
+ }
+ break;
+ }
+ case VAR_LIST: {
+ list_T *const l = tv->vval.v_list;
+ if (l != NULL && !(check_refcount && l->lv_refcount > 1)) {
+ CHANGE_LOCK(lock, l->lv_lock);
+ if (deep < 0 || deep > 1) {
+ // Recursive: lock/unlock the items the List contains.
+ TV_LIST_ITER(l, li, {
tv_item_lock(TV_LIST_ITEM_TV(li), deep - 1, lock, check_refcount);
});
- }
}
- break;
}
- case VAR_DICT: {
- dict_T *const d = tv->vval.v_dict;
- if (d != NULL && !(check_refcount && d->dv_refcount > 1)) {
- CHANGE_LOCK(lock, d->dv_lock);
- if (deep < 0 || deep > 1) {
- // recursive: lock/unlock the items the List contains
- TV_DICT_ITER(d, di, {
+ break;
+ }
+ case VAR_DICT: {
+ dict_T *const d = tv->vval.v_dict;
+ if (d != NULL && !(check_refcount && d->dv_refcount > 1)) {
+ CHANGE_LOCK(lock, d->dv_lock);
+ if (deep < 0 || deep > 1) {
+ // recursive: lock/unlock the items the List contains
+ TV_DICT_ITER(d, di, {
tv_item_lock(&di->di_tv, deep - 1, lock, check_refcount);
});
- }
}
- break;
- }
- case VAR_NUMBER:
- case VAR_FLOAT:
- case VAR_STRING:
- case VAR_FUNC:
- case VAR_PARTIAL:
- case VAR_BOOL:
- case VAR_SPECIAL: {
- break;
- }
- case VAR_UNKNOWN: {
- abort();
}
+ break;
+ }
+ case VAR_NUMBER:
+ case VAR_FLOAT:
+ case VAR_STRING:
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ break;
+ case VAR_UNKNOWN:
+ abort();
}
#undef CHANGE_LOCK
recurse--;
@@ -2776,33 +2724,32 @@ bool tv_islocked(const typval_T *const tv)
/// gettext.
///
/// @return true if variable is locked, false otherwise.
-bool tv_check_lock(const typval_T *tv, const char *name,
- size_t name_len)
+bool tv_check_lock(const typval_T *tv, const char *name, size_t name_len)
FUNC_ATTR_WARN_UNUSED_RESULT
{
VarLockStatus lock = VAR_UNLOCKED;
switch (tv->v_type) {
- case VAR_BLOB:
- if (tv->vval.v_blob != NULL) {
- lock = tv->vval.v_blob->bv_lock;
- }
- break;
- case VAR_LIST:
- if (tv->vval.v_list != NULL) {
- lock = tv->vval.v_list->lv_lock;
- }
- break;
- case VAR_DICT:
- if (tv->vval.v_dict != NULL) {
- lock = tv->vval.v_dict->dv_lock;
- }
- break;
- default:
- break;
+ case VAR_BLOB:
+ if (tv->vval.v_blob != NULL) {
+ lock = tv->vval.v_blob->bv_lock;
+ }
+ break;
+ case VAR_LIST:
+ if (tv->vval.v_list != NULL) {
+ lock = tv->vval.v_list->lv_lock;
+ }
+ break;
+ case VAR_DICT:
+ if (tv->vval.v_dict != NULL) {
+ lock = tv->vval.v_dict->dv_lock;
+ }
+ break;
+ default:
+ break;
}
return var_check_lock(tv->v_lock, name, name_len)
- || (lock != VAR_UNLOCKED && var_check_lock(lock, name, name_len));
+ || (lock != VAR_UNLOCKED && var_check_lock(lock, name, name_len));
}
/// @return true if variable "name" is locked (immutable)
@@ -2810,17 +2757,14 @@ bool var_check_lock(VarLockStatus lock, const char *name, size_t name_len)
{
const char *error_message = NULL;
switch (lock) {
- case VAR_UNLOCKED: {
- return false;
- }
- case VAR_LOCKED: {
- error_message = N_("E741: Value is locked: %.*s");
- break;
- }
- case VAR_FIXED: {
- error_message = N_("E742: Cannot change value of %.*s");
- break;
- }
+ case VAR_UNLOCKED:
+ return false;
+ case VAR_LOCKED:
+ error_message = N_("E741: Value is locked: %.*s");
+ break;
+ case VAR_FIXED:
+ error_message = N_("E742: Cannot change value of %.*s");
+ break;
}
assert(error_message != NULL);
@@ -2856,8 +2800,7 @@ static int tv_equal_recurse_limit;
/// @param[in] recursive True when used recursively.
///
/// @return true if values are equal.
-bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic,
- const bool recursive)
+bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic, const bool recursive)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
// TODO(ZyX-I): Make this not recursive
@@ -2882,58 +2825,52 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic,
}
switch (tv1->v_type) {
- case VAR_LIST: {
- recursive_cnt++;
- const bool r = tv_list_equal(tv1->vval.v_list, tv2->vval.v_list, ic,
- true);
- recursive_cnt--;
- return r;
- }
- case VAR_DICT: {
- recursive_cnt++;
- const bool r = tv_dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic,
- true);
- recursive_cnt--;
- return r;
- }
- case VAR_PARTIAL:
- case VAR_FUNC: {
- if ((tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial == NULL)
- || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial == NULL)) {
- return false;
- }
- recursive_cnt++;
- const bool r = func_equal(tv1, tv2, ic);
- recursive_cnt--;
- return r;
- }
- case VAR_BLOB: {
- return tv_blob_equal(tv1->vval.v_blob, tv2->vval.v_blob);
- }
- case VAR_NUMBER: {
- return tv1->vval.v_number == tv2->vval.v_number;
- }
- case VAR_FLOAT: {
- return tv1->vval.v_float == tv2->vval.v_float;
- }
- case VAR_STRING: {
- char buf1[NUMBUFLEN];
- 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;
- }
- case VAR_BOOL: {
- return tv1->vval.v_bool == tv2->vval.v_bool;
- }
- case VAR_SPECIAL: {
- return tv1->vval.v_special == tv2->vval.v_special;
- }
- case VAR_UNKNOWN: {
- // VAR_UNKNOWN can be the result of an invalid expression, let’s say it
- // does not equal anything, not even self.
+ case VAR_LIST: {
+ recursive_cnt++;
+ const bool r = tv_list_equal(tv1->vval.v_list, tv2->vval.v_list, ic,
+ true);
+ recursive_cnt--;
+ return r;
+ }
+ case VAR_DICT: {
+ recursive_cnt++;
+ const bool r = tv_dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic,
+ true);
+ recursive_cnt--;
+ return r;
+ }
+ case VAR_PARTIAL:
+ case VAR_FUNC: {
+ if ((tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial == NULL)
+ || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial == NULL)) {
return false;
}
+ recursive_cnt++;
+ const bool r = func_equal(tv1, tv2, ic);
+ recursive_cnt--;
+ return r;
+ }
+ case VAR_BLOB:
+ return tv_blob_equal(tv1->vval.v_blob, tv2->vval.v_blob);
+ case VAR_NUMBER:
+ return tv1->vval.v_number == tv2->vval.v_number;
+ case VAR_FLOAT:
+ return tv1->vval.v_float == tv2->vval.v_float;
+ case VAR_STRING: {
+ char buf1[NUMBUFLEN];
+ 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;
+ }
+ case VAR_BOOL:
+ return tv1->vval.v_bool == tv2->vval.v_bool;
+ case VAR_SPECIAL:
+ return tv1->vval.v_special == tv2->vval.v_special;
+ case VAR_UNKNOWN:
+ // VAR_UNKNOWN can be the result of an invalid expression, let’s say it
+ // does not equal anything, not even self.
+ return false;
}
abort();
@@ -2955,43 +2892,34 @@ bool tv_check_str_or_nr(const typval_T *const tv)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
switch (tv->v_type) {
- case VAR_NUMBER:
- case VAR_STRING: {
- return true;
- }
- case VAR_FLOAT: {
- EMSG(_("E805: Expected a Number or a String, Float found"));
- return false;
- }
- case VAR_PARTIAL:
- case VAR_FUNC: {
- EMSG(_("E703: Expected a Number or a String, Funcref found"));
- return false;
- }
- case VAR_LIST: {
- EMSG(_("E745: Expected a Number or a String, List found"));
- return false;
- }
- case VAR_DICT: {
- EMSG(_("E728: Expected a Number or a String, Dictionary found"));
- return false;
- }
- case VAR_BLOB: {
- EMSG(_("E974: Expected a Number or a String, Blob found"));
- return false;
- }
- case VAR_BOOL: {
- EMSG(_("E5299: Expected a Number or a String, Boolean found"));
- return false;
- }
- case VAR_SPECIAL: {
- EMSG(_("E5300: Expected a Number or a String"));
- return false;
- }
- case VAR_UNKNOWN: {
- EMSG2(_(e_intern2), "tv_check_str_or_nr(UNKNOWN)");
- return false;
- }
+ case VAR_NUMBER:
+ case VAR_STRING:
+ return true;
+ case VAR_FLOAT:
+ EMSG(_("E805: Expected a Number or a String, Float found"));
+ return false;
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ EMSG(_("E703: Expected a Number or a String, Funcref found"));
+ return false;
+ case VAR_LIST:
+ EMSG(_("E745: Expected a Number or a String, List found"));
+ return false;
+ case VAR_DICT:
+ EMSG(_("E728: Expected a Number or a String, Dictionary found"));
+ return false;
+ case VAR_BLOB:
+ EMSG(_("E974: Expected a Number or a String, Blob found"));
+ return false;
+ case VAR_BOOL:
+ EMSG(_("E5299: Expected a Number or a String, Boolean found"));
+ return false;
+ case VAR_SPECIAL:
+ EMSG(_("E5300: Expected a Number or a String"));
+ return false;
+ case VAR_UNKNOWN:
+ EMSG2(_(e_intern2), "tv_check_str_or_nr(UNKNOWN)");
+ return false;
}
abort();
return false;
@@ -3023,22 +2951,20 @@ bool tv_check_num(const typval_T *const tv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (tv->v_type) {
- case VAR_NUMBER:
- case VAR_BOOL:
- case VAR_SPECIAL:
- case VAR_STRING: {
- return true;
- }
- case VAR_FUNC:
- case VAR_PARTIAL:
- case VAR_LIST:
- case VAR_DICT:
- case VAR_FLOAT:
- case VAR_BLOB:
- case VAR_UNKNOWN: {
- EMSG(_(num_errors[tv->v_type]));
- return false;
- }
+ case VAR_NUMBER:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ case VAR_STRING:
+ return true;
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_FLOAT:
+ case VAR_BLOB:
+ case VAR_UNKNOWN:
+ EMSG(_(num_errors[tv->v_type]));
+ return false;
}
abort();
return false;
@@ -3070,22 +2996,20 @@ bool tv_check_str(const typval_T *const tv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (tv->v_type) {
- case VAR_NUMBER:
- case VAR_BOOL:
- case VAR_SPECIAL:
- case VAR_STRING: {
- return true;
- }
- case VAR_PARTIAL:
- case VAR_FUNC:
- case VAR_LIST:
- case VAR_DICT:
- case VAR_FLOAT:
- case VAR_BLOB:
- case VAR_UNKNOWN: {
- EMSG(_(str_errors[tv->v_type]));
- return false;
- }
+ case VAR_NUMBER:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ case VAR_STRING:
+ return true;
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_FLOAT:
+ case VAR_BLOB:
+ case VAR_UNKNOWN:
+ EMSG(_(str_errors[tv->v_type]));
+ return false;
}
abort();
return false;
@@ -3125,36 +3049,31 @@ varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1)
{
switch (tv->v_type) {
- case VAR_FUNC:
- case VAR_PARTIAL:
- case VAR_LIST:
- case VAR_DICT:
- case VAR_BLOB:
- case VAR_FLOAT: {
- EMSG(_(num_errors[tv->v_type]));
- break;
- }
- case VAR_NUMBER: {
- return tv->vval.v_number;
- }
- case VAR_STRING: {
- varnumber_T n = 0;
- if (tv->vval.v_string != NULL) {
- vim_str2nr(tv->vval.v_string, NULL, NULL, STR2NR_ALL, &n, NULL, 0,
- false);
- }
- return n;
- }
- case VAR_BOOL: {
- return tv->vval.v_bool == kBoolVarTrue ? 1 : 0;
- }
- case VAR_SPECIAL: {
- return 0;
- }
- case VAR_UNKNOWN: {
- emsgf(_(e_intern2), "tv_get_number(UNKNOWN)");
- break;
- }
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_BLOB:
+ case VAR_FLOAT:
+ EMSG(_(num_errors[tv->v_type]));
+ break;
+ case VAR_NUMBER:
+ return tv->vval.v_number;
+ case VAR_STRING: {
+ varnumber_T n = 0;
+ if (tv->vval.v_string != NULL) {
+ vim_str2nr(tv->vval.v_string, NULL, NULL, STR2NR_ALL, &n, NULL, 0,
+ false);
+ }
+ return n;
+ }
+ case VAR_BOOL:
+ return tv->vval.v_bool == kBoolVarTrue ? 1 : 0;
+ case VAR_SPECIAL:
+ return 0;
+ case VAR_UNKNOWN:
+ emsgf(_(e_intern2), "tv_get_number(UNKNOWN)");
+ break;
}
if (ret_error != NULL) {
*ret_error = true;
@@ -3194,45 +3113,35 @@ float_T tv_get_float(const typval_T *const tv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (tv->v_type) {
- case VAR_NUMBER: {
- return (float_T)(tv->vval.v_number);
- }
- case VAR_FLOAT: {
- return tv->vval.v_float;
- }
- case VAR_PARTIAL:
- case VAR_FUNC: {
- EMSG(_("E891: Using a Funcref as a Float"));
- break;
- }
- case VAR_STRING: {
- EMSG(_("E892: Using a String as a Float"));
- break;
- }
- case VAR_LIST: {
- EMSG(_("E893: Using a List as a Float"));
- break;
- }
- case VAR_DICT: {
- EMSG(_("E894: Using a Dictionary as a Float"));
- break;
- }
- case VAR_BOOL: {
- EMSG(_("E362: Using a boolean value as a Float"));
- break;
- }
- case VAR_SPECIAL: {
- EMSG(_("E907: Using a special value as a Float"));
- break;
- }
- case VAR_BLOB: {
- EMSG(_("E975: Using a Blob as a Float"));
- break;
- }
- case VAR_UNKNOWN: {
- emsgf(_(e_intern2), "tv_get_float(UNKNOWN)");
- break;
- }
+ case VAR_NUMBER:
+ return (float_T)(tv->vval.v_number);
+ case VAR_FLOAT:
+ return tv->vval.v_float;
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ EMSG(_("E891: Using a Funcref as a Float"));
+ break;
+ case VAR_STRING:
+ EMSG(_("E892: Using a String as a Float"));
+ break;
+ case VAR_LIST:
+ EMSG(_("E893: Using a List as a Float"));
+ break;
+ case VAR_DICT:
+ EMSG(_("E894: Using a Dictionary as a Float"));
+ break;
+ case VAR_BOOL:
+ EMSG(_("E362: Using a boolean value as a Float"));
+ break;
+ case VAR_SPECIAL:
+ EMSG(_("E907: Using a special value as a Float"));
+ break;
+ case VAR_BLOB:
+ EMSG(_("E975: Using a Blob as a Float"));
+ break;
+ case VAR_UNKNOWN:
+ emsgf(_(e_intern2), "tv_get_float(UNKNOWN)");
+ break;
}
return 0;
}
@@ -3265,34 +3174,29 @@ const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (tv->v_type) {
- case VAR_NUMBER: {
- snprintf(buf, NUMBUFLEN, "%" PRIdVARNUMBER, tv->vval.v_number); // -V576
- return buf;
- }
- case VAR_STRING: {
- if (tv->vval.v_string != NULL) {
- return (const char *)tv->vval.v_string;
- }
- return "";
- }
- case VAR_BOOL: {
- STRCPY(buf, encode_bool_var_names[tv->vval.v_bool]);
- return buf;
- }
- case VAR_SPECIAL: {
- STRCPY(buf, encode_special_var_names[tv->vval.v_special]);
- return buf;
- }
- case VAR_PARTIAL:
- case VAR_FUNC:
- case VAR_LIST:
- case VAR_DICT:
- case VAR_FLOAT:
- case VAR_BLOB:
- case VAR_UNKNOWN: {
- EMSG(_(str_errors[tv->v_type]));
- return false;
- }
+ case VAR_NUMBER:
+ snprintf(buf, NUMBUFLEN, "%" PRIdVARNUMBER, tv->vval.v_number); // -V576
+ return buf;
+ case VAR_STRING:
+ if (tv->vval.v_string != NULL) {
+ return (const char *)tv->vval.v_string;
+ }
+ return "";
+ case VAR_BOOL:
+ STRCPY(buf, encode_bool_var_names[tv->vval.v_bool]);
+ return buf;
+ case VAR_SPECIAL:
+ STRCPY(buf, encode_special_var_names[tv->vval.v_special]);
+ return buf;
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_FLOAT:
+ case VAR_BLOB:
+ case VAR_UNKNOWN:
+ EMSG(_(str_errors[tv->v_type]));
+ return false;
}
return NULL;
}
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index 350c5ee1c2..2137804fdd 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -13,7 +13,6 @@
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
-#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
#include "nvim/getchar.h"
#include "nvim/globals.h"
@@ -55,24 +54,23 @@ static funccall_T *current_funccal = NULL;
// item in it is still being used.
static funccall_T *previous_funccal = NULL;
-static char *e_funcexts = N_(
- "E122: Function %s already exists, add ! to replace it");
+static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it");
static char *e_funcdict = N_("E717: Dictionary entry already exists");
static char *e_funcref = N_("E718: Funcref required");
static char *e_nofunc = N_("E130: Unknown function: %s");
void func_init(void)
{
- hash_init(&func_hashtab);
+ hash_init(&func_hashtab);
}
/// Get function arguments.
-static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs,
- int *varargs, garray_T *default_args, bool skip)
+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;
- char_u *arg = *argp;
- char_u *p = arg;
+ char_u *arg = *argp;
+ char_u *p = arg;
int c;
int i;
@@ -146,7 +144,7 @@ static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs,
*p = NUL;
expr = vim_strsave(expr);
((char_u **)(default_args->ga_data))
- [default_args->ga_len] = expr;
+ [default_args->ga_len] = expr;
default_args->ga_len++;
*p = c;
} else {
@@ -200,18 +198,18 @@ static void register_closure(ufunc_T *fp)
current_funccal->fc_refcount++;
ga_grow(&current_funccal->fc_funcs, 1);
((ufunc_T **)current_funccal->fc_funcs.ga_data)
- [current_funccal->fc_funcs.ga_len++] = fp;
+ [current_funccal->fc_funcs.ga_len++] = fp;
}
/// Get a name for a lambda. Returned in static memory.
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;
+ snprintf((char *)name, sizeof(name), "<lambda>%d", ++lambda_no);
+ return name;
}
/// Parse a lambda expression and get a Funcref from "*arg".
@@ -220,14 +218,14 @@ char_u * get_lambda_name(void)
int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate)
{
garray_T newargs = GA_EMPTY_INIT_VALUE;
- garray_T *pnewargs;
- ufunc_T *fp = NULL;
+ garray_T *pnewargs;
+ ufunc_T *fp = NULL;
partial_T *pt = NULL;
int varargs;
int ret;
- char_u *start = skipwhite(*arg + 1);
- char_u *s, *e;
- bool *old_eval_lavars = eval_lavars_used;
+ char_u *start = skipwhite(*arg + 1);
+ char_u *s, *e;
+ bool *old_eval_lavars = eval_lavars_used;
bool eval_lavars = false;
// First, check if this is a lambda expression. "->" must exists.
@@ -348,8 +346,7 @@ errret:
/// was not found.
///
/// @return name of the function.
-char_u *deref_func_name(const char *name, int *lenp,
- partial_T **const partialp, bool no_autoload)
+char_u *deref_func_name(const char *name, int *lenp, partial_T **const partialp, bool no_autoload)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
if (partialp != NULL) {
@@ -409,19 +406,16 @@ 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
-)
-{
- char_u *argp;
+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
+ )
+{
+ char_u *argp;
int ret = OK;
- typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */
- int argcount = 0; /* number of arguments found */
+ typval_T argvars[MAX_FUNC_ARGS + 1]; // vars for arguments
+ int argcount = 0; // number of arguments found
/*
* Get the arguments.
@@ -438,13 +432,15 @@ get_func_tv(
break;
}
++argcount;
- if (*argp != ',')
+ if (*argp != ',') {
break;
+ }
}
- if (*argp == ')')
+ if (*argp == ')') {
++argp;
- else
+ } else {
ret = FAIL;
+ }
if (ret == OK) {
int i = 0;
@@ -512,8 +508,7 @@ static inline bool eval_fname_sid(const char *const name)
///
/// @return transformed name: either `fname_buf` or a pointer to an allocated
/// memory.
-static char_u *fname_trans_sid(const char_u *const name,
- char_u *const fname_buf,
+static char_u *fname_trans_sid(const char_u *const name, char_u *const fname_buf,
char_u **const tofree, int *const error)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -553,11 +548,12 @@ static char_u *fname_trans_sid(const char_u *const name,
/// @return NULL for unknown function.
ufunc_T *find_func(const char_u *name)
{
- hashitem_T *hi;
+ hashitem_T *hi;
hi = hash_find(&func_hashtab, name);
- if (!HASHITEM_EMPTY(hi))
+ if (!HASHITEM_EMPTY(hi)) {
return HI2UF(hi);
+ }
return NULL;
}
@@ -571,8 +567,9 @@ static void cat_func_name(char_u *buf, ufunc_T *fp)
if (fp->uf_name[0] == K_SPECIAL) {
STRCPY(buf, "<SNR>");
STRCAT(buf, fp->uf_name + 3);
- } else
+ } else {
STRCPY(buf, fp->uf_name);
+ }
}
/*
@@ -662,7 +659,6 @@ static void cleanup_function_call(funccall_T *fc)
if (may_free_fc && fc->l_varlist.lv_refcount // NOLINT(runtime/deprecated)
== DO_NOT_FREE_CNT) {
fc->l_varlist.lv_first = NULL; // NOLINT(runtime/deprecated)
-
} else {
free_fc = false;
@@ -807,23 +803,22 @@ static void func_clear_free(ufunc_T *fp, bool force)
/// @param[in] firstline First line of range.
/// @param[in] lastline Last line of range.
/// @param selfdict Dictionary for "self" for dictionary functions.
-void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
- typval_T *rettv, linenr_T firstline, linenr_T lastline,
- dict_T *selfdict)
+void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv,
+ linenr_T firstline, linenr_T lastline, dict_T *selfdict)
FUNC_ATTR_NONNULL_ARG(1, 3, 4)
{
- char_u *save_sourcing_name;
+ char_u *save_sourcing_name;
linenr_T save_sourcing_lnum;
bool using_sandbox = false;
- funccall_T *fc;
+ funccall_T *fc;
int save_did_emsg;
static int depth = 0;
- dictitem_T *v;
+ dictitem_T *v;
int fixvar_idx = 0; // index in fixvar[]
int ai;
bool islambda = false;
char_u numbuf[NUMBUFLEN];
- char_u *name;
+ char_u *name;
typval_T *tv_to_free[MAX_FUNC_ARGS];
int tv_to_free_len = 0;
proftime_T wait_start;
@@ -949,7 +944,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
def_rettv.vval.v_number = -1;
default_expr = ((char_u **)(fp->uf_def_args.ga_data))
- [ai + fp->uf_def_args.ga_len];
+ [ai + fp->uf_def_args.ga_len];
if (eval1(&default_expr, &def_rettv, true) == FAIL) {
default_arg_err = true;
break;
@@ -1135,7 +1130,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
call_start = profile_sub_wait(wait_start, call_start); // -V614
fp->uf_tm_total = profile_add(fp->uf_tm_total, call_start);
fp->uf_tm_self = profile_self(fp->uf_tm_self, call_start,
- fp->uf_tm_children);
+ fp->uf_tm_children);
if (fc->caller != NULL && fc->caller->func->uf_profiling) {
fc->caller->func->uf_tm_children =
profile_add(fc->caller->func->uf_tm_children, call_start);
@@ -1153,19 +1148,19 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
++no_wait_return;
verbose_enter_scroll();
- if (aborting())
+ if (aborting()) {
smsg(_("%s aborted"), sourcing_name);
- else if (fc->rettv->v_type == VAR_NUMBER)
+ } else if (fc->rettv->v_type == VAR_NUMBER) {
smsg(_("%s returning #%" PRId64 ""),
sourcing_name, (int64_t)fc->rettv->vval.v_number);
- else {
+ } else {
char_u buf[MSG_BUF_LEN];
// The value may be very long. Skip the middle part, so that we
// have some idea how it starts and ends. smsg() would always
// truncate it at the end. Don't want errors such as E724 here.
emsg_off++;
- char_u *s = (char_u *) encode_tv2string(fc->rettv, NULL);
+ char_u *s = (char_u *)encode_tv2string(fc->rettv, NULL);
char_u *tofree = s;
emsg_off--;
if (s != NULL) {
@@ -1269,8 +1264,8 @@ void set_current_funccal(funccall_T *fc)
#if defined(EXITFREE)
void free_all_functions(void)
{
- hashitem_T *hi;
- ufunc_T *fp;
+ hashitem_T *hi;
+ ufunc_T *fp;
uint64_t skipped = 0;
uint64_t todo = 1;
uint64_t used;
@@ -1357,8 +1352,7 @@ static bool builtin_function(const char *name, int len)
return p == NULL;
}
-int func_call(char_u *name, typval_T *args, partial_T *partial,
- dict_T *selfdict, typval_T *rettv)
+int func_call(char_u *name, typval_T *args, partial_T *partial, dict_T *selfdict, typval_T *rettv)
{
typval_T argv[MAX_FUNC_ARGS + 1];
int argc = 0;
@@ -1397,38 +1391,37 @@ static void user_func_error(int error, const char_u *name)
FUNC_ATTR_NONNULL_ALL
{
switch (error) {
- case ERROR_UNKNOWN:
- emsg_funcname(N_("E117: Unknown function: %s"), name);
- break;
- case ERROR_NOTMETHOD:
- emsg_funcname(N_("E276: Cannot use function as a method: %s"), name);
- break;
- case ERROR_DELETED:
- emsg_funcname(N_("E933: Function was deleted: %s"), name);
- break;
- case ERROR_TOOMANY:
- emsg_funcname(_(e_toomanyarg), name);
- break;
- case ERROR_TOOFEW:
- emsg_funcname(N_("E119: Not enough arguments for function: %s"),
- name);
- break;
- case ERROR_SCRIPT:
- emsg_funcname(N_("E120: Using <SID> not in a script context: %s"),
- name);
- break;
- case ERROR_DICT:
- emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"),
- name);
- break;
+ case ERROR_UNKNOWN:
+ emsg_funcname(N_("E117: Unknown function: %s"), name);
+ break;
+ case ERROR_NOTMETHOD:
+ emsg_funcname(N_("E276: Cannot use function as a method: %s"), name);
+ break;
+ case ERROR_DELETED:
+ emsg_funcname(N_("E933: Function was deleted: %s"), name);
+ break;
+ case ERROR_TOOMANY:
+ emsg_funcname(_(e_toomanyarg), name);
+ break;
+ case ERROR_TOOFEW:
+ emsg_funcname(N_("E119: Not enough arguments for function: %s"),
+ name);
+ break;
+ case ERROR_SCRIPT:
+ emsg_funcname(N_("E120: Using <SID> not in a script context: %s"),
+ name);
+ break;
+ case ERROR_DICT:
+ emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"),
+ name);
+ break;
}
}
/// Used by call_func to add a method base (if any) to a function argument list
/// as the first argument. @see call_func
-static void argv_add_base(typval_T *const basetv, typval_T **const argvars,
- int *const argcount, typval_T *const new_argvars,
- int *const argv_base)
+static void argv_add_base(typval_T *const basetv, typval_T **const argvars, int *const argcount,
+ typval_T *const new_argvars, int *const argv_base)
FUNC_ATTR_NONNULL_ARG(2, 3, 4, 5)
{
if (basetv != NULL) {
@@ -1446,16 +1439,14 @@ static void argv_add_base(typval_T *const basetv, typval_T **const argvars,
/// @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, // 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
+ )
FUNC_ATTR_NONNULL_ARG(1, 3, 5, 6)
{
int ret = FAIL;
@@ -1612,8 +1603,9 @@ call_func(
*/
update_force_abort();
}
- if (error == ERROR_NONE)
+ if (error == ERROR_NONE) {
ret = OK;
+ }
theend:
// Report an error unless the argument evaluation or function call has been
@@ -1641,8 +1633,9 @@ theend:
static void list_func_head(ufunc_T *fp, int indent, bool force)
{
msg_start();
- if (indent)
+ if (indent) {
MSG_PUTS(" ");
+ }
MSG_PUTS(force ? "function! " : "function ");
if (fp->uf_name[0] == K_SPECIAL) {
MSG_PUTS_ATTR("<SNR>", HL_ATTR(HLF_8));
@@ -1698,25 +1691,22 @@ static void list_func_head(ufunc_T *fp, int indent, bool force)
/// Advances "pp" to just after the function name (if no error).
///
/// @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, // 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
+ )
FUNC_ATTR_NONNULL_ARG(1)
{
- char_u *name = NULL;
+ char_u *name = NULL;
const char_u *start;
const char_u *end;
int lead;
int len;
lval_T lv;
- if (fdp != NULL)
+ if (fdp != NULL) {
memset(fdp, 0, sizeof(funcdict_T));
+ }
start = *pp;
/* Check for hard coded <SNR>: already translated function ID (from a user
@@ -1739,8 +1729,9 @@ trans_function_name(
end = get_lval((char_u *)start, NULL, &lv, false, skip, flags | GLV_READ_ONLY,
lead > 2 ? 0 : FNE_CHECK_START);
if (end == start) {
- if (!skip)
+ if (!skip) {
EMSG(_("E129: Function name required"));
+ }
goto theend;
}
if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) {
@@ -1806,7 +1797,7 @@ trans_function_name(
goto theend;
}
- /* Check if the name is a Funcref. If so, use the value. */
+ // Check if the name is a Funcref. If so, use the value.
if (lv.ll_exp_name != NULL) {
len = (int)strlen(lv.ll_exp_name);
name = deref_func_name(lv.ll_exp_name, &len, partial,
@@ -1915,31 +1906,31 @@ theend:
*/
void ex_function(exarg_T *eap)
{
- char_u *theline;
- char_u *line_to_free = NULL;
+ char_u *theline;
+ char_u *line_to_free = NULL;
int c;
int saved_did_emsg;
bool saved_wait_return = need_wait_return;
- char_u *name = NULL;
- char_u *p;
- char_u *arg;
- char_u *line_arg = NULL;
+ char_u *name = NULL;
+ char_u *p;
+ char_u *arg;
+ char_u *line_arg = NULL;
garray_T newargs;
garray_T default_args;
garray_T newlines;
int varargs = false;
int flags = 0;
- ufunc_T *fp;
+ ufunc_T *fp;
bool overwrite = false;
int indent;
int nesting;
- dictitem_T *v;
+ dictitem_T *v;
funcdict_T fudi;
static int func_nr = 0; // number for nameless function
int paren;
- hashtab_T *ht;
+ hashtab_T *ht;
int todo;
- hashitem_T *hi;
+ hashitem_T *hi;
linenr_T sourcing_lnum_off;
linenr_T sourcing_lnum_top;
bool is_heredoc = false;
@@ -1992,15 +1983,17 @@ void ex_function(exarg_T *eap)
--todo;
fp = HI2UF(hi);
if (!isdigit(*fp->uf_name)
- && vim_regexec(&regmatch, fp->uf_name, 0))
+ && vim_regexec(&regmatch, fp->uf_name, 0)) {
list_func_head(fp, false, false);
+ }
}
}
vim_regfree(regmatch.regprog);
}
}
- if (*p == '/')
+ if (*p == '/') {
++p;
+ }
eap->nextcmd = check_nextcmd(p);
return;
}
@@ -2034,8 +2027,9 @@ void ex_function(exarg_T *eap)
}
xfree(fudi.fd_newkey);
return;
- } else
+ } else {
eap->skip = TRUE;
+ }
}
/* An error in a function call during evaluation of an expression in magic
@@ -2055,8 +2049,9 @@ void ex_function(exarg_T *eap)
goto ret_free;
}
eap->nextcmd = check_nextcmd(p);
- if (eap->nextcmd != NULL)
+ if (eap->nextcmd != NULL) {
*p = NUL;
+ }
if (!eap->skip && !got_int) {
fp = find_func(name);
if (fp != NULL) {
@@ -2083,8 +2078,9 @@ void ex_function(exarg_T *eap)
msg_putchar('\n');
msg_puts(eap->forceit ? "endfunction" : " endfunction");
}
- } else
+ } else {
emsg_funcname(N_("E123: Undefined function: %s"), name);
+ }
}
goto ret_free;
}
@@ -2111,17 +2107,20 @@ void ex_function(exarg_T *eap)
if (!eap->skip) {
/* Check the name of the function. Unless it's a dictionary function
* (that we are overwriting). */
- if (name != NULL)
+ if (name != NULL) {
arg = name;
- else
+ } else {
arg = fudi.fd_newkey;
+ }
if (arg != NULL && (fudi.fd_di == NULL || !tv_is_func(fudi.fd_di->di_tv))) {
int j = (*arg == K_SPECIAL) ? 3 : 0;
while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j])
- : eval_isnamec(arg[j])))
+ : eval_isnamec(arg[j]))) {
++j;
- if (arg[j] != NUL)
+ }
+ if (arg[j] != NUL) {
emsg_funcname((char *)e_invarg2, arg);
+ }
}
// Disallow using the g: dict.
if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE) {
@@ -2156,7 +2155,7 @@ void ex_function(exarg_T *eap)
p += 7;
if (current_funccal == NULL) {
emsg_funcname(N_
- ("E932: Closure function should not be at top level: %s"),
+ ("E932: Closure function should not be at top level: %s"),
name == NULL ? (char_u *)"" : name);
goto erret;
}
@@ -2181,14 +2180,16 @@ void ex_function(exarg_T *eap)
* 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)
+ if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) {
EMSG(_(e_funcdict));
- else if (name != NULL && find_func(name) != NULL)
+ } else if (name != NULL && find_func(name) != NULL) {
emsg_funcname(e_funcexts, name);
+ }
}
- if (!eap->skip && did_emsg)
+ if (!eap->skip && did_emsg) {
goto erret;
+ }
if (!ui_has(kUICmdline)) {
msg_putchar('\n'); // don't overwrite the function name
@@ -2212,9 +2213,9 @@ void ex_function(exarg_T *eap)
// Use eap->arg, split up in parts by line breaks.
theline = line_arg;
p = vim_strchr(theline, '\n');
- if (p == NULL)
+ if (p == NULL) {
line_arg += STRLEN(line_arg);
- else {
+ } else {
*p = NUL;
line_arg = p + 1;
}
@@ -2242,7 +2243,7 @@ void ex_function(exarg_T *eap)
// Detect line continuation: sourcing_lnum increased more than one.
sourcing_lnum_off = get_sourced_lnum(eap->getline, eap->cookie);
if (sourcing_lnum < sourcing_lnum_off) {
- sourcing_lnum_off -= sourcing_lnum;
+ sourcing_lnum_off -= sourcing_lnum;
} else {
sourcing_lnum_off = 0;
}
@@ -2306,13 +2307,14 @@ void ex_function(exarg_T *eap)
/* Increase indent inside "if", "while", "for" and "try", decrease
* at "end". */
- if (indent > 2 && STRNCMP(p, "end", 3) == 0)
+ if (indent > 2 && STRNCMP(p, "end", 3) == 0) {
indent -= 2;
- else if (STRNCMP(p, "if", 2) == 0
- || STRNCMP(p, "wh", 2) == 0
- || STRNCMP(p, "for", 3) == 0
- || STRNCMP(p, "try", 3) == 0)
+ } else if (STRNCMP(p, "if", 2) == 0
+ || STRNCMP(p, "wh", 2) == 0
+ || STRNCMP(p, "for", 3) == 0
+ || STRNCMP(p, "try", 3) == 0) {
indent += 2;
+ }
// Check for defining a function inside this function.
if (checkforcmd(&p, "function", 2)) {
@@ -2362,10 +2364,11 @@ void ex_function(exarg_T *eap)
&& (!ASCII_ISALPHA(p[2]) || p[2] == 's')))) {
// ":python <<" continues until a dot, like ":append"
p = skipwhite(arg + 2);
- if (*p == NUL)
+ if (*p == NUL) {
skip_until = vim_strsave((char_u *)".");
- else
+ } else {
skip_until = vim_strsave(p);
+ }
}
// Check for ":let v =<< [trim] EOF"
@@ -2408,8 +2411,9 @@ void ex_function(exarg_T *eap)
/* Add NULL lines for continuation lines, so that the line count is
* equal to the index in the growarray. */
- while (sourcing_lnum_off-- > 0)
+ while (sourcing_lnum_off-- > 0) {
((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL;
+ }
// Check for end of eap->arg.
if (line_arg != NULL && *line_arg == NUL) {
@@ -2419,8 +2423,9 @@ void ex_function(exarg_T *eap)
/* Don't define the function when skipping commands or when an error was
* detected. */
- if (eap->skip || did_emsg)
+ if (eap->skip || did_emsg) {
goto erret;
+ }
/*
* If there are no errors, add the function
@@ -2429,7 +2434,7 @@ void ex_function(exarg_T *eap)
v = find_var((const char *)name, STRLEN(name), &ht, false);
if (v != NULL && v->di_tv.v_type == VAR_FUNC) {
emsg_funcname(N_("E707: Function name conflicts with variable: %s"),
- name);
+ name);
goto erret;
}
@@ -2445,7 +2450,7 @@ void ex_function(exarg_T *eap)
}
if (fp->uf_calls > 0) {
emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"),
- name);
+ name);
goto erret;
}
if (fp->uf_refcount > 1) {
@@ -2493,7 +2498,7 @@ void ex_function(exarg_T *eap)
if (fp == NULL) {
if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) {
int slen, plen;
- char_u *scriptname;
+ char_u *scriptname;
// Check that the autoload name matches the script name.
int j = FAIL;
@@ -2503,14 +2508,14 @@ void ex_function(exarg_T *eap)
plen = (int)STRLEN(p);
slen = (int)STRLEN(sourcing_name);
if (slen > plen && fnamecmp(p,
- sourcing_name + slen - plen) == 0)
+ sourcing_name + slen - plen) == 0) {
j = OK;
+ }
xfree(scriptname);
}
if (j == FAIL) {
- EMSG2(_(
- "E746: Function name does not match script file name: %s"),
- name);
+ EMSG2(_("E746: Function name does not match script file name: %s"),
+ name);
goto erret;
}
}
@@ -2651,8 +2656,8 @@ bool function_exists(const char *const name, bool no_deref)
char_u *get_user_func_name(expand_T *xp, int idx)
{
static size_t done;
- static hashitem_T *hi;
- ufunc_T *fp;
+ static hashitem_T *hi;
+ ufunc_T *fp;
if (idx == 0) {
done = 0;
@@ -2660,10 +2665,12 @@ char_u *get_user_func_name(expand_T *xp, int idx)
}
assert(hi);
if (done < func_hashtab.ht_used) {
- if (done++ > 0)
+ if (done++ > 0) {
++hi;
- while (HASHITEM_EMPTY(hi))
+ }
+ while (HASHITEM_EMPTY(hi)) {
++hi;
+ }
fp = HI2UF(hi);
if ((fp->uf_flags & FC_DICT)
@@ -2678,8 +2685,9 @@ char_u *get_user_func_name(expand_T *xp, int idx)
cat_func_name(IObuff, fp);
if (xp->xp_context != EXPAND_USER_FUNC) {
STRCAT(IObuff, "(");
- if (!fp->uf_varargs && GA_EMPTY(&fp->uf_args))
+ if (!fp->uf_varargs && GA_EMPTY(&fp->uf_args)) {
STRCAT(IObuff, ")");
+ }
}
return IObuff;
}
@@ -2689,17 +2697,18 @@ char_u *get_user_func_name(expand_T *xp, int idx)
/// ":delfunction {name}"
void ex_delfunction(exarg_T *eap)
{
- ufunc_T *fp = NULL;
- char_u *p;
- char_u *name;
+ ufunc_T *fp = NULL;
+ char_u *p;
+ char_u *name;
funcdict_T fudi;
p = eap->arg;
name = trans_function_name(&p, eap->skip, 0, &fudi, NULL);
xfree(fudi.fd_newkey);
if (name == NULL) {
- if (fudi.fd_dict != NULL && !eap->skip)
+ if (fudi.fd_dict != NULL && !eap->skip) {
EMSG(_(e_funcref));
+ }
return;
}
if (!ends_excmd(*skipwhite(p))) {
@@ -2708,11 +2717,13 @@ void ex_delfunction(exarg_T *eap)
return;
}
eap->nextcmd = check_nextcmd(p);
- if (eap->nextcmd != NULL)
+ if (eap->nextcmd != NULL) {
*p = NUL;
+ }
- if (!eap->skip)
+ if (!eap->skip) {
fp = find_func(name);
+ }
xfree(name);
if (!eap->skip) {
@@ -2730,7 +2741,7 @@ void ex_delfunction(exarg_T *eap)
// the reference count, and 1 is the initial refcount.
if (fp->uf_refcount > 2) {
EMSG2(_("Cannot delete function %s: It is being used internally"),
- eap->arg);
+ eap->arg);
return;
}
@@ -2778,8 +2789,8 @@ void func_unref(char_u *name)
abort();
}
#else
- internal_error("func_unref()");
- abort();
+ internal_error("func_unref()");
+ abort();
#endif
}
func_ptr_unref(fp);
@@ -2860,7 +2871,7 @@ static int can_free_funccal(funccall_T *fc, int copyID)
*/
void ex_return(exarg_T *eap)
{
- char_u *arg = eap->arg;
+ char_u *arg = eap->arg;
typval_T rettv;
int returning = FALSE;
@@ -2869,8 +2880,9 @@ void ex_return(exarg_T *eap)
return;
}
- if (eap->skip)
+ if (eap->skip) {
++emsg_skip;
+ }
eap->nextcmd = NULL;
if ((*arg != NUL && *arg != '|' && *arg != '\n')
@@ -2900,21 +2912,22 @@ void ex_return(exarg_T *eap)
eap->nextcmd = check_nextcmd(arg);
}
- if (eap->skip)
+ if (eap->skip) {
--emsg_skip;
+ }
}
// TODO(ZyX-I): move to eval/ex_cmds
/*
- * ":1,25call func(arg1, arg2)" function call.
+ * ":1,25call func(arg1, arg2)" function call.
*/
void ex_call(exarg_T *eap)
{
- char_u *arg = eap->arg;
- char_u *startarg;
- char_u *name;
- char_u *tofree;
+ char_u *arg = eap->arg;
+ char_u *startarg;
+ char_u *name;
+ char_u *tofree;
int len;
typval_T rettv;
linenr_T lnum;
@@ -3063,12 +3076,12 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
if (idx >= 0) {
cstack->cs_pending[idx] = CSTP_RETURN;
- if (!is_cmd && !reanimate)
+ if (!is_cmd && !reanimate) {
/* A pending return again gets pending. "rettv" points to an
* allocated variable with the rettv of the original ":return"'s
* argument if present or is NULL else. */
cstack->cs_rettv[idx] = rettv;
- else {
+ } else {
/* When undoing a return in order to make it pending, get the stored
* return rettv. */
if (reanimate) {
@@ -3080,8 +3093,9 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
// Store the value of the pending return.
cstack->cs_rettv[idx] = xcalloc(1, sizeof(typval_T));
*(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv;
- } else
+ } else {
cstack->cs_rettv[idx] = NULL;
+ }
if (reanimate) {
/* The pending return value could be overwritten by a ":return"
@@ -3101,8 +3115,9 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
if (!reanimate && rettv != NULL) {
tv_clear(current_funccal->rettv);
*current_funccal->rettv = *(typval_T *)rettv;
- if (!is_cmd)
+ if (!is_cmd) {
xfree(rettv);
+ }
}
}
@@ -3119,7 +3134,7 @@ char_u *get_return_cmd(void *rettv)
char_u *tofree = NULL;
if (rettv != NULL) {
- tofree = s = (char_u *) encode_tv2echo((typval_T *) rettv, NULL);
+ tofree = s = (char_u *)encode_tv2echo((typval_T *)rettv, NULL);
}
if (s == NULL) {
s = (char_u *)"";
@@ -3127,8 +3142,9 @@ char_u *get_return_cmd(void *rettv)
STRCPY(IObuff, ":return ");
STRLCPY(IObuff + 8, s, IOSIZE - 8);
- if (STRLEN(s) + 8 >= IOSIZE)
+ if (STRLEN(s) + 8 >= IOSIZE) {
STRCPY(IObuff + IOSIZE - 4, "...");
+ }
xfree(tofree);
return vim_strsave(IObuff);
}
@@ -3140,19 +3156,20 @@ char_u *get_return_cmd(void *rettv)
*/
char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
{
- funccall_T *fcp = (funccall_T *)cookie;
- ufunc_T *fp = fcp->func;
- char_u *retval;
- garray_T *gap; // growarray with function lines
+ funccall_T *fcp = (funccall_T *)cookie;
+ ufunc_T *fp = fcp->func;
+ char_u *retval;
+ garray_T *gap; // growarray with function lines
// If breakpoints have been added/deleted need to check for it.
if (fcp->dbg_tick != debug_tick) {
fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
- sourcing_lnum);
+ sourcing_lnum);
fcp->dbg_tick = debug_tick;
}
- if (do_profiling == PROF_YES)
+ if (do_profiling == PROF_YES) {
func_line_end(cookie);
+ }
gap = &fp->uf_lines;
if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
@@ -3169,8 +3186,9 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
} else {
retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
sourcing_lnum = fcp->linenr;
- if (do_profiling == PROF_YES)
+ if (do_profiling == PROF_YES) {
func_line_start(cookie);
+ }
}
}
@@ -3192,7 +3210,7 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
*/
int func_has_ended(void *cookie)
{
- funccall_T *fcp = (funccall_T *)cookie;
+ funccall_T *fcp = (funccall_T *)cookie;
/* Ignore the "abort" flag if the abortion behavior has been changed due to
* an error inside a try conditional. */
@@ -3448,8 +3466,7 @@ hashitem_T *find_hi_in_scoped_ht(const char *name, hashtab_T **pht)
}
/// Search variable in parent scope.
-dictitem_T *find_var_in_scoped_ht(const char *name, const size_t namelen,
- int no_autoload)
+dictitem_T *find_var_in_scoped_ht(const char *name, const size_t namelen, int no_autoload)
{
if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL) {
return NULL;
@@ -3560,7 +3577,7 @@ bool set_ref_in_func_args(int copyID)
for (int i = 0; i < funcargs.ga_len; i++) {
if (set_ref_in_item(((typval_T **)funcargs.ga_data)[i],
copyID, NULL, NULL)) {
- return true;
+ return true;
}
}
return false;
diff --git a/src/nvim/viml/parser/expressions.c b/src/nvim/viml/parser/expressions.c
index 967d656dc5..c2aa923c49 100644
--- a/src/nvim/viml/parser/expressions.c
+++ b/src/nvim/viml/parser/expressions.c
@@ -50,20 +50,19 @@
// 7. 'isident' no longer applies to environment variables, they always include
// ASCII alphanumeric characters and underscore and nothing except this.
+#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
-#include <assert.h>
#include <string.h>
-#include "nvim/vim.h"
-#include "nvim/memory.h"
-#include "nvim/types.h"
-#include "nvim/charset.h"
#include "nvim/ascii.h"
#include "nvim/assert.h"
-#include "nvim/lib/kvec.h"
+#include "nvim/charset.h"
#include "nvim/eval/typval.h"
-
+#include "nvim/lib/kvec.h"
+#include "nvim/memory.h"
+#include "nvim/types.h"
+#include "nvim/vim.h"
#include "nvim/viml/parser/expressions.h"
#include "nvim/viml/parser/parser.h"
@@ -143,10 +142,8 @@ typedef enum {
/// numbers are not supported.
/// @param[in] exponent Exponent to scale by.
/// @param[in] exponent_negative True if exponent is negative.
-static inline float_T scale_number(const float_T num,
- const uint8_t base,
- const uvarnumber_T exponent,
- const bool exponent_negative)
+static inline float_T scale_number(const float_T num, const uint8_t base,
+ const uvarnumber_T exponent, const bool exponent_negative)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_CONST
{
if (num == 0 || exponent == 0) {
@@ -200,7 +197,7 @@ LexExprToken viml_pexpr_next_token(ParserState *const pstate, const int flags)
if (ret.len < pline.size \
&& strchr("?#", pline.data[ret.len]) != NULL) { \
ret.data.cmp.ccs = \
- (ExprCaseCompareStrategy)pline.data[ret.len]; \
+ (ExprCaseCompareStrategy)pline.data[ret.len]; \
ret.len++; \
} else { \
ret.data.cmp.ccs = kCCStrategyUseOption; \
@@ -209,12 +206,12 @@ LexExprToken viml_pexpr_next_token(ParserState *const pstate, const int flags)
switch (schar) {
// Paired brackets.
#define BRACKET(typ, opning, clsing) \
- case opning: \
- case clsing: { \
- ret.type = typ; \
- ret.data.brc.closing = (schar == clsing); \
- break; \
- }
+case opning: \
+case clsing: { \
+ ret.type = typ; \
+ ret.data.brc.closing = (schar == clsing); \
+ break; \
+}
BRACKET(kExprLexParenthesis, '(', ')')
BRACKET(kExprLexBracket, '[', ']')
BRACKET(kExprLexFigureBrace, '{', '}')
@@ -222,10 +219,10 @@ LexExprToken viml_pexpr_next_token(ParserState *const pstate, const int flags)
// Single character tokens without data.
#define CHAR(typ, ch) \
- case ch: { \
- ret.type = typ; \
- break; \
- }
+case ch: { \
+ ret.type = typ; \
+ break; \
+}
CHAR(kExprLexQuestion, '?')
CHAR(kExprLexColon, ':')
CHAR(kExprLexComma, ',')
@@ -233,198 +230,265 @@ LexExprToken viml_pexpr_next_token(ParserState *const pstate, const int flags)
// Multiplication/division/modulo.
#define MUL(mul_type, ch) \
- case ch: { \
- ret.type = kExprLexMultiplication; \
- ret.data.mul.type = mul_type; \
- break; \
- }
+case ch: { \
+ ret.type = kExprLexMultiplication; \
+ ret.data.mul.type = mul_type; \
+ break; \
+}
MUL(kExprLexMulMul, '*')
MUL(kExprLexMulDiv, '/')
MUL(kExprLexMulMod, '%')
#undef MUL
#define CHARREG(typ, cond) \
- do { \
- ret.type = typ; \
- for (; (ret.len < pline.size \
- && cond(pline.data[ret.len])) \
- ; ret.len++) { \
- } \
- } while (0)
-
- // Whitespace.
- case ' ':
- case TAB: {
- CHARREG(kExprLexSpacing, ascii_iswhite);
- break;
- }
-
- // Control character, except for NUL, NL and TAB.
- case Ctrl_A: case Ctrl_B: case Ctrl_C: case Ctrl_D: case Ctrl_E:
- case Ctrl_F: case Ctrl_G: case Ctrl_H:
+ do { \
+ ret.type = typ; \
+ for (; (ret.len < pline.size \
+ && cond(pline.data[ret.len])) \
+ ; ret.len++) { \
+ } \
+ } while (0)
- case Ctrl_K: case Ctrl_L: case Ctrl_M: case Ctrl_N: case Ctrl_O:
- case Ctrl_P: case Ctrl_Q: case Ctrl_R: case Ctrl_S: case Ctrl_T:
- case Ctrl_U: case Ctrl_V: case Ctrl_W: case Ctrl_X: case Ctrl_Y:
- case Ctrl_Z: {
+ // Whitespace.
+ case ' ':
+ case TAB:
+ CHARREG(kExprLexSpacing, ascii_iswhite);
+ break;
+
+ // Control character, except for NUL, NL and TAB.
+ case Ctrl_A:
+ case Ctrl_B:
+ case Ctrl_C:
+ case Ctrl_D:
+ case Ctrl_E:
+ case Ctrl_F:
+ case Ctrl_G:
+ case Ctrl_H:
+
+ case Ctrl_K:
+ case Ctrl_L:
+ case Ctrl_M:
+ case Ctrl_N:
+ case Ctrl_O:
+ case Ctrl_P:
+ case Ctrl_Q:
+ case Ctrl_R:
+ case Ctrl_S:
+ case Ctrl_T:
+ case Ctrl_U:
+ case Ctrl_V:
+ case Ctrl_W:
+ case Ctrl_X:
+ case Ctrl_Y:
+ case Ctrl_Z:
#define ISCTRL(schar) (schar < ' ')
- CHARREG(kExprLexInvalid, ISCTRL);
- ret.data.err.type = kExprLexSpacing;
- ret.data.err.msg =
- _("E15: Invalid control character present in input: %.*s");
- break;
+ CHARREG(kExprLexInvalid, ISCTRL);
+ ret.data.err.type = kExprLexSpacing;
+ ret.data.err.msg =
+ _("E15: Invalid control character present in input: %.*s");
+ break;
#undef ISCTRL
- }
- // Number.
- case '0': case '1': case '2': case '3': case '4': case '5': case '6':
- case '7': case '8': case '9': {
- ret.data.num.is_float = false;
- ret.data.num.base = 10;
- size_t frac_start = 0;
- size_t exp_start = 0;
- size_t frac_end = 0;
- bool exp_negative = false;
- CHARREG(kExprLexNumber, ascii_isdigit);
- if (flags & kELFlagAllowFloat) {
- const LexExprToken non_float_ret = ret;
+ // Number.
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': {
+ ret.data.num.is_float = false;
+ ret.data.num.base = 10;
+ size_t frac_start = 0;
+ size_t exp_start = 0;
+ size_t frac_end = 0;
+ bool exp_negative = false;
+ CHARREG(kExprLexNumber, ascii_isdigit);
+ if (flags & kELFlagAllowFloat) {
+ const LexExprToken non_float_ret = ret;
+ if (pline.size > ret.len + 1
+ && pline.data[ret.len] == '.'
+ && ascii_isdigit(pline.data[ret.len + 1])) {
+ ret.len++;
+ frac_start = ret.len;
+ frac_end = ret.len;
+ ret.data.num.is_float = true;
+ for (; ret.len < pline.size && ascii_isdigit(pline.data[ret.len])
+ ; ret.len++) {
+ // A small optimization: trailing zeroes in fractional part do not
+ // add anything to significand, so it is useless to include them in
+ // frac_end.
+ if (pline.data[ret.len] != '0') {
+ frac_end = ret.len + 1;
+ }
+ }
if (pline.size > ret.len + 1
- && pline.data[ret.len] == '.'
- && ascii_isdigit(pline.data[ret.len + 1])) {
+ && (pline.data[ret.len] == 'e'
+ || pline.data[ret.len] == 'E')
+ && ((pline.size > ret.len + 2
+ && (pline.data[ret.len + 1] == '+'
+ || pline.data[ret.len + 1] == '-')
+ && ascii_isdigit(pline.data[ret.len + 2]))
+ || ascii_isdigit(pline.data[ret.len + 1]))) {
ret.len++;
- frac_start = ret.len;
- frac_end = ret.len;
- ret.data.num.is_float = true;
- for (; ret.len < pline.size && ascii_isdigit(pline.data[ret.len])
- ; ret.len++) {
- // A small optimization: trailing zeroes in fractional part do not
- // add anything to significand, so it is useless to include them in
- // frac_end.
- if (pline.data[ret.len] != '0') {
- frac_end = ret.len + 1;
- }
- }
- if (pline.size > ret.len + 1
- && (pline.data[ret.len] == 'e'
- || pline.data[ret.len] == 'E')
- && ((pline.size > ret.len + 2
- && (pline.data[ret.len + 1] == '+'
- || pline.data[ret.len + 1] == '-')
- && ascii_isdigit(pline.data[ret.len + 2]))
- || ascii_isdigit(pline.data[ret.len + 1]))) {
+ if (pline.data[ret.len] == '+'
+ || (exp_negative = (pline.data[ret.len] == '-'))) {
ret.len++;
- if (pline.data[ret.len] == '+'
- || (exp_negative = (pline.data[ret.len] == '-'))) {
- ret.len++;
- }
- exp_start = ret.len;
- CHARREG(kExprLexNumber, ascii_isdigit);
}
- }
- if (pline.size > ret.len
- && (pline.data[ret.len] == '.'
- || ASCII_ISALPHA(pline.data[ret.len]))) {
- ret = non_float_ret;
+ exp_start = ret.len;
+ CHARREG(kExprLexNumber, ascii_isdigit);
}
}
- // TODO(ZyX-I): detect overflows
- if (ret.data.num.is_float) {
- // Vim used to use string2float here which in turn uses strtod(). There
- // are two problems with this approach:
- // 1. strtod() is locale-dependent. Not sure how it is worked around so
- // that I do not see relevant bugs, but it still does not look like
- // a good idea.
- // 2. strtod() does not accept length argument.
- //
- // The below variant of parsing floats was recognized as acceptable
- // because it is basically how uClibc does the thing: it generates
- // a number ignoring decimal point (but recording its position), then
- // uses recorded position to scale number down when processing exponent.
- float_T significand_part = 0;
- uvarnumber_T exp_part = 0;
- const size_t frac_size = (size_t)(frac_end - frac_start);
- for (size_t i = 0; i < frac_end; i++) {
- if (i == frac_start - 1) {
- continue;
- }
- significand_part = significand_part * 10 + (pline.data[i] - '0');
- }
- if (exp_start) {
- vim_str2nr(pline.data + exp_start, NULL, NULL, 0, NULL, &exp_part,
- (int)(ret.len - exp_start), false);
+ if (pline.size > ret.len
+ && (pline.data[ret.len] == '.'
+ || ASCII_ISALPHA(pline.data[ret.len]))) {
+ ret = non_float_ret;
+ }
+ }
+ // TODO(ZyX-I): detect overflows
+ if (ret.data.num.is_float) {
+ // Vim used to use string2float here which in turn uses strtod(). There
+ // are two problems with this approach:
+ // 1. strtod() is locale-dependent. Not sure how it is worked around so
+ // that I do not see relevant bugs, but it still does not look like
+ // a good idea.
+ // 2. strtod() does not accept length argument.
+ //
+ // The below variant of parsing floats was recognized as acceptable
+ // because it is basically how uClibc does the thing: it generates
+ // a number ignoring decimal point (but recording its position), then
+ // uses recorded position to scale number down when processing exponent.
+ float_T significand_part = 0;
+ uvarnumber_T exp_part = 0;
+ const size_t frac_size = (size_t)(frac_end - frac_start);
+ for (size_t i = 0; i < frac_end; i++) {
+ if (i == frac_start - 1) {
+ continue;
}
- if (exp_negative) {
- exp_part += frac_size;
+ significand_part = significand_part * 10 + (pline.data[i] - '0');
+ }
+ if (exp_start) {
+ vim_str2nr(pline.data + exp_start, NULL, NULL, 0, NULL, &exp_part,
+ (int)(ret.len - exp_start), false);
+ }
+ if (exp_negative) {
+ exp_part += frac_size;
+ } else {
+ if (exp_part < frac_size) {
+ exp_negative = true;
+ exp_part = frac_size - exp_part;
} else {
- if (exp_part < frac_size) {
- exp_negative = true;
- exp_part = frac_size - exp_part;
- } else {
- exp_part -= frac_size;
- }
+ exp_part -= frac_size;
}
- ret.data.num.val.floating = scale_number(significand_part, 10, exp_part,
- exp_negative);
- } else {
- int len;
- int prep;
- vim_str2nr(pline.data, &prep, &len, STR2NR_ALL, NULL,
- &ret.data.num.val.integer, (int)pline.size, false);
- ret.len = (size_t)len;
- const uint8_t bases[] = {
- [0] = 10,
- ['0'] = 8,
- ['x'] = 16, ['X'] = 16,
- ['b'] = 2, ['B'] = 2,
- };
- ret.data.num.base = bases[prep];
}
- break;
+ ret.data.num.val.floating = scale_number(significand_part, 10, exp_part,
+ exp_negative);
+ } else {
+ int len;
+ int prep;
+ vim_str2nr(pline.data, &prep, &len, STR2NR_ALL, NULL,
+ &ret.data.num.val.integer, (int)pline.size, false);
+ ret.len = (size_t)len;
+ const uint8_t bases[] = {
+ [0] = 10,
+ ['0'] = 8,
+ ['x'] = 16, ['X'] = 16,
+ ['b'] = 2, ['B'] = 2,
+ };
+ ret.data.num.base = bases[prep];
}
+ break;
+ }
#define ISWORD_OR_AUTOLOAD(x) \
- (ascii_isident(x) || (x) == AUTOLOAD_CHAR)
-
- // Environment variable.
- case '$': {
- CHARREG(kExprLexEnv, ascii_isident);
- break;
- }
-
- // Normal variable/function name.
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
- case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
- case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
- case 'v': case 'w': case 'x': case 'y': case 'z':
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
- case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
- case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
- case 'V': case 'W': case 'X': case 'Y': case 'Z':
- case '_': {
- ret.data.var.scope = 0;
- ret.data.var.autoload = false;
- CHARREG(kExprLexPlainIdentifier, ascii_isident);
- // "is" and "isnot" operators.
- if (!(flags & kELFlagIsNotCmp)
- && ((ret.len == 2 && memcmp(pline.data, "is", 2) == 0)
- || (ret.len == 5 && memcmp(pline.data, "isnot", 5) == 0))) {
- ret.type = kExprLexComparison;
- ret.data.cmp.type = kExprCmpIdentical;
- ret.data.cmp.inv = (ret.len == 5);
- GET_CCS(ret, pline);
+ (ascii_isident(x) || (x) == AUTOLOAD_CHAR)
+
+ // Environment variable.
+ case '$':
+ CHARREG(kExprLexEnv, ascii_isident);
+ break;
+
+ // Normal variable/function name.
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'h':
+ case 'i':
+ case 'j':
+ case 'k':
+ case 'l':
+ case 'm':
+ case 'n':
+ case 'o':
+ case 'p':
+ case 'q':
+ case 'r':
+ case 's':
+ case 't':
+ case 'u':
+ case 'v':
+ case 'w':
+ case 'x':
+ case 'y':
+ case 'z':
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ case 'G':
+ case 'H':
+ case 'I':
+ case 'J':
+ case 'K':
+ case 'L':
+ case 'M':
+ case 'N':
+ case 'O':
+ case 'P':
+ case 'Q':
+ case 'R':
+ case 'S':
+ case 'T':
+ case 'U':
+ case 'V':
+ case 'W':
+ case 'X':
+ case 'Y':
+ case 'Z':
+ case '_':
+ ret.data.var.scope = 0;
+ ret.data.var.autoload = false;
+ CHARREG(kExprLexPlainIdentifier, ascii_isident);
+ // "is" and "isnot" operators.
+ if (!(flags & kELFlagIsNotCmp)
+ && ((ret.len == 2 && memcmp(pline.data, "is", 2) == 0)
+ || (ret.len == 5 && memcmp(pline.data, "isnot", 5) == 0))) {
+ ret.type = kExprLexComparison;
+ ret.data.cmp.type = kExprCmpIdentical;
+ ret.data.cmp.inv = (ret.len == 5);
+ GET_CCS(ret, pline);
// Scope: `s:`, etc.
- } else if (ret.len == 1
- && pline.size > 1
- && memchr(EXPR_VAR_SCOPE_LIST, schar,
- sizeof(EXPR_VAR_SCOPE_LIST)) != NULL
- && pline.data[ret.len] == ':'
- && !(flags & kELFlagForbidScope)) {
- ret.len++;
- ret.data.var.scope = (ExprVarScope)schar;
- CHARREG(kExprLexPlainIdentifier, ISWORD_OR_AUTOLOAD);
- ret.data.var.autoload = (
- memchr(pline.data + 2, AUTOLOAD_CHAR, ret.len - 2)
- != NULL);
+ } else if (ret.len == 1
+ && pline.size > 1
+ && memchr(EXPR_VAR_SCOPE_LIST, schar,
+ sizeof(EXPR_VAR_SCOPE_LIST)) != NULL
+ && pline.data[ret.len] == ':'
+ && !(flags & kELFlagForbidScope)) {
+ ret.len++;
+ ret.data.var.scope = (ExprVarScope)schar;
+ CHARREG(kExprLexPlainIdentifier, ISWORD_OR_AUTOLOAD);
+ ret.data.var.autoload = (
+ memchr(pline.data + 2, AUTOLOAD_CHAR, ret.len - 2)
+ != NULL);
// Previous CHARREG stopped at autoload character in order to make it
// possible to detect `is#`. Continue now with autoload characters
// included.
@@ -432,221 +496,213 @@ LexExprToken viml_pexpr_next_token(ParserState *const pstate, const int flags)
// Warning: there is ambiguity for the lexer: `is#Foo(1)` is a call of
// function `is#Foo()`, `1is#Foo(1)` is a comparison `1 is# Foo(1)`. This
// needs to be resolved on the higher level where context is available.
- } else if (pline.size > ret.len
- && pline.data[ret.len] == AUTOLOAD_CHAR) {
- ret.data.var.autoload = true;
- CHARREG(kExprLexPlainIdentifier, ISWORD_OR_AUTOLOAD);
- }
- break;
+ } else if (pline.size > ret.len
+ && pline.data[ret.len] == AUTOLOAD_CHAR) {
+ ret.data.var.autoload = true;
+ CHARREG(kExprLexPlainIdentifier, ISWORD_OR_AUTOLOAD);
}
+ break;
#undef ISWORD_OR_AUTOLOAD
#undef CHARREG
- // Option.
- case '&': {
+ // Option.
+ case '&': {
#define OPTNAMEMISS(ret) \
- do { \
- ret.type = kExprLexInvalid; \
- ret.data.err.type = kExprLexOption; \
- ret.data.err.msg = _("E112: Option name missing: %.*s"); \
- } while (0)
- if (pline.size > 1 && pline.data[1] == '&') {
- ret.type = kExprLexAnd;
- ret.len++;
- break;
+ do { \
+ ret.type = kExprLexInvalid; \
+ ret.data.err.type = kExprLexOption; \
+ ret.data.err.msg = _("E112: Option name missing: %.*s"); \
+ } while (0)
+ if (pline.size > 1 && pline.data[1] == '&') {
+ ret.type = kExprLexAnd;
+ ret.len++;
+ break;
+ }
+ if (pline.size == 1 || !ASCII_ISALPHA(pline.data[1])) {
+ OPTNAMEMISS(ret);
+ break;
+ }
+ ret.type = kExprLexOption;
+ if (pline.size > 2
+ && pline.data[2] == ':'
+ && memchr(EXPR_OPT_SCOPE_LIST, pline.data[1],
+ sizeof(EXPR_OPT_SCOPE_LIST)) != NULL) {
+ ret.len += 2;
+ ret.data.opt.scope = (ExprOptScope)pline.data[1];
+ ret.data.opt.name = pline.data + 3;
+ } else {
+ ret.data.opt.scope = kExprOptScopeUnspecified;
+ ret.data.opt.name = pline.data + 1;
+ }
+ const char *p = ret.data.opt.name;
+ const char *const e = pline.data + pline.size;
+ if (e - p >= 4 && p[0] == 't' && p[1] == '_') {
+ ret.data.opt.len = 4;
+ ret.len += 4;
+ } else {
+ for (; p < e && ASCII_ISALPHA(*p); p++) {
}
- if (pline.size == 1 || !ASCII_ISALPHA(pline.data[1])) {
+ ret.data.opt.len = (size_t)(p - ret.data.opt.name);
+ if (ret.data.opt.len == 0) {
OPTNAMEMISS(ret);
- break;
- }
- ret.type = kExprLexOption;
- if (pline.size > 2
- && pline.data[2] == ':'
- && memchr(EXPR_OPT_SCOPE_LIST, pline.data[1],
- sizeof(EXPR_OPT_SCOPE_LIST)) != NULL) {
- ret.len += 2;
- ret.data.opt.scope = (ExprOptScope)pline.data[1];
- ret.data.opt.name = pline.data + 3;
} else {
- ret.data.opt.scope = kExprOptScopeUnspecified;
- ret.data.opt.name = pline.data + 1;
- }
- const char *p = ret.data.opt.name;
- const char *const e = pline.data + pline.size;
- if (e - p >= 4 && p[0] == 't' && p[1] == '_') {
- ret.data.opt.len = 4;
- ret.len += 4;
- } else {
- for (; p < e && ASCII_ISALPHA(*p); p++) {
- }
- ret.data.opt.len = (size_t)(p - ret.data.opt.name);
- if (ret.data.opt.len == 0) {
- OPTNAMEMISS(ret);
- } else {
- ret.len += ret.data.opt.len;
- }
+ ret.len += ret.data.opt.len;
}
- break;
-#undef OPTNAMEMISS
}
+ break;
+#undef OPTNAMEMISS
+ }
- // Register.
- case '@': {
- ret.type = kExprLexRegister;
- if (pline.size > 1) {
- ret.len++;
- ret.data.reg.name = (uint8_t)pline.data[1];
- } else {
- ret.data.reg.name = -1;
- }
- break;
+ // Register.
+ case '@':
+ ret.type = kExprLexRegister;
+ if (pline.size > 1) {
+ ret.len++;
+ ret.data.reg.name = (uint8_t)pline.data[1];
+ } else {
+ ret.data.reg.name = -1;
}
-
- // Single quoted string.
- case '\'': {
- ret.type = kExprLexSingleQuotedString;
- ret.data.str.closed = false;
- for (; ret.len < pline.size && !ret.data.str.closed; ret.len++) {
- if (pline.data[ret.len] == '\'') {
- if (ret.len + 1 < pline.size && pline.data[ret.len + 1] == '\'') {
- ret.len++;
- } else {
- ret.data.str.closed = true;
- }
+ break;
+
+ // Single quoted string.
+ case '\'':
+ ret.type = kExprLexSingleQuotedString;
+ ret.data.str.closed = false;
+ for (; ret.len < pline.size && !ret.data.str.closed; ret.len++) {
+ if (pline.data[ret.len] == '\'') {
+ if (ret.len + 1 < pline.size && pline.data[ret.len + 1] == '\'') {
+ ret.len++;
+ } else {
+ ret.data.str.closed = true;
}
}
- break;
}
-
- // Double quoted string.
- case '"': {
- ret.type = kExprLexDoubleQuotedString;
- ret.data.str.closed = false;
- for (; ret.len < pline.size && !ret.data.str.closed; ret.len++) {
- if (pline.data[ret.len] == '\\') {
- if (ret.len + 1 < pline.size) {
- ret.len++;
- }
- } else if (pline.data[ret.len] == '"') {
- ret.data.str.closed = true;
+ break;
+
+ // Double quoted string.
+ case '"':
+ ret.type = kExprLexDoubleQuotedString;
+ ret.data.str.closed = false;
+ for (; ret.len < pline.size && !ret.data.str.closed; ret.len++) {
+ if (pline.data[ret.len] == '\\') {
+ if (ret.len + 1 < pline.size) {
+ ret.len++;
}
+ } else if (pline.data[ret.len] == '"') {
+ ret.data.str.closed = true;
}
- break;
}
-
- // Unary not, (un)equality and regex (not) match comparison operators.
- case '!':
- case '=': {
- if (pline.size == 1) {
- ret.type = (schar == '!' ? kExprLexNot : kExprLexAssignment);
- ret.data.ass.type = kExprAsgnPlain;
- break;
- }
- ret.type = kExprLexComparison;
- ret.data.cmp.inv = (schar == '!');
- if (pline.data[1] == '=') {
- ret.data.cmp.type = kExprCmpEqual;
- ret.len++;
- } else if (pline.data[1] == '~') {
- ret.data.cmp.type = kExprCmpMatches;
- ret.len++;
- } else if (schar == '!') {
- ret.type = kExprLexNot;
- } else {
- ret.type = kExprLexAssignment;
- ret.data.ass.type = kExprAsgnPlain;
- }
- GET_CCS(ret, pline);
+ break;
+
+ // Unary not, (un)equality and regex (not) match comparison operators.
+ case '!':
+ case '=':
+ if (pline.size == 1) {
+ ret.type = (schar == '!' ? kExprLexNot : kExprLexAssignment);
+ ret.data.ass.type = kExprAsgnPlain;
break;
}
-
- // Less/greater [or equal to] comparison operators.
- case '>':
- case '<': {
- ret.type = kExprLexComparison;
- const bool haseqsign = (pline.size > 1 && pline.data[1] == '=');
- if (haseqsign) {
- ret.len++;
- }
- GET_CCS(ret, pline);
- ret.data.cmp.inv = (schar == '<');
- ret.data.cmp.type = ((ret.data.cmp.inv ^ haseqsign)
+ ret.type = kExprLexComparison;
+ ret.data.cmp.inv = (schar == '!');
+ if (pline.data[1] == '=') {
+ ret.data.cmp.type = kExprCmpEqual;
+ ret.len++;
+ } else if (pline.data[1] == '~') {
+ ret.data.cmp.type = kExprCmpMatches;
+ ret.len++;
+ } else if (schar == '!') {
+ ret.type = kExprLexNot;
+ } else {
+ ret.type = kExprLexAssignment;
+ ret.data.ass.type = kExprAsgnPlain;
+ }
+ GET_CCS(ret, pline);
+ break;
+
+ // Less/greater [or equal to] comparison operators.
+ case '>':
+ case '<': {
+ ret.type = kExprLexComparison;
+ const bool haseqsign = (pline.size > 1 && pline.data[1] == '=');
+ if (haseqsign) {
+ ret.len++;
+ }
+ GET_CCS(ret, pline);
+ ret.data.cmp.inv = (schar == '<');
+ ret.data.cmp.type = ((ret.data.cmp.inv ^ haseqsign)
? kExprCmpGreaterOrEqual
: kExprCmpGreater);
- break;
- }
+ break;
+ }
- // Minus sign, arrow from lambdas or augmented assignment.
- case '-': {
- if (pline.size > 1 && pline.data[1] == '>') {
- ret.len++;
- ret.type = kExprLexArrow;
- } else if (pline.size > 1 && pline.data[1] == '=') {
- ret.len++;
- ret.type = kExprLexAssignment;
- ret.data.ass.type = kExprAsgnSubtract;
- } else {
- ret.type = kExprLexMinus;
- }
- break;
+ // Minus sign, arrow from lambdas or augmented assignment.
+ case '-': {
+ if (pline.size > 1 && pline.data[1] == '>') {
+ ret.len++;
+ ret.type = kExprLexArrow;
+ } else if (pline.size > 1 && pline.data[1] == '=') {
+ ret.len++;
+ ret.type = kExprLexAssignment;
+ ret.data.ass.type = kExprAsgnSubtract;
+ } else {
+ ret.type = kExprLexMinus;
}
+ break;
+ }
// Sign or augmented assignment.
#define CHAR_OR_ASSIGN(ch, ch_type, ass_type) \
- case ch: { \
- if (pline.size > 1 && pline.data[1] == '=') { \
- ret.len++; \
- ret.type = kExprLexAssignment; \
- ret.data.ass.type = ass_type; \
- } else { \
- ret.type = ch_type; \
- } \
- break; \
- }
+case ch: { \
+ if (pline.size > 1 && pline.data[1] == '=') { \
+ ret.len++; \
+ ret.type = kExprLexAssignment; \
+ ret.data.ass.type = ass_type; \
+ } else { \
+ ret.type = ch_type; \
+ } \
+ break; \
+}
CHAR_OR_ASSIGN('+', kExprLexPlus, kExprAsgnAdd)
CHAR_OR_ASSIGN('.', kExprLexDot, kExprAsgnConcat)
#undef CHAR_OR_ASSIGN
- // Expression end because Ex command ended.
- case NUL:
- case NL: {
- if (flags & kELFlagForbidEOC) {
- ret.type = kExprLexInvalid;
- ret.data.err.msg = _("E15: Unexpected EOC character: %.*s");
- ret.data.err.type = kExprLexSpacing;
- } else {
- ret.type = kExprLexEOC;
- }
- break;
- }
-
- case '|': {
- if (pline.size >= 2 && pline.data[ret.len] == '|') {
- // "||" is or.
- ret.len++;
- ret.type = kExprLexOr;
- } else if (flags & kELFlagForbidEOC) {
- // Note: `<C-r>=1 | 2<CR>` actually yields 1 in Vim without any
- // errors. This will be changed here.
- ret.type = kExprLexInvalid;
- ret.data.err.msg = _("E15: Unexpected EOC character: %.*s");
- ret.data.err.type = kExprLexOr;
- } else {
- ret.type = kExprLexEOC;
- }
- break;
+ // Expression end because Ex command ended.
+ case NUL:
+ case NL:
+ if (flags & kELFlagForbidEOC) {
+ ret.type = kExprLexInvalid;
+ ret.data.err.msg = _("E15: Unexpected EOC character: %.*s");
+ ret.data.err.type = kExprLexSpacing;
+ } else {
+ ret.type = kExprLexEOC;
}
-
- // Everything else is not valid.
- default: {
- ret.len = (size_t)utfc_ptr2len_len((const char_u *)pline.data,
- (int)pline.size);
+ break;
+
+ case '|':
+ if (pline.size >= 2 && pline.data[ret.len] == '|') {
+ // "||" is or.
+ ret.len++;
+ ret.type = kExprLexOr;
+ } else if (flags & kELFlagForbidEOC) {
+ // Note: `<C-r>=1 | 2<CR>` actually yields 1 in Vim without any
+ // errors. This will be changed here.
ret.type = kExprLexInvalid;
- ret.data.err.type = kExprLexPlainIdentifier;
- ret.data.err.msg = _("E15: Unidentified character: %.*s");
- break;
+ ret.data.err.msg = _("E15: Unexpected EOC character: %.*s");
+ ret.data.err.type = kExprLexOr;
+ } else {
+ ret.type = kExprLexEOC;
}
+ break;
+
+ // Everything else is not valid.
+ default:
+ ret.len = (size_t)utfc_ptr2len_len((const char_u *)pline.data,
+ (int)pline.size);
+ ret.type = kExprLexInvalid;
+ ret.data.err.type = kExprLexPlainIdentifier;
+ ret.data.err.msg = _("E15: Unidentified character: %.*s");
+ break;
}
#undef GET_CCS
viml_pexpr_next_token_adv_return:
@@ -737,8 +793,7 @@ static const char *const eltkn_opt_scope_tab[] = {
///
/// @return Token represented in a string form, in a static buffer (overwritten
/// on each call).
-const char *viml_pexpr_repr_token(const ParserState *const pstate,
- const LexExprToken token,
+const char *viml_pexpr_repr_token(const ParserState *const pstate, const LexExprToken token,
size_t *const ret_size)
FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -756,10 +811,10 @@ const char *viml_pexpr_repr_token(const ParserState *const pstate,
eltkn_type_tab[token.type]);
switch (token.type) {
#define TKNARGS(tkn_type, ...) \
- case tkn_type: { \
- ADDSTR(__VA_ARGS__); \
- break; \
- }
+case tkn_type: { \
+ ADDSTR(__VA_ARGS__); \
+ break; \
+}
TKNARGS(kExprLexComparison, "(type=%s,ccs=%s,inv=%i)",
eltkn_cmp_type_tab[token.data.cmp.type],
ccs_tab[token.data.cmp.ccs],
@@ -769,7 +824,7 @@ const char *viml_pexpr_repr_token(const ParserState *const pstate,
TKNARGS(kExprLexAssignment, "(type=%s)",
expr_asgn_type_tab[token.data.ass.type])
TKNARGS(kExprLexRegister, "(name=%s)", intchar2str(token.data.reg.name))
- case kExprLexDoubleQuotedString:
+ case kExprLexDoubleQuotedString:
TKNARGS(kExprLexSingleQuotedString, "(closed=%i)",
(int)token.data.str.closed)
TKNARGS(kExprLexOption, "(scope=%s,name=%.*s)",
@@ -785,19 +840,17 @@ const char *viml_pexpr_repr_token(const ParserState *const pstate,
? (double)token.data.num.val.floating
: (double)token.data.num.val.integer))
TKNARGS(kExprLexInvalid, "(msg=%s)", token.data.err.msg)
- default: {
- // No additional arguments.
- break;
- }
+ default:
+ // No additional arguments.
+ break;
#undef TKNARGS
}
if (pstate == NULL) {
ADDSTR("::%zu", token.len);
} else {
*p++ = ':';
- memmove(
- p, &pstate->reader.lines.items[token.start.line].data[token.start.col],
- token.len);
+ memmove(p, &pstate->reader.lines.items[token.start.line].data[token.start.col],
+ token.len);
p += token.len;
*p = NUL;
}
@@ -886,9 +939,8 @@ static const char *intchar2str(const int ch)
#include <stdio.h>
REAL_FATTR_UNUSED
-static inline void viml_pexpr_debug_print_ast_node(
- const ExprASTNode *const *const eastnode_p,
- const char *const prefix)
+static inline void viml_pexpr_debug_print_ast_node(const ExprASTNode *const *const eastnode_p,
+ const char *const prefix)
{
if (*eastnode_p == NULL) {
fprintf(stderr, "%s %p : NULL\n", prefix, (void *)eastnode_p);
@@ -901,35 +953,33 @@ static inline void viml_pexpr_debug_print_ast_node(
}
REAL_FATTR_UNUSED
-static inline void viml_pexpr_debug_print_ast_stack(
- const ExprASTStack *const ast_stack,
- const char *const msg)
+static inline void viml_pexpr_debug_print_ast_stack(const ExprASTStack *const ast_stack,
+ const char *const msg)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
{
fprintf(stderr, "\n%sstack: %zu:\n", msg, kv_size(*ast_stack));
for (size_t i = 0; i < kv_size(*ast_stack); i++) {
- viml_pexpr_debug_print_ast_node(
- (const ExprASTNode *const *)kv_A(*ast_stack, i),
- "-");
+ viml_pexpr_debug_print_ast_node((const ExprASTNode *const *)kv_A(*ast_stack, i),
+ "-");
}
}
REAL_FATTR_UNUSED
-static inline void viml_pexpr_debug_print_token(
- const ParserState *const pstate, const LexExprToken token)
+static inline void viml_pexpr_debug_print_token(const ParserState *const pstate,
+ const LexExprToken token)
FUNC_ATTR_ALWAYS_INLINE
{
fprintf(stderr, "\ntkn: %s\n", viml_pexpr_repr_token(pstate, token, NULL));
}
#define PSTACK(msg) \
- viml_pexpr_debug_print_ast_stack(&ast_stack, #msg)
+ viml_pexpr_debug_print_ast_stack(&ast_stack, #msg)
#define PSTACK_P(msg) \
- viml_pexpr_debug_print_ast_stack(ast_stack, #msg)
+ viml_pexpr_debug_print_ast_stack(ast_stack, #msg)
#define PNODE_P(eastnode_p, msg) \
- viml_pexpr_debug_print_ast_node((const ExprASTNode *const *)eastnode_p, \
- (#msg))
+ viml_pexpr_debug_print_ast_node((const ExprASTNode *const *)eastnode_p, \
+ (#msg))
#define PTOKEN(tkn) \
- viml_pexpr_debug_print_token(pstate, tkn)
+ viml_pexpr_debug_print_token(pstate, tkn)
#endif
const uint8_t node_maxchildren[] = {
@@ -1009,50 +1059,48 @@ void viml_pexpr_free_ast(ExprAST ast)
} else if (*cur_node != NULL) {
kv_drop(ast_stack, 1);
switch ((*cur_node)->type) {
- case kExprNodeDoubleQuotedString:
- case kExprNodeSingleQuotedString: {
- xfree((*cur_node)->data.str.value);
- break;
- }
- case kExprNodeMissing:
- case kExprNodeOpMissing:
- case kExprNodeTernary:
- case kExprNodeTernaryValue:
- case kExprNodeRegister:
- case kExprNodeSubscript:
- case kExprNodeListLiteral:
- case kExprNodeUnaryPlus:
- case kExprNodeBinaryPlus:
- case kExprNodeNested:
- case kExprNodeCall:
- case kExprNodePlainIdentifier:
- case kExprNodePlainKey:
- case kExprNodeComplexIdentifier:
- case kExprNodeUnknownFigure:
- case kExprNodeLambda:
- case kExprNodeDictLiteral:
- case kExprNodeCurlyBracesIdentifier:
- case kExprNodeAssignment:
- case kExprNodeComma:
- case kExprNodeColon:
- case kExprNodeArrow:
- case kExprNodeComparison:
- case kExprNodeConcat:
- case kExprNodeConcatOrSubscript:
- case kExprNodeInteger:
- case kExprNodeFloat:
- case kExprNodeOr:
- case kExprNodeAnd:
- case kExprNodeUnaryMinus:
- case kExprNodeBinaryMinus:
- case kExprNodeNot:
- case kExprNodeMultiplication:
- case kExprNodeDivision:
- case kExprNodeMod:
- case kExprNodeOption:
- case kExprNodeEnvironment: {
- break;
- }
+ case kExprNodeDoubleQuotedString:
+ case kExprNodeSingleQuotedString:
+ xfree((*cur_node)->data.str.value);
+ break;
+ case kExprNodeMissing:
+ case kExprNodeOpMissing:
+ case kExprNodeTernary:
+ case kExprNodeTernaryValue:
+ case kExprNodeRegister:
+ case kExprNodeSubscript:
+ case kExprNodeListLiteral:
+ case kExprNodeUnaryPlus:
+ case kExprNodeBinaryPlus:
+ case kExprNodeNested:
+ case kExprNodeCall:
+ case kExprNodePlainIdentifier:
+ case kExprNodePlainKey:
+ case kExprNodeComplexIdentifier:
+ case kExprNodeUnknownFigure:
+ case kExprNodeLambda:
+ case kExprNodeDictLiteral:
+ case kExprNodeCurlyBracesIdentifier:
+ case kExprNodeAssignment:
+ case kExprNodeComma:
+ case kExprNodeColon:
+ case kExprNodeArrow:
+ case kExprNodeComparison:
+ case kExprNodeConcat:
+ case kExprNodeConcatOrSubscript:
+ case kExprNodeInteger:
+ case kExprNodeFloat:
+ case kExprNodeOr:
+ case kExprNodeAnd:
+ case kExprNodeUnaryMinus:
+ case kExprNodeBinaryMinus:
+ case kExprNodeNot:
+ case kExprNodeMultiplication:
+ case kExprNodeDivision:
+ case kExprNodeMod:
+ case kExprNodeOption:
+ case kExprNodeEnvironment:
+ break;
}
xfree(*cur_node);
*cur_node = NULL;
@@ -1204,10 +1252,8 @@ static inline ExprOpAssociativity node_ass(const ExprASTNode node)
/// @param[out] ast_err Location where error is saved, if any.
///
/// @return True if no errors occurred, false otherwise.
-static bool viml_pexpr_handle_bop(const ParserState *const pstate,
- ExprASTStack *const ast_stack,
- ExprASTNode *const bop_node,
- ExprASTWantedNode *const want_node_p,
+static bool viml_pexpr_handle_bop(const ParserState *const pstate, ExprASTStack *const ast_stack,
+ ExprASTNode *const bop_node, ExprASTWantedNode *const want_node_p,
ExprASTError *const ast_err)
FUNC_ATTR_NONNULL_ALL
{
@@ -1223,8 +1269,8 @@ static bool viml_pexpr_handle_bop(const ParserState *const pstate,
: node_lvl(*bop_node));
#ifndef NDEBUG
const ExprOpAssociativity bop_node_ass = (
- (bop_node->type == kExprNodeCall
- || bop_node->type == kExprNodeSubscript)
+ (bop_node->type == kExprNodeCall
+ || bop_node->type == kExprNodeSubscript)
? kEOpAssLeft
: node_ass(*bop_node));
#endif
@@ -1301,8 +1347,7 @@ static bool viml_pexpr_handle_bop(const ParserState *const pstate,
/// @param[in] shift Number of bytes to shift.
///
/// @return Shifted position.
-static inline ParserPosition shifted_pos(const ParserPosition pos,
- const size_t shift)
+static inline ParserPosition shifted_pos(const ParserPosition pos, const size_t shift)
FUNC_ATTR_CONST FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
{
return (ParserPosition) { .line = pos.line, .col = pos.col + shift };
@@ -1316,8 +1361,7 @@ static inline ParserPosition shifted_pos(const ParserPosition pos,
/// @param[in] new_col New column.
///
/// @return Shifted position.
-static inline ParserPosition recol_pos(const ParserPosition pos,
- const size_t new_col)
+static inline ParserPosition recol_pos(const ParserPosition pos, const size_t new_col)
FUNC_ATTR_CONST FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
{
return (ParserPosition) { .line = pos.line, .col = new_col };
@@ -1328,22 +1372,22 @@ static inline ParserPosition recol_pos(const ParserPosition pos,
/// Highlight current token with the given group
#define HL_CUR_TOKEN(g) \
- viml_parser_highlight(pstate, cur_token.start, cur_token.len, \
- HL(g))
+ viml_parser_highlight(pstate, cur_token.start, cur_token.len, \
+ HL(g))
/// Allocate new node, saving some values
#define NEW_NODE(type) \
- viml_pexpr_new_node(type)
+ viml_pexpr_new_node(type)
/// Set position of the given node to position from the given token
///
/// @param cur_node Node to modify.
/// @param cur_token Token to set position from.
#define POS_FROM_TOKEN(cur_node, cur_token) \
- do { \
- (cur_node)->start = cur_token.start; \
- (cur_node)->len = cur_token.len; \
- } while (0)
+ do { \
+ (cur_node)->start = cur_token.start; \
+ (cur_node)->len = cur_token.len; \
+ } while (0)
/// Allocate new node and set its position from the current token
///
@@ -1352,27 +1396,27 @@ static inline ParserPosition recol_pos(const ParserPosition pos,
/// @param cur_node Variable to save allocated node to.
/// @param typ Node type.
#define NEW_NODE_WITH_CUR_POS(cur_node, typ) \
- do { \
- (cur_node) = NEW_NODE(typ); \
- POS_FROM_TOKEN((cur_node), cur_token); \
- if (prev_token.type == kExprLexSpacing) { \
- (cur_node)->start = prev_token.start; \
- (cur_node)->len += prev_token.len; \
- } \
- } while (0)
+ do { \
+ (cur_node) = NEW_NODE(typ); \
+ POS_FROM_TOKEN((cur_node), cur_token); \
+ if (prev_token.type == kExprLexSpacing) { \
+ (cur_node)->start = prev_token.start; \
+ (cur_node)->len += prev_token.len; \
+ } \
+ } while (0)
/// Check whether it is possible to have next expression after current
///
/// For :echo: `:echo @a @a` is a valid expression. `:echo (@a @a)` is not.
#define MAY_HAVE_NEXT_EXPR \
- (kv_size(ast_stack) == 1)
+ (kv_size(ast_stack) == 1)
/// Add operator node
///
/// @param[in] cur_node Node to add.
#define ADD_OP_NODE(cur_node) \
- is_invalid |= !viml_pexpr_handle_bop(pstate, &ast_stack, cur_node, \
- &want_node, &ast.err)
+ is_invalid |= !viml_pexpr_handle_bop(pstate, &ast_stack, cur_node, \
+ &want_node, &ast.err)
/// Record missing operator: for things like
///
@@ -1384,33 +1428,33 @@ static inline ParserPosition recol_pos(const ParserPosition pos,
///
/// (parsed as OpMissing(@a, @a)).
#define OP_MISSING \
- do { \
- if (flags & kExprFlagsMulti && MAY_HAVE_NEXT_EXPR) { \
- /* Multiple expressions allowed, return without calling */ \
- /* viml_parser_advance(). */ \
- goto viml_pexpr_parse_end; \
- } else { \
- assert(*top_node_p != NULL); \
- ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Missing operator: %.*s")); \
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeOpMissing); \
- cur_node->len = 0; \
- ADD_OP_NODE(cur_node); \
- goto viml_pexpr_parse_process_token; \
- } \
- } while (0)
+ do { \
+ if (flags & kExprFlagsMulti && MAY_HAVE_NEXT_EXPR) { \
+ /* Multiple expressions allowed, return without calling */ \
+ /* viml_parser_advance(). */ \
+ goto viml_pexpr_parse_end; \
+ } else { \
+ assert(*top_node_p != NULL); \
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Missing operator: %.*s")); \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeOpMissing); \
+ cur_node->len = 0; \
+ ADD_OP_NODE(cur_node); \
+ goto viml_pexpr_parse_process_token; \
+ } \
+ } while (0)
/// Record missing value: for things like "* 5"
///
/// @param[in] msg Error message.
#define ADD_VALUE_IF_MISSING(msg) \
- do { \
- if (want_node == kENodeValue) { \
- ERROR_FROM_TOKEN_AND_MSG(cur_token, (msg)); \
- NEW_NODE_WITH_CUR_POS((*top_node_p), kExprNodeMissing); \
- (*top_node_p)->len = 0; \
- want_node = kENodeOperator; \
- } \
- } while (0)
+ do { \
+ if (want_node == kENodeValue) { \
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, (msg)); \
+ NEW_NODE_WITH_CUR_POS((*top_node_p), kExprNodeMissing); \
+ (*top_node_p)->len = 0; \
+ want_node = kENodeOperator; \
+ } \
+ } while (0)
/// Set AST error, unless AST already is not correct
///
@@ -1419,10 +1463,8 @@ static inline ParserPosition recol_pos(const ParserPosition pos,
/// @param[in] msg Error message, assumed to be already translated and
/// containing a single %token "%.*s".
/// @param[in] start Position at which error occurred.
-static inline void east_set_error(const ParserState *const pstate,
- ExprASTError *const ret_ast_err,
- const char *const msg,
- const ParserPosition start)
+static inline void east_set_error(const ParserState *const pstate, ExprASTError *const ret_ast_err,
+ const char *const msg, const ParserPosition start)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
{
if (ret_ast_err->msg != NULL) {
@@ -1436,21 +1478,21 @@ static inline void east_set_error(const ParserState *const pstate,
/// Set error from the given token and given message
#define ERROR_FROM_TOKEN_AND_MSG(cur_token, msg) \
- do { \
- is_invalid = true; \
- east_set_error(pstate, &ast.err, msg, cur_token.start); \
- } while (0)
+ do { \
+ is_invalid = true; \
+ east_set_error(pstate, &ast.err, msg, cur_token.start); \
+ } while (0)
/// Like #ERROR_FROM_TOKEN_AND_MSG, but gets position from a node
#define ERROR_FROM_NODE_AND_MSG(node, msg) \
- do { \
- is_invalid = true; \
- east_set_error(pstate, &ast.err, msg, node->start); \
- } while (0)
+ do { \
+ is_invalid = true; \
+ east_set_error(pstate, &ast.err, msg, node->start); \
+ } while (0)
/// Set error from the given kExprLexInvalid token
#define ERROR_FROM_TOKEN(cur_token) \
- ERROR_FROM_TOKEN_AND_MSG(cur_token, cur_token.data.err.msg)
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, cur_token.data.err.msg)
/// Select figure brace type, altering highlighting as well if needed
///
@@ -1459,16 +1501,16 @@ static inline void east_set_error(const ParserState *const pstate,
/// kExprNode prefix.
/// @param[in] hl Corresponding highlighting, passed as an argument to #HL.
#define SELECT_FIGURE_BRACE_TYPE(node, new_type, hl) \
- do { \
- ExprASTNode *const node_ = (node); \
- assert(node_->type == kExprNodeUnknownFigure \
- || node_->type == kExprNode##new_type); \
- node_->type = kExprNode##new_type; \
- if (pstate->colors) { \
- kv_A(*pstate->colors, node_->data.fig.opening_hl_idx).group = \
- HL(hl); \
- } \
- } while (0)
+ do { \
+ ExprASTNode *const node_ = (node); \
+ assert(node_->type == kExprNodeUnknownFigure \
+ || node_->type == kExprNode##new_type); \
+ node_->type = kExprNode##new_type; \
+ if (pstate->colors) { \
+ kv_A(*pstate->colors, node_->data.fig.opening_hl_idx).group = \
+ HL(hl); \
+ } \
+ } while (0)
/// Add identifier which should constitute complex identifier node
///
@@ -1479,45 +1521,45 @@ static inline void east_set_error(const ParserState *const pstate,
/// a trailing semicolon.
/// @param hl Highlighting name to use, passed as an argument to #HL.
#define ADD_IDENT(new_ident_node_code, hl) \
- do { \
- assert(want_node == kENodeOperator); \
- /* Operator: may only be curly braces name, but only under certain */ \
- /* conditions. */ \
+ do { \
+ assert(want_node == kENodeOperator); \
+ /* Operator: may only be curly braces name, but only under certain */ \
+ /* conditions. */ \
\
- /* First condition is that there is no space before a part of complex */ \
- /* identifier. */ \
- if (prev_token.type == kExprLexSpacing) { \
- OP_MISSING; \
- } \
- switch ((*top_node_p)->type) { \
- /* Second is that previous node is one of the identifiers: */ \
- /* complex, plain, curly braces. */ \
+ /* First condition is that there is no space before a part of complex */ \
+ /* identifier. */ \
+ if (prev_token.type == kExprLexSpacing) { \
+ OP_MISSING; \
+ } \
+ switch ((*top_node_p)->type) { \
+ /* Second is that previous node is one of the identifiers: */ \
+ /* complex, plain, curly braces. */ \
\
- /* TODO(ZyX-I): Extend syntax to allow ${expr}. This is needed to */ \
- /* handle environment variables like those bash uses for */ \
- /* `export -f`: their names consist not only of alphanumeric */ \
- /* characetrs. */ \
- case kExprNodeComplexIdentifier: \
- case kExprNodePlainIdentifier: \
- case kExprNodeCurlyBracesIdentifier: { \
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComplexIdentifier); \
- cur_node->len = 0; \
- cur_node->children = *top_node_p; \
- *top_node_p = cur_node; \
- kvi_push(ast_stack, &cur_node->children->next); \
- ExprASTNode **const new_top_node_p = kv_last(ast_stack); \
- assert(*new_top_node_p == NULL); \
- new_ident_node_code; \
- *new_top_node_p = cur_node; \
- HL_CUR_TOKEN(hl); \
- break; \
- } \
- default: { \
- OP_MISSING; \
- break; \
- } \
- } \
- } while (0)
+ /* TODO(ZyX-I): Extend syntax to allow ${expr}. This is needed to */ \
+ /* handle environment variables like those bash uses for */ \
+ /* `export -f`: their names consist not only of alphanumeric */ \
+ /* characetrs. */ \
+ case kExprNodeComplexIdentifier: \
+ case kExprNodePlainIdentifier: \
+ case kExprNodeCurlyBracesIdentifier: { \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComplexIdentifier); \
+ cur_node->len = 0; \
+ cur_node->children = *top_node_p; \
+ *top_node_p = cur_node; \
+ kvi_push(ast_stack, &cur_node->children->next); \
+ ExprASTNode **const new_top_node_p = kv_last(ast_stack); \
+ assert(*new_top_node_p == NULL); \
+ new_ident_node_code; \
+ *new_top_node_p = cur_node; \
+ HL_CUR_TOKEN(hl); \
+ break; \
+ } \
+ default: { \
+ OP_MISSING; \
+ break; \
+ } \
+ } \
+ } while (0)
/// Determine whether given parse type is an assignment
///
@@ -1551,10 +1593,8 @@ typedef struct {
/// @param[in] ast_stack Parser AST stack, used to detect whether current
/// string is a regex.
/// @param[in] is_invalid Whether currently processed token is not valid.
-static void parse_quoted_string(ParserState *const pstate,
- ExprASTNode *const node,
- const LexExprToken token,
- const ExprASTStack ast_stack,
+static void parse_quoted_string(ParserState *const pstate, ExprASTNode *const node,
+ const LexExprToken token, const ExprASTStack ast_stack,
const bool is_invalid)
FUNC_ATTR_NONNULL_ALL
{
@@ -1577,10 +1617,10 @@ static void parse_quoted_string(ParserState *const pstate,
p = chunk_e + 2;
if (pstate->colors) {
kvi_push(shifts, ((StringShift) {
- .start = token.start.col + (size_t)(chunk_e - s),
- .orig_len = 2,
- .act_len = 1,
- .escape_not_known = false,
+ .start = token.start.col + (size_t)(chunk_e - s),
+ .orig_len = 2,
+ .act_len = 1,
+ .escape_not_known = false,
}));
}
}
@@ -1613,70 +1653,74 @@ static void parse_quoted_string(ParserState *const pstate,
break;
}
switch (*p) {
- // A "\<x>" form occupies at least 4 characters, and produces up to
- // 6 characters: reserve space for 2 extra, but do not compute actual
- // length just now, it would be costy.
- case '<': {
- size += 2;
- break;
- }
- // Hexadecimal, always single byte, but at least three bytes each.
- case 'x': case 'X': {
+ // A "\<x>" form occupies at least 4 characters, and produces up to
+ // 6 characters: reserve space for 2 extra, but do not compute actual
+ // length just now, it would be costy.
+ case '<':
+ size += 2;
+ break;
+ // Hexadecimal, always single byte, but at least three bytes each.
+ case 'x':
+ case 'X':
+ size--;
+ if (ascii_isxdigit(p[1])) {
size--;
- if (ascii_isxdigit(p[1])) {
+ if (p + 2 < e && ascii_isxdigit(p[2])) {
size--;
- if (p + 2 < e && ascii_isxdigit(p[2])) {
- size--;
- }
}
- break;
}
- // Unicode
- //
- // \uF takes 1 byte which is 2 bytes less then escape sequence.
- // \uFF: 2 bytes, 2 bytes less.
- // \uFFF: 3 bytes, 2 bytes less.
- // \uFFFF: 3 bytes, 3 bytes less.
- // \UFFFFF: 4 bytes, 3 bytes less.
- // \UFFFFFF: 5 bytes, 3 bytes less.
- // \UFFFFFFF: 6 bytes, 3 bytes less.
- // \U7FFFFFFF: 6 bytes, 4 bytes less.
- case 'u': case 'U': {
- const char *const esc_start = p;
- size_t n = (*p == 'u' ? 4 : 8);
- int nr = 0;
+ break;
+ // Unicode
+ //
+ // \uF takes 1 byte which is 2 bytes less then escape sequence.
+ // \uFF: 2 bytes, 2 bytes less.
+ // \uFFF: 3 bytes, 2 bytes less.
+ // \uFFFF: 3 bytes, 3 bytes less.
+ // \UFFFFF: 4 bytes, 3 bytes less.
+ // \UFFFFFF: 5 bytes, 3 bytes less.
+ // \UFFFFFFF: 6 bytes, 3 bytes less.
+ // \U7FFFFFFF: 6 bytes, 4 bytes less.
+ case 'u':
+ case 'U': {
+ const char *const esc_start = p;
+ size_t n = (*p == 'u' ? 4 : 8);
+ int nr = 0;
+ p++;
+ while (p + 1 < e && n-- && ascii_isxdigit(p[1])) {
p++;
- while (p + 1 < e && n-- && ascii_isxdigit(p[1])) {
- p++;
- nr = (nr << 4) + hex2nr(*p);
- }
- // Escape length: (esc_start - 1) points to "\\", esc_start to "u"
- // or "U", p to the byte after last byte. So escape sequence
- // occupies p - (esc_start - 1), but it stands for a utf_char2len
- // bytes.
- size -= (size_t)((p - (esc_start - 1)) - utf_char2len(nr));
- p--;
- break;
+ nr = (nr << 4) + hex2nr(*p);
}
- // Octal, always single byte, but at least two bytes each.
- case '0': case '1': case '2': case '3': case '4': case '5': case '6':
- case '7': {
+ // Escape length: (esc_start - 1) points to "\\", esc_start to "u"
+ // or "U", p to the byte after last byte. So escape sequence
+ // occupies p - (esc_start - 1), but it stands for a utf_char2len
+ // bytes.
+ size -= (size_t)((p - (esc_start - 1)) - utf_char2len(nr));
+ p--;
+ break;
+ }
+ // Octal, always single byte, but at least two bytes each.
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ size--;
+ p++;
+ if (*p >= '0' && *p <= '7') {
size--;
p++;
- if (*p >= '0' && *p <= '7') {
+ if (p < e && *p >= '0' && *p <= '7') {
size--;
p++;
- if (p < e && *p >= '0' && *p <= '7') {
- size--;
- p++;
- }
}
- break;
- }
- default: {
- size--;
- break;
}
+ break;
+ default:
+ size--;
+ break;
}
}
}
@@ -1705,11 +1749,11 @@ static void parse_quoted_string(ParserState *const pstate,
const char *const v_p_start = v_p;
switch (*p) {
#define SINGLE_CHAR_ESC(ch, real_ch) \
- case ch: { \
- *v_p++ = real_ch; \
- p++; \
- break; \
- }
+case ch: { \
+ *v_p++ = real_ch; \
+ p++; \
+ break; \
+}
SINGLE_CHAR_ESC('b', BS)
SINGLE_CHAR_ESC('e', ESC)
SINGLE_CHAR_ESC('f', FF)
@@ -1720,76 +1764,83 @@ static void parse_quoted_string(ParserState *const pstate,
SINGLE_CHAR_ESC('\\', '\\')
#undef SINGLE_CHAR_ESC
- // Hexadecimal or unicode.
- case 'X': case 'x': case 'u': case 'U': {
- if (p + 1 < e && ascii_isxdigit(p[1])) {
- size_t n;
- int nr;
- bool is_hex = (*p == 'x' || *p == 'X');
-
- if (is_hex) {
- n = 2;
- } else if (*p == 'u') {
- n = 4;
- } else {
- n = 8;
- }
- nr = 0;
- while (p + 1 < e && n-- && ascii_isxdigit(p[1])) {
- p++;
- nr = (nr << 4) + hex2nr(*p);
- }
- p++;
- if (is_hex) {
- *v_p++ = (char)nr;
- } else {
- v_p += utf_char2bytes(nr, (char_u *)v_p);
- }
+ // Hexadecimal or unicode.
+ case 'X':
+ case 'x':
+ case 'u':
+ case 'U':
+ if (p + 1 < e && ascii_isxdigit(p[1])) {
+ size_t n;
+ int nr;
+ bool is_hex = (*p == 'x' || *p == 'X');
+
+ if (is_hex) {
+ n = 2;
+ } else if (*p == 'u') {
+ n = 4;
} else {
- is_unknown = true;
- *v_p++ = *p;
+ n = 8;
+ }
+ nr = 0;
+ while (p + 1 < e && n-- && ascii_isxdigit(p[1])) {
p++;
+ nr = (nr << 4) + hex2nr(*p);
+ }
+ p++;
+ if (is_hex) {
+ *v_p++ = (char)nr;
+ } else {
+ v_p += utf_char2bytes(nr, (char_u *)v_p);
}
- break;
+ } else {
+ is_unknown = true;
+ *v_p++ = *p;
+ p++;
}
- // Octal: "\1", "\12", "\123".
- case '0': case '1': case '2': case '3': case '4': case '5': case '6':
- case '7': {
- uint8_t ch = (uint8_t)(*p++ - '0');
+ break;
+ // Octal: "\1", "\12", "\123".
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7': {
+ uint8_t ch = (uint8_t)(*p++ - '0');
+ if (p < e && *p >= '0' && *p <= '7') {
+ ch = (uint8_t)((ch << 3) + *p++ - '0');
if (p < e && *p >= '0' && *p <= '7') {
ch = (uint8_t)((ch << 3) + *p++ - '0');
- if (p < e && *p >= '0' && *p <= '7') {
- ch = (uint8_t)((ch << 3) + *p++ - '0');
- }
}
- *v_p++ = (char)ch;
- break;
}
- // Special key, e.g.: "\<C-W>"
- case '<': {
- const size_t special_len = (
- trans_special((const char_u **)&p, (size_t)(e - p),
- (char_u *)v_p, true, true));
- if (special_len != 0) {
- v_p += special_len;
- } else {
- is_unknown = true;
- mb_copy_char((const char_u **)&p, (char_u **)&v_p);
- }
- break;
- }
- default: {
+ *v_p++ = (char)ch;
+ break;
+ }
+ // Special key, e.g.: "\<C-W>"
+ case '<': {
+ const size_t special_len = (
+ trans_special((const char_u **)&p, (size_t)(e - p),
+ (char_u *)v_p, true, true));
+ if (special_len != 0) {
+ v_p += special_len;
+ } else {
is_unknown = true;
mb_copy_char((const char_u **)&p, (char_u **)&v_p);
- break;
}
+ break;
+ }
+ default:
+ is_unknown = true;
+ mb_copy_char((const char_u **)&p, (char_u **)&v_p);
+ break;
}
if (pstate->colors) {
kvi_push(shifts, ((StringShift) {
- .start = token.start.col + (size_t)(chunk_e - s),
- .orig_len = (size_t)(p - chunk_e),
- .act_len = (size_t)(v_p - (char *)v_p_start),
- .escape_not_known = is_unknown,
+ .start = token.start.col + (size_t)(chunk_e - s),
+ .orig_len = (size_t)(p - chunk_e),
+ .act_len = (size_t)(v_p - (char *)v_p_start),
+ .escape_not_known = is_unknown,
}));
}
}
@@ -1901,21 +1952,23 @@ ExprAST viml_pexpr_parse(ParserState *const pstate, const int flags)
size_t asgn_level = 0;
do {
const bool is_concat_or_subscript = (
- want_node == kENodeValue
- && kv_size(ast_stack) > 1
- && (*kv_Z(ast_stack, 1))->type == kExprNodeConcatOrSubscript);
+ want_node == kENodeValue
+ && kv_size(ast_stack) > 1
+ && (*kv_Z(ast_stack,
+ 1))->type == kExprNodeConcatOrSubscript);
const int lexer_additional_flags = (
- kELFlagPeek
- | ((flags & kExprFlagsDisallowEOC) ? kELFlagForbidEOC : 0)
- | ((want_node == kENodeValue
- && (kv_size(ast_stack) == 1
- || ((*kv_Z(ast_stack, 1))->type != kExprNodeConcat
- && ((*kv_Z(ast_stack, 1))->type
- != kExprNodeConcatOrSubscript))))
+ kELFlagPeek
+ | ((flags & kExprFlagsDisallowEOC) ? kELFlagForbidEOC : 0)
+ | ((want_node == kENodeValue
+ && (kv_size(ast_stack) == 1
+ || ((*kv_Z(ast_stack, 1))->type != kExprNodeConcat
+ && ((*kv_Z(ast_stack, 1))->type
+ != kExprNodeConcatOrSubscript))))
? kELFlagAllowFloat
: 0));
- LexExprToken cur_token = viml_pexpr_next_token(
- pstate, want_node_to_lexer_flags[want_node] | lexer_additional_flags);
+ LexExprToken cur_token = viml_pexpr_next_token(pstate,
+ want_node_to_lexer_flags[want_node] |
+ lexer_additional_flags);
if (cur_token.type == kExprLexEOC) {
break;
}
@@ -1924,8 +1977,8 @@ ExprAST viml_pexpr_parse(ParserState *const pstate, const int flags)
bool is_invalid = token_invalid;
viml_pexpr_parse_process_token:
// May use different flags this time.
- cur_token = viml_pexpr_next_token(
- pstate, want_node_to_lexer_flags[want_node] | lexer_additional_flags);
+ cur_token = viml_pexpr_next_token(pstate,
+ want_node_to_lexer_flags[want_node] | lexer_additional_flags);
if (tok_type == kExprLexSpacing) {
if (is_invalid) {
HL_CUR_TOKEN(Spacing);
@@ -1977,12 +2030,12 @@ viml_pexpr_parse_process_token:
// for ternary and because concatenating dictionary with anything is not
// valid. There are more cases when this will make a difference though.
const bool node_is_key = (
- is_concat_or_subscript
- && (cur_token.type == kExprLexPlainIdentifier
+ is_concat_or_subscript
+ && (cur_token.type == kExprLexPlainIdentifier
? (!cur_token.data.var.autoload
&& cur_token.data.var.scope == kExprVarScopeMissing)
: (cur_token.type == kExprLexNumber))
- && prev_token.type != kExprLexSpacing);
+ && prev_token.type != kExprLexSpacing);
if (is_concat_or_subscript && !node_is_key) {
// Note: in Vim "d. a" (this is the reason behind `prev_token.type !=
// kExprLexSpacing` part of the condition) as well as any other "d.{expr}"
@@ -1997,951 +2050,896 @@ viml_pexpr_parse_process_token:
// Pop some stack pt_stack items in case of misplaced nodes.
const bool is_single_assignment = kv_last(pt_stack) == kEPTSingleAssignment;
switch (kv_last(pt_stack)) {
- case kEPTExpr: {
- break;
- }
- case kEPTLambdaArguments: {
- if ((want_node == kENodeOperator
- && tok_type != kExprLexComma
- && tok_type != kExprLexArrow)
- || (want_node == kENodeValue
- && !(cur_token.type == kExprLexPlainIdentifier
- && cur_token.data.var.scope == kExprVarScopeMissing
- && !cur_token.data.var.autoload)
- && tok_type != kExprLexArrow)) {
- lambda_node->data.fig.type_guesses.allow_lambda = false;
- if (lambda_node->children != NULL
- && lambda_node->children->type == kExprNodeComma) {
- // If lambda has comma child this means that parser has already seen
- // at least "{arg1,", so node cannot possibly be anything, but
- // lambda.
-
- // Vim may give E121 or E720 in this case, but it does not look
- // right to have either because both are results of reevaluation
- // possibly-lambda node as a dictionary and here this is not going
- // to happen.
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E15: Expected lambda arguments list or arrow: %.*s"));
- } else {
- // Else it may appear that possibly-lambda node is actually
- // a dictionary or curly-braces-name identifier.
- lambda_node = NULL;
- kv_drop(pt_stack, 1);
- }
+ case kEPTExpr:
+ break;
+ case kEPTLambdaArguments:
+ if ((want_node == kENodeOperator
+ && tok_type != kExprLexComma
+ && tok_type != kExprLexArrow)
+ || (want_node == kENodeValue
+ && !(cur_token.type == kExprLexPlainIdentifier
+ && cur_token.data.var.scope == kExprVarScopeMissing
+ && !cur_token.data.var.autoload)
+ && tok_type != kExprLexArrow)) {
+ lambda_node->data.fig.type_guesses.allow_lambda = false;
+ if (lambda_node->children != NULL
+ && lambda_node->children->type == kExprNodeComma) {
+ // If lambda has comma child this means that parser has already seen
+ // at least "{arg1,", so node cannot possibly be anything, but
+ // lambda.
+
+ // Vim may give E121 or E720 in this case, but it does not look
+ // right to have either because both are results of reevaluation
+ // possibly-lambda node as a dictionary and here this is not going
+ // to happen.
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E15: Expected lambda arguments list or arrow: %.*s"));
+ } else {
+ // Else it may appear that possibly-lambda node is actually
+ // a dictionary or curly-braces-name identifier.
+ lambda_node = NULL;
+ kv_drop(pt_stack, 1);
}
- break;
}
- case kEPTSingleAssignment:
- case kEPTAssignment: {
- if (want_node == kENodeValue
- && tok_type != kExprLexBracket
- && tok_type != kExprLexPlainIdentifier
- && (tok_type != kExprLexFigureBrace || cur_token.data.brc.closing)
- && !(node_is_key && tok_type == kExprLexNumber)
- && tok_type != kExprLexEnv
- && tok_type != kExprLexOption
- && tok_type != kExprLexRegister) {
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E15: Expected value part of assignment lvalue: %.*s"));
- kv_drop(pt_stack, 1);
- } else if (want_node == kENodeOperator
- && tok_type != kExprLexBracket
- && (tok_type != kExprLexFigureBrace
- || cur_token.data.brc.closing)
- && tok_type != kExprLexDot
- && (tok_type != kExprLexComma || !is_single_assignment)
- && tok_type != kExprLexAssignment
- // Curly brace identifiers: will contain plain identifier or
- // another curly brace in position where operator is wanted.
- && !((tok_type == kExprLexPlainIdentifier
- || (tok_type == kExprLexFigureBrace
- && !cur_token.data.brc.closing))
- && prev_token.type != kExprLexSpacing)) {
- if (flags & kExprFlagsMulti && MAY_HAVE_NEXT_EXPR) {
- goto viml_pexpr_parse_end;
- }
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E15: Expected assignment operator or subscript: %.*s"));
- kv_drop(pt_stack, 1);
+ break;
+ case kEPTSingleAssignment:
+ case kEPTAssignment:
+ if (want_node == kENodeValue
+ && tok_type != kExprLexBracket
+ && tok_type != kExprLexPlainIdentifier
+ && (tok_type != kExprLexFigureBrace || cur_token.data.brc.closing)
+ && !(node_is_key && tok_type == kExprLexNumber)
+ && tok_type != kExprLexEnv
+ && tok_type != kExprLexOption
+ && tok_type != kExprLexRegister) {
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E15: Expected value part of assignment lvalue: %.*s"));
+ kv_drop(pt_stack, 1);
+ } else if (want_node == kENodeOperator
+ && tok_type != kExprLexBracket
+ && (tok_type != kExprLexFigureBrace
+ || cur_token.data.brc.closing)
+ && tok_type != kExprLexDot
+ && (tok_type != kExprLexComma || !is_single_assignment)
+ && tok_type != kExprLexAssignment
+ // Curly brace identifiers: will contain plain identifier or
+ // another curly brace in position where operator is wanted.
+ && !((tok_type == kExprLexPlainIdentifier
+ || (tok_type == kExprLexFigureBrace
+ && !cur_token.data.brc.closing))
+ && prev_token.type != kExprLexSpacing)) {
+ if (flags & kExprFlagsMulti && MAY_HAVE_NEXT_EXPR) {
+ goto viml_pexpr_parse_end;
}
- assert(kv_size(pt_stack));
- break;
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E15: Expected assignment operator or subscript: %.*s"));
+ kv_drop(pt_stack, 1);
}
+ assert(kv_size(pt_stack));
+ break;
}
assert(kv_size(pt_stack));
const ExprASTParseType cur_pt = kv_last(pt_stack);
assert(lambda_node == NULL || cur_pt == kEPTLambdaArguments);
switch (tok_type) {
- case kExprLexMissing:
- case kExprLexSpacing:
- case kExprLexEOC: {
- abort();
- }
- case kExprLexInvalid: {
- ERROR_FROM_TOKEN(cur_token);
- tok_type = cur_token.data.err.type;
- goto viml_pexpr_parse_process_token;
- }
- case kExprLexRegister: {
- if (want_node == kENodeOperator) {
- // Register in operator position: e.g. @a @a
- OP_MISSING;
- }
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeRegister);
- cur_node->data.reg.name = cur_token.data.reg.name;
- *top_node_p = cur_node;
- want_node = kENodeOperator;
- HL_CUR_TOKEN(Register);
- break;
+ case kExprLexMissing:
+ case kExprLexSpacing:
+ case kExprLexEOC:
+ abort();
+ case kExprLexInvalid:
+ ERROR_FROM_TOKEN(cur_token);
+ tok_type = cur_token.data.err.type;
+ goto viml_pexpr_parse_process_token;
+ case kExprLexRegister: {
+ if (want_node == kENodeOperator) {
+ // Register in operator position: e.g. @a @a
+ OP_MISSING;
}
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeRegister);
+ cur_node->data.reg.name = cur_token.data.reg.name;
+ *top_node_p = cur_node;
+ want_node = kENodeOperator;
+ HL_CUR_TOKEN(Register);
+ break;
+ }
#define SIMPLE_UB_OP(op) \
- case kExprLex##op: { \
- if (want_node == kENodeValue) { \
- /* Value level: assume unary operator. */ \
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeUnary##op); \
- *top_node_p = cur_node; \
- kvi_push(ast_stack, &cur_node->children); \
- HL_CUR_TOKEN(Unary##op); \
- } else { \
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeBinary##op); \
- ADD_OP_NODE(cur_node); \
- HL_CUR_TOKEN(Binary##op); \
- } \
- want_node = kENodeValue; \
- break; \
- }
+case kExprLex##op: { \
+ if (want_node == kENodeValue) { \
+ /* Value level: assume unary operator. */ \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeUnary##op); \
+ *top_node_p = cur_node; \
+ kvi_push(ast_stack, &cur_node->children); \
+ HL_CUR_TOKEN(Unary##op); \
+ } else { \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeBinary##op); \
+ ADD_OP_NODE(cur_node); \
+ HL_CUR_TOKEN(Binary##op); \
+ } \
+ want_node = kENodeValue; \
+ break; \
+}
SIMPLE_UB_OP(Plus)
SIMPLE_UB_OP(Minus)
#undef SIMPLE_UB_OP
#define SIMPLE_B_OP(op, msg) \
- case kExprLex##op: { \
- ADD_VALUE_IF_MISSING(_("E15: Unexpected " msg ": %.*s")); \
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNode##op); \
- HL_CUR_TOKEN(op); \
- ADD_OP_NODE(cur_node); \
- break; \
- }
+case kExprLex##op: { \
+ ADD_VALUE_IF_MISSING(_("E15: Unexpected " msg ": %.*s")); \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNode##op); \
+ HL_CUR_TOKEN(op); \
+ ADD_OP_NODE(cur_node); \
+ break; \
+}
SIMPLE_B_OP(Or, "or operator")
SIMPLE_B_OP(And, "and operator")
#undef SIMPLE_B_OP
- case kExprLexMultiplication: {
- ADD_VALUE_IF_MISSING(
- _("E15: Unexpected multiplication-like operator: %.*s"));
- switch (cur_token.data.mul.type) {
+ case kExprLexMultiplication:
+ ADD_VALUE_IF_MISSING(_("E15: Unexpected multiplication-like operator: %.*s"));
+ switch (cur_token.data.mul.type) {
#define MUL_OP(lex_op_tail, node_op_tail) \
- case kExprLexMul##lex_op_tail: { \
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNode##node_op_tail); \
- HL_CUR_TOKEN(node_op_tail); \
- break; \
- }
- MUL_OP(Mul, Multiplication)
- MUL_OP(Div, Division)
- MUL_OP(Mod, Mod)
+case kExprLexMul##lex_op_tail: { \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNode##node_op_tail); \
+ HL_CUR_TOKEN(node_op_tail); \
+ break; \
+}
+ MUL_OP(Mul, Multiplication)
+ MUL_OP(Div, Division)
+ MUL_OP(Mod, Mod)
#undef MUL_OP
- }
- ADD_OP_NODE(cur_node);
- break;
}
- case kExprLexOption: {
- if (want_node == kENodeOperator) {
- OP_MISSING;
- }
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeOption);
- if (cur_token.type == kExprLexInvalid) {
- assert(cur_token.len == 1
- || (cur_token.len == 3
- && pline.data[cur_token.start.col + 2] == ':'));
- cur_node->data.opt.ident = (
- pline.data + cur_token.start.col + cur_token.len);
- cur_node->data.opt.ident_len = 0;
- cur_node->data.opt.scope = (
- cur_token.len == 3
+ ADD_OP_NODE(cur_node);
+ break;
+ case kExprLexOption: {
+ if (want_node == kENodeOperator) {
+ OP_MISSING;
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeOption);
+ if (cur_token.type == kExprLexInvalid) {
+ assert(cur_token.len == 1
+ || (cur_token.len == 3
+ && pline.data[cur_token.start.col + 2] == ':'));
+ cur_node->data.opt.ident = (
+ pline.data + cur_token.start.col + cur_token.len);
+ cur_node->data.opt.ident_len = 0;
+ cur_node->data.opt.scope = (
+ cur_token.len == 3
? (ExprOptScope)pline.data[cur_token.start.col + 1]
: kExprOptScopeUnspecified);
- } else {
- cur_node->data.opt.ident = cur_token.data.opt.name;
- cur_node->data.opt.ident_len = cur_token.data.opt.len;
- cur_node->data.opt.scope = cur_token.data.opt.scope;
- }
+ } else {
+ cur_node->data.opt.ident = cur_token.data.opt.name;
+ cur_node->data.opt.ident_len = cur_token.data.opt.len;
+ cur_node->data.opt.scope = cur_token.data.opt.scope;
+ }
+ *top_node_p = cur_node;
+ want_node = kENodeOperator;
+ viml_parser_highlight(pstate, cur_token.start, 1, HL(OptionSigil));
+ const size_t scope_shift = (
+ cur_token.data.opt.scope == kExprOptScopeUnspecified ? 0 : 2);
+ if (scope_shift) {
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, 1), 1,
+ HL(OptionScope));
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, 2), 1,
+ HL(OptionScopeDelimiter));
+ }
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, scope_shift + 1),
+ cur_token.len - (scope_shift + 1), HL(OptionName));
+ break;
+ }
+ case kExprLexEnv:
+ if (want_node == kENodeOperator) {
+ OP_MISSING;
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeEnvironment);
+ cur_node->data.env.ident = pline.data + cur_token.start.col + 1;
+ cur_node->data.env.ident_len = cur_token.len - 1;
+ if (cur_node->data.env.ident_len == 0) {
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E15: Environment variable name missing"));
+ }
+ *top_node_p = cur_node;
+ want_node = kENodeOperator;
+ viml_parser_highlight(pstate, cur_token.start, 1, HL(EnvironmentSigil));
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, 1),
+ cur_token.len - 1, HL(EnvironmentName));
+ break;
+ case kExprLexNot:
+ if (want_node == kENodeOperator) {
+ OP_MISSING;
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeNot);
+ *top_node_p = cur_node;
+ kvi_push(ast_stack, &cur_node->children);
+ HL_CUR_TOKEN(Not);
+ break;
+ case kExprLexComparison:
+ ADD_VALUE_IF_MISSING(_("E15: Expected value, got comparison operator: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComparison);
+ if (cur_token.type == kExprLexInvalid) {
+ cur_node->data.cmp.ccs = kCCStrategyUseOption;
+ cur_node->data.cmp.type = kExprCmpEqual;
+ cur_node->data.cmp.inv = false;
+ } else {
+ cur_node->data.cmp.ccs = cur_token.data.cmp.ccs;
+ cur_node->data.cmp.type = cur_token.data.cmp.type;
+ cur_node->data.cmp.inv = cur_token.data.cmp.inv;
+ }
+ ADD_OP_NODE(cur_node);
+ if (cur_token.data.cmp.ccs != kCCStrategyUseOption) {
+ viml_parser_highlight(pstate, cur_token.start, cur_token.len - 1,
+ HL(Comparison));
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, cur_token.len - 1), 1,
+ HL(ComparisonModifier));
+ } else {
+ HL_CUR_TOKEN(Comparison);
+ }
+ want_node = kENodeValue;
+ break;
+ case kExprLexComma:
+ assert(!(want_node == kENodeValue && cur_pt == kEPTLambdaArguments));
+ if (want_node == kENodeValue) {
+ // Value level: comma appearing here is not valid.
+ // Note: in Vim string(,x) will give E116, this is not the case here.
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Expected value, got comma: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeMissing);
+ cur_node->len = 0;
*top_node_p = cur_node;
want_node = kENodeOperator;
- viml_parser_highlight(pstate, cur_token.start, 1, HL(OptionSigil));
- const size_t scope_shift = (
- cur_token.data.opt.scope == kExprOptScopeUnspecified ? 0 : 2);
- if (scope_shift) {
- viml_parser_highlight(pstate, shifted_pos(cur_token.start, 1), 1,
- HL(OptionScope));
- viml_parser_highlight(pstate, shifted_pos(cur_token.start, 2), 1,
- HL(OptionScopeDelimiter));
- }
- viml_parser_highlight(
- pstate, shifted_pos(cur_token.start, scope_shift + 1),
- cur_token.len - (scope_shift + 1), HL(OptionName));
- break;
}
- case kExprLexEnv: {
- if (want_node == kENodeOperator) {
- OP_MISSING;
- }
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeEnvironment);
- cur_node->data.env.ident = pline.data + cur_token.start.col + 1;
- cur_node->data.env.ident_len = cur_token.len - 1;
- if (cur_node->data.env.ident_len == 0) {
+ if (cur_pt == kEPTLambdaArguments) {
+ assert(lambda_node != NULL);
+ assert(lambda_node->data.fig.type_guesses.allow_lambda);
+ SELECT_FIGURE_BRACE_TYPE(lambda_node, Lambda, Lambda);
+ }
+ if (kv_size(ast_stack) < 2) {
+ goto viml_pexpr_parse_invalid_comma;
+ }
+ for (size_t i = 1; i < kv_size(ast_stack); i++) {
+ ExprASTNode *const *const eastnode_p =
+ (ExprASTNode *const *)kv_Z(ast_stack, i);
+ const ExprASTNodeType eastnode_type = (*eastnode_p)->type;
+ const ExprOpLvl eastnode_lvl = node_lvl(**eastnode_p);
+ if (eastnode_type == kExprNodeLambda) {
+ assert(cur_pt == kEPTLambdaArguments
+ && want_node == kENodeOperator);
+ break;
+ } else if (eastnode_type == kExprNodeDictLiteral
+ || eastnode_type == kExprNodeListLiteral
+ || eastnode_type == kExprNodeCall) {
+ break;
+ } else if (eastnode_type == kExprNodeComma
+ || eastnode_type == kExprNodeColon
+ || eastnode_lvl > kEOpLvlComma) {
+ // Do nothing
+ } else {
+viml_pexpr_parse_invalid_comma:
ERROR_FROM_TOKEN_AND_MSG(cur_token,
- _("E15: Environment variable name missing"));
+ _("E15: Comma outside of call, lambda or literal: %.*s"));
+ break;
+ }
+ if (i == kv_size(ast_stack) - 1) {
+ goto viml_pexpr_parse_invalid_comma;
}
- *top_node_p = cur_node;
- want_node = kENodeOperator;
- viml_parser_highlight(pstate, cur_token.start, 1, HL(EnvironmentSigil));
- viml_parser_highlight(pstate, shifted_pos(cur_token.start, 1),
- cur_token.len - 1, HL(EnvironmentName));
- break;
}
- case kExprLexNot: {
- if (want_node == kENodeOperator) {
- OP_MISSING;
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComma);
+ ADD_OP_NODE(cur_node);
+ HL_CUR_TOKEN(Comma);
+ break;
+#define EXP_VAL_COLON "E15: Expected value, got colon: %.*s"
+ case kExprLexColon: {
+ bool is_ternary = false;
+ if (kv_size(ast_stack) < 2) {
+ goto viml_pexpr_parse_invalid_colon;
+ }
+ bool can_be_ternary = true;
+ bool is_subscript = false;
+ for (size_t i = 1; i < kv_size(ast_stack); i++) {
+ ExprASTNode *const *const eastnode_p =
+ (ExprASTNode *const *)kv_Z(ast_stack, i);
+ const ExprASTNodeType eastnode_type = (*eastnode_p)->type;
+ const ExprOpLvl eastnode_lvl = node_lvl(**eastnode_p);
+ STATIC_ASSERT(kEOpLvlTernary > kEOpLvlComma,
+ "Unexpected operator priorities");
+ if (can_be_ternary && eastnode_type == kExprNodeTernaryValue
+ && !(*eastnode_p)->data.ter.got_colon) {
+ kv_drop(ast_stack, i);
+ (*eastnode_p)->start = cur_token.start;
+ (*eastnode_p)->len = cur_token.len;
+ if (prev_token.type == kExprLexSpacing) {
+ (*eastnode_p)->start = prev_token.start;
+ (*eastnode_p)->len += prev_token.len;
+ }
+ is_ternary = true;
+ (*eastnode_p)->data.ter.got_colon = true;
+ ADD_VALUE_IF_MISSING(_(EXP_VAL_COLON));
+ assert((*eastnode_p)->children != NULL);
+ assert((*eastnode_p)->children->next == NULL);
+ kvi_push(ast_stack, &(*eastnode_p)->children->next);
+ break;
+ } else if (eastnode_type == kExprNodeUnknownFigure) {
+ SELECT_FIGURE_BRACE_TYPE(*eastnode_p, DictLiteral, Dict);
+ break;
+ } else if (eastnode_type == kExprNodeDictLiteral) {
+ break;
+ } else if (eastnode_type == kExprNodeSubscript) {
+ is_subscript = true;
+ // can_be_ternary = false;
+ assert(!is_ternary);
+ break;
+ } else if (eastnode_type == kExprNodeColon) {
+ goto viml_pexpr_parse_invalid_colon;
+ } else if (eastnode_lvl >= kEOpLvlTernaryValue) {
+ // Do nothing
+ } else if (eastnode_lvl >= kEOpLvlComma) {
+ can_be_ternary = false;
+ } else {
+ goto viml_pexpr_parse_invalid_colon;
+ }
+ if (i == kv_size(ast_stack) - 1) {
+ goto viml_pexpr_parse_invalid_colon;
}
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeNot);
- *top_node_p = cur_node;
- kvi_push(ast_stack, &cur_node->children);
- HL_CUR_TOKEN(Not);
- break;
}
- case kExprLexComparison: {
- ADD_VALUE_IF_MISSING(
- _("E15: Expected value, got comparison operator: %.*s"));
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComparison);
- if (cur_token.type == kExprLexInvalid) {
- cur_node->data.cmp.ccs = kCCStrategyUseOption;
- cur_node->data.cmp.type = kExprCmpEqual;
- cur_node->data.cmp.inv = false;
+ if (is_subscript) {
+ assert(kv_size(ast_stack) > 1);
+ // Colon immediately following subscript start: it is empty subscript
+ // part like a[:2].
+ if (want_node == kENodeValue
+ && (*kv_Z(ast_stack, 1))->type == kExprNodeSubscript) {
+ NEW_NODE_WITH_CUR_POS(*top_node_p, kExprNodeMissing);
+ (*top_node_p)->len = 0;
+ want_node = kENodeOperator;
} else {
- cur_node->data.cmp.ccs = cur_token.data.cmp.ccs;
- cur_node->data.cmp.type = cur_token.data.cmp.type;
- cur_node->data.cmp.inv = cur_token.data.cmp.inv;
+ ADD_VALUE_IF_MISSING(_(EXP_VAL_COLON));
}
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeColon);
ADD_OP_NODE(cur_node);
- if (cur_token.data.cmp.ccs != kCCStrategyUseOption) {
- viml_parser_highlight(pstate, cur_token.start, cur_token.len - 1,
- HL(Comparison));
- viml_parser_highlight(
- pstate, shifted_pos(cur_token.start, cur_token.len - 1), 1,
- HL(ComparisonModifier));
+ HL_CUR_TOKEN(SubscriptColon);
+ } else {
+ goto viml_pexpr_parse_valid_colon;
+viml_pexpr_parse_invalid_colon:
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E15: Colon outside of dictionary or ternary operator: %.*s"));
+viml_pexpr_parse_valid_colon:
+ ADD_VALUE_IF_MISSING(_(EXP_VAL_COLON));
+ if (is_ternary) {
+ HL_CUR_TOKEN(TernaryColon);
} else {
- HL_CUR_TOKEN(Comparison);
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeColon);
+ ADD_OP_NODE(cur_node);
+ HL_CUR_TOKEN(Colon);
}
- want_node = kENodeValue;
- break;
}
- case kExprLexComma: {
- assert(!(want_node == kENodeValue && cur_pt == kEPTLambdaArguments));
- if (want_node == kENodeValue) {
- // Value level: comma appearing here is not valid.
- // Note: in Vim string(,x) will give E116, this is not the case here.
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Expected value, got comma: %.*s"));
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeMissing);
+ want_node = kENodeValue;
+ break;
+ }
+#undef EXP_VAL_COLON
+ case kExprLexBracket:
+ if (cur_token.data.brc.closing) {
+ ExprASTNode **new_top_node_p = NULL;
+ // Always drop the topmost value:
+ //
+ // 1. When want_node != kENodeValue topmost item on stack is
+ // a *finished* left operand, which may as well be "{@a}" which
+ // needs not be finished again.
+ // 2. Otherwise it is pointing to NULL what nobody wants.
+ kv_drop(ast_stack, 1);
+ if (!kv_size(ast_stack)) {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeListLiteral);
cur_node->len = 0;
+ if (want_node != kENodeValue) {
+ cur_node->children = *top_node_p;
+ }
*top_node_p = cur_node;
- want_node = kENodeOperator;
- }
- if (cur_pt == kEPTLambdaArguments) {
- assert(lambda_node != NULL);
- assert(lambda_node->data.fig.type_guesses.allow_lambda);
- SELECT_FIGURE_BRACE_TYPE(lambda_node, Lambda, Lambda);
+ goto viml_pexpr_parse_bracket_closing_error;
}
- if (kv_size(ast_stack) < 2) {
- goto viml_pexpr_parse_invalid_comma;
+ if (want_node == kENodeValue) {
+ // It is OK to want value if
+ //
+ // 1. It is empty list literal, in which case top node will be
+ // ListLiteral.
+ // 2. It is list literal with trailing comma, in which case top node
+ // will be that comma.
+ // 3. It is subscript with colon, but without one of the values:
+ // e.g. "a[:]", "a[1:]", top node will be colon in this case.
+ if ((*kv_last(ast_stack))->type != kExprNodeListLiteral
+ && (*kv_last(ast_stack))->type != kExprNodeComma
+ && (*kv_last(ast_stack))->type != kExprNodeColon) {
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E15: Expected value, got closing bracket: %.*s"));
+ }
}
- for (size_t i = 1; i < kv_size(ast_stack); i++) {
- ExprASTNode *const *const eastnode_p =
- (ExprASTNode *const *)kv_Z(ast_stack, i);
- const ExprASTNodeType eastnode_type = (*eastnode_p)->type;
- const ExprOpLvl eastnode_lvl = node_lvl(**eastnode_p);
- if (eastnode_type == kExprNodeLambda) {
- assert(cur_pt == kEPTLambdaArguments
- && want_node == kENodeOperator);
- break;
- } else if (eastnode_type == kExprNodeDictLiteral
- || eastnode_type == kExprNodeListLiteral
- || eastnode_type == kExprNodeCall) {
- break;
- } else if (eastnode_type == kExprNodeComma
- || eastnode_type == kExprNodeColon
- || eastnode_lvl > kEOpLvlComma) {
- // Do nothing
- } else {
-viml_pexpr_parse_invalid_comma:
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E15: Comma outside of call, lambda or literal: %.*s"));
- break;
+ do {
+ new_top_node_p = kv_pop(ast_stack);
+ } while (kv_size(ast_stack)
+ && (new_top_node_p == NULL
+ || ((*new_top_node_p)->type != kExprNodeListLiteral
+ && (*new_top_node_p)->type != kExprNodeSubscript)));
+ ExprASTNode *new_top_node = *new_top_node_p;
+ switch (new_top_node->type) {
+ case kExprNodeListLiteral:
+ if (pt_is_assignment(cur_pt) && new_top_node->children == NULL) {
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E475: Unable to assign to empty list: %.*s"));
}
- if (i == kv_size(ast_stack) - 1) {
- goto viml_pexpr_parse_invalid_comma;
+ HL_CUR_TOKEN(List);
+ break;
+ case kExprNodeSubscript:
+ HL_CUR_TOKEN(SubscriptBracket);
+ break;
+ default:
+viml_pexpr_parse_bracket_closing_error:
+ assert(!kv_size(ast_stack));
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Unexpected closing figure brace: %.*s"));
+ HL_CUR_TOKEN(List);
+ break;
+ }
+ kvi_push(ast_stack, new_top_node_p);
+ want_node = kENodeOperator;
+ if (kv_size(ast_stack) <= asgn_level) {
+ assert(kv_size(ast_stack) == asgn_level);
+ asgn_level = 0;
+ if (cur_pt == kEPTAssignment) {
+ assert(ast.err.msg);
+ } else if (cur_pt == kEPTExpr
+ && kv_size(pt_stack) > 1
+ && pt_is_assignment(kv_Z(pt_stack, 1))) {
+ kv_drop(pt_stack, 1);
}
}
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComma);
- ADD_OP_NODE(cur_node);
- HL_CUR_TOKEN(Comma);
- break;
- }
-#define EXP_VAL_COLON "E15: Expected value, got colon: %.*s"
- case kExprLexColon: {
- bool is_ternary = false;
- if (kv_size(ast_stack) < 2) {
- goto viml_pexpr_parse_invalid_colon;
+ if (cur_pt == kEPTSingleAssignment && kv_size(ast_stack) == 1) {
+ kv_drop(pt_stack, 1);
}
- bool can_be_ternary = true;
- bool is_subscript = false;
- for (size_t i = 1; i < kv_size(ast_stack); i++) {
- ExprASTNode *const *const eastnode_p =
- (ExprASTNode *const *)kv_Z(ast_stack, i);
- const ExprASTNodeType eastnode_type = (*eastnode_p)->type;
- const ExprOpLvl eastnode_lvl = node_lvl(**eastnode_p);
- STATIC_ASSERT(kEOpLvlTernary > kEOpLvlComma,
- "Unexpected operator priorities");
- if (can_be_ternary && eastnode_type == kExprNodeTernaryValue
- && !(*eastnode_p)->data.ter.got_colon) {
- kv_drop(ast_stack, i);
- (*eastnode_p)->start = cur_token.start;
- (*eastnode_p)->len = cur_token.len;
- if (prev_token.type == kExprLexSpacing) {
- (*eastnode_p)->start = prev_token.start;
- (*eastnode_p)->len += prev_token.len;
- }
- is_ternary = true;
- (*eastnode_p)->data.ter.got_colon = true;
- ADD_VALUE_IF_MISSING(_(EXP_VAL_COLON));
- assert((*eastnode_p)->children != NULL);
- assert((*eastnode_p)->children->next == NULL);
- kvi_push(ast_stack, &(*eastnode_p)->children->next);
- break;
- } else if (eastnode_type == kExprNodeUnknownFigure) {
- SELECT_FIGURE_BRACE_TYPE(*eastnode_p, DictLiteral, Dict);
- break;
- } else if (eastnode_type == kExprNodeDictLiteral) {
- break;
- } else if (eastnode_type == kExprNodeSubscript) {
- is_subscript = true;
- // can_be_ternary = false;
- assert(!is_ternary);
- break;
- } else if (eastnode_type == kExprNodeColon) {
- goto viml_pexpr_parse_invalid_colon;
- } else if (eastnode_lvl >= kEOpLvlTernaryValue) {
- // Do nothing
- } else if (eastnode_lvl >= kEOpLvlComma) {
- can_be_ternary = false;
- } else {
- goto viml_pexpr_parse_invalid_colon;
- }
- if (i == kv_size(ast_stack) - 1) {
- goto viml_pexpr_parse_invalid_colon;
+ } else {
+ if (want_node == kENodeValue) {
+ // Value means list literal or list assignment.
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeListLiteral);
+ *top_node_p = cur_node;
+ kvi_push(ast_stack, &cur_node->children);
+ want_node = kENodeValue;
+ if (cur_pt == kEPTAssignment) {
+ // Additional assignment parse type allows to easily forbid nested
+ // lists.
+ kvi_push(pt_stack, kEPTSingleAssignment);
+ } else if (cur_pt == kEPTSingleAssignment) {
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E475: Nested lists not allowed when assigning: %.*s"));
}
- }
- if (is_subscript) {
- assert(kv_size(ast_stack) > 1);
- // Colon immediately following subscript start: it is empty subscript
- // part like a[:2].
- if (want_node == kENodeValue
- && (*kv_Z(ast_stack, 1))->type == kExprNodeSubscript) {
- NEW_NODE_WITH_CUR_POS(*top_node_p, kExprNodeMissing);
- (*top_node_p)->len = 0;
- want_node = kENodeOperator;
- } else {
- ADD_VALUE_IF_MISSING(_(EXP_VAL_COLON));
+ HL_CUR_TOKEN(List);
+ } else {
+ // Operator means subscript, also in assignment. But in assignment
+ // subscript may be pretty much any expression, so need to push
+ // kEPTExpr.
+ if (prev_token.type == kExprLexSpacing) {
+ OP_MISSING;
}
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeColon);
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeSubscript);
ADD_OP_NODE(cur_node);
- HL_CUR_TOKEN(SubscriptColon);
- } else {
- goto viml_pexpr_parse_valid_colon;
-viml_pexpr_parse_invalid_colon:
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E15: Colon outside of dictionary or ternary operator: %.*s"));
-viml_pexpr_parse_valid_colon:
- ADD_VALUE_IF_MISSING(_(EXP_VAL_COLON));
- if (is_ternary) {
- HL_CUR_TOKEN(TernaryColon);
- } else {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeColon);
- ADD_OP_NODE(cur_node);
- HL_CUR_TOKEN(Colon);
+ HL_CUR_TOKEN(SubscriptBracket);
+ if (pt_is_assignment(cur_pt)) {
+ assert(want_node == kENodeValue); // Subtract 1 for NULL at top.
+ asgn_level = kv_size(ast_stack) - 1;
+ kvi_push(pt_stack, kEPTExpr);
}
}
- want_node = kENodeValue;
- break;
}
-#undef EXP_VAL_COLON
- case kExprLexBracket: {
- if (cur_token.data.brc.closing) {
- ExprASTNode **new_top_node_p = NULL;
- // Always drop the topmost value:
- //
- // 1. When want_node != kENodeValue topmost item on stack is
- // a *finished* left operand, which may as well be "{@a}" which
- // needs not be finished again.
- // 2. Otherwise it is pointing to NULL what nobody wants.
- kv_drop(ast_stack, 1);
- if (!kv_size(ast_stack)) {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeListLiteral);
- cur_node->len = 0;
- if (want_node != kENodeValue) {
- cur_node->children = *top_node_p;
- }
- *top_node_p = cur_node;
- goto viml_pexpr_parse_bracket_closing_error;
- }
- if (want_node == kENodeValue) {
- // It is OK to want value if
- //
- // 1. It is empty list literal, in which case top node will be
- // ListLiteral.
- // 2. It is list literal with trailing comma, in which case top node
- // will be that comma.
- // 3. It is subscript with colon, but without one of the values:
- // e.g. "a[:]", "a[1:]", top node will be colon in this case.
- if ((*kv_last(ast_stack))->type != kExprNodeListLiteral
- && (*kv_last(ast_stack))->type != kExprNodeComma
- && (*kv_last(ast_stack))->type != kExprNodeColon) {
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E15: Expected value, got closing bracket: %.*s"));
- }
+ break;
+ case kExprLexFigureBrace:
+ if (cur_token.data.brc.closing) {
+ ExprASTNode **new_top_node_p = NULL;
+ // Always drop the topmost value:
+ //
+ // 1. When want_node != kENodeValue topmost item on stack is
+ // a *finished* left operand, which may as well be "{@a}" which
+ // needs not be finished again.
+ // 2. Otherwise it is pointing to NULL what nobody wants.
+ kv_drop(ast_stack, 1);
+ if (!kv_size(ast_stack)) {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeUnknownFigure);
+ cur_node->data.fig.type_guesses.allow_lambda = false;
+ cur_node->data.fig.type_guesses.allow_dict = false;
+ cur_node->data.fig.type_guesses.allow_ident = false;
+ cur_node->len = 0;
+ if (want_node != kENodeValue) {
+ cur_node->children = *top_node_p;
}
- do {
- new_top_node_p = kv_pop(ast_stack);
- } while (kv_size(ast_stack)
- && (new_top_node_p == NULL
- || ((*new_top_node_p)->type != kExprNodeListLiteral
- && (*new_top_node_p)->type != kExprNodeSubscript)));
- ExprASTNode *new_top_node = *new_top_node_p;
- switch (new_top_node->type) {
- case kExprNodeListLiteral: {
- if (pt_is_assignment(cur_pt) && new_top_node->children == NULL) {
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E475: Unable to assign to empty list: %.*s"));
- }
- HL_CUR_TOKEN(List);
- break;
- }
- case kExprNodeSubscript: {
- HL_CUR_TOKEN(SubscriptBracket);
- break;
- }
- default: {
-viml_pexpr_parse_bracket_closing_error:
- assert(!kv_size(ast_stack));
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Unexpected closing figure brace: %.*s"));
- HL_CUR_TOKEN(List);
- break;
- }
+ *top_node_p = cur_node;
+ new_top_node_p = top_node_p;
+ goto viml_pexpr_parse_figure_brace_closing_error;
+ }
+ if (want_node == kENodeValue) {
+ if ((*kv_last(ast_stack))->type != kExprNodeUnknownFigure
+ && (*kv_last(ast_stack))->type != kExprNodeComma) {
+ // kv_last being UnknownFigure may occur for empty dictionary
+ // literal, while Comma is expected in case of non-empty one.
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E15: Expected value, got closing figure brace: %.*s"));
}
- kvi_push(ast_stack, new_top_node_p);
- want_node = kENodeOperator;
- if (kv_size(ast_stack) <= asgn_level) {
- assert(kv_size(ast_stack) == asgn_level);
- asgn_level = 0;
- if (cur_pt == kEPTAssignment) {
- assert(ast.err.msg);
- } else if (cur_pt == kEPTExpr
- && kv_size(pt_stack) > 1
- && pt_is_assignment(kv_Z(pt_stack, 1))) {
- kv_drop(pt_stack, 1);
+ }
+ do {
+ new_top_node_p = kv_pop(ast_stack);
+ } while (kv_size(ast_stack)
+ && (new_top_node_p == NULL
+ || ((*new_top_node_p)->type != kExprNodeUnknownFigure
+ && (*new_top_node_p)->type != kExprNodeDictLiteral
+ && ((*new_top_node_p)->type
+ != kExprNodeCurlyBracesIdentifier)
+ && (*new_top_node_p)->type != kExprNodeLambda)));
+ ExprASTNode *new_top_node = *new_top_node_p;
+ switch (new_top_node->type) {
+ case kExprNodeUnknownFigure:
+ if (new_top_node->children == NULL) {
+ // No children of curly braces node indicates empty dictionary.
+ assert(want_node == kENodeValue);
+ assert(new_top_node->data.fig.type_guesses.allow_dict);
+ SELECT_FIGURE_BRACE_TYPE(new_top_node, DictLiteral, Dict);
+ HL_CUR_TOKEN(Dict);
+ } else if (new_top_node->data.fig.type_guesses.allow_ident) {
+ SELECT_FIGURE_BRACE_TYPE(new_top_node, CurlyBracesIdentifier,
+ Curly);
+ HL_CUR_TOKEN(Curly);
+ } else {
+ // If by this time type of the node has not already been
+ // guessed, but it definitely is not a curly braces name then
+ // it is invalid for sure.
+ ERROR_FROM_NODE_AND_MSG(new_top_node,
+ _("E15: Don't know what figure brace means: %.*s"));
+ if (pstate->colors) {
+ // Will reset to NvimInvalidFigureBrace.
+ kv_A(*pstate->colors,
+ new_top_node->data.fig.opening_hl_idx).group = (
+ HL(FigureBrace));
}
+ HL_CUR_TOKEN(FigureBrace);
}
- if (cur_pt == kEPTSingleAssignment && kv_size(ast_stack) == 1) {
+ break;
+ case kExprNodeDictLiteral:
+ HL_CUR_TOKEN(Dict);
+ break;
+ case kExprNodeCurlyBracesIdentifier:
+ HL_CUR_TOKEN(Curly);
+ break;
+ case kExprNodeLambda:
+ HL_CUR_TOKEN(Lambda);
+ break;
+ default:
+viml_pexpr_parse_figure_brace_closing_error:
+ assert(!kv_size(ast_stack));
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Unexpected closing figure brace: %.*s"));
+ HL_CUR_TOKEN(FigureBrace);
+ break;
+ }
+ kvi_push(ast_stack, new_top_node_p);
+ want_node = kENodeOperator;
+ if (kv_size(ast_stack) <= asgn_level) {
+ assert(kv_size(ast_stack) == asgn_level);
+ if (cur_pt == kEPTExpr
+ && kv_size(pt_stack) > 1
+ && pt_is_assignment(kv_Z(pt_stack, 1))) {
kv_drop(pt_stack, 1);
- }
- } else {
- if (want_node == kENodeValue) {
- // Value means list literal or list assignment.
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeListLiteral);
- *top_node_p = cur_node;
- kvi_push(ast_stack, &cur_node->children);
- want_node = kENodeValue;
- if (cur_pt == kEPTAssignment) {
- // Additional assignment parse type allows to easily forbid nested
- // lists.
- kvi_push(pt_stack, kEPTSingleAssignment);
- } else if (cur_pt == kEPTSingleAssignment) {
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E475: Nested lists not allowed when assigning: %.*s"));
- }
- HL_CUR_TOKEN(List);
- } else {
- // Operator means subscript, also in assignment. But in assignment
- // subscript may be pretty much any expression, so need to push
- // kEPTExpr.
- if (prev_token.type == kExprLexSpacing) {
- OP_MISSING;
- }
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeSubscript);
- ADD_OP_NODE(cur_node);
- HL_CUR_TOKEN(SubscriptBracket);
- if (pt_is_assignment(cur_pt)) {
- assert(want_node == kENodeValue); // Subtract 1 for NULL at top.
- asgn_level = kv_size(ast_stack) - 1;
- kvi_push(pt_stack, kEPTExpr);
- }
+ asgn_level = 0;
}
}
- break;
- }
- case kExprLexFigureBrace: {
- if (cur_token.data.brc.closing) {
- ExprASTNode **new_top_node_p = NULL;
- // Always drop the topmost value:
- //
- // 1. When want_node != kENodeValue topmost item on stack is
- // a *finished* left operand, which may as well be "{@a}" which
- // needs not be finished again.
- // 2. Otherwise it is pointing to NULL what nobody wants.
- kv_drop(ast_stack, 1);
- if (!kv_size(ast_stack)) {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeUnknownFigure);
+ } else {
+ if (want_node == kENodeValue) {
+ HL_CUR_TOKEN(FigureBrace);
+ // Value: may be any of lambda, dictionary literal and curly braces
+ // name.
+
+ // Though if we are in an assignment this may only be a curly braces
+ // name.
+ if (pt_is_assignment(cur_pt)) {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeCurlyBracesIdentifier);
cur_node->data.fig.type_guesses.allow_lambda = false;
cur_node->data.fig.type_guesses.allow_dict = false;
- cur_node->data.fig.type_guesses.allow_ident = false;
- cur_node->len = 0;
- if (want_node != kENodeValue) {
- cur_node->children = *top_node_p;
- }
- *top_node_p = cur_node;
- new_top_node_p = top_node_p;
- goto viml_pexpr_parse_figure_brace_closing_error;
- }
- if (want_node == kENodeValue) {
- if ((*kv_last(ast_stack))->type != kExprNodeUnknownFigure
- && (*kv_last(ast_stack))->type != kExprNodeComma) {
- // kv_last being UnknownFigure may occur for empty dictionary
- // literal, while Comma is expected in case of non-empty one.
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E15: Expected value, got closing figure brace: %.*s"));
- }
- }
- do {
- new_top_node_p = kv_pop(ast_stack);
- } while (kv_size(ast_stack)
- && (new_top_node_p == NULL
- || ((*new_top_node_p)->type != kExprNodeUnknownFigure
- && (*new_top_node_p)->type != kExprNodeDictLiteral
- && ((*new_top_node_p)->type
- != kExprNodeCurlyBracesIdentifier)
- && (*new_top_node_p)->type != kExprNodeLambda)));
- ExprASTNode *new_top_node = *new_top_node_p;
- switch (new_top_node->type) {
- case kExprNodeUnknownFigure: {
- if (new_top_node->children == NULL) {
- // No children of curly braces node indicates empty dictionary.
- assert(want_node == kENodeValue);
- assert(new_top_node->data.fig.type_guesses.allow_dict);
- SELECT_FIGURE_BRACE_TYPE(new_top_node, DictLiteral, Dict);
- HL_CUR_TOKEN(Dict);
- } else if (new_top_node->data.fig.type_guesses.allow_ident) {
- SELECT_FIGURE_BRACE_TYPE(new_top_node, CurlyBracesIdentifier,
- Curly);
- HL_CUR_TOKEN(Curly);
- } else {
- // If by this time type of the node has not already been
- // guessed, but it definitely is not a curly braces name then
- // it is invalid for sure.
- ERROR_FROM_NODE_AND_MSG(
- new_top_node,
- _("E15: Don't know what figure brace means: %.*s"));
- if (pstate->colors) {
- // Will reset to NvimInvalidFigureBrace.
- kv_A(*pstate->colors,
- new_top_node->data.fig.opening_hl_idx).group = (
- HL(FigureBrace));
- }
- HL_CUR_TOKEN(FigureBrace);
- }
- break;
- }
- case kExprNodeDictLiteral: {
- HL_CUR_TOKEN(Dict);
- break;
- }
- case kExprNodeCurlyBracesIdentifier: {
- HL_CUR_TOKEN(Curly);
- break;
- }
- case kExprNodeLambda: {
- HL_CUR_TOKEN(Lambda);
- break;
- }
- default: {
-viml_pexpr_parse_figure_brace_closing_error:
- assert(!kv_size(ast_stack));
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Unexpected closing figure brace: %.*s"));
- HL_CUR_TOKEN(FigureBrace);
- break;
- }
+ cur_node->data.fig.type_guesses.allow_ident = true;
+ kvi_push(pt_stack, kEPTExpr);
+ } else {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeUnknownFigure);
+ cur_node->data.fig.type_guesses.allow_lambda = true;
+ cur_node->data.fig.type_guesses.allow_dict = true;
+ cur_node->data.fig.type_guesses.allow_ident = true;
}
- kvi_push(ast_stack, new_top_node_p);
- want_node = kENodeOperator;
- if (kv_size(ast_stack) <= asgn_level) {
- assert(kv_size(ast_stack) == asgn_level);
- if (cur_pt == kEPTExpr
- && kv_size(pt_stack) > 1
- && pt_is_assignment(kv_Z(pt_stack, 1))) {
- kv_drop(pt_stack, 1);
- asgn_level = 0;
- }
+ if (pstate->colors) {
+ cur_node->data.fig.opening_hl_idx = kv_size(*pstate->colors) - 1;
}
+ *top_node_p = cur_node;
+ kvi_push(ast_stack, &cur_node->children);
+ kvi_push(pt_stack, kEPTLambdaArguments);
+ lambda_node = cur_node;
} else {
- if (want_node == kENodeValue) {
- HL_CUR_TOKEN(FigureBrace);
- // Value: may be any of lambda, dictionary literal and curly braces
- // name.
-
- // Though if we are in an assignment this may only be a curly braces
- // name.
+ ADD_IDENT(do {
+ NEW_NODE_WITH_CUR_POS(cur_node,
+ kExprNodeCurlyBracesIdentifier);
+ cur_node->data.fig.opening_hl_idx = kv_size(*pstate->colors);
+ cur_node->data.fig.type_guesses.allow_lambda = false;
+ cur_node->data.fig.type_guesses.allow_dict = false;
+ cur_node->data.fig.type_guesses.allow_ident = true;
+ kvi_push(ast_stack, &cur_node->children);
if (pt_is_assignment(cur_pt)) {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeCurlyBracesIdentifier);
- cur_node->data.fig.type_guesses.allow_lambda = false;
- cur_node->data.fig.type_guesses.allow_dict = false;
- cur_node->data.fig.type_guesses.allow_ident = true;
kvi_push(pt_stack, kEPTExpr);
- } else {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeUnknownFigure);
- cur_node->data.fig.type_guesses.allow_lambda = true;
- cur_node->data.fig.type_guesses.allow_dict = true;
- cur_node->data.fig.type_guesses.allow_ident = true;
- }
- if (pstate->colors) {
- cur_node->data.fig.opening_hl_idx = kv_size(*pstate->colors) - 1;
}
- *top_node_p = cur_node;
- kvi_push(ast_stack, &cur_node->children);
- kvi_push(pt_stack, kEPTLambdaArguments);
- lambda_node = cur_node;
- } else {
- ADD_IDENT(
- do {
- NEW_NODE_WITH_CUR_POS(cur_node,
- kExprNodeCurlyBracesIdentifier);
- cur_node->data.fig.opening_hl_idx = kv_size(*pstate->colors);
- cur_node->data.fig.type_guesses.allow_lambda = false;
- cur_node->data.fig.type_guesses.allow_dict = false;
- cur_node->data.fig.type_guesses.allow_ident = true;
- kvi_push(ast_stack, &cur_node->children);
- if (pt_is_assignment(cur_pt)) {
- kvi_push(pt_stack, kEPTExpr);
- }
- want_node = kENodeValue;
- } while (0),
- Curly);
- }
- if (pt_is_assignment(cur_pt)
- && !pt_is_assignment(kv_last(pt_stack))) {
- assert(want_node == kENodeValue); // Subtract 1 for NULL at top.
- asgn_level = kv_size(ast_stack) - 1;
- }
+ want_node = kENodeValue;
+ } while (0),
+ Curly);
+ }
+ if (pt_is_assignment(cur_pt)
+ && !pt_is_assignment(kv_last(pt_stack))) {
+ assert(want_node == kENodeValue); // Subtract 1 for NULL at top.
+ asgn_level = kv_size(ast_stack) - 1;
}
- break;
}
- case kExprLexArrow: {
- if (cur_pt == kEPTLambdaArguments) {
- kv_drop(pt_stack, 1);
- assert(kv_size(pt_stack));
- if (want_node == kENodeValue) {
- // Wanting value means trailing comma and NULL at the top of the
- // stack.
- kv_drop(ast_stack, 1);
- }
- assert(kv_size(ast_stack) >= 1);
- while ((*kv_last(ast_stack))->type != kExprNodeLambda
- && (*kv_last(ast_stack))->type != kExprNodeUnknownFigure) {
- kv_drop(ast_stack, 1);
- }
- assert((*kv_last(ast_stack)) == lambda_node);
- SELECT_FIGURE_BRACE_TYPE(lambda_node, Lambda, Lambda);
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeArrow);
- if (lambda_node->children == NULL) {
- assert(want_node == kENodeValue);
- lambda_node->children = cur_node;
- kvi_push(ast_stack, &lambda_node->children);
- } else {
- assert(lambda_node->children->next == NULL);
- lambda_node->children->next = cur_node;
- kvi_push(ast_stack, &lambda_node->children->next);
- }
- kvi_push(ast_stack, &cur_node->children);
- lambda_node = NULL;
+ break;
+ case kExprLexArrow:
+ if (cur_pt == kEPTLambdaArguments) {
+ kv_drop(pt_stack, 1);
+ assert(kv_size(pt_stack));
+ if (want_node == kENodeValue) {
+ // Wanting value means trailing comma and NULL at the top of the
+ // stack.
+ kv_drop(ast_stack, 1);
+ }
+ assert(kv_size(ast_stack) >= 1);
+ while ((*kv_last(ast_stack))->type != kExprNodeLambda
+ && (*kv_last(ast_stack))->type != kExprNodeUnknownFigure) {
+ kv_drop(ast_stack, 1);
+ }
+ assert((*kv_last(ast_stack)) == lambda_node);
+ SELECT_FIGURE_BRACE_TYPE(lambda_node, Lambda, Lambda);
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeArrow);
+ if (lambda_node->children == NULL) {
+ assert(want_node == kENodeValue);
+ lambda_node->children = cur_node;
+ kvi_push(ast_stack, &lambda_node->children);
} else {
- // Only first branch is valid.
- ADD_VALUE_IF_MISSING(_("E15: Unexpected arrow: %.*s"));
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Arrow outside of lambda: %.*s"));
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeArrow);
- ADD_OP_NODE(cur_node);
+ assert(lambda_node->children->next == NULL);
+ lambda_node->children->next = cur_node;
+ kvi_push(ast_stack, &lambda_node->children->next);
}
- want_node = kENodeValue;
- HL_CUR_TOKEN(Arrow);
- break;
+ kvi_push(ast_stack, &cur_node->children);
+ lambda_node = NULL;
+ } else {
+ // Only first branch is valid.
+ ADD_VALUE_IF_MISSING(_("E15: Unexpected arrow: %.*s"));
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Arrow outside of lambda: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeArrow);
+ ADD_OP_NODE(cur_node);
}
- case kExprLexPlainIdentifier: {
- const ExprVarScope scope = (cur_token.type == kExprLexInvalid
+ want_node = kENodeValue;
+ HL_CUR_TOKEN(Arrow);
+ break;
+ case kExprLexPlainIdentifier: {
+ const ExprVarScope scope = (cur_token.type == kExprLexInvalid
? kExprVarScopeMissing
: cur_token.data.var.scope);
- if (want_node == kENodeValue) {
- want_node = kENodeOperator;
- NEW_NODE_WITH_CUR_POS(cur_node,
- (node_is_key
+ if (want_node == kENodeValue) {
+ want_node = kENodeOperator;
+ NEW_NODE_WITH_CUR_POS(cur_node,
+ (node_is_key
? kExprNodePlainKey
: kExprNodePlainIdentifier));
- cur_node->data.var.scope = scope;
- const size_t scope_shift = (scope == kExprVarScopeMissing ? 0 : 2);
- cur_node->data.var.ident = (pline.data + cur_token.start.col
- + scope_shift);
- cur_node->data.var.ident_len = cur_token.len - scope_shift;
- *top_node_p = cur_node;
- if (scope_shift) {
- assert(!node_is_key);
- viml_parser_highlight(pstate, cur_token.start, 1,
- HL(IdentifierScope));
- viml_parser_highlight(pstate, shifted_pos(cur_token.start, 1), 1,
- HL(IdentifierScopeDelimiter));
- }
- viml_parser_highlight(pstate, shifted_pos(cur_token.start,
- scope_shift),
- cur_token.len - scope_shift,
- (node_is_key
+ cur_node->data.var.scope = scope;
+ const size_t scope_shift = (scope == kExprVarScopeMissing ? 0 : 2);
+ cur_node->data.var.ident = (pline.data + cur_token.start.col
+ + scope_shift);
+ cur_node->data.var.ident_len = cur_token.len - scope_shift;
+ *top_node_p = cur_node;
+ if (scope_shift) {
+ assert(!node_is_key);
+ viml_parser_highlight(pstate, cur_token.start, 1,
+ HL(IdentifierScope));
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, 1), 1,
+ HL(IdentifierScopeDelimiter));
+ }
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start,
+ scope_shift),
+ cur_token.len - scope_shift,
+ (node_is_key
? HL(IdentifierKey)
: HL(IdentifierName)));
+ } else {
+ if (scope == kExprVarScopeMissing) {
+ ADD_IDENT(do {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodePlainIdentifier);
+ cur_node->data.var.scope = scope;
+ cur_node->data.var.ident = pline.data + cur_token.start.col;
+ cur_node->data.var.ident_len = cur_token.len;
+ want_node = kENodeOperator;
+ } while (0),
+ IdentifierName);
} else {
- if (scope == kExprVarScopeMissing) {
- ADD_IDENT(
- do {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodePlainIdentifier);
- cur_node->data.var.scope = scope;
- cur_node->data.var.ident = pline.data + cur_token.start.col;
- cur_node->data.var.ident_len = cur_token.len;
- want_node = kENodeOperator;
- } while (0),
- IdentifierName);
- } else {
- OP_MISSING;
- }
- }
- break;
- }
- case kExprLexNumber: {
- if (want_node != kENodeValue) {
OP_MISSING;
}
- if (node_is_key) {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodePlainKey);
- cur_node->data.var.ident = pline.data + cur_token.start.col;
- cur_node->data.var.ident_len = cur_token.len;
- HL_CUR_TOKEN(IdentifierKey);
- } else if (cur_token.data.num.is_float) {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeFloat);
- cur_node->data.flt.value = cur_token.data.num.val.floating;
- HL_CUR_TOKEN(Float);
- } else {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeInteger);
- cur_node->data.num.value = cur_token.data.num.val.integer;
- const uint8_t prefix_length = base_to_prefix_length[
- cur_token.data.num.base];
- viml_parser_highlight(pstate, cur_token.start, prefix_length,
- HL(NumberPrefix));
- viml_parser_highlight(
- pstate, shifted_pos(cur_token.start, prefix_length),
- cur_token.len - prefix_length, HL(Number));
- }
- want_node = kENodeOperator;
- *top_node_p = cur_node;
- break;
}
- case kExprLexDot: {
- ADD_VALUE_IF_MISSING(_("E15: Unexpected dot: %.*s"));
- if (prev_token.type == kExprLexSpacing) {
- if (cur_pt == kEPTAssignment) {
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Cannot concatenate in assignments: %.*s"));
- }
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeConcat);
- HL_CUR_TOKEN(Concat);
- } else {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeConcatOrSubscript);
- HL_CUR_TOKEN(ConcatOrSubscript);
+ break;
+ }
+ case kExprLexNumber:
+ if (want_node != kENodeValue) {
+ OP_MISSING;
+ }
+ if (node_is_key) {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodePlainKey);
+ cur_node->data.var.ident = pline.data + cur_token.start.col;
+ cur_node->data.var.ident_len = cur_token.len;
+ HL_CUR_TOKEN(IdentifierKey);
+ } else if (cur_token.data.num.is_float) {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeFloat);
+ cur_node->data.flt.value = cur_token.data.num.val.floating;
+ HL_CUR_TOKEN(Float);
+ } else {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeInteger);
+ cur_node->data.num.value = cur_token.data.num.val.integer;
+ const uint8_t prefix_length = base_to_prefix_length[
+ cur_token.data.num.base];
+ viml_parser_highlight(pstate, cur_token.start, prefix_length,
+ HL(NumberPrefix));
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, prefix_length),
+ cur_token.len - prefix_length, HL(Number));
+ }
+ want_node = kENodeOperator;
+ *top_node_p = cur_node;
+ break;
+ case kExprLexDot:
+ ADD_VALUE_IF_MISSING(_("E15: Unexpected dot: %.*s"));
+ if (prev_token.type == kExprLexSpacing) {
+ if (cur_pt == kEPTAssignment) {
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Cannot concatenate in assignments: %.*s"));
}
- ADD_OP_NODE(cur_node);
- break;
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeConcat);
+ HL_CUR_TOKEN(Concat);
+ } else {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeConcatOrSubscript);
+ HL_CUR_TOKEN(ConcatOrSubscript);
}
- case kExprLexParenthesis: {
- if (cur_token.data.brc.closing) {
- if (want_node == kENodeValue) {
- if (kv_size(ast_stack) > 1) {
- const ExprASTNode *const prev_top_node = *kv_Z(ast_stack, 1);
- if (prev_top_node->type == kExprNodeCall) {
- // Function call without arguments, this is not an error.
- // But further code does not expect NULL nodes.
- kv_drop(ast_stack, 1);
- goto viml_pexpr_parse_no_paren_closing_error;
- }
+ ADD_OP_NODE(cur_node);
+ break;
+ case kExprLexParenthesis:
+ if (cur_token.data.brc.closing) {
+ if (want_node == kENodeValue) {
+ if (kv_size(ast_stack) > 1) {
+ const ExprASTNode *const prev_top_node = *kv_Z(ast_stack, 1);
+ if (prev_top_node->type == kExprNodeCall) {
+ // Function call without arguments, this is not an error.
+ // But further code does not expect NULL nodes.
+ kv_drop(ast_stack, 1);
+ goto viml_pexpr_parse_no_paren_closing_error;
}
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Expected value, got parenthesis: %.*s"));
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeMissing);
- cur_node->len = 0;
- *top_node_p = cur_node;
- } else {
- // Always drop the topmost value: when want_node != kENodeValue
- // topmost item on stack is a *finished* left operand, which may as
- // well be "(@a)" which needs not be finished again.
- kv_drop(ast_stack, 1);
}
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Expected value, got parenthesis: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeMissing);
+ cur_node->len = 0;
+ *top_node_p = cur_node;
+ } else {
+ // Always drop the topmost value: when want_node != kENodeValue
+ // topmost item on stack is a *finished* left operand, which may as
+ // well be "(@a)" which needs not be finished again.
+ kv_drop(ast_stack, 1);
+ }
viml_pexpr_parse_no_paren_closing_error: {}
- ExprASTNode **new_top_node_p = NULL;
- while (kv_size(ast_stack)
- && (new_top_node_p == NULL
- || ((*new_top_node_p)->type != kExprNodeNested
- && (*new_top_node_p)->type != kExprNodeCall))) {
- new_top_node_p = kv_pop(ast_stack);
- }
- if (new_top_node_p != NULL
- && ((*new_top_node_p)->type == kExprNodeNested
- || (*new_top_node_p)->type == kExprNodeCall)) {
- if ((*new_top_node_p)->type == kExprNodeNested) {
- HL_CUR_TOKEN(NestingParenthesis);
- } else {
- HL_CUR_TOKEN(CallingParenthesis);
- }
- } else {
- // “Always drop the topmost value” branch has got rid of the single
- // value stack had, so there is nothing known to enclose. Correct
- // this.
- if (new_top_node_p == NULL) {
- new_top_node_p = top_node_p;
- }
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Unexpected closing parenthesis: %.*s"));
+ ExprASTNode **new_top_node_p = NULL;
+ while (kv_size(ast_stack)
+ && (new_top_node_p == NULL
+ || ((*new_top_node_p)->type != kExprNodeNested
+ && (*new_top_node_p)->type != kExprNodeCall))) {
+ new_top_node_p = kv_pop(ast_stack);
+ }
+ if (new_top_node_p != NULL
+ && ((*new_top_node_p)->type == kExprNodeNested
+ || (*new_top_node_p)->type == kExprNodeCall)) {
+ if ((*new_top_node_p)->type == kExprNodeNested) {
HL_CUR_TOKEN(NestingParenthesis);
- cur_node = NEW_NODE(kExprNodeNested);
- cur_node->start = cur_token.start;
- cur_node->len = 0;
- // Unexpected closing parenthesis, assume that it was wanted to
- // enclose everything in ().
- cur_node->children = *new_top_node_p;
- *new_top_node_p = cur_node;
- assert(cur_node->next == NULL);
+ } else {
+ HL_CUR_TOKEN(CallingParenthesis);
}
- kvi_push(ast_stack, new_top_node_p);
- want_node = kENodeOperator;
} else {
- switch (want_node) {
- case kENodeValue: {
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeNested);
- *top_node_p = cur_node;
- kvi_push(ast_stack, &cur_node->children);
- HL_CUR_TOKEN(NestingParenthesis);
- break;
- }
- case kENodeOperator: {
- if (prev_token.type == kExprLexSpacing) {
- // For some reason "function (args)" is a function call, but
- // "(funcref) (args)" is not. AFAIR this somehow involves
- // compatibility and Bram was commenting that this is
- // intentionally inconsistent and he is not very happy with the
- // situation himself.
- if ((*top_node_p)->type != kExprNodePlainIdentifier
- && (*top_node_p)->type != kExprNodeComplexIdentifier
- && (*top_node_p)->type != kExprNodeCurlyBracesIdentifier) {
- OP_MISSING;
- }
- }
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeCall);
- ADD_OP_NODE(cur_node);
- HL_CUR_TOKEN(CallingParenthesis);
- break;
+ // “Always drop the topmost value” branch has got rid of the single
+ // value stack had, so there is nothing known to enclose. Correct
+ // this.
+ if (new_top_node_p == NULL) {
+ new_top_node_p = top_node_p;
+ }
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Unexpected closing parenthesis: %.*s"));
+ HL_CUR_TOKEN(NestingParenthesis);
+ cur_node = NEW_NODE(kExprNodeNested);
+ cur_node->start = cur_token.start;
+ cur_node->len = 0;
+ // Unexpected closing parenthesis, assume that it was wanted to
+ // enclose everything in ().
+ cur_node->children = *new_top_node_p;
+ *new_top_node_p = cur_node;
+ assert(cur_node->next == NULL);
+ }
+ kvi_push(ast_stack, new_top_node_p);
+ want_node = kENodeOperator;
+ } else {
+ switch (want_node) {
+ case kENodeValue:
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeNested);
+ *top_node_p = cur_node;
+ kvi_push(ast_stack, &cur_node->children);
+ HL_CUR_TOKEN(NestingParenthesis);
+ break;
+ case kENodeOperator:
+ if (prev_token.type == kExprLexSpacing) {
+ // For some reason "function (args)" is a function call, but
+ // "(funcref) (args)" is not. AFAIR this somehow involves
+ // compatibility and Bram was commenting that this is
+ // intentionally inconsistent and he is not very happy with the
+ // situation himself.
+ if ((*top_node_p)->type != kExprNodePlainIdentifier
+ && (*top_node_p)->type != kExprNodeComplexIdentifier
+ && (*top_node_p)->type != kExprNodeCurlyBracesIdentifier) {
+ OP_MISSING;
}
}
- want_node = kENodeValue;
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeCall);
+ ADD_OP_NODE(cur_node);
+ HL_CUR_TOKEN(CallingParenthesis);
+ break;
}
- break;
- }
- case kExprLexQuestion: {
- ADD_VALUE_IF_MISSING(_("E15: Expected value, got question mark: %.*s"));
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeTernary);
- ADD_OP_NODE(cur_node);
- HL_CUR_TOKEN(Ternary);
- ExprASTNode *ter_val_node;
- NEW_NODE_WITH_CUR_POS(ter_val_node, kExprNodeTernaryValue);
- ter_val_node->data.ter.got_colon = false;
- assert(cur_node->children != NULL);
- assert(cur_node->children->next == NULL);
- assert(kv_last(ast_stack) == &cur_node->children->next);
- *kv_last(ast_stack) = ter_val_node;
- kvi_push(ast_stack, &ter_val_node->children);
- break;
+ want_node = kENodeValue;
}
- case kExprLexDoubleQuotedString:
- case kExprLexSingleQuotedString: {
- const bool is_double = (tok_type == kExprLexDoubleQuotedString);
- if (!cur_token.data.str.closed) {
- // It is weird, but Vim has two identical errors messages with
- // different error numbers: "E114: Missing quote" and
- // "E115: Missing quote".
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, (is_double
+ break;
+ case kExprLexQuestion: {
+ ADD_VALUE_IF_MISSING(_("E15: Expected value, got question mark: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeTernary);
+ ADD_OP_NODE(cur_node);
+ HL_CUR_TOKEN(Ternary);
+ ExprASTNode *ter_val_node;
+ NEW_NODE_WITH_CUR_POS(ter_val_node, kExprNodeTernaryValue);
+ ter_val_node->data.ter.got_colon = false;
+ assert(cur_node->children != NULL);
+ assert(cur_node->children->next == NULL);
+ assert(kv_last(ast_stack) == &cur_node->children->next);
+ *kv_last(ast_stack) = ter_val_node;
+ kvi_push(ast_stack, &ter_val_node->children);
+ break;
+ }
+ case kExprLexDoubleQuotedString:
+ case kExprLexSingleQuotedString: {
+ const bool is_double = (tok_type == kExprLexDoubleQuotedString);
+ if (!cur_token.data.str.closed) {
+ // It is weird, but Vim has two identical errors messages with
+ // different error numbers: "E114: Missing quote" and
+ // "E115: Missing quote".
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, (is_double
? _("E114: Missing double quote: %.*s")
: _("E115: Missing single quote: %.*s")));
- }
- if (want_node == kENodeOperator) {
- OP_MISSING;
- }
- NEW_NODE_WITH_CUR_POS(
- cur_node, (is_double
+ }
+ if (want_node == kENodeOperator) {
+ OP_MISSING;
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, (is_double
? kExprNodeDoubleQuotedString
: kExprNodeSingleQuotedString));
- *top_node_p = cur_node;
- parse_quoted_string(pstate, cur_node, cur_token, ast_stack, is_invalid);
- want_node = kENodeOperator;
- break;
+ *top_node_p = cur_node;
+ parse_quoted_string(pstate, cur_node, cur_token, ast_stack, is_invalid);
+ want_node = kENodeOperator;
+ break;
+ }
+ case kExprLexAssignment:
+ if (cur_pt == kEPTAssignment) {
+ kv_drop(pt_stack, 1);
+ } else if (cur_pt == kEPTSingleAssignment) {
+ kv_drop(pt_stack, 2);
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E475: Expected closing bracket to end list assignment "
+ "lvalue: %.*s"));
+ } else {
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Misplaced assignment: %.*s"));
}
- case kExprLexAssignment: {
- if (cur_pt == kEPTAssignment) {
- kv_drop(pt_stack, 1);
- } else if (cur_pt == kEPTSingleAssignment) {
- kv_drop(pt_stack, 2);
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token,
- _("E475: Expected closing bracket to end list assignment "
- "lvalue: %.*s"));
- } else {
- ERROR_FROM_TOKEN_AND_MSG(
- cur_token, _("E15: Misplaced assignment: %.*s"));
- }
- assert(kv_size(pt_stack));
- assert(kv_last(pt_stack) == kEPTExpr);
- ADD_VALUE_IF_MISSING(_("E15: Unexpected assignment: %.*s"));
- NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeAssignment);
- cur_node->data.ass.type = cur_token.data.ass.type;
- switch (cur_token.data.ass.type) {
+ assert(kv_size(pt_stack));
+ assert(kv_last(pt_stack) == kEPTExpr);
+ ADD_VALUE_IF_MISSING(_("E15: Unexpected assignment: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeAssignment);
+ cur_node->data.ass.type = cur_token.data.ass.type;
+ switch (cur_token.data.ass.type) {
#define HL_ASGN(asgn, hl) \
- case kExprAsgn##asgn: { HL_CUR_TOKEN(hl); break; }
- HL_ASGN(Plain, PlainAssignment)
- HL_ASGN(Add, AssignmentWithAddition)
- HL_ASGN(Subtract, AssignmentWithSubtraction)
- HL_ASGN(Concat, AssignmentWithConcatenation)
+case kExprAsgn##asgn: { HL_CUR_TOKEN(hl); break; }
+ HL_ASGN(Plain, PlainAssignment)
+ HL_ASGN(Add, AssignmentWithAddition)
+ HL_ASGN(Subtract, AssignmentWithSubtraction)
+ HL_ASGN(Concat, AssignmentWithConcatenation)
#undef HL_ASGN
- }
- ADD_OP_NODE(cur_node);
- break;
}
+ ADD_OP_NODE(cur_node);
+ break;
}
viml_pexpr_parse_cycle_end:
prev_token = cur_token;
@@ -2972,115 +2970,96 @@ viml_pexpr_parse_end:
assert(cur_node != NULL);
// TODO(ZyX-I): Rehighlight as invalid?
switch (cur_node->type) {
- case kExprNodeOpMissing:
- case kExprNodeMissing: {
- // Error should’ve been already reported.
- break;
- }
- case kExprNodeCall: {
- east_set_error(
- pstate, &ast.err,
- _("E116: Missing closing parenthesis for function call: %.*s"),
- cur_node->start);
- break;
- }
- case kExprNodeNested: {
- east_set_error(
- pstate, &ast.err,
- _("E110: Missing closing parenthesis for nested expression"
- ": %.*s"),
- cur_node->start);
- break;
- }
- case kExprNodeListLiteral: {
- // For whatever reason "[1" yields "E696: Missing comma in list" error
- // in Vim while "[1," yields E697.
- east_set_error(
- pstate, &ast.err,
- _("E697: Missing end of List ']': %.*s"),
- cur_node->start);
- break;
- }
- case kExprNodeDictLiteral: {
- // Same problem like with list literal with E722 (missing comma) vs
- // E723, but additionally just "{" yields only E15.
- east_set_error(
- pstate, &ast.err,
- _("E723: Missing end of Dictionary '}': %.*s"),
- cur_node->start);
- break;
- }
- case kExprNodeUnknownFigure: {
- east_set_error(
- pstate, &ast.err,
- _("E15: Missing closing figure brace: %.*s"),
- cur_node->start);
- break;
- }
- case kExprNodeLambda: {
- east_set_error(
- pstate, &ast.err,
- _("E15: Missing closing figure brace for lambda: %.*s"),
- cur_node->start);
- break;
- }
- case kExprNodeCurlyBracesIdentifier: {
- // Until trailing "}" it is impossible to distinguish curly braces
- // identifier and dictionary, so it must not appear in the stack like
- // this.
- abort();
- }
- case kExprNodeInteger:
- case kExprNodeFloat:
- case kExprNodeSingleQuotedString:
- case kExprNodeDoubleQuotedString:
- case kExprNodeOption:
- case kExprNodeEnvironment:
- case kExprNodeRegister:
- case kExprNodePlainIdentifier:
- case kExprNodePlainKey: {
- // These are plain values and not containers, for them it should only
- // be possible to show up in the topmost stack element, but it was
- // unconditionally popped at the start.
- abort();
- }
- case kExprNodeComma:
- case kExprNodeColon:
- case kExprNodeArrow: {
- // It is actually only valid inside something else, but everything
- // where one of the above is valid requires to be closed and thus is
- // to be caught later.
- break;
- }
- case kExprNodeSubscript:
- case kExprNodeConcatOrSubscript:
- case kExprNodeComplexIdentifier:
- case kExprNodeAssignment:
- case kExprNodeMod:
- case kExprNodeDivision:
- case kExprNodeMultiplication:
- case kExprNodeNot:
- case kExprNodeAnd:
- case kExprNodeOr:
- case kExprNodeConcat:
- case kExprNodeComparison:
- case kExprNodeUnaryMinus:
- case kExprNodeUnaryPlus:
- case kExprNodeBinaryMinus:
- case kExprNodeTernary:
- case kExprNodeBinaryPlus: {
- // It is OK to see these in the stack.
- break;
- }
- case kExprNodeTernaryValue: {
- if (!cur_node->data.ter.got_colon) {
- // Actually Vim throws E109 in more cases.
- east_set_error(
- pstate, &ast.err, _("E109: Missing ':' after '?': %.*s"),
- cur_node->start);
- }
- break;
+ case kExprNodeOpMissing:
+ case kExprNodeMissing:
+ // Error should’ve been already reported.
+ break;
+ case kExprNodeCall:
+ east_set_error(pstate, &ast.err,
+ _("E116: Missing closing parenthesis for function call: %.*s"),
+ cur_node->start);
+ break;
+ case kExprNodeNested:
+ east_set_error(pstate, &ast.err,
+ _("E110: Missing closing parenthesis for nested expression"
+ ": %.*s"),
+ cur_node->start);
+ break;
+ case kExprNodeListLiteral:
+ // For whatever reason "[1" yields "E696: Missing comma in list" error
+ // in Vim while "[1," yields E697.
+ east_set_error(pstate, &ast.err,
+ _("E697: Missing end of List ']': %.*s"),
+ cur_node->start);
+ break;
+ case kExprNodeDictLiteral:
+ // Same problem like with list literal with E722 (missing comma) vs
+ // E723, but additionally just "{" yields only E15.
+ east_set_error(pstate, &ast.err,
+ _("E723: Missing end of Dictionary '}': %.*s"),
+ cur_node->start);
+ break;
+ case kExprNodeUnknownFigure:
+ east_set_error(pstate, &ast.err,
+ _("E15: Missing closing figure brace: %.*s"),
+ cur_node->start);
+ break;
+ case kExprNodeLambda:
+ east_set_error(pstate, &ast.err,
+ _("E15: Missing closing figure brace for lambda: %.*s"),
+ cur_node->start);
+ break;
+ case kExprNodeCurlyBracesIdentifier:
+ // Until trailing "}" it is impossible to distinguish curly braces
+ // identifier and dictionary, so it must not appear in the stack like
+ // this.
+ abort();
+ case kExprNodeInteger:
+ case kExprNodeFloat:
+ case kExprNodeSingleQuotedString:
+ case kExprNodeDoubleQuotedString:
+ case kExprNodeOption:
+ case kExprNodeEnvironment:
+ case kExprNodeRegister:
+ case kExprNodePlainIdentifier:
+ case kExprNodePlainKey:
+ // These are plain values and not containers, for them it should only
+ // be possible to show up in the topmost stack element, but it was
+ // unconditionally popped at the start.
+ abort();
+ case kExprNodeComma:
+ case kExprNodeColon:
+ case kExprNodeArrow:
+ // It is actually only valid inside something else, but everything
+ // where one of the above is valid requires to be closed and thus is
+ // to be caught later.
+ break;
+ case kExprNodeSubscript:
+ case kExprNodeConcatOrSubscript:
+ case kExprNodeComplexIdentifier:
+ case kExprNodeAssignment:
+ case kExprNodeMod:
+ case kExprNodeDivision:
+ case kExprNodeMultiplication:
+ case kExprNodeNot:
+ case kExprNodeAnd:
+ case kExprNodeOr:
+ case kExprNodeConcat:
+ case kExprNodeComparison:
+ case kExprNodeUnaryMinus:
+ case kExprNodeUnaryPlus:
+ case kExprNodeBinaryMinus:
+ case kExprNodeTernary:
+ case kExprNodeBinaryPlus:
+ // It is OK to see these in the stack.
+ break;
+ case kExprNodeTernaryValue:
+ if (!cur_node->data.ter.got_colon) {
+ // Actually Vim throws E109 in more cases.
+ east_set_error(pstate, &ast.err, _("E109: Missing ':' after '?': %.*s"),
+ cur_node->start);
}
+ break;
}
}
}