mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 19:38:20 +00:00
refactor: format #15702
This commit is contained in:
@@ -3,40 +3,39 @@
|
|||||||
|
|
||||||
// Some of this code was adapted from 'if_py_both.h' from the original
|
// Some of this code was adapted from 'if_py_both.h' from the original
|
||||||
// vim source
|
// vim source
|
||||||
|
#include <lauxlib.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include <lauxlib.h>
|
|
||||||
|
|
||||||
#include "nvim/api/buffer.h"
|
#include "nvim/api/buffer.h"
|
||||||
#include "nvim/api/private/helpers.h"
|
|
||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/api/private/defs.h"
|
||||||
#include "nvim/lua/executor.h"
|
#include "nvim/api/private/helpers.h"
|
||||||
#include "nvim/vim.h"
|
|
||||||
#include "nvim/buffer.h"
|
#include "nvim/buffer.h"
|
||||||
|
#include "nvim/buffer_updates.h"
|
||||||
#include "nvim/change.h"
|
#include "nvim/change.h"
|
||||||
#include "nvim/charset.h"
|
#include "nvim/charset.h"
|
||||||
#include "nvim/cursor.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/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/memline.h"
|
||||||
#include "nvim/memory.h"
|
#include "nvim/memory.h"
|
||||||
#include "nvim/misc1.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/move.h"
|
||||||
|
#include "nvim/ops.h"
|
||||||
#include "nvim/syntax.h"
|
#include "nvim/syntax.h"
|
||||||
#include "nvim/window.h"
|
|
||||||
#include "nvim/undo.h"
|
#include "nvim/undo.h"
|
||||||
#include "nvim/ex_docmd.h"
|
#include "nvim/vim.h"
|
||||||
#include "nvim/buffer_updates.h"
|
#include "nvim/window.h"
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "api/buffer.c.generated.h"
|
# 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
|
/// @param[out] err Error details, if any
|
||||||
/// @return False if attach failed (invalid parameter, or buffer isn't loaded);
|
/// @return False if attach failed (invalid parameter, or buffer isn't loaded);
|
||||||
/// otherwise True. TODO: LUA_API_NO_EVAL
|
/// otherwise True. TODO: LUA_API_NO_EVAL
|
||||||
Boolean nvim_buf_attach(uint64_t channel_id,
|
Boolean nvim_buf_attach(uint64_t channel_id, Buffer buffer, Boolean send_buffer,
|
||||||
Buffer buffer,
|
DictionaryOf(LuaRef) opts, Error *err)
|
||||||
Boolean send_buffer,
|
|
||||||
DictionaryOf(LuaRef) opts,
|
|
||||||
Error *err)
|
|
||||||
FUNC_API_SINCE(4)
|
FUNC_API_SINCE(4)
|
||||||
{
|
{
|
||||||
buf_T *buf = find_buffer_by_handle(buffer, err);
|
buf_T *buf = find_buffer_by_handle(buffer, err);
|
||||||
@@ -237,9 +233,7 @@ error:
|
|||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
/// @return False if detach failed (because the buffer isn't loaded);
|
/// @return False if detach failed (because the buffer isn't loaded);
|
||||||
/// otherwise True.
|
/// otherwise True.
|
||||||
Boolean nvim_buf_detach(uint64_t channel_id,
|
Boolean nvim_buf_detach(uint64_t channel_id, Buffer buffer, Error *err)
|
||||||
Buffer buffer,
|
|
||||||
Error *err)
|
|
||||||
FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY
|
FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY
|
||||||
{
|
{
|
||||||
buf_T *buf = find_buffer_by_handle(buffer, err);
|
buf_T *buf = find_buffer_by_handle(buffer, err);
|
||||||
@@ -252,8 +246,7 @@ Boolean nvim_buf_detach(uint64_t channel_id,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nvim__buf_redraw_range(Buffer buffer, Integer first, Integer last,
|
void nvim__buf_redraw_range(Buffer buffer, Integer first, Integer last, Error *err)
|
||||||
Error *err)
|
|
||||||
FUNC_API_LUA_ONLY
|
FUNC_API_LUA_ONLY
|
||||||
{
|
{
|
||||||
buf_T *buf = find_buffer_by_handle(buffer, err);
|
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 strict_indexing Whether out-of-bounds should be an error.
|
||||||
/// @param replacement Array of lines to use as replacement
|
/// @param replacement Array of lines to use as replacement
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
void nvim_buf_set_lines(uint64_t channel_id,
|
void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integer end,
|
||||||
Buffer buffer,
|
Boolean strict_indexing, ArrayOf(String) replacement, Error *err)
|
||||||
Integer start,
|
|
||||||
Integer end,
|
|
||||||
Boolean strict_indexing,
|
|
||||||
ArrayOf(String) replacement,
|
|
||||||
Error *err)
|
|
||||||
FUNC_API_SINCE(1)
|
FUNC_API_SINCE(1)
|
||||||
FUNC_API_CHECK_TEXTLOCK
|
FUNC_API_CHECK_TEXTLOCK
|
||||||
{
|
{
|
||||||
@@ -554,10 +542,8 @@ end:
|
|||||||
/// @param end_column Last column
|
/// @param end_column Last column
|
||||||
/// @param replacement Array of lines to use as replacement
|
/// @param replacement Array of lines to use as replacement
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
void nvim_buf_set_text(uint64_t channel_id, Buffer buffer,
|
void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, Integer start_col,
|
||||||
Integer start_row, Integer start_col,
|
Integer end_row, Integer end_col, ArrayOf(String) replacement, Error *err)
|
||||||
Integer end_row, Integer end_col,
|
|
||||||
ArrayOf(String) replacement, Error *err)
|
|
||||||
FUNC_API_SINCE(7)
|
FUNC_API_SINCE(7)
|
||||||
{
|
{
|
||||||
FIXED_TEMP_ARRAY(scratch, 1);
|
FIXED_TEMP_ARRAY(scratch, 1);
|
||||||
@@ -824,7 +810,7 @@ Object nvim_buf_get_var(Buffer buffer, String name, Error *err)
|
|||||||
buf_T *buf = find_buffer_by_handle(buffer, err);
|
buf_T *buf = find_buffer_by_handle(buffer, err);
|
||||||
|
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
return (Object) OBJECT_INIT;
|
return (Object)OBJECT_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dict_get_value(buf->b_vars, name, err);
|
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()|
|
/// @see |nvim_set_keymap()|
|
||||||
///
|
///
|
||||||
/// @param buffer Buffer handle, or 0 for current buffer
|
/// @param buffer Buffer handle, or 0 for current buffer
|
||||||
void nvim_buf_set_keymap(Buffer buffer, String mode, String lhs, String rhs,
|
void nvim_buf_set_keymap(Buffer buffer, String mode, String lhs, String rhs, Dictionary opts,
|
||||||
Dictionary opts, Error *err)
|
Error *err)
|
||||||
FUNC_API_SINCE(6)
|
FUNC_API_SINCE(6)
|
||||||
{
|
{
|
||||||
modify_keymap(buffer, false, mode, lhs, rhs, opts, err);
|
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);
|
buf_T *buf = find_buffer_by_handle(buffer, err);
|
||||||
|
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
return (Object) OBJECT_INIT;
|
return (Object)OBJECT_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return get_option_from(buf, SREQ_BUF, name, err);
|
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 name Option name
|
||||||
/// @param value Option value
|
/// @param value Option value
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
void nvim_buf_set_option(uint64_t channel_id, Buffer buffer,
|
void nvim_buf_set_option(uint64_t channel_id, Buffer buffer, String name, Object value, Error *err)
|
||||||
String name, Object value, Error *err)
|
|
||||||
FUNC_API_SINCE(1)
|
FUNC_API_SINCE(1)
|
||||||
{
|
{
|
||||||
buf_T *buf = find_buffer_by_handle(buffer, err);
|
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
|
// Using aucmd_*: autocommands will be executed by rename_buffer
|
||||||
aco_save_T aco;
|
aco_save_T aco;
|
||||||
aucmd_prepbuf(&aco, buf);
|
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);
|
aucmd_restbuf(&aco);
|
||||||
|
|
||||||
if (try_end(err)) {
|
if (try_end(err)) {
|
||||||
@@ -1105,8 +1090,7 @@ void nvim_buf_delete(Buffer buffer, Dictionary opts, Error *err)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = do_buffer(
|
int result = do_buffer(unload ? DOBUF_UNLOAD : DOBUF_WIPE,
|
||||||
unload ? DOBUF_UNLOAD : DOBUF_WIPE,
|
|
||||||
DOBUF_FIRST,
|
DOBUF_FIRST,
|
||||||
FORWARD,
|
FORWARD,
|
||||||
buf->handle,
|
buf->handle,
|
||||||
@@ -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)));
|
ADD(chunk, STRING_OBJ(cstr_to_string(vtc->text)));
|
||||||
if (vtc->hl_id > 0) {
|
if (vtc->hl_id > 0) {
|
||||||
ADD(chunk,
|
ADD(chunk,
|
||||||
STRING_OBJ(cstr_to_string(
|
STRING_OBJ(cstr_to_string((const char *)syn_id2name(vtc->hl_id))));
|
||||||
(const char *)syn_id2name(vtc->hl_id))));
|
|
||||||
}
|
}
|
||||||
ADD(chunks, ARRAY_OBJ(chunk));
|
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
|
/// - details Whether to include the details dict
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
/// @return List of [extmark_id, row, col] tuples in "traversal order".
|
/// @return List of [extmark_id, row, col] tuples in "traversal order".
|
||||||
Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id,
|
Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object end, Dictionary opts,
|
||||||
Object start, Object end,
|
Error *err)
|
||||||
Dictionary opts, Error *err)
|
|
||||||
FUNC_API_SINCE(7)
|
FUNC_API_SINCE(7)
|
||||||
{
|
{
|
||||||
Array rv = ARRAY_DICT_INIT;
|
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.
|
/// example treesitter highlighting uses a value of 100.
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
/// @return Id of the created/updated extmark
|
/// @return Id of the created/updated extmark
|
||||||
Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
|
Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer col,
|
||||||
Integer line, Integer col,
|
|
||||||
Dictionary opts, Error *err)
|
Dictionary opts, Error *err)
|
||||||
FUNC_API_SINCE(7)
|
FUNC_API_SINCE(7)
|
||||||
{
|
{
|
||||||
@@ -1548,8 +1529,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
|
|||||||
switch (v->type) {
|
switch (v->type) {
|
||||||
case kObjectTypeString:
|
case kObjectTypeString:
|
||||||
hl_group = v->data.string;
|
hl_group = v->data.string;
|
||||||
decor.hl_id = syn_check_group(
|
decor.hl_id = syn_check_group((char_u *)(hl_group.data),
|
||||||
(char_u *)(hl_group.data),
|
|
||||||
(int)hl_group.size);
|
(int)hl_group.size);
|
||||||
break;
|
break;
|
||||||
case kObjectTypeInteger:
|
case kObjectTypeInteger:
|
||||||
@@ -1692,8 +1672,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
|
|||||||
|
|
||||||
if (col2 >= 0) {
|
if (col2 >= 0) {
|
||||||
if (line2 >= 0 && line2 < buf->b_ml.ml_line_count) {
|
if (line2 >= 0 && line2 < buf->b_ml.ml_line_count) {
|
||||||
len = ephemeral ? MAXCOL : STRLEN(
|
len = ephemeral ? MAXCOL : STRLEN(ml_get_buf(buf, (linenr_T)line2 + 1, false));
|
||||||
ml_get_buf(buf, (linenr_T)line2 + 1, false));
|
|
||||||
} else if (line2 == buf->b_ml.ml_line_count) {
|
} else if (line2 == buf->b_ml.ml_line_count) {
|
||||||
// We are trying to add an extmark past final newline
|
// We are trying to add an extmark past final newline
|
||||||
len = 0;
|
len = 0;
|
||||||
@@ -1761,10 +1740,7 @@ error:
|
|||||||
/// @param id Extmark id
|
/// @param id Extmark id
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
/// @return true if the extmark was found, else false
|
/// @return true if the extmark was found, else false
|
||||||
Boolean nvim_buf_del_extmark(Buffer buffer,
|
Boolean nvim_buf_del_extmark(Buffer buffer, Integer ns_id, Integer id, Error *err)
|
||||||
Integer ns_id,
|
|
||||||
Integer id,
|
|
||||||
Error *err)
|
|
||||||
FUNC_API_SINCE(7)
|
FUNC_API_SINCE(7)
|
||||||
{
|
{
|
||||||
buf_T *buf = find_buffer_by_handle(buffer, err);
|
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
|
/// or -1 to highlight to end of line
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
/// @return The ns_id that was used
|
/// @return The ns_id that was used
|
||||||
Integer nvim_buf_add_highlight(Buffer buffer,
|
Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, Integer line,
|
||||||
Integer ns_id,
|
Integer col_start, Integer col_end, Error *err)
|
||||||
String hl_group,
|
|
||||||
Integer line,
|
|
||||||
Integer col_start,
|
|
||||||
Integer col_end,
|
|
||||||
Error *err)
|
|
||||||
FUNC_API_SINCE(1)
|
FUNC_API_SINCE(1)
|
||||||
{
|
{
|
||||||
buf_T *buf = find_buffer_by_handle(buffer, err);
|
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
|
/// @param line_end End of range of lines to clear (exclusive) or -1 to clear
|
||||||
/// to end of buffer.
|
/// to end of buffer.
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
void nvim_buf_clear_namespace(Buffer buffer,
|
void nvim_buf_clear_namespace(Buffer buffer, Integer ns_id, Integer line_start, Integer line_end,
|
||||||
Integer ns_id,
|
|
||||||
Integer line_start,
|
|
||||||
Integer line_end,
|
|
||||||
Error *err)
|
Error *err)
|
||||||
FUNC_API_SINCE(5)
|
FUNC_API_SINCE(5)
|
||||||
{
|
{
|
||||||
|
@@ -1,18 +1,18 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// 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
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include "nvim/api/deprecated.h"
|
|
||||||
#include "nvim/api/buffer.h"
|
#include "nvim/api/buffer.h"
|
||||||
#include "nvim/api/vim.h"
|
#include "nvim/api/deprecated.h"
|
||||||
#include "nvim/api/private/helpers.h"
|
|
||||||
#include "nvim/api/private/defs.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/extmark.h"
|
||||||
|
#include "nvim/lua/executor.h"
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "api/deprecated.c.generated.h"
|
# 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
|
/// @param line_end End of range of lines to clear (exclusive) or -1 to clear
|
||||||
/// to end of file.
|
/// to end of file.
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
void nvim_buf_clear_highlight(Buffer buffer,
|
void nvim_buf_clear_highlight(Buffer buffer, Integer ns_id, Integer line_start, Integer line_end,
|
||||||
Integer ns_id,
|
|
||||||
Integer line_start,
|
|
||||||
Integer line_end,
|
|
||||||
Error *err)
|
Error *err)
|
||||||
FUNC_API_SINCE(1)
|
FUNC_API_SINCE(1)
|
||||||
FUNC_API_DEPRECATED_SINCE(7)
|
FUNC_API_DEPRECATED_SINCE(7)
|
||||||
@@ -111,12 +108,8 @@ void nvim_buf_clear_highlight(Buffer buffer,
|
|||||||
/// @param opts Optional parameters. Currently not used.
|
/// @param opts Optional parameters. Currently not used.
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
/// @return The ns_id that was used
|
/// @return The ns_id that was used
|
||||||
Integer nvim_buf_set_virtual_text(Buffer buffer,
|
Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, Array chunks,
|
||||||
Integer src_id,
|
Dictionary opts, Error *err)
|
||||||
Integer line,
|
|
||||||
Array chunks,
|
|
||||||
Dictionary opts,
|
|
||||||
Error *err)
|
|
||||||
FUNC_API_SINCE(5)
|
FUNC_API_SINCE(5)
|
||||||
FUNC_API_DEPRECATED_SINCE(8)
|
FUNC_API_DEPRECATED_SINCE(8)
|
||||||
{
|
{
|
||||||
@@ -171,10 +164,7 @@ Integer nvim_buf_set_virtual_text(Buffer buffer,
|
|||||||
/// the end of the buffer.
|
/// the end of the buffer.
|
||||||
/// @param lines Array of lines
|
/// @param lines Array of lines
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
void buffer_insert(Buffer buffer,
|
void buffer_insert(Buffer buffer, Integer lnum, ArrayOf(String) lines, Error *err)
|
||||||
Integer lnum,
|
|
||||||
ArrayOf(String) lines,
|
|
||||||
Error *err)
|
|
||||||
{
|
{
|
||||||
// "lnum" will be the index of the line after inserting,
|
// "lnum" will be the index of the line after inserting,
|
||||||
// no matter if it is negative or not
|
// 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;
|
start = convert_index(start) + !include_start;
|
||||||
end = convert_index(end) + include_end;
|
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
|
/// 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
|
/// @param replacement Array of lines to use as replacement (0-length
|
||||||
// array will delete the line range)
|
// array will delete the line range)
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
void buffer_set_line_slice(Buffer buffer,
|
void buffer_set_line_slice(Buffer buffer, Integer start, Integer end, Boolean include_start,
|
||||||
Integer start,
|
Boolean include_end, ArrayOf(String) replacement, Error *err)
|
||||||
Integer end,
|
|
||||||
Boolean include_start,
|
|
||||||
Boolean include_end,
|
|
||||||
ArrayOf(String) replacement,
|
|
||||||
Error *err)
|
|
||||||
{
|
{
|
||||||
start = convert_index(start) + !include_start;
|
start = convert_index(start) + !include_start;
|
||||||
end = convert_index(end) + include_end;
|
end = convert_index(end) + include_end;
|
||||||
|
@@ -1,38 +1,35 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// 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
|
// 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 <assert.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <msgpack.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/private/dispatch.h"
|
|
||||||
#include "nvim/api/private/helpers.h"
|
|
||||||
#include "nvim/api/private/defs.h"
|
|
||||||
|
|
||||||
#include "nvim/api/buffer.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/tabpage.h"
|
#include "nvim/api/tabpage.h"
|
||||||
#include "nvim/api/ui.h"
|
#include "nvim/api/ui.h"
|
||||||
#include "nvim/api/vim.h"
|
#include "nvim/api/vim.h"
|
||||||
#include "nvim/api/window.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 Map(String, MsgpackRpcRequestHandler) methods = MAP_INIT;
|
||||||
|
|
||||||
static void msgpack_rpc_add_method_handler(String method,
|
static void msgpack_rpc_add_method_handler(String method, MsgpackRpcRequestHandler handler)
|
||||||
MsgpackRpcRequestHandler handler)
|
|
||||||
{
|
{
|
||||||
map_put(String, MsgpackRpcRequestHandler)(&methods, method, handler);
|
map_put(String, MsgpackRpcRequestHandler)(&methods, method, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param name API method name
|
/// @param name API method name
|
||||||
/// @param name_len name size (includes terminating NUL)
|
/// @param name_len name size (includes terminating NUL)
|
||||||
MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name,
|
MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name, size_t name_len,
|
||||||
size_t name_len,
|
|
||||||
Error *error)
|
Error *error)
|
||||||
{
|
{
|
||||||
String m = { .data = (char *)name, .size = name_len };
|
String m = { .data = (char *)name, .size = name_len };
|
||||||
|
@@ -7,33 +7,33 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "nvim/api/private/helpers.h"
|
|
||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/api/private/defs.h"
|
||||||
|
#include "nvim/api/private/helpers.h"
|
||||||
#include "nvim/api/vim.h"
|
#include "nvim/api/vim.h"
|
||||||
#include "nvim/msgpack_rpc/helpers.h"
|
|
||||||
#include "nvim/lua/executor.h"
|
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
#include "nvim/assert.h"
|
#include "nvim/assert.h"
|
||||||
#include "nvim/charset.h"
|
|
||||||
#include "nvim/syntax.h"
|
|
||||||
#include "nvim/vim.h"
|
|
||||||
#include "nvim/buffer.h"
|
#include "nvim/buffer.h"
|
||||||
#include "nvim/window.h"
|
#include "nvim/charset.h"
|
||||||
#include "nvim/memline.h"
|
#include "nvim/decoration.h"
|
||||||
#include "nvim/memory.h"
|
|
||||||
#include "nvim/eval.h"
|
#include "nvim/eval.h"
|
||||||
#include "nvim/eval/typval.h"
|
#include "nvim/eval/typval.h"
|
||||||
#include "nvim/map_defs.h"
|
|
||||||
#include "nvim/map.h"
|
|
||||||
#include "nvim/extmark.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.h"
|
||||||
#include "nvim/option_defs.h"
|
#include "nvim/option_defs.h"
|
||||||
#include "nvim/version.h"
|
#include "nvim/syntax.h"
|
||||||
#include "nvim/lib/kvec.h"
|
|
||||||
#include "nvim/getchar.h"
|
|
||||||
#include "nvim/fileio.h"
|
|
||||||
#include "nvim/ui.h"
|
#include "nvim/ui.h"
|
||||||
|
#include "nvim/version.h"
|
||||||
|
#include "nvim/vim.h"
|
||||||
|
#include "nvim/window.h"
|
||||||
|
|
||||||
/// Helper structure for vim_to_object
|
/// Helper structure for vim_to_object
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -41,8 +41,8 @@ typedef struct {
|
|||||||
} EncodedData;
|
} EncodedData;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "api/private/helpers.c.generated.h"
|
|
||||||
# include "api/private/funcs_metadata.generated.h"
|
# include "api/private/funcs_metadata.generated.h"
|
||||||
|
# include "api/private/helpers.c.generated.h"
|
||||||
# include "api/private/ui_events_metadata.generated.h"
|
# include "api/private/ui_events_metadata.generated.h"
|
||||||
#endif
|
#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 retval If true the old value will be converted and returned.
|
||||||
/// @param[out] err Details of an error that may have occurred
|
/// @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
|
/// @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,
|
Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retval, Error *err)
|
||||||
bool retval, Error *err)
|
|
||||||
{
|
{
|
||||||
Object rv = OBJECT_INIT;
|
Object rv = OBJECT_INIT;
|
||||||
dictitem_T *di = dict_check_writable(dict, key, del, err);
|
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 type One of `SREQ_GLOBAL`, `SREQ_WIN` or `SREQ_BUF`
|
||||||
/// @param name The option name
|
/// @param name The option name
|
||||||
/// @param[out] err Details of an error that may have occurred
|
/// @param[out] err Details of an error that may have occurred
|
||||||
void set_option_to(uint64_t channel_id, void *to, int type,
|
void set_option_to(uint64_t channel_id, void *to, int type, String name, Object value, Error *err)
|
||||||
String name, Object value, Error *err)
|
|
||||||
{
|
{
|
||||||
if (name.size == 0) {
|
if (name.size == 0) {
|
||||||
api_set_error(err, kErrorTypeValidation, "Empty option name");
|
api_set_error(err, kErrorTypeValidation, "Empty option name");
|
||||||
@@ -471,8 +469,7 @@ void set_option_to(uint64_t channel_id, void *to, int type,
|
|||||||
kvi_push(edata->stack, \
|
kvi_push(edata->stack, \
|
||||||
DICTIONARY_OBJ(((Dictionary) { .capacity = 0, .size = 0 })))
|
DICTIONARY_OBJ(((Dictionary) { .capacity = 0, .size = 0 })))
|
||||||
|
|
||||||
static inline void typval_encode_list_start(EncodedData *const edata,
|
static inline void typval_encode_list_start(EncodedData *const edata, const size_t len)
|
||||||
const size_t len)
|
|
||||||
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
kvi_push(edata->stack, ARRAY_OBJ(((Array) {
|
kvi_push(edata->stack, ARRAY_OBJ(((Array) {
|
||||||
@@ -513,8 +510,7 @@ static inline void typval_encode_list_end(EncodedData *const edata)
|
|||||||
#define TYPVAL_ENCODE_CONV_LIST_END(tv) \
|
#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,
|
static inline void typval_encode_dict_start(EncodedData *const edata, const size_t len)
|
||||||
const size_t len)
|
|
||||||
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
kvi_push(edata->stack, DICTIONARY_OBJ(((Dictionary) {
|
kvi_push(edata->stack, DICTIONARY_OBJ(((Dictionary) {
|
||||||
@@ -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
|
/// @param buffer Buffer handle for a specific buffer, or 0 for the current
|
||||||
/// buffer, or -1 to signify global behavior ("all buffers")
|
/// buffer, or -1 to signify global behavior ("all buffers")
|
||||||
/// @param is_unmap When true, removes the mapping that matches {lhs}.
|
/// @param is_unmap When true, removes the mapping that matches {lhs}.
|
||||||
void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs,
|
void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String rhs,
|
||||||
String rhs, Dictionary opts, Error *err)
|
Dictionary opts, Error *err)
|
||||||
{
|
{
|
||||||
char *err_msg = NULL; // the error message to report, if any
|
char *err_msg = NULL; // the error message to report, if any
|
||||||
char *err_arg = NULL; // argument for the error message format string
|
char *err_arg = NULL; // argument for the error message format string
|
||||||
@@ -1050,8 +1046,7 @@ fail_with_message:
|
|||||||
/// @param[out] l Lines are copied here
|
/// @param[out] l Lines are copied here
|
||||||
/// @param err[out] Error, if any
|
/// @param err[out] Error, if any
|
||||||
/// @return true unless `err` was set
|
/// @return true unless `err` was set
|
||||||
bool buf_collect_lines(buf_T *buf, size_t n, int64_t start, bool replace_nl,
|
bool buf_collect_lines(buf_T *buf, size_t n, int64_t start, bool replace_nl, Array *l, Error *err)
|
||||||
Array *l, Error *err)
|
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
int64_t lnum = start + (int64_t)i;
|
int64_t lnum = start + (int64_t)i;
|
||||||
@@ -1400,21 +1395,15 @@ Object copy_object(Object obj)
|
|||||||
case kObjectTypeArray:
|
case kObjectTypeArray:
|
||||||
return ARRAY_OBJ(copy_array(obj.data.array));
|
return ARRAY_OBJ(copy_array(obj.data.array));
|
||||||
|
|
||||||
case kObjectTypeDictionary: {
|
case kObjectTypeDictionary:
|
||||||
return DICTIONARY_OBJ(copy_dictionary(obj.data.dictionary));
|
return DICTIONARY_OBJ(copy_dictionary(obj.data.dictionary));
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_option_value_for(char *key,
|
static void set_option_value_for(char *key, int numval, char *stringval, int opt_flags,
|
||||||
int numval,
|
int opt_type, void *from, Error *err)
|
||||||
char *stringval,
|
|
||||||
int opt_flags,
|
|
||||||
int opt_type,
|
|
||||||
void *from,
|
|
||||||
Error *err)
|
|
||||||
{
|
{
|
||||||
win_T *save_curwin = NULL;
|
win_T *save_curwin = NULL;
|
||||||
tabpage_T *save_curtab = NULL;
|
tabpage_T *save_curtab = NULL;
|
||||||
@@ -1425,8 +1414,7 @@ static void set_option_value_for(char *key,
|
|||||||
{
|
{
|
||||||
case SREQ_WIN:
|
case SREQ_WIN:
|
||||||
if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
|
if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
|
||||||
win_find_tabpage((win_T *)from), false) == FAIL)
|
win_find_tabpage((win_T *)from), false) == FAIL) {
|
||||||
{
|
|
||||||
if (try_end(err)) {
|
if (try_end(err)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1456,11 +1444,7 @@ static void set_option_value_for(char *key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void set_option_value_err(char *key,
|
static void set_option_value_err(char *key, int numval, char *stringval, int opt_flags, Error *err)
|
||||||
int numval,
|
|
||||||
char *stringval,
|
|
||||||
int opt_flags,
|
|
||||||
Error *err)
|
|
||||||
{
|
{
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
|
|
||||||
@@ -1519,8 +1503,7 @@ ArrayOf(Dictionary) keymap_array(String mode, buf_T *buf)
|
|||||||
// Check for correct mode
|
// Check for correct mode
|
||||||
if (int_mode & current_maphash->m_mode) {
|
if (int_mode & current_maphash->m_mode) {
|
||||||
mapblock_fill_dict(dict, current_maphash, buffer_value, false);
|
mapblock_fill_dict(dict, current_maphash, buffer_value, false);
|
||||||
ADD(mappings, vim_to_object(
|
ADD(mappings, vim_to_object((typval_T[]) { { .v_type = VAR_DICT, .vval.v_dict = dict } }));
|
||||||
(typval_T[]) { { .v_type = VAR_DICT, .vval.v_dict = dict } }));
|
|
||||||
|
|
||||||
tv_dict_clear(dict);
|
tv_dict_clear(dict);
|
||||||
}
|
}
|
||||||
@@ -1662,8 +1645,7 @@ free_exit:
|
|||||||
/// @param what The name of the object, used for error message
|
/// @param what The name of the object, used for error message
|
||||||
/// @param nil_value What to return if the type is nil.
|
/// @param nil_value What to return if the type is nil.
|
||||||
/// @param err Set if there was an error in converting to a bool
|
/// @param err Set if there was an error in converting to a bool
|
||||||
bool api_object_to_bool(Object obj, const char *what,
|
bool api_object_to_bool(Object obj, const char *what, bool nil_value, Error *err)
|
||||||
bool nil_value, Error *err)
|
|
||||||
{
|
{
|
||||||
if (obj.type == kObjectTypeBoolean) {
|
if (obj.type == kObjectTypeBoolean) {
|
||||||
return obj.data.boolean;
|
return obj.data.boolean;
|
||||||
@@ -1800,7 +1782,7 @@ static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
|
|||||||
{ "shadow", { "", "", " ", " ", " ", " ", " ", "" }, true },
|
{ "shadow", { "", "", " ", " ", " ", " ", " ", "" }, true },
|
||||||
{ "rounded", { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, false },
|
{ "rounded", { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, false },
|
||||||
{ "solid", { " ", " ", " ", " ", " ", " ", " ", " " }, false },
|
{ "solid", { " ", " ", " ", " ", " ", " ", " ", " " }, false },
|
||||||
{ NULL, { { NUL } } , false },
|
{ NULL, { { NUL } }, false },
|
||||||
};
|
};
|
||||||
|
|
||||||
schar_T *chars = fconfig->border_chars;
|
schar_T *chars = fconfig->border_chars;
|
||||||
@@ -1837,7 +1819,6 @@ static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (iytem.type == kObjectTypeString) {
|
} else if (iytem.type == kObjectTypeString) {
|
||||||
string = iytem.data.string;
|
string = iytem.data.string;
|
||||||
} else {
|
} 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 parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf, bool new_win,
|
||||||
bool new_win, Error *err)
|
Error *err)
|
||||||
{
|
{
|
||||||
// TODO(bfredl): use a get/has_key interface instead and get rid of extra
|
// TODO(bfredl): use a get/has_key interface instead and get rid of extra
|
||||||
// flags
|
// flags
|
||||||
|
@@ -5,10 +5,10 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "nvim/api/tabpage.h"
|
|
||||||
#include "nvim/api/vim.h"
|
|
||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/api/private/defs.h"
|
||||||
#include "nvim/api/private/helpers.h"
|
#include "nvim/api/private/helpers.h"
|
||||||
|
#include "nvim/api/tabpage.h"
|
||||||
|
#include "nvim/api/vim.h"
|
||||||
#include "nvim/memory.h"
|
#include "nvim/memory.h"
|
||||||
#include "nvim/window.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);
|
tabpage_T *tab = find_tab_by_handle(tabpage, err);
|
||||||
|
|
||||||
if (!tab) {
|
if (!tab) {
|
||||||
return (Object) OBJECT_INIT;
|
return (Object)OBJECT_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dict_get_value(tab->tp_vars, name, err);
|
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 name Variable name
|
||||||
/// @param value Variable value
|
/// @param value Variable value
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
void nvim_tabpage_set_var(Tabpage tabpage,
|
void nvim_tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err)
|
||||||
String name,
|
|
||||||
Object value,
|
|
||||||
Error *err)
|
|
||||||
FUNC_API_SINCE(1)
|
FUNC_API_SINCE(1)
|
||||||
{
|
{
|
||||||
tabpage_T *tab = find_tab_by_handle(tabpage, err);
|
tabpage_T *tab = find_tab_by_handle(tabpage, err);
|
||||||
|
@@ -2,22 +2,22 @@
|
|||||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.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/defs.h"
|
||||||
#include "nvim/api/private/helpers.h"
|
#include "nvim/api/private/helpers.h"
|
||||||
#include "nvim/popupmnu.h"
|
#include "nvim/api/ui.h"
|
||||||
#include "nvim/cursor_shape.h"
|
#include "nvim/cursor_shape.h"
|
||||||
#include "nvim/highlight.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/screen.h"
|
||||||
|
#include "nvim/ui.h"
|
||||||
|
#include "nvim/vim.h"
|
||||||
#include "nvim/window.h"
|
#include "nvim/window.h"
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
@@ -85,8 +85,8 @@ void remote_ui_wait_for_attach(void)
|
|||||||
/// @param height Requested screen rows
|
/// @param height Requested screen rows
|
||||||
/// @param options |ui-option| map
|
/// @param options |ui-option| map
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
|
void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictionary options,
|
||||||
Dictionary options, Error *err)
|
Error *err)
|
||||||
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
|
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
|
||||||
{
|
{
|
||||||
if (pmap_has(uint64_t)(&connected_uis, channel_id)) {
|
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
|
/// @deprecated
|
||||||
void ui_attach(uint64_t channel_id, Integer width, Integer height,
|
void ui_attach(uint64_t channel_id, Integer width, Integer height, Boolean enable_rgb, Error *err)
|
||||||
Boolean enable_rgb, Error *err)
|
|
||||||
{
|
{
|
||||||
Dictionary opts = ARRAY_DICT_INIT;
|
Dictionary opts = ARRAY_DICT_INIT;
|
||||||
PUT(opts, "rgb", BOOLEAN_OBJ(enable_rgb));
|
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,
|
void nvim_ui_try_resize(uint64_t channel_id, Integer width, Integer height, Error *err)
|
||||||
Integer height, Error *err)
|
|
||||||
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
|
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
|
||||||
{
|
{
|
||||||
if (!pmap_has(uint64_t)(&connected_uis, channel_id)) {
|
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();
|
ui_refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void nvim_ui_set_option(uint64_t channel_id, String name,
|
void nvim_ui_set_option(uint64_t channel_id, String name, Object value, Error *error)
|
||||||
Object value, Error *error)
|
|
||||||
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
|
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
|
||||||
{
|
{
|
||||||
if (!pmap_has(uint64_t)(&connected_uis, channel_id)) {
|
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);
|
ui_set_option(ui, false, name, value, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ui_set_option(UI *ui, bool init, String name, Object value,
|
static void ui_set_option(UI *ui, bool init, String name, Object value, Error *error)
|
||||||
Error *error)
|
|
||||||
{
|
{
|
||||||
if (strequal(name.data, "override")) {
|
if (strequal(name.data, "override")) {
|
||||||
if (value.type != kObjectTypeBoolean) {
|
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 width The new requested width.
|
||||||
/// @param height The new requested height.
|
/// @param height The new requested height.
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width,
|
void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width, Integer height,
|
||||||
Integer height, Error *err)
|
Error *err)
|
||||||
FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY
|
FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY
|
||||||
{
|
{
|
||||||
if (!pmap_has(uint64_t)(&connected_uis, channel_id)) {
|
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 row Popupmenu row.
|
||||||
/// @param col Popupmenu height.
|
/// @param col Popupmenu height.
|
||||||
/// @param[out] err Error details, if any.
|
/// @param[out] err Error details, if any.
|
||||||
void nvim_ui_pum_set_bounds(uint64_t channel_id, Float width, Float height,
|
void nvim_ui_pum_set_bounds(uint64_t channel_id, Float width, Float height, Float row, Float col,
|
||||||
Float row, Float col, Error *err)
|
Error *err)
|
||||||
FUNC_API_SINCE(7) FUNC_API_REMOTE_ONLY
|
FUNC_API_SINCE(7) FUNC_API_REMOTE_ONLY
|
||||||
{
|
{
|
||||||
if (!pmap_has(uint64_t)(&connected_uis, channel_id)) {
|
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);
|
push_call(ui, name, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remote_ui_grid_resize(UI *ui, Integer grid,
|
static void remote_ui_grid_resize(UI *ui, Integer grid, Integer width, Integer height)
|
||||||
Integer width, Integer height)
|
|
||||||
{
|
{
|
||||||
Array args = ARRAY_DICT_INIT;
|
Array args = ARRAY_DICT_INIT;
|
||||||
if (ui->ui_ext[kUILinegrid]) {
|
if (ui->ui_ext[kUILinegrid]) {
|
||||||
@@ -437,9 +432,8 @@ static void remote_ui_grid_resize(UI *ui, Integer grid,
|
|||||||
push_call(ui, name, args);
|
push_call(ui, name, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remote_ui_grid_scroll(UI *ui, Integer grid, Integer top,
|
static void remote_ui_grid_scroll(UI *ui, Integer grid, Integer top, Integer bot, Integer left,
|
||||||
Integer bot, Integer left, Integer right,
|
Integer right, Integer rows, Integer cols)
|
||||||
Integer rows, Integer cols)
|
|
||||||
{
|
{
|
||||||
if (ui->ui_ext[kUILinegrid]) {
|
if (ui->ui_ext[kUILinegrid]) {
|
||||||
Array args = ARRAY_DICT_INIT;
|
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,
|
static void remote_ui_default_colors_set(UI *ui, Integer rgb_fg, Integer rgb_bg, Integer rgb_sp,
|
||||||
Integer rgb_bg, Integer rgb_sp,
|
|
||||||
Integer cterm_fg, Integer cterm_bg)
|
Integer cterm_fg, Integer cterm_bg)
|
||||||
{
|
{
|
||||||
if (!ui->ui_ext[kUITermColors]) {
|
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,
|
static void remote_ui_hl_attr_define(UI *ui, Integer id, HlAttrs rgb_attrs, HlAttrs cterm_attrs,
|
||||||
HlAttrs cterm_attrs, Array info)
|
Array info)
|
||||||
{
|
{
|
||||||
if (!ui->ui_ext[kUILinegrid]) {
|
if (!ui->ui_ext[kUILinegrid]) {
|
||||||
return;
|
return;
|
||||||
@@ -543,8 +536,7 @@ static void remote_ui_highlight_set(UI *ui, int id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "true" cursor used only for input focus
|
/// "true" cursor used only for input focus
|
||||||
static void remote_ui_grid_cursor_goto(UI *ui, Integer grid, Integer row,
|
static void remote_ui_grid_cursor_goto(UI *ui, Integer grid, Integer row, Integer col)
|
||||||
Integer col)
|
|
||||||
{
|
{
|
||||||
if (ui->ui_ext[kUILinegrid]) {
|
if (ui->ui_ext[kUILinegrid]) {
|
||||||
Array args = ARRAY_DICT_INIT;
|
Array args = ARRAY_DICT_INIT;
|
||||||
@@ -584,11 +576,9 @@ static void remote_ui_put(UI *ui, const char *cell)
|
|||||||
push_call(ui, "put", args);
|
push_call(ui, "put", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remote_ui_raw_line(UI *ui, Integer grid, Integer row,
|
static void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Integer endcol,
|
||||||
Integer startcol, Integer endcol,
|
Integer clearcol, Integer clearattr, LineFlags flags,
|
||||||
Integer clearcol, Integer clearattr,
|
const schar_T *chunk, const sattr_T *attrs)
|
||||||
LineFlags flags, const schar_T *chunk,
|
|
||||||
const sattr_T *attrs)
|
|
||||||
{
|
{
|
||||||
UIData *data = ui->data;
|
UIData *data = ui->data;
|
||||||
if (ui->ui_ext[kUILinegrid]) {
|
if (ui->ui_ext[kUILinegrid]) {
|
||||||
|
@@ -3,54 +3,54 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include "nvim/api/vim.h"
|
#include "nvim/api/buffer.h"
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/api/deprecated.h"
|
||||||
#include "nvim/api/private/helpers.h"
|
|
||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/api/private/defs.h"
|
||||||
#include "nvim/api/private/dispatch.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/window.h"
|
||||||
#include "nvim/api/deprecated.h"
|
#include "nvim/ascii.h"
|
||||||
#include "nvim/msgpack_rpc/channel.h"
|
|
||||||
#include "nvim/msgpack_rpc/helpers.h"
|
|
||||||
#include "nvim/lua/executor.h"
|
|
||||||
#include "nvim/vim.h"
|
|
||||||
#include "nvim/buffer.h"
|
#include "nvim/buffer.h"
|
||||||
#include "nvim/context.h"
|
#include "nvim/context.h"
|
||||||
#include "nvim/file_search.h"
|
#include "nvim/decoration.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/edit.h"
|
#include "nvim/edit.h"
|
||||||
#include "nvim/eval.h"
|
#include "nvim/eval.h"
|
||||||
#include "nvim/eval/typval.h"
|
#include "nvim/eval/typval.h"
|
||||||
#include "nvim/eval/userfunc.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/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/move.h"
|
||||||
|
#include "nvim/msgpack_rpc/channel.h"
|
||||||
|
#include "nvim/msgpack_rpc/helpers.h"
|
||||||
#include "nvim/ops.h"
|
#include "nvim/ops.h"
|
||||||
#include "nvim/option.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/input.h"
|
||||||
#include "nvim/os/process.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/expressions.h"
|
||||||
#include "nvim/viml/parser/parser.h"
|
#include "nvim/viml/parser/parser.h"
|
||||||
#include "nvim/ui.h"
|
#include "nvim/window.h"
|
||||||
|
|
||||||
#define LINE_BUFFER_SIZE 4096
|
#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) {
|
for (size_t i = 0; i < mode.size; ++i) {
|
||||||
switch (mode.data[i]) {
|
switch (mode.data[i]) {
|
||||||
case 'n': remap = false; break;
|
case 'n':
|
||||||
case 'm': remap = true; break;
|
remap = false; break;
|
||||||
case 't': typed = true; break;
|
case 'm':
|
||||||
case 'i': insert = true; break;
|
remap = true; break;
|
||||||
case 'x': execute = true; break;
|
case 't':
|
||||||
case '!': dangerous = true; break;
|
typed = true; break;
|
||||||
|
case 'i':
|
||||||
|
insert = true; break;
|
||||||
|
case 'x':
|
||||||
|
execute = true; break;
|
||||||
|
case '!':
|
||||||
|
dangerous = true; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,8 +397,8 @@ Integer nvim_input(String keys)
|
|||||||
/// @param row Mouse row-position (zero-based, like redraw events)
|
/// @param row Mouse row-position (zero-based, like redraw events)
|
||||||
/// @param col Mouse column-position (zero-based, like redraw events)
|
/// @param col Mouse column-position (zero-based, like redraw events)
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
void nvim_input_mouse(String button, String action, String modifier,
|
void nvim_input_mouse(String button, String action, String modifier, Integer grid, Integer row,
|
||||||
Integer grid, Integer row, Integer col, Error *err)
|
Integer col, Error *err)
|
||||||
FUNC_API_SINCE(6) FUNC_API_FAST
|
FUNC_API_SINCE(6) FUNC_API_FAST
|
||||||
{
|
{
|
||||||
if (button.data == NULL || action.data == NULL) {
|
if (button.data == NULL || action.data == NULL) {
|
||||||
@@ -469,8 +475,7 @@ error:
|
|||||||
/// @param special Replace |keycodes|, e.g. <CR> becomes a "\n" char.
|
/// @param special Replace |keycodes|, e.g. <CR> becomes a "\n" char.
|
||||||
/// @see replace_termcodes
|
/// @see replace_termcodes
|
||||||
/// @see cpoptions
|
/// @see cpoptions
|
||||||
String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt,
|
String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, Boolean special)
|
||||||
Boolean special)
|
|
||||||
FUNC_API_SINCE(1)
|
FUNC_API_SINCE(1)
|
||||||
{
|
{
|
||||||
if (str.size == 0) {
|
if (str.size == 0) {
|
||||||
@@ -663,7 +668,7 @@ Object nvim_call_dict_function(Object dict, String fn, Array args, Error *err)
|
|||||||
typval_T rettv;
|
typval_T rettv;
|
||||||
bool mustfree = false;
|
bool mustfree = false;
|
||||||
switch (dict.type) {
|
switch (dict.type) {
|
||||||
case kObjectTypeString: {
|
case kObjectTypeString:
|
||||||
try_start();
|
try_start();
|
||||||
if (eval0((char_u *)dict.data.string.data, &rettv, NULL, true) == FAIL) {
|
if (eval0((char_u *)dict.data.string.data, &rettv, NULL, true) == FAIL) {
|
||||||
api_set_error(err, kErrorTypeException,
|
api_set_error(err, kErrorTypeException,
|
||||||
@@ -676,19 +681,16 @@ Object nvim_call_dict_function(Object dict, String fn, Array args, Error *err)
|
|||||||
// refcount of a dict. Not necessary for a RPC dict.
|
// refcount of a dict. Not necessary for a RPC dict.
|
||||||
mustfree = true;
|
mustfree = true;
|
||||||
break;
|
break;
|
||||||
}
|
case kObjectTypeDictionary:
|
||||||
case kObjectTypeDictionary: {
|
|
||||||
if (!object_to_vim(dict, &rettv, err)) {
|
if (!object_to_vim(dict, &rettv, err)) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
default: {
|
|
||||||
api_set_error(err, kErrorTypeValidation,
|
api_set_error(err, kErrorTypeValidation,
|
||||||
"dict argument type must be String or Dictionary");
|
"dict argument type must be String or Dictionary");
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
dict_T *self_dict = rettv.vval.v_dict;
|
dict_T *self_dict = rettv.vval.v_dict;
|
||||||
if (rettv.v_type != VAR_DICT || !self_dict) {
|
if (rettv.v_type != VAR_DICT || !self_dict) {
|
||||||
api_set_error(err, kErrorTypeValidation, "dict not found");
|
api_set_error(err, kErrorTypeValidation, "dict not found");
|
||||||
@@ -1420,8 +1422,7 @@ void nvim_chan_send(Integer chan, String data, Error *err)
|
|||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
///
|
///
|
||||||
/// @return Window handle, or 0 on error
|
/// @return Window handle, or 0 on error
|
||||||
Window nvim_open_win(Buffer buffer, Boolean enter, Dictionary config,
|
Window nvim_open_win(Buffer buffer, Boolean enter, Dictionary config, Error *err)
|
||||||
Error *err)
|
|
||||||
FUNC_API_SINCE(6)
|
FUNC_API_SINCE(6)
|
||||||
FUNC_API_CHECK_TEXTLOCK
|
FUNC_API_CHECK_TEXTLOCK
|
||||||
{
|
{
|
||||||
@@ -1579,7 +1580,7 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Error *err)
|
|||||||
bool cancel = false;
|
bool cancel = false;
|
||||||
|
|
||||||
if (phase < -1 || phase > 3) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
Array args = ARRAY_DICT_INIT;
|
Array args = ARRAY_DICT_INIT;
|
||||||
@@ -1643,8 +1644,7 @@ theend:
|
|||||||
/// @param after If true insert after cursor (like |p|), or before (like |P|).
|
/// @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 follow If true place cursor at end of inserted text.
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
void nvim_put(ArrayOf(String) lines, String type, Boolean after,
|
void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, Error *err)
|
||||||
Boolean follow, Error *err)
|
|
||||||
FUNC_API_SINCE(6)
|
FUNC_API_SINCE(6)
|
||||||
FUNC_API_CHECK_TEXTLOCK
|
FUNC_API_CHECK_TEXTLOCK
|
||||||
{
|
{
|
||||||
@@ -1885,8 +1885,7 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode)
|
|||||||
/// as keys excluding |<buffer>| but including |noremap|.
|
/// as keys excluding |<buffer>| but including |noremap|.
|
||||||
/// Values are Booleans. Unknown key is an error.
|
/// Values are Booleans. Unknown key is an error.
|
||||||
/// @param[out] err Error details, if any.
|
/// @param[out] err Error details, if any.
|
||||||
void nvim_set_keymap(String mode, String lhs, String rhs,
|
void nvim_set_keymap(String mode, String lhs, String rhs, Dictionary opts, Error *err)
|
||||||
Dictionary opts, Error *err)
|
|
||||||
FUNC_API_SINCE(6)
|
FUNC_API_SINCE(6)
|
||||||
{
|
{
|
||||||
modify_keymap(-1, false, mode, lhs, rhs, opts, err);
|
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.
|
/// .png or .svg format is preferred.
|
||||||
///
|
///
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
void nvim_set_client_info(uint64_t channel_id, String name,
|
void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version, String type,
|
||||||
Dictionary version, String type,
|
Dictionary methods, Dictionary attributes, Error *err)
|
||||||
Dictionary methods, Dictionary attributes,
|
|
||||||
Error *err)
|
|
||||||
FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY
|
FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY
|
||||||
{
|
{
|
||||||
Dictionary info = ARRAY_DICT_INIT;
|
Dictionary info = ARRAY_DICT_INIT;
|
||||||
@@ -2232,28 +2229,28 @@ typedef kvec_withinit_t(ExprASTConvStackItem, 16) ExprASTConvStack;
|
|||||||
/// - "svalue": String, value for "SingleQuotedString" and
|
/// - "svalue": String, value for "SingleQuotedString" and
|
||||||
/// "DoubleQuotedString" nodes.
|
/// "DoubleQuotedString" nodes.
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
|
Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight, Error *err)
|
||||||
Error *err)
|
|
||||||
FUNC_API_SINCE(4) FUNC_API_FAST
|
FUNC_API_SINCE(4) FUNC_API_FAST
|
||||||
{
|
{
|
||||||
int pflags = 0;
|
int pflags = 0;
|
||||||
for (size_t i = 0 ; i < flags.size ; i++) {
|
for (size_t i = 0 ; i < flags.size ; i++) {
|
||||||
switch (flags.data[i]) {
|
switch (flags.data[i]) {
|
||||||
case 'm': { pflags |= kExprFlagsMulti; break; }
|
case 'm':
|
||||||
case 'E': { pflags |= kExprFlagsDisallowEOC; break; }
|
pflags |= kExprFlagsMulti; break;
|
||||||
case 'l': { pflags |= kExprFlagsParseLet; break; }
|
case 'E':
|
||||||
case NUL: {
|
pflags |= kExprFlagsDisallowEOC; break;
|
||||||
|
case 'l':
|
||||||
|
pflags |= kExprFlagsParseLet; break;
|
||||||
|
case NUL:
|
||||||
api_set_error(err, kErrorTypeValidation, "Invalid flag: '\\0' (%u)",
|
api_set_error(err, kErrorTypeValidation, "Invalid flag: '\\0' (%u)",
|
||||||
(unsigned)flags.data[i]);
|
(unsigned)flags.data[i]);
|
||||||
return (Dictionary)ARRAY_DICT_INIT;
|
return (Dictionary)ARRAY_DICT_INIT;
|
||||||
}
|
default:
|
||||||
default: {
|
|
||||||
api_set_error(err, kErrorTypeValidation, "Invalid flag: '%c' (%u)",
|
api_set_error(err, kErrorTypeValidation, "Invalid flag: '%c' (%u)",
|
||||||
flags.data[i], (unsigned)flags.data[i]);
|
flags.data[i], (unsigned)flags.data[i]);
|
||||||
return (Dictionary)ARRAY_DICT_INIT;
|
return (Dictionary)ARRAY_DICT_INIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ParserLine parser_lines[] = {
|
ParserLine parser_lines[] = {
|
||||||
{
|
{
|
||||||
.data = expr.data,
|
.data = expr.data,
|
||||||
@@ -2267,8 +2264,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
|
|||||||
kvi_init(colors);
|
kvi_init(colors);
|
||||||
ParserHighlight *const colors_p = (highlight ? &colors : NULL);
|
ParserHighlight *const colors_p = (highlight ? &colors : NULL);
|
||||||
ParserState pstate;
|
ParserState pstate;
|
||||||
viml_parser_init(
|
viml_parser_init(&pstate, parser_simple_get_line, &plines_p, colors_p);
|
||||||
&pstate, parser_simple_get_line, &plines_p, colors_p);
|
|
||||||
ExprAST east = viml_pexpr_parse(&pstate, pflags);
|
ExprAST east = viml_pexpr_parse(&pstate, pflags);
|
||||||
|
|
||||||
const size_t ret_size = (
|
const size_t ret_size = (
|
||||||
@@ -2433,7 +2429,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
|
|||||||
};
|
};
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case kExprNodeDoubleQuotedString:
|
case kExprNodeDoubleQuotedString:
|
||||||
case kExprNodeSingleQuotedString: {
|
case kExprNodeSingleQuotedString:
|
||||||
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
||||||
.key = STATIC_CSTR_TO_STRING("svalue"),
|
.key = STATIC_CSTR_TO_STRING("svalue"),
|
||||||
.value = STRING_OBJ(((String) {
|
.value = STRING_OBJ(((String) {
|
||||||
@@ -2442,8 +2438,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
|
|||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
case kExprNodeOption:
|
||||||
case kExprNodeOption: {
|
|
||||||
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
||||||
.key = STATIC_CSTR_TO_STRING("scope"),
|
.key = STATIC_CSTR_TO_STRING("scope"),
|
||||||
.value = INTEGER_OBJ(node->data.opt.scope),
|
.value = INTEGER_OBJ(node->data.opt.scope),
|
||||||
@@ -2457,8 +2452,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
|
|||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
case kExprNodePlainIdentifier:
|
||||||
case kExprNodePlainIdentifier: {
|
|
||||||
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
||||||
.key = STATIC_CSTR_TO_STRING("scope"),
|
.key = STATIC_CSTR_TO_STRING("scope"),
|
||||||
.value = INTEGER_OBJ(node->data.var.scope),
|
.value = INTEGER_OBJ(node->data.var.scope),
|
||||||
@@ -2472,8 +2466,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
|
|||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
case kExprNodePlainKey:
|
||||||
case kExprNodePlainKey: {
|
|
||||||
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
||||||
.key = STATIC_CSTR_TO_STRING("ident"),
|
.key = STATIC_CSTR_TO_STRING("ident"),
|
||||||
.value = STRING_OBJ(((String) {
|
.value = STRING_OBJ(((String) {
|
||||||
@@ -2483,8 +2476,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
|
|||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
case kExprNodeEnvironment:
|
||||||
case kExprNodeEnvironment: {
|
|
||||||
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
||||||
.key = STATIC_CSTR_TO_STRING("ident"),
|
.key = STATIC_CSTR_TO_STRING("ident"),
|
||||||
.value = STRING_OBJ(((String) {
|
.value = STRING_OBJ(((String) {
|
||||||
@@ -2494,39 +2486,33 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
|
|||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
case kExprNodeRegister:
|
||||||
case kExprNodeRegister: {
|
|
||||||
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
||||||
.key = STATIC_CSTR_TO_STRING("name"),
|
.key = STATIC_CSTR_TO_STRING("name"),
|
||||||
.value = INTEGER_OBJ(node->data.reg.name),
|
.value = INTEGER_OBJ(node->data.reg.name),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
case kExprNodeComparison:
|
||||||
case kExprNodeComparison: {
|
|
||||||
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
||||||
.key = STATIC_CSTR_TO_STRING("cmp_type"),
|
.key = STATIC_CSTR_TO_STRING("cmp_type"),
|
||||||
.value = STRING_OBJ(cstr_to_string(
|
.value = STRING_OBJ(cstr_to_string(eltkn_cmp_type_tab[node->data.cmp.type])),
|
||||||
eltkn_cmp_type_tab[node->data.cmp.type])),
|
|
||||||
};
|
};
|
||||||
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
||||||
.key = STATIC_CSTR_TO_STRING("ccs_strategy"),
|
.key = STATIC_CSTR_TO_STRING("ccs_strategy"),
|
||||||
.value = STRING_OBJ(cstr_to_string(
|
.value = STRING_OBJ(cstr_to_string(ccs_tab[node->data.cmp.ccs])),
|
||||||
ccs_tab[node->data.cmp.ccs])),
|
|
||||||
};
|
};
|
||||||
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
||||||
.key = STATIC_CSTR_TO_STRING("invert"),
|
.key = STATIC_CSTR_TO_STRING("invert"),
|
||||||
.value = BOOLEAN_OBJ(node->data.cmp.inv),
|
.value = BOOLEAN_OBJ(node->data.cmp.inv),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
case kExprNodeFloat:
|
||||||
case kExprNodeFloat: {
|
|
||||||
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
||||||
.key = STATIC_CSTR_TO_STRING("fvalue"),
|
.key = STATIC_CSTR_TO_STRING("fvalue"),
|
||||||
.value = FLOAT_OBJ(node->data.flt.value),
|
.value = FLOAT_OBJ(node->data.flt.value),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
case kExprNodeInteger:
|
||||||
case kExprNodeInteger: {
|
|
||||||
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
||||||
.key = STATIC_CSTR_TO_STRING("ivalue"),
|
.key = STATIC_CSTR_TO_STRING("ivalue"),
|
||||||
.value = INTEGER_OBJ((Integer)(
|
.value = INTEGER_OBJ((Integer)(
|
||||||
@@ -2535,13 +2521,11 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
|
|||||||
: (Integer)node->data.num.value)),
|
: (Integer)node->data.num.value)),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case kExprNodeAssignment: {
|
case kExprNodeAssignment: {
|
||||||
const ExprAssignmentType asgn_type = node->data.ass.type;
|
const ExprAssignmentType asgn_type = node->data.ass.type;
|
||||||
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
ret_node->items[ret_node->size++] = (KeyValuePair) {
|
||||||
.key = STATIC_CSTR_TO_STRING("augmentation"),
|
.key = STATIC_CSTR_TO_STRING("augmentation"),
|
||||||
.value = STRING_OBJ(
|
.value = STRING_OBJ(asgn_type == kExprAsgnPlain
|
||||||
asgn_type == kExprAsgnPlain
|
|
||||||
? (String)STRING_INIT
|
? (String)STRING_INIT
|
||||||
: cstr_to_string(expr_asgn_type_tab[asgn_type])),
|
: cstr_to_string(expr_asgn_type_tab[asgn_type])),
|
||||||
};
|
};
|
||||||
@@ -2574,10 +2558,9 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
|
|||||||
case kExprNodeNot:
|
case kExprNodeNot:
|
||||||
case kExprNodeMultiplication:
|
case kExprNodeMultiplication:
|
||||||
case kExprNodeDivision:
|
case kExprNodeDivision:
|
||||||
case kExprNodeMod: {
|
case kExprNodeMod:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
assert(cur_item.ret_node_p->data.dictionary.size
|
assert(cur_item.ret_node_p->data.dictionary.size
|
||||||
== cur_item.ret_node_p->data.dictionary.capacity);
|
== cur_item.ret_node_p->data.dictionary.capacity);
|
||||||
xfree(*cur_item.node_p);
|
xfree(*cur_item.node_p);
|
||||||
@@ -2806,8 +2789,8 @@ Object nvim_get_proc(Integer pid, Error *err)
|
|||||||
/// `insert`.
|
/// `insert`.
|
||||||
/// @param opts Optional parameters. Reserved for future use.
|
/// @param opts Optional parameters. Reserved for future use.
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish,
|
void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish, Dictionary opts,
|
||||||
Dictionary opts, Error *err)
|
Error *err)
|
||||||
FUNC_API_SINCE(6)
|
FUNC_API_SINCE(6)
|
||||||
{
|
{
|
||||||
if (opts.size > 0) {
|
if (opts.size > 0) {
|
||||||
@@ -2904,8 +2887,7 @@ void nvim__screenshot(String path)
|
|||||||
/// ["win", winid, bufnr, row]
|
/// ["win", winid, bufnr, row]
|
||||||
/// - on_end: called at the end of a redraw cycle
|
/// - on_end: called at the end of a redraw cycle
|
||||||
/// ["end", tick]
|
/// ["end", tick]
|
||||||
void nvim_set_decoration_provider(Integer ns_id, DictionaryOf(LuaRef) opts,
|
void nvim_set_decoration_provider(Integer ns_id, DictionaryOf(LuaRef) opts, Error *err)
|
||||||
Error *err)
|
|
||||||
FUNC_API_SINCE(7) FUNC_API_LUA_ONLY
|
FUNC_API_SINCE(7) FUNC_API_LUA_ONLY
|
||||||
{
|
{
|
||||||
DecorProvider *p = get_decor_provider((NS)ns_id, true);
|
DecorProvider *p = get_decor_provider((NS)ns_id, true);
|
||||||
|
@@ -1,25 +1,25 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// 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
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/api/private/defs.h"
|
||||||
#include "nvim/api/private/helpers.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/api/window.h"
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
#include "nvim/buffer.h"
|
#include "nvim/buffer.h"
|
||||||
#include "nvim/cursor.h"
|
#include "nvim/cursor.h"
|
||||||
|
#include "nvim/ex_docmd.h"
|
||||||
#include "nvim/globals.h"
|
#include "nvim/globals.h"
|
||||||
|
#include "nvim/lua/executor.h"
|
||||||
#include "nvim/move.h"
|
#include "nvim/move.h"
|
||||||
#include "nvim/option.h"
|
#include "nvim/option.h"
|
||||||
#include "nvim/screen.h"
|
#include "nvim/screen.h"
|
||||||
#include "nvim/syntax.h"
|
#include "nvim/syntax.h"
|
||||||
|
#include "nvim/vim.h"
|
||||||
#include "nvim/window.h"
|
#include "nvim/window.h"
|
||||||
|
|
||||||
/// Gets the current buffer in a window
|
/// 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);
|
win_T *win = find_window_by_handle(window, err);
|
||||||
|
|
||||||
if (!win) {
|
if (!win) {
|
||||||
return (Object) OBJECT_INIT;
|
return (Object)OBJECT_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dict_get_value(win->w_vars, name, err);
|
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);
|
win_T *win = find_window_by_handle(window, err);
|
||||||
|
|
||||||
if (!win) {
|
if (!win) {
|
||||||
return (Object) OBJECT_INIT;
|
return (Object)OBJECT_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return get_option_from(win, SREQ_WIN, name, err);
|
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 name Option name
|
||||||
/// @param value Option value
|
/// @param value Option value
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
void nvim_win_set_option(uint64_t channel_id, Window window,
|
void nvim_win_set_option(uint64_t channel_id, Window window, String name, Object value, Error *err)
|
||||||
String name, Object value, Error *err)
|
|
||||||
FUNC_API_SINCE(1)
|
FUNC_API_SINCE(1)
|
||||||
{
|
{
|
||||||
win_T *win = find_window_by_handle(window, err);
|
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, "bufpos", ARRAY_OBJ(pos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PUT(rv, "anchor", STRING_OBJ(cstr_to_string(
|
PUT(rv, "anchor", STRING_OBJ(cstr_to_string(float_anchor_str[config->anchor])));
|
||||||
float_anchor_str[config->anchor])));
|
|
||||||
PUT(rv, "row", FLOAT_OBJ(config->row));
|
PUT(rv, "row", FLOAT_OBJ(config->row));
|
||||||
PUT(rv, "col", FLOAT_OBJ(config->col));
|
PUT(rv, "col", FLOAT_OBJ(config->col));
|
||||||
PUT(rv, "zindex", INTEGER_OBJ(config->zindex));
|
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++) {
|
for (size_t i = 0; i < 8; i++) {
|
||||||
Array tuple = ARRAY_DICT_INIT;
|
Array tuple = ARRAY_DICT_INIT;
|
||||||
|
|
||||||
String s = cstrn_to_string(
|
String s = cstrn_to_string((const char *)config->border_chars[i], sizeof(schar_T));
|
||||||
(const char *)config->border_chars[i], sizeof(schar_T));
|
|
||||||
|
|
||||||
int hi_id = config->border_hl_ids[i];
|
int hi_id = config->border_hl_ids[i];
|
||||||
char_u *hi_name = syn_id2name(hi_id);
|
char_u *hi_name = syn_id2name(hi_id);
|
||||||
|
@@ -1,20 +1,19 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// 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
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
|
#include <msgpack.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include <msgpack.h>
|
#include "nvim/ascii.h"
|
||||||
|
#include "nvim/charset.h" // vim_str2nr
|
||||||
#include "nvim/eval/typval.h"
|
|
||||||
#include "nvim/eval.h"
|
#include "nvim/eval.h"
|
||||||
#include "nvim/eval/decode.h"
|
#include "nvim/eval/decode.h"
|
||||||
#include "nvim/eval/encode.h"
|
#include "nvim/eval/encode.h"
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/eval/typval.h"
|
||||||
|
#include "nvim/globals.h"
|
||||||
|
#include "nvim/lib/kvec.h"
|
||||||
#include "nvim/macros.h"
|
#include "nvim/macros.h"
|
||||||
#include "nvim/message.h"
|
#include "nvim/message.h"
|
||||||
#include "nvim/globals.h"
|
|
||||||
#include "nvim/charset.h" // vim_str2nr
|
|
||||||
#include "nvim/lib/kvec.h"
|
|
||||||
#include "nvim/vim.h" // OK, FAIL
|
#include "nvim/vim.h" // OK, FAIL
|
||||||
|
|
||||||
/// Helper structure for container_struct
|
/// 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[out] rettv Location where created dictionary will be saved.
|
||||||
/// @param[in] type Type of the dictionary.
|
/// @param[in] type Type of the dictionary.
|
||||||
/// @param[in] val Value associated with the _VAL key.
|
/// @param[in] val Value associated with the _VAL key.
|
||||||
static inline void create_special_dict(typval_T *const rettv,
|
static inline void create_special_dict(typval_T *const rettv, const MessagePackType type,
|
||||||
const MessagePackType type,
|
|
||||||
typval_T val)
|
typval_T val)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
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.
|
/// value when decoder is restarted, otherwise unused.
|
||||||
///
|
///
|
||||||
/// @return OK in case of success, FAIL in case of error.
|
/// @return OK in case of success, FAIL in case of error.
|
||||||
static inline int json_decoder_pop(ValuesStackItem obj,
|
static inline int json_decoder_pop(ValuesStackItem obj, ValuesStack *const stack,
|
||||||
ValuesStack *const stack,
|
ContainerStack *const container_stack, const char **const pp,
|
||||||
ContainerStack *const container_stack,
|
bool *const next_map_special, bool *const didcomma,
|
||||||
const char **const pp,
|
|
||||||
bool *const next_map_special,
|
|
||||||
bool *const didcomma,
|
|
||||||
bool *const didcolon)
|
bool *const didcolon)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
@@ -114,9 +109,9 @@ static inline int json_decoder_pop(ValuesStackItem obj,
|
|||||||
const char *val_location = *pp;
|
const char *val_location = *pp;
|
||||||
if (obj.val.v_type == last_container.container.v_type
|
if (obj.val.v_type == last_container.container.v_type
|
||||||
// vval.v_list and vval.v_dict should have the same size and offset
|
// vval.v_list and vval.v_dict should have the same size and offset
|
||||||
&& ((void *) obj.val.vval.v_list
|
&& ((void *)obj.val.vval.v_list
|
||||||
== (void *) last_container.container.vval.v_list)) {
|
== (void *)last_container.container.vval.v_list)) {
|
||||||
(void) kv_pop(*container_stack);
|
(void)kv_pop(*container_stack);
|
||||||
val_location = last_container.s;
|
val_location = last_container.s;
|
||||||
last_container = kv_last(*container_stack);
|
last_container = kv_last(*container_stack);
|
||||||
}
|
}
|
||||||
@@ -142,8 +137,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
|
|||||||
assert(!(key.is_special_string
|
assert(!(key.is_special_string
|
||||||
|| key.val.vval.v_string == NULL
|
|| key.val.vval.v_string == NULL
|
||||||
|| *key.val.vval.v_string == NUL));
|
|| *key.val.vval.v_string == NUL));
|
||||||
dictitem_T *const obj_di = tv_dict_item_alloc(
|
dictitem_T *const obj_di = tv_dict_item_alloc((const char *)key.val.vval.v_string);
|
||||||
(const char *)key.val.vval.v_string);
|
|
||||||
tv_clear(&key.val);
|
tv_clear(&key.val);
|
||||||
if (tv_dict_add(last_container.container.vval.v_dict, obj_di)
|
if (tv_dict_add(last_container.container.vval.v_dict, obj_di)
|
||||||
== FAIL) {
|
== FAIL) {
|
||||||
@@ -179,7 +173,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
|
|||||||
tv_clear(&obj.val);
|
tv_clear(&obj.val);
|
||||||
|
|
||||||
// Restart
|
// Restart
|
||||||
(void) kv_pop(*container_stack);
|
(void)kv_pop(*container_stack);
|
||||||
ValuesStackItem last_container_val =
|
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) {
|
while (kv_size(*stack) > last_container.stack_index) {
|
||||||
@@ -197,7 +191,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define LENP(p, e) \
|
#define LENP(p, e) \
|
||||||
((int) ((e) - (p))), (p)
|
((int)((e) - (p))), (p)
|
||||||
#define OBJ(obj_tv, is_sp_string, didcomma_, didcolon_) \
|
#define OBJ(obj_tv, is_sp_string, didcomma_, didcolon_) \
|
||||||
((ValuesStackItem) { \
|
((ValuesStackItem) { \
|
||||||
.is_special_string = (is_sp_string), \
|
.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
|
/// @return [allocated] list which should contain key-value pairs. Return value
|
||||||
/// may be safely ignored.
|
/// may be safely ignored.
|
||||||
list_T *decode_create_map_special_dict(typval_T *const ret_tv,
|
list_T *decode_create_map_special_dict(typval_T *const ret_tv, const ptrdiff_t len)
|
||||||
const ptrdiff_t len)
|
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
list_T *const list = tv_list_alloc(len);
|
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.
|
/// will be freed.
|
||||||
///
|
///
|
||||||
/// @return Decoded string.
|
/// @return Decoded string.
|
||||||
typval_T decode_string(const char *const s, const size_t len,
|
typval_T decode_string(const char *const s, const size_t len, const TriState hasnul,
|
||||||
const TriState hasnul, const bool binary,
|
const bool binary, const bool s_allocated)
|
||||||
const bool s_allocated)
|
|
||||||
FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
assert(s != NULL || len == 0);
|
assert(s != NULL || len == 0);
|
||||||
@@ -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.
|
/// @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,
|
static inline int parse_json_string(const char *const buf, const size_t buf_len,
|
||||||
const char **const pp,
|
const char **const pp, ValuesStack *const stack,
|
||||||
ValuesStack *const stack,
|
|
||||||
ContainerStack *const container_stack,
|
ContainerStack *const container_stack,
|
||||||
bool *const next_map_special,
|
bool *const next_map_special, bool *const didcomma,
|
||||||
bool *const didcomma,
|
|
||||||
bool *const didcolon)
|
bool *const didcolon)
|
||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
|
||||||
{
|
{
|
||||||
@@ -341,14 +331,14 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
|
|||||||
p++;
|
p++;
|
||||||
if (p == e) {
|
if (p == e) {
|
||||||
emsgf(_("E474: Unfinished escape sequence: %.*s"),
|
emsgf(_("E474: Unfinished escape sequence: %.*s"),
|
||||||
(int) buf_len, buf);
|
(int)buf_len, buf);
|
||||||
goto parse_json_string_fail;
|
goto parse_json_string_fail;
|
||||||
}
|
}
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case 'u': {
|
case 'u':
|
||||||
if (p + 4 >= e) {
|
if (p + 4 >= e) {
|
||||||
emsgf(_("E474: Unfinished unicode escape sequence: %.*s"),
|
emsgf(_("E474: Unfinished unicode escape sequence: %.*s"),
|
||||||
(int) buf_len, buf);
|
(int)buf_len, buf);
|
||||||
goto parse_json_string_fail;
|
goto parse_json_string_fail;
|
||||||
} else if (!ascii_isxdigit(p[1])
|
} else if (!ascii_isxdigit(p[1])
|
||||||
|| !ascii_isxdigit(p[2])
|
|| !ascii_isxdigit(p[2])
|
||||||
@@ -363,7 +353,6 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
|
|||||||
len += 3;
|
len += 3;
|
||||||
p += 5;
|
p += 5;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case '\\':
|
case '\\':
|
||||||
case '/':
|
case '/':
|
||||||
case '"':
|
case '"':
|
||||||
@@ -371,25 +360,23 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
|
|||||||
case 'b':
|
case 'b':
|
||||||
case 'n':
|
case 'n':
|
||||||
case 'r':
|
case 'r':
|
||||||
case 'f': {
|
case 'f':
|
||||||
len++;
|
len++;
|
||||||
p++;
|
p++;
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
default: {
|
|
||||||
emsgf(_("E474: Unknown escape sequence: %.*s"), LENP(p - 1, e));
|
emsgf(_("E474: Unknown escape sequence: %.*s"), LENP(p - 1, e));
|
||||||
goto parse_json_string_fail;
|
goto parse_json_string_fail;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
uint8_t p_byte = (uint8_t) *p;
|
uint8_t p_byte = (uint8_t)*p;
|
||||||
// unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
|
// unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
|
||||||
if (p_byte < 0x20) {
|
if (p_byte < 0x20) {
|
||||||
emsgf(_("E474: ASCII control characters cannot be present "
|
emsgf(_("E474: ASCII control characters cannot be present "
|
||||||
"inside string: %.*s"), LENP(p, e));
|
"inside string: %.*s"), LENP(p, e));
|
||||||
goto parse_json_string_fail;
|
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
|
// All characters above U+007F are encoded using two or more bytes
|
||||||
// and thus cannot possibly be equal to *p. But utf_ptr2char({0xFF,
|
// and thus cannot possibly be equal to *p. But utf_ptr2char({0xFF,
|
||||||
// 0}) will return 0xFF, even though 0xFF cannot start any UTF-8
|
// 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.
|
// The only exception is U+00C3 which is represented as 0xC3 0x83.
|
||||||
if (ch >= 0x80 && p_byte == ch
|
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));
|
emsgf(_("E474: Only UTF-8 strings allowed: %.*s"), LENP(p, e));
|
||||||
goto parse_json_string_fail;
|
goto parse_json_string_fail;
|
||||||
} else if (ch > 0x10FFFF) {
|
} 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));
|
"are allowed to appear unescaped: %.*s"), LENP(p, e));
|
||||||
goto parse_json_string_fail;
|
goto parse_json_string_fail;
|
||||||
}
|
}
|
||||||
const size_t ch_len = (size_t) utf_char2len(ch);
|
const size_t ch_len = (size_t)utf_char2len(ch);
|
||||||
assert(ch_len == (size_t) (ch ? utf_ptr2len((char_u *) p) : 1));
|
assert(ch_len == (size_t)(ch ? utf_ptr2len((char_u *)p) : 1));
|
||||||
len += ch_len;
|
len += ch_len;
|
||||||
p += ch_len;
|
p += ch_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p == e || *p != '"') {
|
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;
|
goto parse_json_string_fail;
|
||||||
}
|
}
|
||||||
if (len == 0) {
|
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) \
|
#define PUT_FST_IN_PAIR(fst_in_pair, str_end) \
|
||||||
do { \
|
do { \
|
||||||
if (fst_in_pair != 0) { \
|
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; \
|
fst_in_pair = 0; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
@@ -451,18 +438,18 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
|
|||||||
}
|
}
|
||||||
if (SURROGATE_HI_START <= ch && ch <= SURROGATE_HI_END) {
|
if (SURROGATE_HI_START <= ch && ch <= SURROGATE_HI_END) {
|
||||||
PUT_FST_IN_PAIR(fst_in_pair, str_end);
|
PUT_FST_IN_PAIR(fst_in_pair, str_end);
|
||||||
fst_in_pair = (int) ch;
|
fst_in_pair = (int)ch;
|
||||||
} else if (SURROGATE_LO_START <= ch && ch <= SURROGATE_LO_END
|
} else if (SURROGATE_LO_START <= ch && ch <= SURROGATE_LO_END
|
||||||
&& fst_in_pair != 0) {
|
&& fst_in_pair != 0) {
|
||||||
const int full_char = (
|
const int full_char = (
|
||||||
(int) (ch - SURROGATE_LO_START)
|
(int)(ch - SURROGATE_LO_START)
|
||||||
+ ((fst_in_pair - SURROGATE_HI_START) << 10)
|
+ ((fst_in_pair - SURROGATE_HI_START) << 10)
|
||||||
+ SURROGATE_FIRST_CHAR);
|
+ SURROGATE_FIRST_CHAR);
|
||||||
str_end += utf_char2bytes(full_char, (char_u *) str_end);
|
str_end += utf_char2bytes(full_char, (char_u *)str_end);
|
||||||
fst_in_pair = 0;
|
fst_in_pair = 0;
|
||||||
} else {
|
} else {
|
||||||
PUT_FST_IN_PAIR(fst_in_pair, str_end);
|
PUT_FST_IN_PAIR(fst_in_pair, str_end);
|
||||||
str_end += utf_char2bytes((int) ch, (char_u *) str_end);
|
str_end += utf_char2bytes((int)ch, (char_u *)str_end);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -484,13 +471,12 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
|
|||||||
['r'] = CAR,
|
['r'] = CAR,
|
||||||
['f'] = FF,
|
['f'] = FF,
|
||||||
};
|
};
|
||||||
*str_end++ = escapes[(int) *t];
|
*str_end++ = escapes[(int)*t];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
*str_end++ = *t;
|
*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);
|
PUT_FST_IN_PAIR(fst_in_pair, str_end);
|
||||||
#undef PUT_FST_IN_PAIR
|
#undef PUT_FST_IN_PAIR
|
||||||
*str_end = NUL;
|
*str_end = NUL;
|
||||||
typval_T obj = decode_string(
|
typval_T obj = decode_string(str, (size_t)(str_end - str), hasnul ? kTrue : kFalse, false, true);
|
||||||
str, (size_t)(str_end - str), hasnul ? kTrue : kFalse, false, true);
|
|
||||||
if (obj.v_type == VAR_UNKNOWN) {
|
if (obj.v_type == VAR_UNKNOWN) {
|
||||||
goto parse_json_string_fail;
|
goto parse_json_string_fail;
|
||||||
}
|
}
|
||||||
@@ -536,11 +521,9 @@ parse_json_string_ret:
|
|||||||
///
|
///
|
||||||
/// @return OK in case of success, FAIL in case of error.
|
/// @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,
|
static inline int parse_json_number(const char *const buf, const size_t buf_len,
|
||||||
const char **const pp,
|
const char **const pp, ValuesStack *const stack,
|
||||||
ValuesStack *const stack,
|
|
||||||
ContainerStack *const container_stack,
|
ContainerStack *const container_stack,
|
||||||
bool *const next_map_special,
|
bool *const next_map_special, bool *const didcomma,
|
||||||
bool *const didcomma,
|
|
||||||
bool *const didcolon)
|
bool *const didcolon)
|
||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
|
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_type = VAR_NUMBER,
|
||||||
.v_lock = VAR_UNLOCKED,
|
.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) {
|
if (fracs || exps) {
|
||||||
// Convert floating-point number
|
// Convert floating-point number
|
||||||
const size_t num_len = string2float(s, &tv.vval.v_float);
|
const size_t num_len = string2float(s, &tv.vval.v_float);
|
||||||
if (exp_num_len != num_len) {
|
if (exp_num_len != num_len) {
|
||||||
emsgf(_("E685: internal error: while converting number \"%.*s\" "
|
emsgf(_("E685: internal error: while converting number \"%.*s\" "
|
||||||
"to float string2float consumed %zu bytes in place of %zu"),
|
"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;
|
tv.v_type = VAR_FLOAT;
|
||||||
} else {
|
} else {
|
||||||
@@ -623,7 +606,7 @@ parse_json_number_check:
|
|||||||
if ((int)exp_num_len != num_len) {
|
if ((int)exp_num_len != num_len) {
|
||||||
emsgf(_("E685: internal error: while converting number \"%.*s\" "
|
emsgf(_("E685: internal error: while converting number \"%.*s\" "
|
||||||
"to integer vim_str2nr consumed %i bytes in place of %zu"),
|
"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;
|
tv.vval.v_number = nr;
|
||||||
}
|
}
|
||||||
@@ -664,8 +647,7 @@ parse_json_number_ret:
|
|||||||
/// @param[out] rettv Location where to save results.
|
/// @param[out] rettv Location where to save results.
|
||||||
///
|
///
|
||||||
/// @return OK in case of success, FAIL otherwise.
|
/// @return OK in case of success, FAIL otherwise.
|
||||||
int json_decode_string(const char *const buf, const size_t buf_len,
|
int json_decode_string(const char *const buf, const size_t buf_len, typval_T *const rettv)
|
||||||
typval_T *const rettv)
|
|
||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
const char *p = buf;
|
const char *p = buf;
|
||||||
@@ -715,7 +697,7 @@ json_decode_string_cycle_start:
|
|||||||
}
|
}
|
||||||
if (kv_size(stack) == 1) {
|
if (kv_size(stack) == 1) {
|
||||||
p++;
|
p++;
|
||||||
(void) kv_pop(container_stack);
|
(void)kv_pop(container_stack);
|
||||||
goto json_decode_string_after_cycle;
|
goto json_decode_string_after_cycle;
|
||||||
} else {
|
} else {
|
||||||
if (json_decoder_pop(kv_pop(stack), &stack, &container_stack, &p,
|
if (json_decoder_pop(kv_pop(stack), &stack, &container_stack, &p,
|
||||||
@@ -780,10 +762,9 @@ json_decode_string_cycle_start:
|
|||||||
case ' ':
|
case ' ':
|
||||||
case TAB:
|
case TAB:
|
||||||
case NL:
|
case NL:
|
||||||
case CAR: {
|
case CAR:
|
||||||
continue;
|
continue;
|
||||||
}
|
case 'n':
|
||||||
case 'n': {
|
|
||||||
if ((p + 3) >= e || strncmp(p + 1, "ull", 3) != 0) {
|
if ((p + 3) >= e || strncmp(p + 1, "ull", 3) != 0) {
|
||||||
emsgf(_("E474: Expected null: %.*s"), LENP(p, e));
|
emsgf(_("E474: Expected null: %.*s"), LENP(p, e));
|
||||||
goto json_decode_string_fail;
|
goto json_decode_string_fail;
|
||||||
@@ -795,8 +776,7 @@ json_decode_string_cycle_start:
|
|||||||
.vval = { .v_special = kSpecialVarNull },
|
.vval = { .v_special = kSpecialVarNull },
|
||||||
}), false);
|
}), false);
|
||||||
break;
|
break;
|
||||||
}
|
case 't':
|
||||||
case 't': {
|
|
||||||
if ((p + 3) >= e || strncmp(p + 1, "rue", 3) != 0) {
|
if ((p + 3) >= e || strncmp(p + 1, "rue", 3) != 0) {
|
||||||
emsgf(_("E474: Expected true: %.*s"), LENP(p, e));
|
emsgf(_("E474: Expected true: %.*s"), LENP(p, e));
|
||||||
goto json_decode_string_fail;
|
goto json_decode_string_fail;
|
||||||
@@ -808,8 +788,7 @@ json_decode_string_cycle_start:
|
|||||||
.vval = { .v_bool = kBoolVarTrue },
|
.vval = { .v_bool = kBoolVarTrue },
|
||||||
}), false);
|
}), false);
|
||||||
break;
|
break;
|
||||||
}
|
case 'f':
|
||||||
case 'f': {
|
|
||||||
if ((p + 4) >= e || strncmp(p + 1, "alse", 4) != 0) {
|
if ((p + 4) >= e || strncmp(p + 1, "alse", 4) != 0) {
|
||||||
emsgf(_("E474: Expected false: %.*s"), LENP(p, e));
|
emsgf(_("E474: Expected false: %.*s"), LENP(p, e));
|
||||||
goto json_decode_string_fail;
|
goto json_decode_string_fail;
|
||||||
@@ -821,8 +800,7 @@ json_decode_string_cycle_start:
|
|||||||
.vval = { .v_bool = kBoolVarFalse },
|
.vval = { .v_bool = kBoolVarFalse },
|
||||||
}), false);
|
}), false);
|
||||||
break;
|
break;
|
||||||
}
|
case '"':
|
||||||
case '"': {
|
|
||||||
if (parse_json_string(buf, buf_len, &p, &stack, &container_stack,
|
if (parse_json_string(buf, buf_len, &p, &stack, &container_stack,
|
||||||
&next_map_special, &didcomma, &didcolon)
|
&next_map_special, &didcomma, &didcolon)
|
||||||
== FAIL) {
|
== FAIL) {
|
||||||
@@ -833,7 +811,6 @@ json_decode_string_cycle_start:
|
|||||||
goto json_decode_string_cycle_start;
|
goto json_decode_string_cycle_start;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case '-':
|
case '-':
|
||||||
case '0':
|
case '0':
|
||||||
case '1':
|
case '1':
|
||||||
@@ -844,7 +821,7 @@ json_decode_string_cycle_start:
|
|||||||
case '6':
|
case '6':
|
||||||
case '7':
|
case '7':
|
||||||
case '8':
|
case '8':
|
||||||
case '9': {
|
case '9':
|
||||||
if (parse_json_number(buf, buf_len, &p, &stack, &container_stack,
|
if (parse_json_number(buf, buf_len, &p, &stack, &container_stack,
|
||||||
&next_map_special, &didcomma, &didcolon)
|
&next_map_special, &didcomma, &didcolon)
|
||||||
== FAIL) {
|
== FAIL) {
|
||||||
@@ -855,7 +832,6 @@ json_decode_string_cycle_start:
|
|||||||
goto json_decode_string_cycle_start;
|
goto json_decode_string_cycle_start;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case '[': {
|
case '[': {
|
||||||
list_T *list = tv_list_alloc(kListLenMayKnow);
|
list_T *list = tv_list_alloc(kListLenMayKnow);
|
||||||
tv_list_ref(list);
|
tv_list_ref(list);
|
||||||
@@ -897,11 +873,10 @@ json_decode_string_cycle_start:
|
|||||||
kv_push(stack, OBJ(tv, false, didcomma, didcolon));
|
kv_push(stack, OBJ(tv, false, didcomma, didcolon));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default:
|
||||||
emsgf(_("E474: Unidentified byte: %.*s"), LENP(p, e));
|
emsgf(_("E474: Unidentified byte: %.*s"), LENP(p, e));
|
||||||
goto json_decode_string_fail;
|
goto json_decode_string_fail;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
didcomma = false;
|
didcomma = false;
|
||||||
didcolon = false;
|
didcolon = false;
|
||||||
if (kv_size(container_stack) == 0) {
|
if (kv_size(container_stack) == 0) {
|
||||||
@@ -915,20 +890,18 @@ json_decode_string_after_cycle:
|
|||||||
case NL:
|
case NL:
|
||||||
case ' ':
|
case ' ':
|
||||||
case TAB:
|
case TAB:
|
||||||
case CAR: {
|
case CAR:
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
default: {
|
|
||||||
emsgf(_("E474: Trailing characters: %.*s"), LENP(p, e));
|
emsgf(_("E474: Trailing characters: %.*s"), LENP(p, e));
|
||||||
goto json_decode_string_fail;
|
goto json_decode_string_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (kv_size(stack) == 1 && kv_size(container_stack) == 0) {
|
if (kv_size(stack) == 1 && kv_size(container_stack) == 0) {
|
||||||
*rettv = kv_pop(stack).val;
|
*rettv = kv_pop(stack).val;
|
||||||
goto json_decode_string_ret;
|
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:
|
json_decode_string_fail:
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
while (kv_size(stack)) {
|
while (kv_size(stack)) {
|
||||||
@@ -952,15 +925,14 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
|
|||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
switch (mobj.type) {
|
switch (mobj.type) {
|
||||||
case MSGPACK_OBJECT_NIL: {
|
case MSGPACK_OBJECT_NIL:
|
||||||
*rettv = (typval_T) {
|
*rettv = (typval_T) {
|
||||||
.v_type = VAR_SPECIAL,
|
.v_type = VAR_SPECIAL,
|
||||||
.v_lock = VAR_UNLOCKED,
|
.v_lock = VAR_UNLOCKED,
|
||||||
.vval = { .v_special = kSpecialVarNull },
|
.vval = { .v_special = kSpecialVarNull },
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
case MSGPACK_OBJECT_BOOLEAN:
|
||||||
case MSGPACK_OBJECT_BOOLEAN: {
|
|
||||||
*rettv = (typval_T) {
|
*rettv = (typval_T) {
|
||||||
.v_type = VAR_BOOL,
|
.v_type = VAR_BOOL,
|
||||||
.v_lock = VAR_UNLOCKED,
|
.v_lock = VAR_UNLOCKED,
|
||||||
@@ -969,13 +941,12 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
case MSGPACK_OBJECT_POSITIVE_INTEGER:
|
||||||
case MSGPACK_OBJECT_POSITIVE_INTEGER: {
|
|
||||||
if (mobj.via.u64 <= VARNUMBER_MAX) {
|
if (mobj.via.u64 <= VARNUMBER_MAX) {
|
||||||
*rettv = (typval_T) {
|
*rettv = (typval_T) {
|
||||||
.v_type = VAR_NUMBER,
|
.v_type = VAR_NUMBER,
|
||||||
.v_lock = VAR_UNLOCKED,
|
.v_lock = VAR_UNLOCKED,
|
||||||
.vval = { .v_number = (varnumber_T) mobj.via.u64 },
|
.vval = { .v_number = (varnumber_T)mobj.via.u64 },
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
list_T *const list = tv_list_alloc(4);
|
list_T *const list = tv_list_alloc(4);
|
||||||
@@ -992,13 +963,12 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
|
|||||||
tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
|
tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case MSGPACK_OBJECT_NEGATIVE_INTEGER:
|
||||||
case MSGPACK_OBJECT_NEGATIVE_INTEGER: {
|
|
||||||
if (mobj.via.i64 >= VARNUMBER_MIN) { // -V547
|
if (mobj.via.i64 >= VARNUMBER_MIN) { // -V547
|
||||||
*rettv = (typval_T) {
|
*rettv = (typval_T) {
|
||||||
.v_type = VAR_NUMBER,
|
.v_type = VAR_NUMBER,
|
||||||
.v_lock = VAR_UNLOCKED,
|
.v_lock = VAR_UNLOCKED,
|
||||||
.vval = { .v_number = (varnumber_T) mobj.via.i64 },
|
.vval = { .v_number = (varnumber_T)mobj.via.i64 },
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
list_T *const list = tv_list_alloc(4);
|
list_T *const list = tv_list_alloc(4);
|
||||||
@@ -1015,37 +985,32 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
|
|||||||
tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
|
tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
#ifdef NVIM_MSGPACK_HAS_FLOAT32
|
#ifdef NVIM_MSGPACK_HAS_FLOAT32
|
||||||
case MSGPACK_OBJECT_FLOAT32:
|
case MSGPACK_OBJECT_FLOAT32:
|
||||||
case MSGPACK_OBJECT_FLOAT64:
|
case MSGPACK_OBJECT_FLOAT64:
|
||||||
#else
|
#else
|
||||||
case MSGPACK_OBJECT_FLOAT:
|
case MSGPACK_OBJECT_FLOAT:
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
*rettv = (typval_T) {
|
*rettv = (typval_T) {
|
||||||
.v_type = VAR_FLOAT,
|
.v_type = VAR_FLOAT,
|
||||||
.v_lock = VAR_UNLOCKED,
|
.v_lock = VAR_UNLOCKED,
|
||||||
.vval = { .v_float = mobj.via.f64 },
|
.vval = { .v_float = mobj.via.f64 },
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
case MSGPACK_OBJECT_STR:
|
||||||
case MSGPACK_OBJECT_STR: {
|
|
||||||
*rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kTrue, false,
|
*rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kTrue, false,
|
||||||
false);
|
false);
|
||||||
if (rettv->v_type == VAR_UNKNOWN) {
|
if (rettv->v_type == VAR_UNKNOWN) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case MSGPACK_OBJECT_BIN:
|
||||||
case MSGPACK_OBJECT_BIN: {
|
|
||||||
*rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kNone, true,
|
*rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kNone, true,
|
||||||
false);
|
false);
|
||||||
if (rettv->v_type == VAR_UNKNOWN) {
|
if (rettv->v_type == VAR_UNKNOWN) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case MSGPACK_OBJECT_ARRAY: {
|
case MSGPACK_OBJECT_ARRAY: {
|
||||||
list_T *const list = tv_list_alloc((ptrdiff_t)mobj.via.array.size);
|
list_T *const list = tv_list_alloc((ptrdiff_t)mobj.via.array.size);
|
||||||
tv_list_ref(list);
|
tv_list_ref(list);
|
||||||
@@ -1099,8 +1064,7 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
msgpack_to_vim_generic_map: {}
|
msgpack_to_vim_generic_map: {}
|
||||||
list_T *const list = decode_create_map_special_dict(
|
list_T *const list = decode_create_map_special_dict(rettv, (ptrdiff_t)mobj.via.map.size);
|
||||||
rettv, (ptrdiff_t)mobj.via.map.size);
|
|
||||||
for (size_t i = 0; i < mobj.via.map.size; i++) {
|
for (size_t i = 0; i < mobj.via.map.size; i++) {
|
||||||
list_T *const kv_pair = tv_list_alloc(2);
|
list_T *const kv_pair = tv_list_alloc(2);
|
||||||
tv_list_append_list(list, kv_pair);
|
tv_list_append_list(list, kv_pair);
|
||||||
@@ -1132,7 +1096,7 @@ msgpack_to_vim_generic_map: {}
|
|||||||
.v_lock = VAR_UNLOCKED,
|
.v_lock = VAR_UNLOCKED,
|
||||||
.vval = { .v_list = list },
|
.vval = { .v_list = list },
|
||||||
}));
|
}));
|
||||||
if (encode_list_write((void *) ext_val_list, mobj.via.ext.ptr,
|
if (encode_list_write((void *)ext_val_list, mobj.via.ext.ptr,
|
||||||
mobj.via.ext.size) == -1) {
|
mobj.via.ext.size) == -1) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
@@ -7,27 +7,27 @@
|
|||||||
///
|
///
|
||||||
/// Split out from eval.c.
|
/// Split out from eval.c.
|
||||||
|
|
||||||
#include <msgpack.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <msgpack.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "nvim/eval/encode.h"
|
|
||||||
#include "nvim/buffer_defs.h"
|
|
||||||
#include "nvim/eval.h"
|
|
||||||
#include "nvim/eval/typval.h"
|
|
||||||
#include "nvim/garray.h"
|
|
||||||
#include "nvim/mbyte.h"
|
|
||||||
#include "nvim/math.h"
|
|
||||||
#include "nvim/message.h"
|
|
||||||
#include "nvim/memory.h"
|
|
||||||
#include "nvim/charset.h" // vim_isprintc()
|
|
||||||
#include "nvim/macros.h"
|
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
#include "nvim/vim.h" // For _()
|
#include "nvim/buffer_defs.h"
|
||||||
#include "nvim/lib/kvec.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/eval/typval_encode.h"
|
||||||
|
#include "nvim/garray.h"
|
||||||
|
#include "nvim/lib/kvec.h"
|
||||||
|
#include "nvim/macros.h"
|
||||||
|
#include "nvim/math.h"
|
||||||
|
#include "nvim/mbyte.h"
|
||||||
|
#include "nvim/memory.h"
|
||||||
|
#include "nvim/message.h"
|
||||||
|
#include "nvim/vim.h" // For _()
|
||||||
|
|
||||||
#define ga_concat(a, b) ga_concat(a, (char_u *)b)
|
#define ga_concat(a, b) ga_concat(a, (char_u *)b)
|
||||||
#define utf_ptr2char(b) utf_ptr2char((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) {
|
if (len == 0) {
|
||||||
return 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 *const end = buf + len;
|
||||||
const char *line_end = buf;
|
const char *line_end = buf;
|
||||||
listitem_T *li = tv_list_last(list);
|
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);
|
const size_t line_length = (size_t)(line_end - buf);
|
||||||
char *str = (char *)TV_LIST_ITEM_TV(li)->vval.v_string;
|
char *str = (char *)TV_LIST_ITEM_TV(li)->vval.v_string;
|
||||||
const size_t li_len = (str == NULL ? 0 : strlen(str));
|
const size_t li_len = (str == NULL ? 0 : strlen(str));
|
||||||
TV_LIST_ITEM_TV(li)->vval.v_string = xrealloc(
|
TV_LIST_ITEM_TV(li)->vval.v_string = xrealloc(str, li_len + line_length + 1);
|
||||||
str, li_len + line_length + 1);
|
|
||||||
str = (char *)TV_LIST_ITEM_TV(li)->vval.v_string + li_len;
|
str = (char *)TV_LIST_ITEM_TV(li)->vval.v_string + li_len;
|
||||||
memcpy(str, buf, line_length);
|
memcpy(str, buf, line_length);
|
||||||
str[line_length] = 0;
|
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) {
|
while (line_end < end) {
|
||||||
const char *line_start = line_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;
|
char *str = NULL;
|
||||||
if (line_end != line_start) {
|
if (line_end != line_start) {
|
||||||
const size_t line_length = (size_t)(line_end - line_start);
|
const size_t line_length = (size_t)(line_end - line_start);
|
||||||
@@ -141,7 +140,7 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
|
|||||||
: (v.data.d.hi - 1))->hi_key },
|
: (v.data.d.hi - 1))->hi_key },
|
||||||
};
|
};
|
||||||
char *const key = encode_tv2string(&key_tv, NULL);
|
char *const key = encode_tv2string(&key_tv, NULL);
|
||||||
vim_snprintf((char *) IObuff, IOSIZE, key_msg, key);
|
vim_snprintf((char *)IObuff, IOSIZE, key_msg, key);
|
||||||
xfree(key);
|
xfree(key);
|
||||||
ga_concat(&msg_ga, IObuff);
|
ga_concat(&msg_ga, IObuff);
|
||||||
break;
|
break;
|
||||||
@@ -152,8 +151,7 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
|
|||||||
? 0
|
? 0
|
||||||
: (v.data.l.li == NULL
|
: (v.data.l.li == NULL
|
||||||
? tv_list_len(v.data.l.list) - 1
|
? tv_list_len(v.data.l.list) - 1
|
||||||
: (int)tv_list_idx_of_item(
|
: (int)tv_list_idx_of_item(v.data.l.list,
|
||||||
v.data.l.list,
|
|
||||||
TV_LIST_ITEM_PREV(v.data.l.list,
|
TV_LIST_ITEM_PREV(v.data.l.list,
|
||||||
v.data.l.li))));
|
v.data.l.li))));
|
||||||
const listitem_T *const li = (v.data.l.li == NULL
|
const listitem_T *const li = (v.data.l.li == NULL
|
||||||
@@ -173,29 +171,25 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
|
|||||||
assert(first_item != NULL);
|
assert(first_item != NULL);
|
||||||
typval_T key_tv = *TV_LIST_ITEM_TV(first_item);
|
typval_T key_tv = *TV_LIST_ITEM_TV(first_item);
|
||||||
char *const key = encode_tv2echo(&key_tv, NULL);
|
char *const key = encode_tv2echo(&key_tv, NULL);
|
||||||
vim_snprintf((char *) IObuff, IOSIZE, key_pair_msg, key, idx);
|
vim_snprintf((char *)IObuff, IOSIZE, key_pair_msg, key, idx);
|
||||||
xfree(key);
|
xfree(key);
|
||||||
ga_concat(&msg_ga, IObuff);
|
ga_concat(&msg_ga, IObuff);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kMPConvPartial: {
|
case kMPConvPartial:
|
||||||
switch (v.data.p.stage) {
|
switch (v.data.p.stage) {
|
||||||
case kMPConvPartialArgs: {
|
case kMPConvPartialArgs:
|
||||||
abort();
|
abort();
|
||||||
break;
|
break;
|
||||||
}
|
case kMPConvPartialSelf:
|
||||||
case kMPConvPartialSelf: {
|
|
||||||
ga_concat(&msg_ga, partial_arg_msg);
|
ga_concat(&msg_ga, partial_arg_msg);
|
||||||
break;
|
break;
|
||||||
}
|
case kMPConvPartialEnd:
|
||||||
case kMPConvPartialEnd: {
|
|
||||||
ga_concat(&msg_ga, partial_self_msg);
|
ga_concat(&msg_ga, partial_self_msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case kMPConvPartialList: {
|
case kMPConvPartialList: {
|
||||||
const int idx = (int)(v.data.a.arg - v.data.a.argv) - 1;
|
const int idx = (int)(v.data.a.arg - v.data.a.argv) - 1;
|
||||||
vim_snprintf((char *)IObuff, IOSIZE, partial_arg_i_msg, idx);
|
vim_snprintf((char *)IObuff, IOSIZE, partial_arg_i_msg, idx);
|
||||||
@@ -219,8 +213,7 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
|
|||||||
/// zero.
|
/// zero.
|
||||||
///
|
///
|
||||||
/// @return true in case of success, false in case of failure.
|
/// @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,
|
bool encode_vim_list_to_buf(const list_T *const list, size_t *const ret_len, char **const ret_buf)
|
||||||
char **const ret_buf)
|
|
||||||
FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
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
|
/// @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
|
/// was not a string), NOTDONE if reading was successful, but there are
|
||||||
/// more bytes to read.
|
/// more bytes to read.
|
||||||
int encode_read_from_list(ListReaderState *const state, char *const buf,
|
int encode_read_from_list(ListReaderState *const state, char *const buf, const size_t nbuf,
|
||||||
const size_t nbuf, size_t *const read_bytes)
|
size_t *const read_bytes)
|
||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
char *const buf_end = buf + nbuf;
|
char *const buf_end = buf + nbuf;
|
||||||
@@ -282,7 +275,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
|
|||||||
if (p < buf_end) {
|
if (p < buf_end) {
|
||||||
state->li = TV_LIST_ITEM_NEXT(state->list, state->li);
|
state->li = TV_LIST_ITEM_NEXT(state->list, state->li);
|
||||||
if (state->li == NULL) {
|
if (state->li == NULL) {
|
||||||
*read_bytes = (size_t) (p - buf);
|
*read_bytes = (size_t)(p - buf);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
*p++ = NL;
|
*p++ = NL;
|
||||||
@@ -305,12 +298,12 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
|
|||||||
|
|
||||||
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
|
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
|
||||||
do { \
|
do { \
|
||||||
const char *const buf_ = (const char *) buf; \
|
const char *const buf_ = (const char *)buf; \
|
||||||
if (buf == NULL) { \
|
if (buf == NULL) { \
|
||||||
ga_concat(gap, "''"); \
|
ga_concat(gap, "''"); \
|
||||||
} else { \
|
} else { \
|
||||||
const size_t len_ = (len); \
|
const size_t len_ = (len); \
|
||||||
ga_grow(gap, (int) (2 + len_ + memcnt(buf_, '\'', len_))); \
|
ga_grow(gap, (int)(2 + len_ + memcnt(buf_, '\'', len_))); \
|
||||||
ga_append(gap, '\''); \
|
ga_append(gap, '\''); \
|
||||||
for (size_t i_ = 0; i_ < len_; i_++) { \
|
for (size_t i_ = 0; i_ < len_; i_++) { \
|
||||||
if (buf_[i_] == '\'') { \
|
if (buf_[i_] == '\'') { \
|
||||||
@@ -354,7 +347,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
|
|||||||
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
|
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
|
||||||
do { \
|
do { \
|
||||||
char numbuf[NUMBUFLEN]; \
|
char numbuf[NUMBUFLEN]; \
|
||||||
vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%" PRId64, (int64_t) (num)); \
|
vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%" PRId64, (int64_t)(num)); \
|
||||||
ga_concat(gap, numbuf); \
|
ga_concat(gap, numbuf); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
@@ -363,20 +356,20 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
|
|||||||
const float_T flt_ = (flt); \
|
const float_T flt_ = (flt); \
|
||||||
switch (xfpclassify(flt_)) { \
|
switch (xfpclassify(flt_)) { \
|
||||||
case FP_NAN: { \
|
case FP_NAN: { \
|
||||||
ga_concat(gap, (char_u *) "str2float('nan')"); \
|
ga_concat(gap, (char_u *)"str2float('nan')"); \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
case FP_INFINITE: { \
|
case FP_INFINITE: { \
|
||||||
if (flt_ < 0) { \
|
if (flt_ < 0) { \
|
||||||
ga_append(gap, '-'); \
|
ga_append(gap, '-'); \
|
||||||
} \
|
} \
|
||||||
ga_concat(gap, (char_u *) "str2float('inf')"); \
|
ga_concat(gap, (char_u *)"str2float('inf')"); \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
default: { \
|
default: { \
|
||||||
char numbuf[NUMBUFLEN]; \
|
char numbuf[NUMBUFLEN]; \
|
||||||
vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \
|
vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \
|
||||||
ga_concat(gap, (char_u *) numbuf); \
|
ga_concat(gap, (char_u *)numbuf); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
@@ -466,11 +459,11 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
|
|||||||
const MPConvStackVal mpval = kv_A(*mpstack, backref); \
|
const MPConvStackVal mpval = kv_A(*mpstack, backref); \
|
||||||
if (mpval.type == conv_type) { \
|
if (mpval.type == conv_type) { \
|
||||||
if (conv_type == kMPConvDict) { \
|
if (conv_type == kMPConvDict) { \
|
||||||
if ((void *) mpval.data.d.dict == (void *) (val)) { \
|
if ((void *)mpval.data.d.dict == (void *)(val)) { \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
} else if (conv_type == kMPConvList) { \
|
} else if (conv_type == kMPConvList) { \
|
||||||
if ((void *) mpval.data.l.list == (void *) (val)) { \
|
if ((void *)mpval.data.l.list == (void *)(val)) { \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
@@ -501,11 +494,11 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
|
|||||||
const MPConvStackVal mpval = kv_A(*mpstack, backref); \
|
const MPConvStackVal mpval = kv_A(*mpstack, backref); \
|
||||||
if (mpval.type == conv_type) { \
|
if (mpval.type == conv_type) { \
|
||||||
if (conv_type == kMPConvDict) { \
|
if (conv_type == kMPConvDict) { \
|
||||||
if ((void *) mpval.data.d.dict == (void *) val) { \
|
if ((void *)mpval.data.d.dict == (void *)val) { \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
} else if (conv_type == kMPConvList) { \
|
} else if (conv_type == kMPConvList) { \
|
||||||
if ((void *) mpval.data.l.list == (void *) val) { \
|
if ((void *)mpval.data.l.list == (void *)val) { \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
@@ -577,7 +570,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
|
|||||||
default: { \
|
default: { \
|
||||||
char numbuf[NUMBUFLEN]; \
|
char numbuf[NUMBUFLEN]; \
|
||||||
vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \
|
vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%g", flt_); \
|
||||||
ga_concat(gap, (char_u *) numbuf); \
|
ga_concat(gap, (char_u *)numbuf); \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
@@ -603,8 +596,7 @@ static const char xdigits[] = "0123456789ABCDEF";
|
|||||||
/// @param[in] len Converted string length.
|
/// @param[in] len Converted string length.
|
||||||
///
|
///
|
||||||
/// @return OK in case of success, FAIL otherwise.
|
/// @return OK in case of success, FAIL otherwise.
|
||||||
static inline int convert_to_json_string(garray_T *const gap,
|
static inline int convert_to_json_string(garray_T *const gap, const char *const buf,
|
||||||
const char *const buf,
|
|
||||||
const size_t len)
|
const size_t len)
|
||||||
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_ALWAYS_INLINE
|
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_ALWAYS_INLINE
|
||||||
{
|
{
|
||||||
@@ -635,11 +627,10 @@ static inline int convert_to_json_string(garray_T *const gap,
|
|||||||
case FF:
|
case FF:
|
||||||
case CAR:
|
case CAR:
|
||||||
case '"':
|
case '"':
|
||||||
case '\\': {
|
case '\\':
|
||||||
str_len += 2;
|
str_len += 2;
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
default: {
|
|
||||||
if (ch > 0x7F && shift == 1) {
|
if (ch > 0x7F && shift == 1) {
|
||||||
emsgf(_("E474: String \"%.*s\" contains byte that does not start "
|
emsgf(_("E474: String \"%.*s\" contains byte that does not start "
|
||||||
"any UTF-8 character"),
|
"any UTF-8 character"),
|
||||||
@@ -657,14 +648,13 @@ static inline int convert_to_json_string(garray_T *const gap,
|
|||||||
str_len += shift;
|
str_len += shift;
|
||||||
} else {
|
} else {
|
||||||
str_len += ((sizeof("\\u1234") - 1)
|
str_len += ((sizeof("\\u1234") - 1)
|
||||||
* (size_t) (1 + (ch >= SURROGATE_FIRST_CHAR)));
|
* (size_t)(1 + (ch >= SURROGATE_FIRST_CHAR)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ga_append(gap, '"');
|
ga_append(gap, '"');
|
||||||
ga_grow(gap, (int) str_len);
|
ga_grow(gap, (int)str_len);
|
||||||
for (size_t i = 0; i < utf_len;) {
|
for (size_t i = 0; i < utf_len;) {
|
||||||
const int ch = utf_ptr2char(utf_buf + i);
|
const int ch = utf_ptr2char(utf_buf + i);
|
||||||
const size_t shift = (ch == 0? 1: utf_char2len(ch));
|
const size_t shift = (ch == 0? 1: utf_char2len(ch));
|
||||||
@@ -678,11 +668,10 @@ static inline int convert_to_json_string(garray_T *const gap,
|
|||||||
case FF:
|
case FF:
|
||||||
case CAR:
|
case CAR:
|
||||||
case '"':
|
case '"':
|
||||||
case '\\': {
|
case '\\':
|
||||||
ga_concat_len(gap, escapes[ch], 2);
|
ga_concat_len(gap, escapes[ch], 2);
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
default: {
|
|
||||||
if (ENCODE_RAW(ch)) {
|
if (ENCODE_RAW(ch)) {
|
||||||
ga_concat_len(gap, utf_buf + i, shift);
|
ga_concat_len(gap, utf_buf + i, shift);
|
||||||
} else if (ch < SURROGATE_FIRST_CHAR) {
|
} else if (ch < SURROGATE_FIRST_CHAR) {
|
||||||
@@ -712,7 +701,6 @@ static inline int convert_to_json_string(garray_T *const gap,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
i += shift;
|
i += shift;
|
||||||
}
|
}
|
||||||
ga_append(gap, '"');
|
ga_append(gap, '"');
|
||||||
@@ -724,7 +712,7 @@ static inline int convert_to_json_string(garray_T *const gap,
|
|||||||
#undef TYPVAL_ENCODE_CONV_STRING
|
#undef TYPVAL_ENCODE_CONV_STRING
|
||||||
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
|
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
|
||||||
do { \
|
do { \
|
||||||
if (convert_to_json_string(gap, (const char *) (buf), (len)) != OK) { \
|
if (convert_to_json_string(gap, (const char *)(buf), (len)) != OK) { \
|
||||||
return FAIL; \
|
return FAIL; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
@@ -867,10 +855,10 @@ char *encode_tv2string(typval_T *tv, size_t *len)
|
|||||||
assert(evs_ret == OK);
|
assert(evs_ret == OK);
|
||||||
did_echo_string_emsg = false;
|
did_echo_string_emsg = false;
|
||||||
if (len != NULL) {
|
if (len != NULL) {
|
||||||
*len = (size_t) ga.ga_len;
|
*len = (size_t)ga.ga_len;
|
||||||
}
|
}
|
||||||
ga_append(&ga, '\0');
|
ga_append(&ga, '\0');
|
||||||
return (char *) ga.ga_data;
|
return (char *)ga.ga_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a string with the string representation of a variable.
|
/// 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);
|
assert(eve_ret == OK);
|
||||||
}
|
}
|
||||||
if (len != NULL) {
|
if (len != NULL) {
|
||||||
*len = (size_t) ga.ga_len;
|
*len = (size_t)ga.ga_len;
|
||||||
}
|
}
|
||||||
ga_append(&ga, '\0');
|
ga_append(&ga, '\0');
|
||||||
return (char *) ga.ga_data;
|
return (char *)ga.ga_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a string with the string representation of a variable.
|
/// Return a string with the string representation of a variable.
|
||||||
@@ -951,10 +939,10 @@ char *encode_tv2json(typval_T *tv, size_t *len)
|
|||||||
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) \
|
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) \
|
||||||
do { \
|
do { \
|
||||||
if (buf == NULL) { \
|
if (buf == NULL) { \
|
||||||
msgpack_pack_ext(packer, 0, (int8_t) type); \
|
msgpack_pack_ext(packer, 0, (int8_t)type); \
|
||||||
} else { \
|
} else { \
|
||||||
const size_t len_ = (len); \
|
const size_t len_ = (len); \
|
||||||
msgpack_pack_ext(packer, len_, (int8_t) type); \
|
msgpack_pack_ext(packer, len_, (int8_t)type); \
|
||||||
msgpack_pack_ext_body(packer, buf, len_); \
|
msgpack_pack_ext_body(packer, buf, len_); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// 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
|
// 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.h"
|
||||||
|
#include "nvim/eval/executor.h"
|
||||||
|
#include "nvim/eval/typval.h"
|
||||||
|
#include "nvim/globals.h"
|
||||||
#include "nvim/message.h"
|
#include "nvim/message.h"
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
#include "nvim/globals.h"
|
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "eval/executor.c.generated.h"
|
# include "eval/executor.c.generated.h"
|
||||||
@@ -23,8 +23,7 @@ char *e_listidx = N_("E684: list index out of range: %" PRId64);
|
|||||||
/// @param[in] op Used operator.
|
/// @param[in] op Used operator.
|
||||||
///
|
///
|
||||||
/// @return OK or FAIL.
|
/// @return OK or FAIL.
|
||||||
int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
|
int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2, const char *const op)
|
||||||
const char *const op)
|
|
||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NO_SANITIZE_UNDEFINED
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NO_SANITIZE_UNDEFINED
|
||||||
{
|
{
|
||||||
// Can't do anything with a Funcref, a Dict or special value on the right.
|
// Can't do anything with a Funcref, a Dict or special value on the right.
|
||||||
@@ -35,10 +34,9 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
|
|||||||
case VAR_FUNC:
|
case VAR_FUNC:
|
||||||
case VAR_PARTIAL:
|
case VAR_PARTIAL:
|
||||||
case VAR_BOOL:
|
case VAR_BOOL:
|
||||||
case VAR_SPECIAL: {
|
case VAR_SPECIAL:
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_BLOB:
|
||||||
case VAR_BLOB: {
|
|
||||||
if (*op != '+' || tv2->v_type != VAR_BLOB) {
|
if (*op != '+' || tv2->v_type != VAR_BLOB) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -51,8 +49,7 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
case VAR_LIST:
|
||||||
case VAR_LIST: {
|
|
||||||
if (*op != '+' || tv2->v_type != VAR_LIST) {
|
if (*op != '+' || tv2->v_type != VAR_LIST) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -61,9 +58,8 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
|
|||||||
tv_list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
|
tv_list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
|
||||||
case VAR_NUMBER:
|
case VAR_NUMBER:
|
||||||
case VAR_STRING: {
|
case VAR_STRING:
|
||||||
if (tv2->v_type == VAR_LIST) {
|
if (tv2->v_type == VAR_LIST) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -77,21 +73,30 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (*op) {
|
switch (*op) {
|
||||||
case '+': f += tv2->vval.v_float; break;
|
case '+':
|
||||||
case '-': f -= tv2->vval.v_float; break;
|
f += tv2->vval.v_float; break;
|
||||||
case '*': f *= tv2->vval.v_float; break;
|
case '-':
|
||||||
case '/': f /= tv2->vval.v_float; break;
|
f -= tv2->vval.v_float; break;
|
||||||
|
case '*':
|
||||||
|
f *= tv2->vval.v_float; break;
|
||||||
|
case '/':
|
||||||
|
f /= tv2->vval.v_float; break;
|
||||||
}
|
}
|
||||||
tv_clear(tv1);
|
tv_clear(tv1);
|
||||||
tv1->v_type = VAR_FLOAT;
|
tv1->v_type = VAR_FLOAT;
|
||||||
tv1->vval.v_float = f;
|
tv1->vval.v_float = f;
|
||||||
} else {
|
} else {
|
||||||
switch (*op) {
|
switch (*op) {
|
||||||
case '+': n += tv_get_number(tv2); break;
|
case '+':
|
||||||
case '-': n -= tv_get_number(tv2); break;
|
n += tv_get_number(tv2); break;
|
||||||
case '*': n *= tv_get_number(tv2); break;
|
case '-':
|
||||||
case '/': n = num_divide(n, tv_get_number(tv2)); break;
|
n -= tv_get_number(tv2); break;
|
||||||
case '%': n = num_modulus(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);
|
tv_clear(tv1);
|
||||||
tv1->v_type = VAR_NUMBER;
|
tv1->v_type = VAR_NUMBER;
|
||||||
@@ -104,15 +109,14 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
|
|||||||
}
|
}
|
||||||
const char *tvs = tv_get_string(tv1);
|
const char *tvs = tv_get_string(tv1);
|
||||||
char numbuf[NUMBUFLEN];
|
char numbuf[NUMBUFLEN];
|
||||||
char *const s = (char *)concat_str(
|
char *const s =
|
||||||
(const char_u *)tvs, (const char_u *)tv_get_string_buf(tv2,
|
(char *)concat_str((const char_u *)tvs, (const char_u *)tv_get_string_buf(tv2,
|
||||||
numbuf));
|
numbuf));
|
||||||
tv_clear(tv1);
|
tv_clear(tv1);
|
||||||
tv1->v_type = VAR_STRING;
|
tv1->v_type = VAR_STRING;
|
||||||
tv1->vval.v_string = (char_u *)s;
|
tv1->vval.v_string = (char_u *)s;
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
|
||||||
case VAR_FLOAT: {
|
case VAR_FLOAT: {
|
||||||
if (*op == '%' || *op == '.'
|
if (*op == '%' || *op == '.'
|
||||||
|| (tv2->v_type != VAR_FLOAT
|
|| (tv2->v_type != VAR_FLOAT
|
||||||
@@ -124,18 +128,21 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
|
|||||||
? tv2->vval.v_float
|
? tv2->vval.v_float
|
||||||
: (float_T)tv_get_number(tv2));
|
: (float_T)tv_get_number(tv2));
|
||||||
switch (*op) {
|
switch (*op) {
|
||||||
case '+': tv1->vval.v_float += f; break;
|
case '+':
|
||||||
case '-': tv1->vval.v_float -= f; break;
|
tv1->vval.v_float += f; break;
|
||||||
case '*': tv1->vval.v_float *= f; break;
|
case '-':
|
||||||
case '/': tv1->vval.v_float /= f; break;
|
tv1->vval.v_float -= f; break;
|
||||||
|
case '*':
|
||||||
|
tv1->vval.v_float *= f; break;
|
||||||
|
case '/':
|
||||||
|
tv1->vval.v_float /= f; break;
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
case VAR_UNKNOWN: {
|
case VAR_UNKNOWN:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
EMSG2(_(e_letwrong), op);
|
EMSG2(_(e_letwrong), op);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// 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
|
// 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/gc.h"
|
||||||
|
#include "nvim/eval/typval.h"
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "eval/gc.c.generated.h"
|
# include "eval/gc.c.generated.h"
|
||||||
|
@@ -1,36 +1,36 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// 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
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "nvim/lib/queue.h"
|
|
||||||
#include "nvim/eval/typval.h"
|
|
||||||
#include "nvim/eval/gc.h"
|
|
||||||
#include "nvim/eval/executor.h"
|
|
||||||
#include "nvim/eval/encode.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/ascii.h"
|
||||||
#include "nvim/pos.h"
|
#include "nvim/assert.h"
|
||||||
#include "nvim/charset.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/userfunc.h"
|
||||||
#include "nvim/garray.h"
|
#include "nvim/garray.h"
|
||||||
#include "nvim/gettext.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/macros.h"
|
||||||
#include "nvim/mbyte.h"
|
#include "nvim/mbyte.h"
|
||||||
|
#include "nvim/memory.h"
|
||||||
#include "nvim/message.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
|
// TODO(ZyX-I): Move line_breakcheck out of misc1
|
||||||
#include "nvim/misc1.h" // For line_breakcheck
|
#include "nvim/misc1.h" // For line_breakcheck
|
||||||
#include "nvim/os/fileio.h"
|
#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];
|
char buf[10 + 1 + ((16 + 3) * 3) + (8 + 2) + 2];
|
||||||
// act : hex " c:" len "[]" "\n\0"
|
// act : hex " c:" len "[]" "\n\0"
|
||||||
const ListLogEntry entry = chunk->entries[i];
|
const ListLogEntry entry = chunk->entries[i];
|
||||||
const size_t snp_len = (size_t)snprintf(
|
const size_t snp_len = (size_t)snprintf(buf, sizeof(buf),
|
||||||
buf, sizeof(buf),
|
|
||||||
"%-10.10s: l:%016" PRIxPTR "[%08d] 1:%016" PRIxPTR " 2:%016" PRIxPTR
|
"%-10.10s: l:%016" PRIxPTR "[%08d] 1:%016" PRIxPTR " 2:%016" PRIxPTR
|
||||||
"\n",
|
"\n",
|
||||||
entry.action, entry.l, entry.len, entry.li1, entry.li2);
|
entry.action, entry.l, entry.len, entry.li1,
|
||||||
|
entry.li2);
|
||||||
assert(snp_len + 1 == sizeof(buf));
|
assert(snp_len + 1 == sizeof(buf));
|
||||||
const ptrdiff_t fw_ret = file_write(&fp, buf, snp_len);
|
const ptrdiff_t fw_ret = file_write(&fp, buf, snp_len);
|
||||||
if (fw_ret != (ptrdiff_t)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[out] l List to remove from.
|
||||||
/// @param[in] item First item to remove.
|
/// @param[in] item First item to remove.
|
||||||
/// @param[in] item2 Last item to remove.
|
/// @param[in] item2 Last item to remove.
|
||||||
void tv_list_drop_items(list_T *const l, listitem_T *const item,
|
void tv_list_drop_items(list_T *const l, listitem_T *const item, listitem_T *const item2)
|
||||||
listitem_T *const item2)
|
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
list_log(l, item, item2, "drop");
|
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
|
/// Like tv_list_drop_items, but also frees all removed items
|
||||||
void tv_list_remove_items(list_T *const l, listitem_T *const item,
|
void tv_list_remove_items(list_T *const l, listitem_T *const item, listitem_T *const item2)
|
||||||
listitem_T *const item2)
|
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
list_log(l, item, item2, "remove");
|
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[in] item2 Last item to move.
|
||||||
/// @param[out] tgt_l List to move to.
|
/// @param[out] tgt_l List to move to.
|
||||||
/// @param[in] cnt Number of items moved.
|
/// @param[in] cnt Number of items moved.
|
||||||
void tv_list_move_items(list_T *const l, listitem_T *const item,
|
void tv_list_move_items(list_T *const l, listitem_T *const item, listitem_T *const item2,
|
||||||
listitem_T *const item2, list_T *const tgt_l,
|
list_T *const tgt_l, const int cnt)
|
||||||
const int cnt)
|
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
list_log(l, item, item2, "move");
|
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,out] ni Item to insert.
|
||||||
/// @param[in] item Item to insert before. If NULL, inserts at the end of the
|
/// @param[in] item Item to insert before. If NULL, inserts at the end of the
|
||||||
/// list.
|
/// list.
|
||||||
void tv_list_insert(list_T *const l, listitem_T *const ni,
|
void tv_list_insert(list_T *const l, listitem_T *const ni, listitem_T *const item)
|
||||||
listitem_T *const item)
|
|
||||||
FUNC_ATTR_NONNULL_ARG(1, 2)
|
FUNC_ATTR_NONNULL_ARG(1, 2)
|
||||||
{
|
{
|
||||||
if (item == NULL) {
|
if (item == NULL) {
|
||||||
@@ -449,8 +445,7 @@ void tv_list_insert(list_T *const l, listitem_T *const ni,
|
|||||||
/// allocated listitem_T and inserted.
|
/// allocated listitem_T and inserted.
|
||||||
/// @param[in] item Item to insert before. If NULL, inserts at the end of the
|
/// @param[in] item Item to insert before. If NULL, inserts at the end of the
|
||||||
/// list.
|
/// list.
|
||||||
void tv_list_insert_tv(list_T *const l, typval_T *const tv,
|
void tv_list_insert_tv(list_T *const l, typval_T *const tv, listitem_T *const item)
|
||||||
listitem_T *const item)
|
|
||||||
{
|
{
|
||||||
listitem_T *const ni = tv_list_item_alloc();
|
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
|
/// @param[in] len Length of the appended string. May be -1, in this
|
||||||
/// case string is considered to be usual zero-terminated
|
/// case string is considered to be usual zero-terminated
|
||||||
/// string or NULL “empty” string.
|
/// string or NULL “empty” string.
|
||||||
void tv_list_append_string(list_T *const l, const char *const str,
|
void tv_list_append_string(list_T *const l, const char *const str, const ssize_t len)
|
||||||
const ssize_t len)
|
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
tv_list_append_owned_tv(l, (typval_T) {
|
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
|
/// @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.
|
/// 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,
|
list_T *tv_list_copy(const vimconv_T *const conv, list_T *const orig, const bool deep,
|
||||||
const bool deep, const int copyID)
|
const int copyID)
|
||||||
FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
if (orig == NULL) {
|
if (orig == NULL) {
|
||||||
@@ -697,8 +691,7 @@ int tv_list_flatten(list_T *list, long maxdepth)
|
|||||||
/// @param[out] l1 List to extend.
|
/// @param[out] l1 List to extend.
|
||||||
/// @param[in] l2 List to extend with.
|
/// @param[in] l2 List to extend with.
|
||||||
/// @param[in] bef If not NULL, extends before this item.
|
/// @param[in] bef If not NULL, extends before this item.
|
||||||
void tv_list_extend(list_T *const l1, list_T *const l2,
|
void tv_list_extend(list_T *const l1, list_T *const l2, listitem_T *const bef)
|
||||||
listitem_T *const bef)
|
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
int todo = tv_list_len(l2);
|
int todo = tv_list_len(l2);
|
||||||
@@ -758,8 +751,8 @@ typedef struct {
|
|||||||
/// @param[in] join_gap Garray to keep each list item string.
|
/// @param[in] join_gap Garray to keep each list item string.
|
||||||
///
|
///
|
||||||
/// @return OK in case of success, FAIL otherwise.
|
/// @return OK in case of success, FAIL otherwise.
|
||||||
static int list_join_inner(garray_T *const gap, list_T *const l,
|
static int list_join_inner(garray_T *const gap, list_T *const l, const char *const sep,
|
||||||
const char *const sep, garray_T *const join_gap)
|
garray_T *const join_gap)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
size_t sumlen = 0;
|
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.
|
/// @param[in] recursive True when used recursively.
|
||||||
///
|
///
|
||||||
/// @return True if lists are equal, false otherwise.
|
/// @return True if lists are equal, false otherwise.
|
||||||
bool tv_list_equal(list_T *const l1, list_T *const l2, const bool ic,
|
bool tv_list_equal(list_T *const l1, list_T *const l2, const bool ic, const bool recursive)
|
||||||
const bool recursive)
|
|
||||||
FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
if (l1 == l2) {
|
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
|
/// true list will not be modified. Must be initialized to false
|
||||||
/// by the caller.
|
/// by the caller.
|
||||||
void tv_list_item_sort(list_T *const l, ListSortItem *const ptrs,
|
void tv_list_item_sort(list_T *const l, ListSortItem *const ptrs,
|
||||||
const ListSorter item_compare_func,
|
const ListSorter item_compare_func, bool *errp)
|
||||||
bool *errp)
|
|
||||||
FUNC_ATTR_NONNULL_ARG(3, 4)
|
FUNC_ATTR_NONNULL_ARG(3, 4)
|
||||||
{
|
{
|
||||||
const int len = tv_list_len(l);
|
const int len = tv_list_len(l);
|
||||||
@@ -1127,18 +1118,15 @@ bool tv_callback_equal(const Callback *cb1, const Callback *cb2)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
switch (cb1->type) {
|
switch (cb1->type) {
|
||||||
case kCallbackFuncref: {
|
case kCallbackFuncref:
|
||||||
return STRCMP(cb1->data.funcref, cb2->data.funcref) == 0;
|
return STRCMP(cb1->data.funcref, cb2->data.funcref) == 0;
|
||||||
}
|
case kCallbackPartial:
|
||||||
case kCallbackPartial: {
|
|
||||||
// FIXME: this is inconsistent with tv_equal but is needed for precision
|
// FIXME: this is inconsistent with tv_equal but is needed for precision
|
||||||
// maybe change dictwatcheradd to return a watcher id instead?
|
// maybe change dictwatcheradd to return a watcher id instead?
|
||||||
return cb1->data.partial == cb2->data.partial;
|
return cb1->data.partial == cb2->data.partial;
|
||||||
}
|
case kCallbackNone:
|
||||||
case kCallbackNone: {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
abort();
|
abort();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1148,19 +1136,16 @@ void callback_free(Callback *callback)
|
|||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
switch (callback->type) {
|
switch (callback->type) {
|
||||||
case kCallbackFuncref: {
|
case kCallbackFuncref:
|
||||||
func_unref(callback->data.funcref);
|
func_unref(callback->data.funcref);
|
||||||
xfree(callback->data.funcref);
|
xfree(callback->data.funcref);
|
||||||
break;
|
break;
|
||||||
}
|
case kCallbackPartial:
|
||||||
case kCallbackPartial: {
|
|
||||||
partial_unref(callback->data.partial);
|
partial_unref(callback->data.partial);
|
||||||
break;
|
break;
|
||||||
}
|
case kCallbackNone:
|
||||||
case kCallbackNone: {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
callback->type = kCallbackNone;
|
callback->type = kCallbackNone;
|
||||||
callback->data.funcref = NULL;
|
callback->data.funcref = NULL;
|
||||||
}
|
}
|
||||||
@@ -1216,8 +1201,7 @@ void callback_copy(Callback *dest, Callback *src)
|
|||||||
///
|
///
|
||||||
/// @return True on success, false if relevant watcher was not found.
|
/// @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,
|
bool tv_dict_watcher_remove(dict_T *const dict, const char *const key_pattern,
|
||||||
const size_t key_pattern_len,
|
const size_t key_pattern_len, Callback callback)
|
||||||
Callback callback)
|
|
||||||
FUNC_ATTR_NONNULL_ARG(2)
|
FUNC_ATTR_NONNULL_ARG(2)
|
||||||
{
|
{
|
||||||
if (dict == NULL) {
|
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] key Key which was modified.
|
||||||
/// @param[in] newtv New key value.
|
/// @param[in] newtv New key value.
|
||||||
/// @param[in] oldtv Old key value.
|
/// @param[in] oldtv Old key value.
|
||||||
void tv_dict_watcher_notify(dict_T *const dict, const char *const key,
|
void tv_dict_watcher_notify(dict_T *const dict, const char *const key, typval_T *const newtv,
|
||||||
typval_T *const newtv, typval_T *const oldtv)
|
typval_T *const oldtv)
|
||||||
FUNC_ATTR_NONNULL_ARG(1, 2)
|
FUNC_ATTR_NONNULL_ARG(1, 2)
|
||||||
{
|
{
|
||||||
typval_T argv[3];
|
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.
|
/// @param[in] len Key length. If negative, then strlen(key) is used.
|
||||||
///
|
///
|
||||||
/// @return found item or NULL if nothing was found.
|
/// @return found item or NULL if nothing was found.
|
||||||
dictitem_T *tv_dict_find(const dict_T *const d, const char *const key,
|
dictitem_T *tv_dict_find(const dict_T *const d, const char *const key, const ptrdiff_t len)
|
||||||
const ptrdiff_t len)
|
|
||||||
FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
if (d == NULL) {
|
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,
|
/// @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
|
/// string item value otherwise. If returned value is not NULL, it may
|
||||||
/// be allocated depending on `save` argument.
|
/// be allocated depending on `save` argument.
|
||||||
char *tv_dict_get_string(const dict_T *const d, const char *const key,
|
char *tv_dict_get_string(const dict_T *const d, const char *const key, const bool save)
|
||||||
const bool save)
|
|
||||||
FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
static char numbuf[NUMBUFLEN];
|
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,
|
/// @return NULL if key does not exist, empty string in case of type error,
|
||||||
/// string item value otherwise.
|
/// string item value otherwise.
|
||||||
const char *tv_dict_get_string_buf(const dict_T *const d, const char *const key,
|
const char *tv_dict_get_string_buf(const dict_T *const d, const char *const key, char *const numbuf)
|
||||||
char *const numbuf)
|
|
||||||
FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
const dictitem_T *const di = tv_dict_find(d, key, -1);
|
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,
|
/// @return `def` when key does not exist,
|
||||||
/// NULL in case of type error,
|
/// NULL in case of type error,
|
||||||
/// string item value in case of success.
|
/// string item value in case of success.
|
||||||
const char *tv_dict_get_string_buf_chk(const dict_T *const d,
|
const char *tv_dict_get_string_buf_chk(const dict_T *const d, const char *const key,
|
||||||
const char *const key,
|
const ptrdiff_t key_len, char *const numbuf,
|
||||||
const ptrdiff_t key_len,
|
|
||||||
char *const numbuf,
|
|
||||||
const char *const def)
|
const char *const def)
|
||||||
FUNC_ATTR_WARN_UNUSED_RESULT
|
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.
|
/// will be left.
|
||||||
///
|
///
|
||||||
/// @return true/false on success/failure.
|
/// @return true/false on success/failure.
|
||||||
bool tv_dict_get_callback(dict_T *const d,
|
bool tv_dict_get_callback(dict_T *const d, const char *const key, const ptrdiff_t key_len,
|
||||||
const char *const key, const ptrdiff_t key_len,
|
|
||||||
Callback *const result)
|
Callback *const result)
|
||||||
FUNC_ATTR_NONNULL_ARG(2, 4) FUNC_ATTR_WARN_UNUSED_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.
|
/// @param list List to add. Will have reference count incremented.
|
||||||
///
|
///
|
||||||
/// @return OK in case of success, FAIL when key already exists.
|
/// @return OK in case of success, FAIL when key already exists.
|
||||||
int tv_dict_add_list(dict_T *const d, const char *const key,
|
int tv_dict_add_list(dict_T *const d, const char *const key, const size_t key_len,
|
||||||
const size_t key_len, list_T *const list)
|
list_T *const list)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
|
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
|
||||||
@@ -1766,8 +1744,7 @@ int tv_dict_add_list(dict_T *const d, const char *const key,
|
|||||||
/// @param[in] key_len Key length.
|
/// @param[in] key_len Key length.
|
||||||
///
|
///
|
||||||
/// @return FAIL if out of memory or key already exists.
|
/// @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,
|
int tv_dict_add_tv(dict_T *d, const char *key, const size_t key_len, typval_T *tv)
|
||||||
typval_T *tv)
|
|
||||||
{
|
{
|
||||||
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
|
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
|
||||||
|
|
||||||
@@ -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.
|
/// @param dict Dictionary to add. Will have reference count incremented.
|
||||||
///
|
///
|
||||||
/// @return OK in case of success, FAIL when key already exists.
|
/// @return OK in case of success, FAIL when key already exists.
|
||||||
int tv_dict_add_dict(dict_T *const d, const char *const key,
|
int tv_dict_add_dict(dict_T *const d, const char *const key, const size_t key_len,
|
||||||
const size_t key_len, dict_T *const dict)
|
dict_T *const dict)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
|
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.
|
/// @param[in] nr Number to add.
|
||||||
///
|
///
|
||||||
/// @return OK in case of success, FAIL when key already exists.
|
/// @return OK in case of success, FAIL when key already exists.
|
||||||
int tv_dict_add_nr(dict_T *const d, const char *const key,
|
int tv_dict_add_nr(dict_T *const d, const char *const key, const size_t key_len,
|
||||||
const size_t key_len, const varnumber_T nr)
|
const varnumber_T nr)
|
||||||
{
|
{
|
||||||
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
|
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.
|
/// @param[in] nr Floating point number to add.
|
||||||
///
|
///
|
||||||
/// @return OK in case of success, FAIL when key already exists.
|
/// @return OK in case of success, FAIL when key already exists.
|
||||||
int tv_dict_add_float(dict_T *const d, const char *const key,
|
int tv_dict_add_float(dict_T *const d, const char *const key, const size_t key_len,
|
||||||
const size_t key_len, const float_T nr)
|
const float_T nr)
|
||||||
{
|
{
|
||||||
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
|
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.
|
/// @param[in] val BoolVarValue to add.
|
||||||
///
|
///
|
||||||
/// @return OK in case of success, FAIL when key already exists.
|
/// @return OK in case of success, FAIL when key already exists.
|
||||||
int tv_dict_add_bool(dict_T *const d, const char *const key,
|
int tv_dict_add_bool(dict_T *const d, const char *const key, const size_t key_len, BoolVarValue val)
|
||||||
const size_t key_len, BoolVarValue val)
|
|
||||||
{
|
{
|
||||||
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
|
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
|
/// Add a string entry to dictionary
|
||||||
///
|
///
|
||||||
/// @see tv_dict_add_allocated_str
|
/// @see tv_dict_add_allocated_str
|
||||||
int tv_dict_add_str(dict_T *const d,
|
int tv_dict_add_str(dict_T *const d, const char *const key, const size_t key_len,
|
||||||
const char *const key, const size_t key_len,
|
|
||||||
const char *const val)
|
const char *const val)
|
||||||
FUNC_ATTR_NONNULL_ARG(1, 2)
|
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.
|
/// @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.
|
/// @return OK in case of success, FAIL when key already exists.
|
||||||
int tv_dict_add_str_len(dict_T *const d,
|
int tv_dict_add_str_len(dict_T *const d, const char *const key, const size_t key_len,
|
||||||
const char *const key, const size_t key_len,
|
|
||||||
const char *const val, int len)
|
const char *const val, int len)
|
||||||
FUNC_ATTR_NONNULL_ARG(1, 2)
|
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.
|
/// @param[in] val String to add.
|
||||||
///
|
///
|
||||||
/// @return OK in case of success, FAIL when key already exists.
|
/// @return OK in case of success, FAIL when key already exists.
|
||||||
int tv_dict_add_allocated_str(dict_T *const d,
|
int tv_dict_add_allocated_str(dict_T *const d, const char *const key, const size_t key_len,
|
||||||
const char *const key, const size_t key_len,
|
|
||||||
char *const val)
|
char *const val)
|
||||||
FUNC_ATTR_NONNULL_ARG(1, 2)
|
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.
|
/// e*, including "error": duplicate key gives an error.
|
||||||
/// f*, including "force": duplicate d2 keys override d1.
|
/// f*, including "force": duplicate d2 keys override d1.
|
||||||
/// other, including "keep": duplicate d2 keys ignored.
|
/// other, including "keep": duplicate d2 keys ignored.
|
||||||
void tv_dict_extend(dict_T *const d1, dict_T *const d2,
|
void tv_dict_extend(dict_T *const d1, dict_T *const d2, const char *const action)
|
||||||
const char *const action)
|
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
const bool watched = tv_dict_is_watched(d1);
|
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] d2 Second dictionary.
|
||||||
/// @param[in] ic True if case is to be ignored.
|
/// @param[in] ic True if case is to be ignored.
|
||||||
/// @param[in] recursive True when used recursively.
|
/// @param[in] recursive True when used recursively.
|
||||||
bool tv_dict_equal(dict_T *const d1, dict_T *const d2,
|
bool tv_dict_equal(dict_T *const d1, dict_T *const d2, const bool ic, const bool recursive)
|
||||||
const bool ic, const bool recursive)
|
|
||||||
FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
if (d1 == d2) {
|
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
|
/// @return Copied dictionary. May be NULL in case original dictionary is NULL
|
||||||
/// or some failure happens. The refcount of the new dictionary is set
|
/// or some failure happens. The refcount of the new dictionary is set
|
||||||
/// to 1.
|
/// to 1.
|
||||||
dict_T *tv_dict_copy(const vimconv_T *const conv,
|
dict_T *tv_dict_copy(const vimconv_T *const conv, dict_T *const orig, const bool deep,
|
||||||
dict_T *const orig,
|
|
||||||
const bool deep,
|
|
||||||
const int copyID)
|
const int copyID)
|
||||||
{
|
{
|
||||||
if (orig == NULL) {
|
if (orig == NULL) {
|
||||||
@@ -2326,8 +2295,7 @@ void tv_blob_copy(typval_T *const from, typval_T *const to)
|
|||||||
tv->v_lock = VAR_UNLOCKED; \
|
tv->v_lock = VAR_UNLOCKED; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static inline int _nothing_conv_func_start(typval_T *const tv,
|
static inline int _nothing_conv_func_start(typval_T *const tv, char_u *const fun)
|
||||||
char_u *const fun)
|
|
||||||
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
tv->v_lock = VAR_UNLOCKED;
|
tv->v_lock = VAR_UNLOCKED;
|
||||||
@@ -2386,8 +2354,7 @@ static inline void _nothing_conv_func_end(typval_T *const tv, const int copyID)
|
|||||||
tv->v_lock = VAR_UNLOCKED; \
|
tv->v_lock = VAR_UNLOCKED; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static inline void _nothing_conv_empty_dict(typval_T *const tv,
|
static inline void _nothing_conv_empty_dict(typval_T *const tv, dict_T **const dictp)
|
||||||
dict_T **const dictp)
|
|
||||||
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(2)
|
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(2)
|
||||||
{
|
{
|
||||||
tv_dict_unref(*dictp);
|
tv_dict_unref(*dictp);
|
||||||
@@ -2402,8 +2369,8 @@ static inline void _nothing_conv_empty_dict(typval_T *const tv,
|
|||||||
_nothing_conv_empty_dict(tv, ((dict_T **)&dict)); \
|
_nothing_conv_empty_dict(tv, ((dict_T **)&dict)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static inline int _nothing_conv_real_list_after_start(
|
static inline int _nothing_conv_real_list_after_start(typval_T *const tv,
|
||||||
typval_T *const tv, MPConvStackVal *const mpsv)
|
MPConvStackVal *const mpsv)
|
||||||
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
assert(tv != NULL);
|
assert(tv != NULL);
|
||||||
@@ -2440,8 +2407,8 @@ static inline void _nothing_conv_list_end(typval_T *const tv)
|
|||||||
}
|
}
|
||||||
#define TYPVAL_ENCODE_CONV_LIST_END(tv) _nothing_conv_list_end(tv)
|
#define TYPVAL_ENCODE_CONV_LIST_END(tv) _nothing_conv_list_end(tv)
|
||||||
|
|
||||||
static inline int _nothing_conv_real_dict_after_start(
|
static inline int _nothing_conv_real_dict_after_start(typval_T *const tv, dict_T **const dictp,
|
||||||
typval_T *const tv, dict_T **const dictp, const void *const nodictvar,
|
const void *const nodictvar,
|
||||||
MPConvStackVal *const mpsv)
|
MPConvStackVal *const mpsv)
|
||||||
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
@@ -2460,8 +2427,7 @@ static inline int _nothing_conv_real_dict_after_start(
|
|||||||
|
|
||||||
#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv) \
|
#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv) \
|
||||||
do { \
|
do { \
|
||||||
if (_nothing_conv_real_dict_after_start( \
|
if (_nothing_conv_real_dict_after_start(tv, (dict_T **)&dict, (void *)&TYPVAL_ENCODE_NODICT_VAR, \
|
||||||
tv, (dict_T **)&dict, (void *)&TYPVAL_ENCODE_NODICT_VAR, \
|
|
||||||
&mpsv) != NOTDONE) { \
|
&mpsv) != NOTDONE) { \
|
||||||
goto typval_encode_stop_converting_one_item; \
|
goto typval_encode_stop_converting_one_item; \
|
||||||
} \
|
} \
|
||||||
@@ -2471,8 +2437,7 @@ static inline int _nothing_conv_real_dict_after_start(
|
|||||||
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict)
|
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict)
|
||||||
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict)
|
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict)
|
||||||
|
|
||||||
static inline void _nothing_conv_dict_end(typval_T *const tv,
|
static inline void _nothing_conv_dict_end(typval_T *const tv, dict_T **const dictp,
|
||||||
dict_T **const dictp,
|
|
||||||
const void *const nodictvar)
|
const void *const nodictvar)
|
||||||
FUNC_ATTR_ALWAYS_INLINE
|
FUNC_ATTR_ALWAYS_INLINE
|
||||||
{
|
{
|
||||||
@@ -2554,38 +2519,31 @@ void tv_free(typval_T *tv)
|
|||||||
{
|
{
|
||||||
if (tv != NULL) {
|
if (tv != NULL) {
|
||||||
switch (tv->v_type) {
|
switch (tv->v_type) {
|
||||||
case VAR_PARTIAL: {
|
case VAR_PARTIAL:
|
||||||
partial_unref(tv->vval.v_partial);
|
partial_unref(tv->vval.v_partial);
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_FUNC:
|
||||||
case VAR_FUNC: {
|
|
||||||
func_unref(tv->vval.v_string);
|
func_unref(tv->vval.v_string);
|
||||||
FALLTHROUGH;
|
FALLTHROUGH;
|
||||||
}
|
case VAR_STRING:
|
||||||
case VAR_STRING: {
|
|
||||||
xfree(tv->vval.v_string);
|
xfree(tv->vval.v_string);
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_BLOB:
|
||||||
case VAR_BLOB: {
|
|
||||||
tv_blob_unref(tv->vval.v_blob);
|
tv_blob_unref(tv->vval.v_blob);
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_LIST:
|
||||||
case VAR_LIST: {
|
|
||||||
tv_list_unref(tv->vval.v_list);
|
tv_list_unref(tv->vval.v_list);
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_DICT:
|
||||||
case VAR_DICT: {
|
|
||||||
tv_dict_unref(tv->vval.v_dict);
|
tv_dict_unref(tv->vval.v_dict);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case VAR_BOOL:
|
case VAR_BOOL:
|
||||||
case VAR_SPECIAL:
|
case VAR_SPECIAL:
|
||||||
case VAR_NUMBER:
|
case VAR_NUMBER:
|
||||||
case VAR_FLOAT:
|
case VAR_FLOAT:
|
||||||
case VAR_UNKNOWN: {
|
case VAR_UNKNOWN:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
xfree(tv);
|
xfree(tv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2611,11 +2569,10 @@ void tv_copy(const typval_T *const from, typval_T *const to)
|
|||||||
case VAR_NUMBER:
|
case VAR_NUMBER:
|
||||||
case VAR_FLOAT:
|
case VAR_FLOAT:
|
||||||
case VAR_BOOL:
|
case VAR_BOOL:
|
||||||
case VAR_SPECIAL: {
|
case VAR_SPECIAL:
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case VAR_STRING:
|
case VAR_STRING:
|
||||||
case VAR_FUNC: {
|
case VAR_FUNC:
|
||||||
if (from->vval.v_string != NULL) {
|
if (from->vval.v_string != NULL) {
|
||||||
to->vval.v_string = vim_strsave(from->vval.v_string);
|
to->vval.v_string = vim_strsave(from->vval.v_string);
|
||||||
if (from->v_type == VAR_FUNC) {
|
if (from->v_type == VAR_FUNC) {
|
||||||
@@ -2623,34 +2580,28 @@ void tv_copy(const typval_T *const from, typval_T *const to)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_PARTIAL:
|
||||||
case VAR_PARTIAL: {
|
|
||||||
if (to->vval.v_partial != NULL) {
|
if (to->vval.v_partial != NULL) {
|
||||||
to->vval.v_partial->pt_refcount++;
|
to->vval.v_partial->pt_refcount++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_BLOB:
|
||||||
case VAR_BLOB: {
|
|
||||||
if (from->vval.v_blob != NULL) {
|
if (from->vval.v_blob != NULL) {
|
||||||
to->vval.v_blob->bv_refcount++;
|
to->vval.v_blob->bv_refcount++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_LIST:
|
||||||
case VAR_LIST: {
|
|
||||||
tv_list_ref(to->vval.v_list);
|
tv_list_ref(to->vval.v_list);
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_DICT:
|
||||||
case VAR_DICT: {
|
|
||||||
if (from->vval.v_dict != NULL) {
|
if (from->vval.v_dict != NULL) {
|
||||||
to->vval.v_dict->dv_refcount++;
|
to->vval.v_dict->dv_refcount++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_UNKNOWN:
|
||||||
case VAR_UNKNOWN: {
|
|
||||||
emsgf(_(e_intern2), "tv_copy(UNKNOWN)");
|
emsgf(_(e_intern2), "tv_copy(UNKNOWN)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//{{{2 Locks
|
//{{{2 Locks
|
||||||
@@ -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] 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
|
/// @param[in] check_refcount If true, do not lock a list or dict with a
|
||||||
/// reference count larger than 1.
|
/// reference count larger than 1.
|
||||||
void tv_item_lock(typval_T *const tv, const int deep, const bool lock,
|
void tv_item_lock(typval_T *const tv, const int deep, const bool lock, const bool check_refcount)
|
||||||
const bool check_refcount)
|
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
// TODO(ZyX-I): Make this not recursive
|
// TODO(ZyX-I): Make this not recursive
|
||||||
@@ -2729,13 +2679,11 @@ void tv_item_lock(typval_T *const tv, const int deep, const bool lock,
|
|||||||
case VAR_FUNC:
|
case VAR_FUNC:
|
||||||
case VAR_PARTIAL:
|
case VAR_PARTIAL:
|
||||||
case VAR_BOOL:
|
case VAR_BOOL:
|
||||||
case VAR_SPECIAL: {
|
case VAR_SPECIAL:
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_UNKNOWN:
|
||||||
case VAR_UNKNOWN: {
|
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#undef CHANGE_LOCK
|
#undef CHANGE_LOCK
|
||||||
recurse--;
|
recurse--;
|
||||||
}
|
}
|
||||||
@@ -2776,8 +2724,7 @@ bool tv_islocked(const typval_T *const tv)
|
|||||||
/// gettext.
|
/// gettext.
|
||||||
///
|
///
|
||||||
/// @return true if variable is locked, false otherwise.
|
/// @return true if variable is locked, false otherwise.
|
||||||
bool tv_check_lock(const typval_T *tv, const char *name,
|
bool tv_check_lock(const typval_T *tv, const char *name, size_t name_len)
|
||||||
size_t name_len)
|
|
||||||
FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
VarLockStatus lock = VAR_UNLOCKED;
|
VarLockStatus lock = VAR_UNLOCKED;
|
||||||
@@ -2810,18 +2757,15 @@ bool var_check_lock(VarLockStatus lock, const char *name, size_t name_len)
|
|||||||
{
|
{
|
||||||
const char *error_message = NULL;
|
const char *error_message = NULL;
|
||||||
switch (lock) {
|
switch (lock) {
|
||||||
case VAR_UNLOCKED: {
|
case VAR_UNLOCKED:
|
||||||
return false;
|
return false;
|
||||||
}
|
case VAR_LOCKED:
|
||||||
case VAR_LOCKED: {
|
|
||||||
error_message = N_("E741: Value is locked: %.*s");
|
error_message = N_("E741: Value is locked: %.*s");
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_FIXED:
|
||||||
case VAR_FIXED: {
|
|
||||||
error_message = N_("E742: Cannot change value of %.*s");
|
error_message = N_("E742: Cannot change value of %.*s");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
assert(error_message != NULL);
|
assert(error_message != NULL);
|
||||||
|
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
@@ -2856,8 +2800,7 @@ static int tv_equal_recurse_limit;
|
|||||||
/// @param[in] recursive True when used recursively.
|
/// @param[in] recursive True when used recursively.
|
||||||
///
|
///
|
||||||
/// @return true if values are equal.
|
/// @return true if values are equal.
|
||||||
bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic,
|
bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic, const bool recursive)
|
||||||
const bool recursive)
|
|
||||||
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
// TODO(ZyX-I): Make this not recursive
|
// TODO(ZyX-I): Make this not recursive
|
||||||
@@ -2907,15 +2850,12 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic,
|
|||||||
recursive_cnt--;
|
recursive_cnt--;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
case VAR_BLOB: {
|
case VAR_BLOB:
|
||||||
return tv_blob_equal(tv1->vval.v_blob, tv2->vval.v_blob);
|
return tv_blob_equal(tv1->vval.v_blob, tv2->vval.v_blob);
|
||||||
}
|
case VAR_NUMBER:
|
||||||
case VAR_NUMBER: {
|
|
||||||
return tv1->vval.v_number == tv2->vval.v_number;
|
return tv1->vval.v_number == tv2->vval.v_number;
|
||||||
}
|
case VAR_FLOAT:
|
||||||
case VAR_FLOAT: {
|
|
||||||
return tv1->vval.v_float == tv2->vval.v_float;
|
return tv1->vval.v_float == tv2->vval.v_float;
|
||||||
}
|
|
||||||
case VAR_STRING: {
|
case VAR_STRING: {
|
||||||
char buf1[NUMBUFLEN];
|
char buf1[NUMBUFLEN];
|
||||||
char buf2[NUMBUFLEN];
|
char buf2[NUMBUFLEN];
|
||||||
@@ -2923,18 +2863,15 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic,
|
|||||||
const char *s2 = tv_get_string_buf(tv2, buf2);
|
const char *s2 = tv_get_string_buf(tv2, buf2);
|
||||||
return mb_strcmp_ic((bool)ic, s1, s2) == 0;
|
return mb_strcmp_ic((bool)ic, s1, s2) == 0;
|
||||||
}
|
}
|
||||||
case VAR_BOOL: {
|
case VAR_BOOL:
|
||||||
return tv1->vval.v_bool == tv2->vval.v_bool;
|
return tv1->vval.v_bool == tv2->vval.v_bool;
|
||||||
}
|
case VAR_SPECIAL:
|
||||||
case VAR_SPECIAL: {
|
|
||||||
return tv1->vval.v_special == tv2->vval.v_special;
|
return tv1->vval.v_special == tv2->vval.v_special;
|
||||||
}
|
case VAR_UNKNOWN:
|
||||||
case VAR_UNKNOWN: {
|
|
||||||
// VAR_UNKNOWN can be the result of an invalid expression, let’s say it
|
// VAR_UNKNOWN can be the result of an invalid expression, let’s say it
|
||||||
// does not equal anything, not even self.
|
// does not equal anything, not even self.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
abort();
|
abort();
|
||||||
return false;
|
return false;
|
||||||
@@ -2956,43 +2893,34 @@ bool tv_check_str_or_nr(const typval_T *const tv)
|
|||||||
{
|
{
|
||||||
switch (tv->v_type) {
|
switch (tv->v_type) {
|
||||||
case VAR_NUMBER:
|
case VAR_NUMBER:
|
||||||
case VAR_STRING: {
|
case VAR_STRING:
|
||||||
return true;
|
return true;
|
||||||
}
|
case VAR_FLOAT:
|
||||||
case VAR_FLOAT: {
|
|
||||||
EMSG(_("E805: Expected a Number or a String, Float found"));
|
EMSG(_("E805: Expected a Number or a String, Float found"));
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
case VAR_PARTIAL:
|
case VAR_PARTIAL:
|
||||||
case VAR_FUNC: {
|
case VAR_FUNC:
|
||||||
EMSG(_("E703: Expected a Number or a String, Funcref found"));
|
EMSG(_("E703: Expected a Number or a String, Funcref found"));
|
||||||
return false;
|
return false;
|
||||||
}
|
case VAR_LIST:
|
||||||
case VAR_LIST: {
|
|
||||||
EMSG(_("E745: Expected a Number or a String, List found"));
|
EMSG(_("E745: Expected a Number or a String, List found"));
|
||||||
return false;
|
return false;
|
||||||
}
|
case VAR_DICT:
|
||||||
case VAR_DICT: {
|
|
||||||
EMSG(_("E728: Expected a Number or a String, Dictionary found"));
|
EMSG(_("E728: Expected a Number or a String, Dictionary found"));
|
||||||
return false;
|
return false;
|
||||||
}
|
case VAR_BLOB:
|
||||||
case VAR_BLOB: {
|
|
||||||
EMSG(_("E974: Expected a Number or a String, Blob found"));
|
EMSG(_("E974: Expected a Number or a String, Blob found"));
|
||||||
return false;
|
return false;
|
||||||
}
|
case VAR_BOOL:
|
||||||
case VAR_BOOL: {
|
|
||||||
EMSG(_("E5299: Expected a Number or a String, Boolean found"));
|
EMSG(_("E5299: Expected a Number or a String, Boolean found"));
|
||||||
return false;
|
return false;
|
||||||
}
|
case VAR_SPECIAL:
|
||||||
case VAR_SPECIAL: {
|
|
||||||
EMSG(_("E5300: Expected a Number or a String"));
|
EMSG(_("E5300: Expected a Number or a String"));
|
||||||
return false;
|
return false;
|
||||||
}
|
case VAR_UNKNOWN:
|
||||||
case VAR_UNKNOWN: {
|
|
||||||
EMSG2(_(e_intern2), "tv_check_str_or_nr(UNKNOWN)");
|
EMSG2(_(e_intern2), "tv_check_str_or_nr(UNKNOWN)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
abort();
|
abort();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -3026,20 +2954,18 @@ bool tv_check_num(const typval_T *const tv)
|
|||||||
case VAR_NUMBER:
|
case VAR_NUMBER:
|
||||||
case VAR_BOOL:
|
case VAR_BOOL:
|
||||||
case VAR_SPECIAL:
|
case VAR_SPECIAL:
|
||||||
case VAR_STRING: {
|
case VAR_STRING:
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
case VAR_FUNC:
|
case VAR_FUNC:
|
||||||
case VAR_PARTIAL:
|
case VAR_PARTIAL:
|
||||||
case VAR_LIST:
|
case VAR_LIST:
|
||||||
case VAR_DICT:
|
case VAR_DICT:
|
||||||
case VAR_FLOAT:
|
case VAR_FLOAT:
|
||||||
case VAR_BLOB:
|
case VAR_BLOB:
|
||||||
case VAR_UNKNOWN: {
|
case VAR_UNKNOWN:
|
||||||
EMSG(_(num_errors[tv->v_type]));
|
EMSG(_(num_errors[tv->v_type]));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
abort();
|
abort();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -3073,20 +2999,18 @@ bool tv_check_str(const typval_T *const tv)
|
|||||||
case VAR_NUMBER:
|
case VAR_NUMBER:
|
||||||
case VAR_BOOL:
|
case VAR_BOOL:
|
||||||
case VAR_SPECIAL:
|
case VAR_SPECIAL:
|
||||||
case VAR_STRING: {
|
case VAR_STRING:
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
case VAR_PARTIAL:
|
case VAR_PARTIAL:
|
||||||
case VAR_FUNC:
|
case VAR_FUNC:
|
||||||
case VAR_LIST:
|
case VAR_LIST:
|
||||||
case VAR_DICT:
|
case VAR_DICT:
|
||||||
case VAR_FLOAT:
|
case VAR_FLOAT:
|
||||||
case VAR_BLOB:
|
case VAR_BLOB:
|
||||||
case VAR_UNKNOWN: {
|
case VAR_UNKNOWN:
|
||||||
EMSG(_(str_errors[tv->v_type]));
|
EMSG(_(str_errors[tv->v_type]));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
abort();
|
abort();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -3130,13 +3054,11 @@ varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error)
|
|||||||
case VAR_LIST:
|
case VAR_LIST:
|
||||||
case VAR_DICT:
|
case VAR_DICT:
|
||||||
case VAR_BLOB:
|
case VAR_BLOB:
|
||||||
case VAR_FLOAT: {
|
case VAR_FLOAT:
|
||||||
EMSG(_(num_errors[tv->v_type]));
|
EMSG(_(num_errors[tv->v_type]));
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_NUMBER:
|
||||||
case VAR_NUMBER: {
|
|
||||||
return tv->vval.v_number;
|
return tv->vval.v_number;
|
||||||
}
|
|
||||||
case VAR_STRING: {
|
case VAR_STRING: {
|
||||||
varnumber_T n = 0;
|
varnumber_T n = 0;
|
||||||
if (tv->vval.v_string != NULL) {
|
if (tv->vval.v_string != NULL) {
|
||||||
@@ -3145,17 +3067,14 @@ varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error)
|
|||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
case VAR_BOOL: {
|
case VAR_BOOL:
|
||||||
return tv->vval.v_bool == kBoolVarTrue ? 1 : 0;
|
return tv->vval.v_bool == kBoolVarTrue ? 1 : 0;
|
||||||
}
|
case VAR_SPECIAL:
|
||||||
case VAR_SPECIAL: {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
case VAR_UNKNOWN:
|
||||||
case VAR_UNKNOWN: {
|
|
||||||
emsgf(_(e_intern2), "tv_get_number(UNKNOWN)");
|
emsgf(_(e_intern2), "tv_get_number(UNKNOWN)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (ret_error != NULL) {
|
if (ret_error != NULL) {
|
||||||
*ret_error = true;
|
*ret_error = true;
|
||||||
}
|
}
|
||||||
@@ -3194,46 +3113,36 @@ float_T tv_get_float(const typval_T *const tv)
|
|||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
switch (tv->v_type) {
|
switch (tv->v_type) {
|
||||||
case VAR_NUMBER: {
|
case VAR_NUMBER:
|
||||||
return (float_T)(tv->vval.v_number);
|
return (float_T)(tv->vval.v_number);
|
||||||
}
|
case VAR_FLOAT:
|
||||||
case VAR_FLOAT: {
|
|
||||||
return tv->vval.v_float;
|
return tv->vval.v_float;
|
||||||
}
|
|
||||||
case VAR_PARTIAL:
|
case VAR_PARTIAL:
|
||||||
case VAR_FUNC: {
|
case VAR_FUNC:
|
||||||
EMSG(_("E891: Using a Funcref as a Float"));
|
EMSG(_("E891: Using a Funcref as a Float"));
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_STRING:
|
||||||
case VAR_STRING: {
|
|
||||||
EMSG(_("E892: Using a String as a Float"));
|
EMSG(_("E892: Using a String as a Float"));
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_LIST:
|
||||||
case VAR_LIST: {
|
|
||||||
EMSG(_("E893: Using a List as a Float"));
|
EMSG(_("E893: Using a List as a Float"));
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_DICT:
|
||||||
case VAR_DICT: {
|
|
||||||
EMSG(_("E894: Using a Dictionary as a Float"));
|
EMSG(_("E894: Using a Dictionary as a Float"));
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_BOOL:
|
||||||
case VAR_BOOL: {
|
|
||||||
EMSG(_("E362: Using a boolean value as a Float"));
|
EMSG(_("E362: Using a boolean value as a Float"));
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_SPECIAL:
|
||||||
case VAR_SPECIAL: {
|
|
||||||
EMSG(_("E907: Using a special value as a Float"));
|
EMSG(_("E907: Using a special value as a Float"));
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_BLOB:
|
||||||
case VAR_BLOB: {
|
|
||||||
EMSG(_("E975: Using a Blob as a Float"));
|
EMSG(_("E975: Using a Blob as a Float"));
|
||||||
break;
|
break;
|
||||||
}
|
case VAR_UNKNOWN:
|
||||||
case VAR_UNKNOWN: {
|
|
||||||
emsgf(_(e_intern2), "tv_get_float(UNKNOWN)");
|
emsgf(_(e_intern2), "tv_get_float(UNKNOWN)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3265,35 +3174,30 @@ const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf)
|
|||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
switch (tv->v_type) {
|
switch (tv->v_type) {
|
||||||
case VAR_NUMBER: {
|
case VAR_NUMBER:
|
||||||
snprintf(buf, NUMBUFLEN, "%" PRIdVARNUMBER, tv->vval.v_number); // -V576
|
snprintf(buf, NUMBUFLEN, "%" PRIdVARNUMBER, tv->vval.v_number); // -V576
|
||||||
return buf;
|
return buf;
|
||||||
}
|
case VAR_STRING:
|
||||||
case VAR_STRING: {
|
|
||||||
if (tv->vval.v_string != NULL) {
|
if (tv->vval.v_string != NULL) {
|
||||||
return (const char *)tv->vval.v_string;
|
return (const char *)tv->vval.v_string;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
case VAR_BOOL:
|
||||||
case VAR_BOOL: {
|
|
||||||
STRCPY(buf, encode_bool_var_names[tv->vval.v_bool]);
|
STRCPY(buf, encode_bool_var_names[tv->vval.v_bool]);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
case VAR_SPECIAL:
|
||||||
case VAR_SPECIAL: {
|
|
||||||
STRCPY(buf, encode_special_var_names[tv->vval.v_special]);
|
STRCPY(buf, encode_special_var_names[tv->vval.v_special]);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
|
||||||
case VAR_PARTIAL:
|
case VAR_PARTIAL:
|
||||||
case VAR_FUNC:
|
case VAR_FUNC:
|
||||||
case VAR_LIST:
|
case VAR_LIST:
|
||||||
case VAR_DICT:
|
case VAR_DICT:
|
||||||
case VAR_FLOAT:
|
case VAR_FLOAT:
|
||||||
case VAR_BLOB:
|
case VAR_BLOB:
|
||||||
case VAR_UNKNOWN: {
|
case VAR_UNKNOWN:
|
||||||
EMSG(_(str_errors[tv->v_type]));
|
EMSG(_(str_errors[tv->v_type]));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
#include "nvim/ex_cmds2.h"
|
#include "nvim/ex_cmds2.h"
|
||||||
#include "nvim/ex_docmd.h"
|
#include "nvim/ex_docmd.h"
|
||||||
#include "nvim/ex_getln.h"
|
#include "nvim/ex_getln.h"
|
||||||
#include "nvim/ex_getln.h"
|
|
||||||
#include "nvim/fileio.h"
|
#include "nvim/fileio.h"
|
||||||
#include "nvim/getchar.h"
|
#include "nvim/getchar.h"
|
||||||
#include "nvim/globals.h"
|
#include "nvim/globals.h"
|
||||||
@@ -55,8 +54,7 @@ static funccall_T *current_funccal = NULL;
|
|||||||
// item in it is still being used.
|
// item in it is still being used.
|
||||||
static funccall_T *previous_funccal = NULL;
|
static funccall_T *previous_funccal = NULL;
|
||||||
|
|
||||||
static char *e_funcexts = N_(
|
static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it");
|
||||||
"E122: Function %s already exists, add ! to replace it");
|
|
||||||
static char *e_funcdict = N_("E717: Dictionary entry already exists");
|
static char *e_funcdict = N_("E717: Dictionary entry already exists");
|
||||||
static char *e_funcref = N_("E718: Funcref required");
|
static char *e_funcref = N_("E718: Funcref required");
|
||||||
static char *e_nofunc = N_("E130: Unknown function: %s");
|
static char *e_nofunc = N_("E130: Unknown function: %s");
|
||||||
@@ -67,8 +65,8 @@ void func_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get function arguments.
|
/// Get function arguments.
|
||||||
static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs,
|
static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, int *varargs,
|
||||||
int *varargs, garray_T *default_args, bool skip)
|
garray_T *default_args, bool skip)
|
||||||
{
|
{
|
||||||
bool mustend = false;
|
bool mustend = false;
|
||||||
char_u *arg = *argp;
|
char_u *arg = *argp;
|
||||||
@@ -348,8 +346,7 @@ errret:
|
|||||||
/// was not found.
|
/// was not found.
|
||||||
///
|
///
|
||||||
/// @return name of the function.
|
/// @return name of the function.
|
||||||
char_u *deref_func_name(const char *name, int *lenp,
|
char_u *deref_func_name(const char *name, int *lenp, partial_T **const partialp, bool no_autoload)
|
||||||
partial_T **const partialp, bool no_autoload)
|
|
||||||
FUNC_ATTR_NONNULL_ARG(1, 2)
|
FUNC_ATTR_NONNULL_ARG(1, 2)
|
||||||
{
|
{
|
||||||
if (partialp != NULL) {
|
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.
|
* Allocate a variable for the result of a function.
|
||||||
* Return OK or FAIL.
|
* Return OK or FAIL.
|
||||||
*/
|
*/
|
||||||
int
|
int get_func_tv(const char_u *name, // name of the function
|
||||||
get_func_tv(
|
|
||||||
const char_u *name, // name of the function
|
|
||||||
int len, // length of "name" or -1 to use strlen()
|
int len, // length of "name" or -1 to use strlen()
|
||||||
typval_T *rettv,
|
typval_T *rettv, char_u **arg, // argument, pointing to the '('
|
||||||
char_u **arg, // argument, pointing to the '('
|
|
||||||
funcexe_T *funcexe // various values
|
funcexe_T *funcexe // various values
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
char_u *argp;
|
char_u *argp;
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */
|
typval_T argvars[MAX_FUNC_ARGS + 1]; // vars for arguments
|
||||||
int argcount = 0; /* number of arguments found */
|
int argcount = 0; // number of arguments found
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the arguments.
|
* Get the arguments.
|
||||||
@@ -438,13 +432,15 @@ get_func_tv(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++argcount;
|
++argcount;
|
||||||
if (*argp != ',')
|
if (*argp != ',') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (*argp == ')')
|
}
|
||||||
|
if (*argp == ')') {
|
||||||
++argp;
|
++argp;
|
||||||
else
|
} else {
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == OK) {
|
if (ret == OK) {
|
||||||
int i = 0;
|
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
|
/// @return transformed name: either `fname_buf` or a pointer to an allocated
|
||||||
/// memory.
|
/// memory.
|
||||||
static char_u *fname_trans_sid(const char_u *const name,
|
static char_u *fname_trans_sid(const char_u *const name, char_u *const fname_buf,
|
||||||
char_u *const fname_buf,
|
|
||||||
char_u **const tofree, int *const error)
|
char_u **const tofree, int *const error)
|
||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
@@ -556,8 +551,9 @@ ufunc_T *find_func(const char_u *name)
|
|||||||
hashitem_T *hi;
|
hashitem_T *hi;
|
||||||
|
|
||||||
hi = hash_find(&func_hashtab, name);
|
hi = hash_find(&func_hashtab, name);
|
||||||
if (!HASHITEM_EMPTY(hi))
|
if (!HASHITEM_EMPTY(hi)) {
|
||||||
return HI2UF(hi);
|
return HI2UF(hi);
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -571,8 +567,9 @@ static void cat_func_name(char_u *buf, ufunc_T *fp)
|
|||||||
if (fp->uf_name[0] == K_SPECIAL) {
|
if (fp->uf_name[0] == K_SPECIAL) {
|
||||||
STRCPY(buf, "<SNR>");
|
STRCPY(buf, "<SNR>");
|
||||||
STRCAT(buf, fp->uf_name + 3);
|
STRCAT(buf, fp->uf_name + 3);
|
||||||
} else
|
} else {
|
||||||
STRCPY(buf, fp->uf_name);
|
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)
|
if (may_free_fc && fc->l_varlist.lv_refcount // NOLINT(runtime/deprecated)
|
||||||
== DO_NOT_FREE_CNT) {
|
== DO_NOT_FREE_CNT) {
|
||||||
fc->l_varlist.lv_first = NULL; // NOLINT(runtime/deprecated)
|
fc->l_varlist.lv_first = NULL; // NOLINT(runtime/deprecated)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
free_fc = false;
|
free_fc = false;
|
||||||
|
|
||||||
@@ -807,9 +803,8 @@ static void func_clear_free(ufunc_T *fp, bool force)
|
|||||||
/// @param[in] firstline First line of range.
|
/// @param[in] firstline First line of range.
|
||||||
/// @param[in] lastline Last line of range.
|
/// @param[in] lastline Last line of range.
|
||||||
/// @param selfdict Dictionary for "self" for dictionary functions.
|
/// @param selfdict Dictionary for "self" for dictionary functions.
|
||||||
void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
|
void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv,
|
||||||
typval_T *rettv, linenr_T firstline, linenr_T lastline,
|
linenr_T firstline, linenr_T lastline, dict_T *selfdict)
|
||||||
dict_T *selfdict)
|
|
||||||
FUNC_ATTR_NONNULL_ARG(1, 3, 4)
|
FUNC_ATTR_NONNULL_ARG(1, 3, 4)
|
||||||
{
|
{
|
||||||
char_u *save_sourcing_name;
|
char_u *save_sourcing_name;
|
||||||
@@ -1153,19 +1148,19 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
|
|||||||
++no_wait_return;
|
++no_wait_return;
|
||||||
verbose_enter_scroll();
|
verbose_enter_scroll();
|
||||||
|
|
||||||
if (aborting())
|
if (aborting()) {
|
||||||
smsg(_("%s aborted"), sourcing_name);
|
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 ""),
|
smsg(_("%s returning #%" PRId64 ""),
|
||||||
sourcing_name, (int64_t)fc->rettv->vval.v_number);
|
sourcing_name, (int64_t)fc->rettv->vval.v_number);
|
||||||
else {
|
} else {
|
||||||
char_u buf[MSG_BUF_LEN];
|
char_u buf[MSG_BUF_LEN];
|
||||||
|
|
||||||
// The value may be very long. Skip the middle part, so that we
|
// The value may be very long. Skip the middle part, so that we
|
||||||
// have some idea how it starts and ends. smsg() would always
|
// have some idea how it starts and ends. smsg() would always
|
||||||
// truncate it at the end. Don't want errors such as E724 here.
|
// truncate it at the end. Don't want errors such as E724 here.
|
||||||
emsg_off++;
|
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;
|
char_u *tofree = s;
|
||||||
emsg_off--;
|
emsg_off--;
|
||||||
if (s != NULL) {
|
if (s != NULL) {
|
||||||
@@ -1357,8 +1352,7 @@ static bool builtin_function(const char *name, int len)
|
|||||||
return p == NULL;
|
return p == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int func_call(char_u *name, typval_T *args, partial_T *partial,
|
int func_call(char_u *name, typval_T *args, partial_T *partial, dict_T *selfdict, typval_T *rettv)
|
||||||
dict_T *selfdict, typval_T *rettv)
|
|
||||||
{
|
{
|
||||||
typval_T argv[MAX_FUNC_ARGS + 1];
|
typval_T argv[MAX_FUNC_ARGS + 1];
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
@@ -1426,9 +1420,8 @@ static void user_func_error(int error, const char_u *name)
|
|||||||
|
|
||||||
/// Used by call_func to add a method base (if any) to a function argument list
|
/// Used by call_func to add a method base (if any) to a function argument list
|
||||||
/// as the first argument. @see call_func
|
/// as the first argument. @see call_func
|
||||||
static void argv_add_base(typval_T *const basetv, typval_T **const argvars,
|
static void argv_add_base(typval_T *const basetv, typval_T **const argvars, int *const argcount,
|
||||||
int *const argcount, typval_T *const new_argvars,
|
typval_T *const new_argvars, int *const argv_base)
|
||||||
int *const argv_base)
|
|
||||||
FUNC_ATTR_NONNULL_ARG(2, 3, 4, 5)
|
FUNC_ATTR_NONNULL_ARG(2, 3, 4, 5)
|
||||||
{
|
{
|
||||||
if (basetv != NULL) {
|
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
|
/// @return FAIL if function cannot be called, else OK (even if an error
|
||||||
/// occurred while executing the function! Set `msg_list` to capture
|
/// occurred while executing the function! Set `msg_list` to capture
|
||||||
/// the error, see do_cmdline()).
|
/// the error, see do_cmdline()).
|
||||||
int
|
int call_func(const char_u *funcname, // name of the function
|
||||||
call_func(
|
|
||||||
const char_u *funcname, // name of the function
|
|
||||||
int len, // length of "name" or -1 to use strlen()
|
int len, // length of "name" or -1 to use strlen()
|
||||||
typval_T *rettv, // [out] value goes here
|
typval_T *rettv, // [out] value goes here
|
||||||
int argcount_in, // number of "argvars"
|
int argcount_in, // number of "argvars"
|
||||||
typval_T *argvars_in, // vars for arguments, must have "argcount"
|
typval_T *argvars_in, // vars for arguments, must have "argcount"
|
||||||
// PLUS ONE elements!
|
// PLUS ONE elements!
|
||||||
funcexe_T *funcexe // more arguments
|
funcexe_T *funcexe // more arguments
|
||||||
)
|
)
|
||||||
FUNC_ATTR_NONNULL_ARG(1, 3, 5, 6)
|
FUNC_ATTR_NONNULL_ARG(1, 3, 5, 6)
|
||||||
{
|
{
|
||||||
int ret = FAIL;
|
int ret = FAIL;
|
||||||
@@ -1612,8 +1603,9 @@ call_func(
|
|||||||
*/
|
*/
|
||||||
update_force_abort();
|
update_force_abort();
|
||||||
}
|
}
|
||||||
if (error == ERROR_NONE)
|
if (error == ERROR_NONE) {
|
||||||
ret = OK;
|
ret = OK;
|
||||||
|
}
|
||||||
|
|
||||||
theend:
|
theend:
|
||||||
// Report an error unless the argument evaluation or function call has been
|
// 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)
|
static void list_func_head(ufunc_T *fp, int indent, bool force)
|
||||||
{
|
{
|
||||||
msg_start();
|
msg_start();
|
||||||
if (indent)
|
if (indent) {
|
||||||
MSG_PUTS(" ");
|
MSG_PUTS(" ");
|
||||||
|
}
|
||||||
MSG_PUTS(force ? "function! " : "function ");
|
MSG_PUTS(force ? "function! " : "function ");
|
||||||
if (fp->uf_name[0] == K_SPECIAL) {
|
if (fp->uf_name[0] == K_SPECIAL) {
|
||||||
MSG_PUTS_ATTR("<SNR>", HL_ATTR(HLF_8));
|
MSG_PUTS_ATTR("<SNR>", HL_ATTR(HLF_8));
|
||||||
@@ -1698,14 +1691,10 @@ static void list_func_head(ufunc_T *fp, int indent, bool force)
|
|||||||
/// Advances "pp" to just after the function name (if no error).
|
/// Advances "pp" to just after the function name (if no error).
|
||||||
///
|
///
|
||||||
/// @return the function name in allocated memory, or NULL for failure.
|
/// @return the function name in allocated memory, or NULL for failure.
|
||||||
char_u *
|
char_u *trans_function_name(char_u **pp, bool skip, // only find the end, don't evaluate
|
||||||
trans_function_name(
|
int flags, funcdict_T *fdp, // return: info about dictionary used
|
||||||
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
|
partial_T **partial // return: partial of a FuncRef
|
||||||
)
|
)
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
char_u *name = NULL;
|
char_u *name = NULL;
|
||||||
@@ -1715,8 +1704,9 @@ trans_function_name(
|
|||||||
int len;
|
int len;
|
||||||
lval_T lv;
|
lval_T lv;
|
||||||
|
|
||||||
if (fdp != NULL)
|
if (fdp != NULL) {
|
||||||
memset(fdp, 0, sizeof(funcdict_T));
|
memset(fdp, 0, sizeof(funcdict_T));
|
||||||
|
}
|
||||||
start = *pp;
|
start = *pp;
|
||||||
|
|
||||||
/* Check for hard coded <SNR>: already translated function ID (from a user
|
/* 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,
|
end = get_lval((char_u *)start, NULL, &lv, false, skip, flags | GLV_READ_ONLY,
|
||||||
lead > 2 ? 0 : FNE_CHECK_START);
|
lead > 2 ? 0 : FNE_CHECK_START);
|
||||||
if (end == start) {
|
if (end == start) {
|
||||||
if (!skip)
|
if (!skip) {
|
||||||
EMSG(_("E129: Function name required"));
|
EMSG(_("E129: Function name required"));
|
||||||
|
}
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) {
|
if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) {
|
||||||
@@ -1806,7 +1797,7 @@ trans_function_name(
|
|||||||
goto theend;
|
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) {
|
if (lv.ll_exp_name != NULL) {
|
||||||
len = (int)strlen(lv.ll_exp_name);
|
len = (int)strlen(lv.ll_exp_name);
|
||||||
name = deref_func_name(lv.ll_exp_name, &len, partial,
|
name = deref_func_name(lv.ll_exp_name, &len, partial,
|
||||||
@@ -1992,15 +1983,17 @@ void ex_function(exarg_T *eap)
|
|||||||
--todo;
|
--todo;
|
||||||
fp = HI2UF(hi);
|
fp = HI2UF(hi);
|
||||||
if (!isdigit(*fp->uf_name)
|
if (!isdigit(*fp->uf_name)
|
||||||
&& vim_regexec(®match, fp->uf_name, 0))
|
&& vim_regexec(®match, fp->uf_name, 0)) {
|
||||||
list_func_head(fp, false, false);
|
list_func_head(fp, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
vim_regfree(regmatch.regprog);
|
vim_regfree(regmatch.regprog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*p == '/')
|
if (*p == '/') {
|
||||||
++p;
|
++p;
|
||||||
|
}
|
||||||
eap->nextcmd = check_nextcmd(p);
|
eap->nextcmd = check_nextcmd(p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2034,9 +2027,10 @@ void ex_function(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
xfree(fudi.fd_newkey);
|
xfree(fudi.fd_newkey);
|
||||||
return;
|
return;
|
||||||
} else
|
} else {
|
||||||
eap->skip = TRUE;
|
eap->skip = TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* An error in a function call during evaluation of an expression in magic
|
/* An error in a function call during evaluation of an expression in magic
|
||||||
* braces should not cause the function not to be defined. */
|
* braces should not cause the function not to be defined. */
|
||||||
@@ -2055,8 +2049,9 @@ void ex_function(exarg_T *eap)
|
|||||||
goto ret_free;
|
goto ret_free;
|
||||||
}
|
}
|
||||||
eap->nextcmd = check_nextcmd(p);
|
eap->nextcmd = check_nextcmd(p);
|
||||||
if (eap->nextcmd != NULL)
|
if (eap->nextcmd != NULL) {
|
||||||
*p = NUL;
|
*p = NUL;
|
||||||
|
}
|
||||||
if (!eap->skip && !got_int) {
|
if (!eap->skip && !got_int) {
|
||||||
fp = find_func(name);
|
fp = find_func(name);
|
||||||
if (fp != NULL) {
|
if (fp != NULL) {
|
||||||
@@ -2083,9 +2078,10 @@ void ex_function(exarg_T *eap)
|
|||||||
msg_putchar('\n');
|
msg_putchar('\n');
|
||||||
msg_puts(eap->forceit ? "endfunction" : " endfunction");
|
msg_puts(eap->forceit ? "endfunction" : " endfunction");
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
emsg_funcname(N_("E123: Undefined function: %s"), name);
|
emsg_funcname(N_("E123: Undefined function: %s"), name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
goto ret_free;
|
goto ret_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2111,18 +2107,21 @@ void ex_function(exarg_T *eap)
|
|||||||
if (!eap->skip) {
|
if (!eap->skip) {
|
||||||
/* Check the name of the function. Unless it's a dictionary function
|
/* Check the name of the function. Unless it's a dictionary function
|
||||||
* (that we are overwriting). */
|
* (that we are overwriting). */
|
||||||
if (name != NULL)
|
if (name != NULL) {
|
||||||
arg = name;
|
arg = name;
|
||||||
else
|
} else {
|
||||||
arg = fudi.fd_newkey;
|
arg = fudi.fd_newkey;
|
||||||
|
}
|
||||||
if (arg != NULL && (fudi.fd_di == NULL || !tv_is_func(fudi.fd_di->di_tv))) {
|
if (arg != NULL && (fudi.fd_di == NULL || !tv_is_func(fudi.fd_di->di_tv))) {
|
||||||
int j = (*arg == K_SPECIAL) ? 3 : 0;
|
int j = (*arg == K_SPECIAL) ? 3 : 0;
|
||||||
while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j])
|
while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j])
|
||||||
: eval_isnamec(arg[j])))
|
: eval_isnamec(arg[j]))) {
|
||||||
++j;
|
++j;
|
||||||
if (arg[j] != NUL)
|
}
|
||||||
|
if (arg[j] != NUL) {
|
||||||
emsg_funcname((char *)e_invarg2, arg);
|
emsg_funcname((char *)e_invarg2, arg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Disallow using the g: dict.
|
// Disallow using the g: dict.
|
||||||
if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE) {
|
if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE) {
|
||||||
EMSG(_("E862: Cannot use g: here"));
|
EMSG(_("E862: Cannot use g: here"));
|
||||||
@@ -2181,14 +2180,16 @@ void ex_function(exarg_T *eap)
|
|||||||
* whole function before telling him it doesn't work! For a script we
|
* 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. */
|
* need to skip the body to be able to find what follows. */
|
||||||
if (!eap->skip && !eap->forceit) {
|
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));
|
EMSG(_(e_funcdict));
|
||||||
else if (name != NULL && find_func(name) != NULL)
|
} else if (name != NULL && find_func(name) != NULL) {
|
||||||
emsg_funcname(e_funcexts, name);
|
emsg_funcname(e_funcexts, name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!eap->skip && did_emsg)
|
if (!eap->skip && did_emsg) {
|
||||||
goto erret;
|
goto erret;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ui_has(kUICmdline)) {
|
if (!ui_has(kUICmdline)) {
|
||||||
msg_putchar('\n'); // don't overwrite the function name
|
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.
|
// Use eap->arg, split up in parts by line breaks.
|
||||||
theline = line_arg;
|
theline = line_arg;
|
||||||
p = vim_strchr(theline, '\n');
|
p = vim_strchr(theline, '\n');
|
||||||
if (p == NULL)
|
if (p == NULL) {
|
||||||
line_arg += STRLEN(line_arg);
|
line_arg += STRLEN(line_arg);
|
||||||
else {
|
} else {
|
||||||
*p = NUL;
|
*p = NUL;
|
||||||
line_arg = p + 1;
|
line_arg = p + 1;
|
||||||
}
|
}
|
||||||
@@ -2306,13 +2307,14 @@ void ex_function(exarg_T *eap)
|
|||||||
|
|
||||||
/* Increase indent inside "if", "while", "for" and "try", decrease
|
/* Increase indent inside "if", "while", "for" and "try", decrease
|
||||||
* at "end". */
|
* at "end". */
|
||||||
if (indent > 2 && STRNCMP(p, "end", 3) == 0)
|
if (indent > 2 && STRNCMP(p, "end", 3) == 0) {
|
||||||
indent -= 2;
|
indent -= 2;
|
||||||
else if (STRNCMP(p, "if", 2) == 0
|
} else if (STRNCMP(p, "if", 2) == 0
|
||||||
|| STRNCMP(p, "wh", 2) == 0
|
|| STRNCMP(p, "wh", 2) == 0
|
||||||
|| STRNCMP(p, "for", 3) == 0
|
|| STRNCMP(p, "for", 3) == 0
|
||||||
|| STRNCMP(p, "try", 3) == 0)
|
|| STRNCMP(p, "try", 3) == 0) {
|
||||||
indent += 2;
|
indent += 2;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for defining a function inside this function.
|
// Check for defining a function inside this function.
|
||||||
if (checkforcmd(&p, "function", 2)) {
|
if (checkforcmd(&p, "function", 2)) {
|
||||||
@@ -2362,11 +2364,12 @@ void ex_function(exarg_T *eap)
|
|||||||
&& (!ASCII_ISALPHA(p[2]) || p[2] == 's')))) {
|
&& (!ASCII_ISALPHA(p[2]) || p[2] == 's')))) {
|
||||||
// ":python <<" continues until a dot, like ":append"
|
// ":python <<" continues until a dot, like ":append"
|
||||||
p = skipwhite(arg + 2);
|
p = skipwhite(arg + 2);
|
||||||
if (*p == NUL)
|
if (*p == NUL) {
|
||||||
skip_until = vim_strsave((char_u *)".");
|
skip_until = vim_strsave((char_u *)".");
|
||||||
else
|
} else {
|
||||||
skip_until = vim_strsave(p);
|
skip_until = vim_strsave(p);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check for ":let v =<< [trim] EOF"
|
// Check for ":let v =<< [trim] EOF"
|
||||||
// and ":let [a, b] =<< [trim] EOF"
|
// and ":let [a, b] =<< [trim] EOF"
|
||||||
@@ -2408,8 +2411,9 @@ void ex_function(exarg_T *eap)
|
|||||||
|
|
||||||
/* Add NULL lines for continuation lines, so that the line count is
|
/* Add NULL lines for continuation lines, so that the line count is
|
||||||
* equal to the index in the growarray. */
|
* 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;
|
((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for end of eap->arg.
|
// Check for end of eap->arg.
|
||||||
if (line_arg != NULL && *line_arg == NUL) {
|
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
|
/* Don't define the function when skipping commands or when an error was
|
||||||
* detected. */
|
* detected. */
|
||||||
if (eap->skip || did_emsg)
|
if (eap->skip || did_emsg) {
|
||||||
goto erret;
|
goto erret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there are no errors, add the function
|
* If there are no errors, add the function
|
||||||
@@ -2503,13 +2508,13 @@ void ex_function(exarg_T *eap)
|
|||||||
plen = (int)STRLEN(p);
|
plen = (int)STRLEN(p);
|
||||||
slen = (int)STRLEN(sourcing_name);
|
slen = (int)STRLEN(sourcing_name);
|
||||||
if (slen > plen && fnamecmp(p,
|
if (slen > plen && fnamecmp(p,
|
||||||
sourcing_name + slen - plen) == 0)
|
sourcing_name + slen - plen) == 0) {
|
||||||
j = OK;
|
j = OK;
|
||||||
|
}
|
||||||
xfree(scriptname);
|
xfree(scriptname);
|
||||||
}
|
}
|
||||||
if (j == FAIL) {
|
if (j == FAIL) {
|
||||||
EMSG2(_(
|
EMSG2(_("E746: Function name does not match script file name: %s"),
|
||||||
"E746: Function name does not match script file name: %s"),
|
|
||||||
name);
|
name);
|
||||||
goto erret;
|
goto erret;
|
||||||
}
|
}
|
||||||
@@ -2660,10 +2665,12 @@ char_u *get_user_func_name(expand_T *xp, int idx)
|
|||||||
}
|
}
|
||||||
assert(hi);
|
assert(hi);
|
||||||
if (done < func_hashtab.ht_used) {
|
if (done < func_hashtab.ht_used) {
|
||||||
if (done++ > 0)
|
if (done++ > 0) {
|
||||||
++hi;
|
++hi;
|
||||||
while (HASHITEM_EMPTY(hi))
|
}
|
||||||
|
while (HASHITEM_EMPTY(hi)) {
|
||||||
++hi;
|
++hi;
|
||||||
|
}
|
||||||
fp = HI2UF(hi);
|
fp = HI2UF(hi);
|
||||||
|
|
||||||
if ((fp->uf_flags & FC_DICT)
|
if ((fp->uf_flags & FC_DICT)
|
||||||
@@ -2678,9 +2685,10 @@ char_u *get_user_func_name(expand_T *xp, int idx)
|
|||||||
cat_func_name(IObuff, fp);
|
cat_func_name(IObuff, fp);
|
||||||
if (xp->xp_context != EXPAND_USER_FUNC) {
|
if (xp->xp_context != EXPAND_USER_FUNC) {
|
||||||
STRCAT(IObuff, "(");
|
STRCAT(IObuff, "(");
|
||||||
if (!fp->uf_varargs && GA_EMPTY(&fp->uf_args))
|
if (!fp->uf_varargs && GA_EMPTY(&fp->uf_args)) {
|
||||||
STRCAT(IObuff, ")");
|
STRCAT(IObuff, ")");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return IObuff;
|
return IObuff;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -2698,8 +2706,9 @@ void ex_delfunction(exarg_T *eap)
|
|||||||
name = trans_function_name(&p, eap->skip, 0, &fudi, NULL);
|
name = trans_function_name(&p, eap->skip, 0, &fudi, NULL);
|
||||||
xfree(fudi.fd_newkey);
|
xfree(fudi.fd_newkey);
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
if (fudi.fd_dict != NULL && !eap->skip)
|
if (fudi.fd_dict != NULL && !eap->skip) {
|
||||||
EMSG(_(e_funcref));
|
EMSG(_(e_funcref));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!ends_excmd(*skipwhite(p))) {
|
if (!ends_excmd(*skipwhite(p))) {
|
||||||
@@ -2708,11 +2717,13 @@ void ex_delfunction(exarg_T *eap)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
eap->nextcmd = check_nextcmd(p);
|
eap->nextcmd = check_nextcmd(p);
|
||||||
if (eap->nextcmd != NULL)
|
if (eap->nextcmd != NULL) {
|
||||||
*p = NUL;
|
*p = NUL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!eap->skip)
|
if (!eap->skip) {
|
||||||
fp = find_func(name);
|
fp = find_func(name);
|
||||||
|
}
|
||||||
xfree(name);
|
xfree(name);
|
||||||
|
|
||||||
if (!eap->skip) {
|
if (!eap->skip) {
|
||||||
@@ -2869,8 +2880,9 @@ void ex_return(exarg_T *eap)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eap->skip)
|
if (eap->skip) {
|
||||||
++emsg_skip;
|
++emsg_skip;
|
||||||
|
}
|
||||||
|
|
||||||
eap->nextcmd = NULL;
|
eap->nextcmd = NULL;
|
||||||
if ((*arg != NUL && *arg != '|' && *arg != '\n')
|
if ((*arg != NUL && *arg != '|' && *arg != '\n')
|
||||||
@@ -2900,8 +2912,9 @@ void ex_return(exarg_T *eap)
|
|||||||
eap->nextcmd = check_nextcmd(arg);
|
eap->nextcmd = check_nextcmd(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eap->skip)
|
if (eap->skip) {
|
||||||
--emsg_skip;
|
--emsg_skip;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(ZyX-I): move to eval/ex_cmds
|
// TODO(ZyX-I): move to eval/ex_cmds
|
||||||
@@ -3063,12 +3076,12 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
|
|||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
cstack->cs_pending[idx] = CSTP_RETURN;
|
cstack->cs_pending[idx] = CSTP_RETURN;
|
||||||
|
|
||||||
if (!is_cmd && !reanimate)
|
if (!is_cmd && !reanimate) {
|
||||||
/* A pending return again gets pending. "rettv" points to an
|
/* A pending return again gets pending. "rettv" points to an
|
||||||
* allocated variable with the rettv of the original ":return"'s
|
* allocated variable with the rettv of the original ":return"'s
|
||||||
* argument if present or is NULL else. */
|
* argument if present or is NULL else. */
|
||||||
cstack->cs_rettv[idx] = rettv;
|
cstack->cs_rettv[idx] = rettv;
|
||||||
else {
|
} else {
|
||||||
/* When undoing a return in order to make it pending, get the stored
|
/* When undoing a return in order to make it pending, get the stored
|
||||||
* return rettv. */
|
* return rettv. */
|
||||||
if (reanimate) {
|
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.
|
// Store the value of the pending return.
|
||||||
cstack->cs_rettv[idx] = xcalloc(1, sizeof(typval_T));
|
cstack->cs_rettv[idx] = xcalloc(1, sizeof(typval_T));
|
||||||
*(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv;
|
*(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv;
|
||||||
} else
|
} else {
|
||||||
cstack->cs_rettv[idx] = NULL;
|
cstack->cs_rettv[idx] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (reanimate) {
|
if (reanimate) {
|
||||||
/* The pending return value could be overwritten by a ":return"
|
/* The pending return value could be overwritten by a ":return"
|
||||||
@@ -3101,10 +3115,11 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
|
|||||||
if (!reanimate && rettv != NULL) {
|
if (!reanimate && rettv != NULL) {
|
||||||
tv_clear(current_funccal->rettv);
|
tv_clear(current_funccal->rettv);
|
||||||
*current_funccal->rettv = *(typval_T *)rettv;
|
*current_funccal->rettv = *(typval_T *)rettv;
|
||||||
if (!is_cmd)
|
if (!is_cmd) {
|
||||||
xfree(rettv);
|
xfree(rettv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return idx < 0;
|
return idx < 0;
|
||||||
}
|
}
|
||||||
@@ -3119,7 +3134,7 @@ char_u *get_return_cmd(void *rettv)
|
|||||||
char_u *tofree = NULL;
|
char_u *tofree = NULL;
|
||||||
|
|
||||||
if (rettv != 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) {
|
if (s == NULL) {
|
||||||
s = (char_u *)"";
|
s = (char_u *)"";
|
||||||
@@ -3127,8 +3142,9 @@ char_u *get_return_cmd(void *rettv)
|
|||||||
|
|
||||||
STRCPY(IObuff, ":return ");
|
STRCPY(IObuff, ":return ");
|
||||||
STRLCPY(IObuff + 8, s, IOSIZE - 8);
|
STRLCPY(IObuff + 8, s, IOSIZE - 8);
|
||||||
if (STRLEN(s) + 8 >= IOSIZE)
|
if (STRLEN(s) + 8 >= IOSIZE) {
|
||||||
STRCPY(IObuff + IOSIZE - 4, "...");
|
STRCPY(IObuff + IOSIZE - 4, "...");
|
||||||
|
}
|
||||||
xfree(tofree);
|
xfree(tofree);
|
||||||
return vim_strsave(IObuff);
|
return vim_strsave(IObuff);
|
||||||
}
|
}
|
||||||
@@ -3151,8 +3167,9 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
|
|||||||
sourcing_lnum);
|
sourcing_lnum);
|
||||||
fcp->dbg_tick = debug_tick;
|
fcp->dbg_tick = debug_tick;
|
||||||
}
|
}
|
||||||
if (do_profiling == PROF_YES)
|
if (do_profiling == PROF_YES) {
|
||||||
func_line_end(cookie);
|
func_line_end(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
gap = &fp->uf_lines;
|
gap = &fp->uf_lines;
|
||||||
if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
|
if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
|
||||||
@@ -3169,10 +3186,11 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
|
|||||||
} else {
|
} else {
|
||||||
retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
|
retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
|
||||||
sourcing_lnum = fcp->linenr;
|
sourcing_lnum = fcp->linenr;
|
||||||
if (do_profiling == PROF_YES)
|
if (do_profiling == PROF_YES) {
|
||||||
func_line_start(cookie);
|
func_line_start(cookie);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Did we encounter a breakpoint?
|
// Did we encounter a breakpoint?
|
||||||
if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) {
|
if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) {
|
||||||
@@ -3448,8 +3466,7 @@ hashitem_T *find_hi_in_scoped_ht(const char *name, hashtab_T **pht)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Search variable in parent scope.
|
/// Search variable in parent scope.
|
||||||
dictitem_T *find_var_in_scoped_ht(const char *name, const size_t namelen,
|
dictitem_T *find_var_in_scoped_ht(const char *name, const size_t namelen, int no_autoload)
|
||||||
int no_autoload)
|
|
||||||
{
|
{
|
||||||
if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL) {
|
if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user