diff options
author | Jakob Schnitzer <mail@jakobschnitzer.de> | 2017-04-24 11:35:10 +0200 |
---|---|---|
committer | Jakob Schnitzer <mail@jakobschnitzer.de> | 2017-04-24 11:35:10 +0200 |
commit | ff8b2eb435c518f0eafd0e509afe1f5ee4a81fd1 (patch) | |
tree | 526b1df09b06121bdbc6ef5254ef53821958a6cb /src/nvim/api | |
parent | 4049492b6d7b8805686b14dbacb3b729abd03308 (diff) | |
parent | 7f6d3d305269fd1139bc2aec9a91bf98ad595199 (diff) | |
download | rneovim-ff8b2eb435c518f0eafd0e509afe1f5ee4a81fd1.tar.gz rneovim-ff8b2eb435c518f0eafd0e509afe1f5ee4a81fd1.tar.bz2 rneovim-ff8b2eb435c518f0eafd0e509afe1f5ee4a81fd1.zip |
Merge branch 'master' into option-fixes
Diffstat (limited to 'src/nvim/api')
-rw-r--r-- | src/nvim/api/buffer.c | 53 | ||||
-rw-r--r-- | src/nvim/api/private/defs.h | 8 | ||||
-rw-r--r-- | src/nvim/api/private/dispatch.c | 3 | ||||
-rw-r--r-- | src/nvim/api/private/handle.c | 3 | ||||
-rw-r--r-- | src/nvim/api/private/helpers.c | 133 | ||||
-rw-r--r-- | src/nvim/api/private/helpers.h | 9 | ||||
-rw-r--r-- | src/nvim/api/tabpage.c | 7 | ||||
-rw-r--r-- | src/nvim/api/ui.c | 64 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 57 | ||||
-rw-r--r-- | src/nvim/api/window.c | 19 |
10 files changed, 211 insertions, 145 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 26f9a6f592..ae5728ee21 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + // Much of this code was adapted from 'if_py_both.h' from the original // vim source #include <stdbool.h> @@ -62,7 +65,7 @@ String buffer_get_line(Buffer buffer, Integer index, Error *err) index = convert_index(index); Array slice = nvim_buf_get_lines(0, buffer, index, index+1, true, err); - if (!err->set && slice.size) { + if (!ERROR_SET(err) && slice.size) { rv = slice.items[0].data.string; } @@ -168,7 +171,7 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id, end = normalize_index(buf, end, &oob); if (strict_indexing && oob) { - api_set_error(err, Validation, _("Index out of bounds")); + api_set_error(err, kErrorTypeValidation, "Index out of bounds"); return rv; } @@ -184,7 +187,7 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id, int64_t lnum = start + (int64_t)i; if (lnum > LONG_MAX) { - api_set_error(err, Validation, _("Line index is too high")); + api_set_error(err, kErrorTypeValidation, "Line index is too high"); goto end; } @@ -200,7 +203,7 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id, } end: - if (err->set) { + if (ERROR_SET(err)) { for (size_t i = 0; i < rv.size; i++) { xfree(rv.items[i].data.string.data); } @@ -280,15 +283,15 @@ void nvim_buf_set_lines(uint64_t channel_id, end = normalize_index(buf, end, &oob); if (strict_indexing && oob) { - api_set_error(err, Validation, _("Index out of bounds")); + api_set_error(err, kErrorTypeValidation, "Index out of bounds"); return; } if (start > end) { api_set_error(err, - Validation, - _("Argument \"start\" is higher than \"end\"")); + kErrorTypeValidation, + "Argument \"start\" is higher than \"end\""); return; } @@ -302,8 +305,8 @@ void nvim_buf_set_lines(uint64_t channel_id, for (size_t i = 0; i < new_len; i++) { if (replacement.items[i].type != kObjectTypeString) { api_set_error(err, - Validation, - _("All items in the replacement array must be strings")); + kErrorTypeValidation, + "All items in the replacement array must be strings"); goto end; } @@ -314,7 +317,8 @@ void nvim_buf_set_lines(uint64_t channel_id, lines[i] = xmallocz(l.size); for (size_t j = 0; j < l.size; j++) { if (l.data[j] == '\n' && channel_id != INTERNAL_CALL) { - api_set_error(err, Exception, _("string cannot contain newlines")); + api_set_error(err, kErrorTypeException, + "String cannot contain newlines"); new_len = i + 1; goto end; } @@ -327,7 +331,7 @@ void nvim_buf_set_lines(uint64_t channel_id, switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf); if (u_save((linenr_T)(start - 1), (linenr_T)end) == FAIL) { - api_set_error(err, Exception, _("Failed to save undo information")); + api_set_error(err, kErrorTypeException, "Failed to save undo information"); goto end; } @@ -337,7 +341,7 @@ void nvim_buf_set_lines(uint64_t channel_id, size_t to_delete = (new_len < old_len) ? (size_t)(old_len - new_len) : 0; for (size_t i = 0; i < to_delete; i++) { if (ml_delete((linenr_T)start, false) == FAIL) { - api_set_error(err, Exception, _("Failed to delete line")); + api_set_error(err, kErrorTypeException, "Failed to delete line"); goto end; } } @@ -354,12 +358,12 @@ void nvim_buf_set_lines(uint64_t channel_id, int64_t lnum = start + (int64_t)i; if (lnum > LONG_MAX) { - api_set_error(err, Validation, _("Index value is too high")); + api_set_error(err, kErrorTypeValidation, "Index value is too high"); goto end; } if (ml_replace((linenr_T)lnum, (char_u *)lines[i], false) == FAIL) { - api_set_error(err, Exception, _("Failed to replace line")); + api_set_error(err, kErrorTypeException, "Failed to replace line"); goto end; } // Mark lines that haven't been passed to the buffer as they need @@ -372,12 +376,12 @@ void nvim_buf_set_lines(uint64_t channel_id, int64_t lnum = start + (int64_t)i - 1; if (lnum > LONG_MAX) { - api_set_error(err, Validation, _("Index value is too high")); + api_set_error(err, kErrorTypeValidation, "Index value is too high"); goto end; } if (ml_append((linenr_T)lnum, (char_u *)lines[i], 0, false) == FAIL) { - api_set_error(err, Exception, _("Failed to insert line")); + api_set_error(err, kErrorTypeException, "Failed to insert line"); goto end; } @@ -624,7 +628,7 @@ void nvim_buf_set_name(Buffer buffer, String name, Error *err) } if (ren_ret == FAIL) { - api_set_error(err, Exception, _("Failed to rename buffer")); + api_set_error(err, kErrorTypeException, "Failed to rename buffer"); } } @@ -636,7 +640,9 @@ Boolean nvim_buf_is_valid(Buffer buffer) FUNC_API_SINCE(1) { Error stub = ERROR_INIT; - return find_buffer_by_handle(buffer, &stub) != NULL; + Boolean ret = find_buffer_by_handle(buffer, &stub) != NULL; + api_clear_error(&stub); + return ret; } /// Inserts a sequence of lines to a buffer at a certain index @@ -675,7 +681,8 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) } if (name.size != 1) { - api_set_error(err, Validation, _("Mark name must be a single character")); + api_set_error(err, kErrorTypeValidation, + "Mark name must be a single character"); return rv; } @@ -693,7 +700,7 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) } if (posp == NULL) { - api_set_error(err, Validation, _("Invalid mark name")); + api_set_error(err, kErrorTypeValidation, "Invalid mark name"); return rv; } @@ -748,11 +755,11 @@ Integer nvim_buf_add_highlight(Buffer buffer, } if (line < 0 || line >= MAXLNUM) { - api_set_error(err, Validation, _("Line number outside range")); + api_set_error(err, kErrorTypeValidation, "Line number outside range"); return 0; } if (col_start < 0 || col_start > MAXCOL) { - api_set_error(err, Validation, _("Column value outside range")); + api_set_error(err, kErrorTypeValidation, "Column value outside range"); return 0; } if (col_end < 0 || col_end > MAXCOL) { @@ -789,7 +796,7 @@ void nvim_buf_clear_highlight(Buffer buffer, } if (line_start < 0 || line_start >= MAXLNUM) { - api_set_error(err, Validation, _("Line number outside range")); + api_set_error(err, kErrorTypeValidation, "Line number outside range"); return; } if (line_end < 0 || line_end > MAXLNUM) { diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index 223aab09dc..60bf38265f 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -8,9 +8,11 @@ #define ARRAY_DICT_INIT {.size = 0, .capacity = 0, .items = NULL} #define STRING_INIT {.data = NULL, .size = 0} #define OBJECT_INIT { .type = kObjectTypeNil } -#define ERROR_INIT { .set = false } +#define ERROR_INIT { .type = kErrorTypeNone, .msg = NULL } #define REMOTE_TYPE(type) typedef handle_T type +#define ERROR_SET(e) ((e)->type != kErrorTypeNone) + #ifdef INCLUDE_GENERATED_DECLARATIONS # define ArrayOf(...) Array # define DictionaryOf(...) Dictionary @@ -20,6 +22,7 @@ typedef int handle_T; // Basic types typedef enum { + kErrorTypeNone = -1, kErrorTypeException, kErrorTypeValidation } ErrorType; @@ -38,8 +41,7 @@ typedef enum { typedef struct { ErrorType type; - char msg[1024]; - bool set; + char *msg; } Error; typedef bool Boolean; diff --git a/src/nvim/api/private/dispatch.c b/src/nvim/api/private/dispatch.c index 9b3bcc380a..f8eebcdb10 100644 --- a/src/nvim/api/private/dispatch.c +++ b/src/nvim/api/private/dispatch.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + #include <inttypes.h> #include <stdbool.h> #include <stdint.h> diff --git a/src/nvim/api/private/handle.c b/src/nvim/api/private/handle.c index acb0fb332a..eb96192af2 100644 --- a/src/nvim/api/private/handle.c +++ b/src/nvim/api/private/handle.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + #include <assert.h> #include <stdint.h> diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index fe15b28041..69cb19c14f 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + #include <assert.h> #include <inttypes.h> #include <stdbool.h> @@ -58,7 +61,7 @@ bool try_end(Error *err) discard_current_exception(); } - api_set_error(err, Exception, _("Keyboard interrupt")); + api_set_error(err, kErrorTypeException, "Keyboard interrupt"); got_int = false; } else if (msg_list != NULL && *msg_list != NULL) { int should_free; @@ -66,19 +69,18 @@ bool try_end(Error *err) ET_ERROR, NULL, &should_free); - xstrlcpy(err->msg, msg, sizeof(err->msg)); - err->set = true; + api_set_error(err, kErrorTypeException, "%s", msg); free_global_msglist(); if (should_free) { xfree(msg); } } else if (did_throw) { - api_set_error(err, Exception, "%s", current_exception->value); + api_set_error(err, kErrorTypeException, "%s", current_exception->value); discard_current_exception(); } - return err->set; + return ERROR_SET(err); } /// Recursively expands a vimscript value in a dict @@ -91,8 +93,8 @@ Object dict_get_value(dict_T *dict, String key, Error *err) dictitem_T *const di = tv_dict_find(dict, key.data, (ptrdiff_t)key.size); if (di == NULL) { - api_set_error(err, Validation, _("Key not found")); - return (Object) OBJECT_INIT; + api_set_error(err, kErrorTypeValidation, "Key not found"); + return (Object)OBJECT_INIT; } return vim_to_object(&di->di_tv); @@ -115,17 +117,18 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, Object rv = OBJECT_INIT; if (dict->dv_lock) { - api_set_error(err, Exception, _("Dictionary is locked")); + api_set_error(err, kErrorTypeException, "Dictionary is locked"); return rv; } if (key.size == 0) { - api_set_error(err, Validation, _("Empty variable names aren't allowed")); + api_set_error(err, kErrorTypeValidation, + "Empty variable names aren't allowed"); return rv; } if (key.size > INT_MAX) { - api_set_error(err, Validation, _("Key length is too high")); + api_set_error(err, kErrorTypeValidation, "Key length is too high"); return rv; } @@ -133,13 +136,13 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, if (di != NULL) { if (di->di_flags & DI_FLAGS_RO) { - api_set_error(err, Exception, _("Key is read-only: %s"), key.data); + api_set_error(err, kErrorTypeException, "Key is read-only: %s", key.data); return rv; } else if (di->di_flags & DI_FLAGS_FIX) { - api_set_error(err, Exception, _("Key is fixed: %s"), key.data); + api_set_error(err, kErrorTypeException, "Key is fixed: %s", key.data); return rv; } else if (di->di_flags & DI_FLAGS_LOCK) { - api_set_error(err, Exception, _("Key is locked: %s"), key.data); + api_set_error(err, kErrorTypeException, "Key is locked: %s", key.data); return rv; } } @@ -148,7 +151,8 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, // Delete the key if (di == NULL) { // Doesn't exist, fail - api_set_error(err, Validation, _("Key \"%s\" doesn't exist"), key.data); + api_set_error(err, kErrorTypeValidation, "Key does not exist: %s", + key.data); } else { // Return the old value if (retval) { @@ -200,7 +204,7 @@ Object get_option_from(void *from, int type, String name, Error *err) Object rv = OBJECT_INIT; if (name.size == 0) { - api_set_error(err, Validation, _("Empty option name")); + api_set_error(err, kErrorTypeValidation, "Empty option name"); return rv; } @@ -212,8 +216,8 @@ Object get_option_from(void *from, int type, String name, Error *err) if (!flags) { api_set_error(err, - Validation, - _("Invalid option name \"%s\""), + kErrorTypeValidation, + "Invalid option name \"%s\"", name.data); return rv; } @@ -231,14 +235,14 @@ Object get_option_from(void *from, int type, String name, Error *err) rv.data.string.size = strlen(stringval); } else { api_set_error(err, - Exception, - _("Unable to get value for option \"%s\""), + kErrorTypeException, + "Unable to get value for option \"%s\"", name.data); } } else { api_set_error(err, - Exception, - _("Unknown type for option \"%s\""), + kErrorTypeException, + "Unknown type for option \"%s\"", name.data); } @@ -255,7 +259,7 @@ Object get_option_from(void *from, int type, String name, Error *err) void set_option_to(void *to, int type, String name, Object value, Error *err) { if (name.size == 0) { - api_set_error(err, Validation, _("Empty option name")); + api_set_error(err, kErrorTypeValidation, "Empty option name"); return; } @@ -263,8 +267,8 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) if (flags == 0) { api_set_error(err, - Validation, - _("Invalid option name \"%s\""), + kErrorTypeValidation, + "Invalid option name \"%s\"", name.data); return; } @@ -272,15 +276,15 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) if (value.type == kObjectTypeNil) { if (type == SREQ_GLOBAL) { api_set_error(err, - Exception, - _("Unable to unset option \"%s\""), + kErrorTypeException, + "Unable to unset option \"%s\"", name.data); return; } else if (!(flags & SOPT_GLOBAL)) { api_set_error(err, - Exception, - _("Cannot unset option \"%s\" " - "because it doesn't have a global value"), + kErrorTypeException, + "Cannot unset option \"%s\" " + "because it doesn't have a global value", name.data); return; } else { @@ -294,8 +298,8 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) if (flags & SOPT_BOOL) { if (value.type != kObjectTypeBoolean) { api_set_error(err, - Validation, - _("Option \"%s\" requires a boolean value"), + kErrorTypeValidation, + "Option \"%s\" requires a boolean value", name.data); return; } @@ -305,16 +309,16 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) } else if (flags & SOPT_NUM) { if (value.type != kObjectTypeInteger) { api_set_error(err, - Validation, - _("Option \"%s\" requires an integer value"), + kErrorTypeValidation, + "Option \"%s\" requires an integer value", name.data); return; } if (value.data.integer > INT_MAX || value.data.integer < INT_MIN) { api_set_error(err, - Validation, - _("Value for option \"%s\" is outside range"), + kErrorTypeValidation, + "Value for option \"%s\" is outside range", name.data); return; } @@ -324,8 +328,8 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) } else { if (value.type != kObjectTypeString) { api_set_error(err, - Validation, - _("Option \"%s\" requires a string value"), + kErrorTypeValidation, + "Option \"%s\" requires a string value", name.data); return; } @@ -558,13 +562,13 @@ buf_T *find_buffer_by_handle(Buffer buffer, Error *err) buf_T *rv = handle_get_buffer(buffer); if (!rv) { - api_set_error(err, Validation, _("Invalid buffer id")); + api_set_error(err, kErrorTypeValidation, "Invalid buffer id"); } return rv; } -win_T * find_window_by_handle(Window window, Error *err) +win_T *find_window_by_handle(Window window, Error *err) { if (window == 0) { return curwin; @@ -573,13 +577,13 @@ win_T * find_window_by_handle(Window window, Error *err) win_T *rv = handle_get_window(window); if (!rv) { - api_set_error(err, Validation, _("Invalid window id")); + api_set_error(err, kErrorTypeValidation, "Invalid window id"); } return rv; } -tabpage_T * find_tab_by_handle(Tabpage tabpage, Error *err) +tabpage_T *find_tab_by_handle(Tabpage tabpage, Error *err) { if (tabpage == 0) { return curtab; @@ -588,7 +592,7 @@ tabpage_T * find_tab_by_handle(Tabpage tabpage, Error *err) tabpage_T *rv = handle_get_tabpage(tabpage); if (!rv) { - api_set_error(err, Validation, _("Invalid tabpage id")); + api_set_error(err, kErrorTypeValidation, "Invalid tabpage id"); } return rv; @@ -656,7 +660,7 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err) case kObjectTypeInteger: if (obj.data.integer > VARNUMBER_MAX || obj.data.integer < VARNUMBER_MIN) { - api_set_error(err, Validation, _("Integer value outside range")); + api_set_error(err, kErrorTypeValidation, "Integer value outside range"); return false; } @@ -710,8 +714,8 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err) String key = item.key; if (key.size == 0) { - api_set_error(err, Validation, - _("Empty dictionary keys aren't allowed")); + api_set_error(err, kErrorTypeValidation, + "Empty dictionary keys aren't allowed"); // cleanup tv_dict_free(dict); return false; @@ -798,6 +802,17 @@ void api_free_dictionary(Dictionary value) xfree(value.items); } +void api_clear_error(Error *value) + FUNC_ATTR_NONNULL_ALL +{ + if (!ERROR_SET(value)) { + return; + } + xfree(value->msg); + value->msg = NULL; + value->type = kErrorTypeNone; +} + Dictionary api_metadata(void) { static Dictionary metadata = ARRAY_DICT_INIT; @@ -924,8 +939,8 @@ static void set_option_value_for(char *key, return; } api_set_error(err, - Exception, - _("Problem while switching windows")); + kErrorTypeException, + "Problem while switching windows"); return; } set_option_value_err(key, numval, stringval, opt_flags, err); @@ -941,7 +956,7 @@ static void set_option_value_for(char *key, break; } - if (err->set) { + if (ERROR_SET(err)) { return; } @@ -962,6 +977,26 @@ static void set_option_value_err(char *key, return; } - api_set_error(err, Exception, "%s", errmsg); + api_set_error(err, kErrorTypeException, "%s", errmsg); } } + +void api_set_error(Error *err, ErrorType errType, const char *format, ...) + FUNC_ATTR_NONNULL_ALL +{ + assert(kErrorTypeNone != errType); + va_list args1; + va_list args2; + va_start(args1, format); + va_copy(args2, args1); + int len = vsnprintf(NULL, 0, format, args1); + va_end(args1); + assert(len >= 0); + // Limit error message to 1 MB. + size_t bufsize = MIN((size_t)len + 1, 1024 * 1024); + err->msg = xmalloc(bufsize); + vsnprintf(err->msg, bufsize, format, args2); + va_end(args2); + + err->type = errType; +} diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index 9fe8c351cf..681945ac9c 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -8,15 +8,6 @@ #include "nvim/memory.h" #include "nvim/lib/kvec.h" -#define api_set_error(err, errtype, ...) \ - do { \ - snprintf((err)->msg, \ - sizeof((err)->msg), \ - __VA_ARGS__); \ - (err)->set = true; \ - (err)->type = kErrorType##errtype; \ - } while (0) - #define OBJECT_OBJ(o) o #define BOOLEAN_OBJ(b) ((Object) { \ diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c index 0f0c33f621..6f2f9e1d2a 100644 --- a/src/nvim/api/tabpage.c +++ b/src/nvim/api/tabpage.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + #include <stdbool.h> #include <stdint.h> #include <stdlib.h> @@ -190,6 +193,8 @@ Boolean nvim_tabpage_is_valid(Tabpage tabpage) FUNC_API_SINCE(1) { Error stub = ERROR_INIT; - return find_tab_by_handle(tabpage, &stub) != NULL; + Boolean ret = find_tab_by_handle(tabpage, &stub) != NULL; + api_clear_error(&stub); + return ret; } diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 625bcc6b4b..f0da0d1812 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + #include <assert.h> #include <stddef.h> #include <stdint.h> @@ -12,6 +15,7 @@ #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/popupmnu.h" +#include "nvim/cursor_shape.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/ui.c.generated.h" @@ -51,13 +55,13 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, FUNC_API_SINCE(1) FUNC_API_NOEVAL { if (pmap_has(uint64_t)(connected_uis, channel_id)) { - api_set_error(err, Exception, _("UI already attached for channel")); + api_set_error(err, kErrorTypeException, "UI already attached for channel"); return; } if (width <= 0 || height <= 0) { - api_set_error(err, Validation, - _("Expected width > 0 and height > 0")); + api_set_error(err, kErrorTypeValidation, + "Expected width > 0 and height > 0"); return; } UI *ui = xcalloc(1, sizeof(UI)); @@ -69,6 +73,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, ui->clear = remote_ui_clear; ui->eol_clear = remote_ui_eol_clear; ui->cursor_goto = remote_ui_cursor_goto; + ui->mode_info_set = remote_ui_mode_info_set; ui->update_menu = remote_ui_update_menu; ui->busy_start = remote_ui_busy_start; ui->busy_stop = remote_ui_busy_stop; @@ -92,7 +97,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, for (size_t i = 0; i < options.size; i++) { ui_set_option(ui, options.items[i].key, options.items[i].value, err); - if (err->set) { + if (ERROR_SET(err)) { xfree(ui); return; } @@ -121,7 +126,7 @@ void nvim_ui_detach(uint64_t channel_id, Error *err) FUNC_API_SINCE(1) FUNC_API_NOEVAL { if (!pmap_has(uint64_t)(connected_uis, channel_id)) { - api_set_error(err, Exception, _("UI is not attached for channel")); + api_set_error(err, kErrorTypeException, "UI is not attached for channel"); return; } remote_ui_disconnect(channel_id); @@ -133,13 +138,13 @@ void nvim_ui_try_resize(uint64_t channel_id, Integer width, FUNC_API_SINCE(1) FUNC_API_NOEVAL { if (!pmap_has(uint64_t)(connected_uis, channel_id)) { - api_set_error(err, Exception, _("UI is not attached for channel")); + api_set_error(err, kErrorTypeException, "UI is not attached for channel"); return; } if (width <= 0 || height <= 0) { - api_set_error(err, Validation, - _("Expected width > 0 and height > 0")); + api_set_error(err, kErrorTypeValidation, + "Expected width > 0 and height > 0"); return; } @@ -154,13 +159,13 @@ void nvim_ui_set_option(uint64_t channel_id, String name, FUNC_API_SINCE(1) FUNC_API_NOEVAL { if (!pmap_has(uint64_t)(connected_uis, channel_id)) { - api_set_error(error, Exception, _("UI is not attached for channel")); + api_set_error(error, kErrorTypeException, "UI is not attached for channel"); return; } UI *ui = pmap_get(uint64_t)(connected_uis, channel_id); ui_set_option(ui, name, value, error); - if (!error->set) { + if (!ERROR_SET(error)) { ui_refresh(); } } @@ -168,19 +173,19 @@ void nvim_ui_set_option(uint64_t channel_id, String name, static void ui_set_option(UI *ui, String name, Object value, Error *error) { if (strcmp(name.data, "rgb") == 0) { if (value.type != kObjectTypeBoolean) { - api_set_error(error, Validation, _("rgb must be a Boolean")); + api_set_error(error, kErrorTypeValidation, "rgb must be a Boolean"); return; } ui->rgb = value.data.boolean; } else if (strcmp(name.data, "popupmenu_external") == 0) { if (value.type != kObjectTypeBoolean) { - api_set_error(error, Validation, - _("popupmenu_external must be a Boolean")); + api_set_error(error, kErrorTypeValidation, + "popupmenu_external must be a Boolean"); return; } ui->pum_external = value.data.boolean; } else { - api_set_error(error, Validation, _("No such ui option")); + api_set_error(error, kErrorTypeValidation, "No such ui option"); } } @@ -264,19 +269,14 @@ static void remote_ui_mouse_off(UI *ui) push_call(ui, "mouse_off", args); } -static void remote_ui_mode_change(UI *ui, int mode) +static void remote_ui_mode_change(UI *ui, int mode_idx) { Array args = ARRAY_DICT_INIT; - if (mode == INSERT) { - ADD(args, STRING_OBJ(cstr_to_string("insert"))); - } else if (mode == REPLACE) { - ADD(args, STRING_OBJ(cstr_to_string("replace"))); - } else if (mode == CMDLINE) { - ADD(args, STRING_OBJ(cstr_to_string("cmdline"))); - } else { - assert(mode == NORMAL); - ADD(args, STRING_OBJ(cstr_to_string("normal"))); - } + + char *full_name = shape_table[mode_idx].full_name; + ADD(args, STRING_OBJ(cstr_to_string(full_name))); + + ADD(args, INTEGER_OBJ(mode_idx)); push_call(ui, "mode_change", args); } @@ -298,6 +298,14 @@ static void remote_ui_scroll(UI *ui, int count) push_call(ui, "scroll", args); } +static void remote_ui_mode_info_set(UI *ui, bool guicursor_enabled, Array data) +{ + Array args = ARRAY_DICT_INIT; + ADD(args, BOOLEAN_OBJ(guicursor_enabled)); + ADD(args, copy_object(ARRAY_OBJ(data))); + push_call(ui, "mode_info_set", args); +} + static void remote_ui_highlight_set(UI *ui, HlAttrs attrs) { Array args = ARRAY_DICT_INIT; @@ -383,8 +391,10 @@ static void remote_ui_update_sp(UI *ui, int sp) static void remote_ui_flush(UI *ui) { UIData *data = ui->data; - channel_send_event(data->channel_id, "redraw", data->buffer); - data->buffer = (Array)ARRAY_DICT_INIT; + if (data->buffer.size > 0) { + channel_send_event(data->channel_id, "redraw", data->buffer); + data->buffer = (Array)ARRAY_DICT_INIT; + } } static void remote_ui_suspend(UI *ui) diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 6926436d2f..da00fbc6e3 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + #include <assert.h> #include <stdint.h> #include <inttypes.h> @@ -162,8 +165,8 @@ String nvim_command_output(String str, Error *err) nvim_command(str, err); do_cmdline_cmd("redir END"); - if (err->set) { - return (String) STRING_INIT; + if (ERROR_SET(err)) { + return (String)STRING_INIT; } return cstr_to_string((char *)get_vim_var_str(VV_COMMAND_OUTPUT)); @@ -185,7 +188,7 @@ Object nvim_eval(String expr, Error *err) typval_T rettv; if (eval0((char_u *)expr.data, &rettv, NULL, true) == FAIL) { - api_set_error(err, Exception, "Failed to evaluate expression"); + api_set_error(err, kErrorTypeException, "Failed to evaluate expression"); } if (!try_end(err)) { @@ -211,8 +214,8 @@ Object nvim_call_function(String fname, Array args, Error *err) { Object rv = OBJECT_INIT; if (args.size > MAX_FUNC_ARGS) { - api_set_error(err, Validation, - _("Function called with too many arguments.")); + api_set_error(err, kErrorTypeValidation, + "Function called with too many arguments."); return rv; } @@ -234,7 +237,7 @@ Object nvim_call_function(String fname, Array args, Error *err) curwin->w_cursor.lnum, curwin->w_cursor.lnum, &dummy, true, NULL, NULL); if (r == FAIL) { - api_set_error(err, Exception, _("Error calling function.")); + api_set_error(err, kErrorTypeException, "Error calling function."); } if (!try_end(err)) { rv = vim_to_object(&rettv); @@ -259,7 +262,7 @@ Integer nvim_strwidth(String str, Error *err) FUNC_API_SINCE(1) { if (str.size > INT_MAX) { - api_set_error(err, Validation, _("String length is too high")); + api_set_error(err, kErrorTypeValidation, "String length is too high"); return 0; } @@ -315,7 +318,7 @@ void nvim_set_current_dir(String dir, Error *err) FUNC_API_SINCE(1) { if (dir.size >= MAXPATHL) { - api_set_error(err, Validation, _("Directory string is too long")); + api_set_error(err, kErrorTypeValidation, "Directory string is too long"); return; } @@ -327,7 +330,7 @@ void nvim_set_current_dir(String dir, Error *err) if (vim_chdir((char_u *)string, kCdScopeGlobal)) { if (!try_end(err)) { - api_set_error(err, Exception, _("Failed to change directory")); + api_set_error(err, kErrorTypeException, "Failed to change directory"); } return; } @@ -536,8 +539,8 @@ void nvim_set_current_buf(Buffer buffer, Error *err) int result = do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0); if (!try_end(err) && result == FAIL) { api_set_error(err, - Exception, - _("Failed to switch to buffer %d"), + kErrorTypeException, + "Failed to switch to buffer %d", buffer); } } @@ -589,8 +592,8 @@ void nvim_set_current_win(Window window, Error *err) goto_tabpage_win(win_find_tabpage(win), win); if (!try_end(err) && win != curwin) { api_set_error(err, - Exception, - _("Failed to switch to window %d"), + kErrorTypeException, + "Failed to switch to window %d", window); } } @@ -643,8 +646,8 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err) goto_tabpage_tp(tp, true, true); if (!try_end(err) && tp != curtab) { api_set_error(err, - Exception, - _("Failed to switch to tabpage %d"), + kErrorTypeException, + "Failed to switch to tabpage %d", tabpage); } } @@ -742,30 +745,30 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err) for (i = 0; i < calls.size; i++) { if (calls.items[i].type != kObjectTypeArray) { api_set_error(err, - Validation, - _("All items in calls array must be arrays")); + kErrorTypeValidation, + "All items in calls array must be arrays"); goto validation_error; } Array call = calls.items[i].data.array; if (call.size != 2) { api_set_error(err, - Validation, - _("All items in calls array must be arrays of size 2")); + kErrorTypeValidation, + "All items in calls array must be arrays of size 2"); goto validation_error; } if (call.items[0].type != kObjectTypeString) { api_set_error(err, - Validation, - _("name must be String")); + kErrorTypeValidation, + "Name must be String"); goto validation_error; } String name = call.items[0].data.string; if (call.items[1].type != kObjectTypeArray) { api_set_error(err, - Validation, - _("args must be Array")); + kErrorTypeValidation, + "Args must be Array"); goto validation_error; } Array args = call.items[1].data.array; @@ -773,7 +776,7 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err) MsgpackRpcRequestHandler handler = msgpack_rpc_get_handler_for(name.data, name.size); Object result = handler.fn(channel_id, args, &nested_error); - if (nested_error.set) { + if (ERROR_SET(&nested_error)) { // error handled after loop break; } @@ -782,7 +785,7 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err) } ADD(rv, ARRAY_OBJ(results)); - if (nested_error.set) { + if (ERROR_SET(&nested_error)) { Array errval = ARRAY_DICT_INIT; ADD(errval, INTEGER_OBJ((Integer)i)); ADD(errval, INTEGER_OBJ(nested_error.type)); @@ -791,10 +794,12 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err) } else { ADD(rv, NIL); } - return rv; + goto theend; validation_error: api_free_array(results); +theend: + api_clear_error(&nested_error); return rv; } diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index 3c564ada99..859bf88398 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + #include <stdbool.h> #include <stdint.h> #include <stdlib.h> @@ -62,8 +65,8 @@ void nvim_win_set_cursor(Window window, ArrayOf(Integer, 2) pos, Error *err) if (pos.size != 2 || pos.items[0].type != kObjectTypeInteger || pos.items[1].type != kObjectTypeInteger) { api_set_error(err, - Validation, - _("Argument \"pos\" must be a [row, col] array")); + kErrorTypeValidation, + "Argument \"pos\" must be a [row, col] array"); return; } @@ -75,12 +78,12 @@ void nvim_win_set_cursor(Window window, ArrayOf(Integer, 2) pos, Error *err) int64_t col = pos.items[1].data.integer; if (row <= 0 || row > win->w_buffer->b_ml.ml_line_count) { - api_set_error(err, Validation, _("Cursor position outside buffer")); + api_set_error(err, kErrorTypeValidation, "Cursor position outside buffer"); return; } if (col > MAXCOL || col < 0) { - api_set_error(err, Validation, _("Column value outside range")); + api_set_error(err, kErrorTypeValidation, "Column value outside range"); return; } @@ -129,7 +132,7 @@ void nvim_win_set_height(Window window, Integer height, Error *err) } if (height > INT_MAX || height < INT_MIN) { - api_set_error(err, Validation, _("Height value outside range")); + api_set_error(err, kErrorTypeValidation, "Height value outside range"); return; } @@ -174,7 +177,7 @@ void nvim_win_set_width(Window window, Integer width, Error *err) } if (width > INT_MAX || width < INT_MIN) { - api_set_error(err, Validation, _("Width value outside range")); + api_set_error(err, kErrorTypeValidation, "Width value outside range"); return; } @@ -384,6 +387,8 @@ Boolean nvim_win_is_valid(Window window) FUNC_API_SINCE(1) { Error stub = ERROR_INIT; - return find_window_by_handle(window, &stub) != NULL; + Boolean ret = find_window_by_handle(window, &stub) != NULL; + api_clear_error(&stub); + return ret; } |