diff options
87 files changed, 1950 insertions, 2238 deletions
diff --git a/.travis.yml b/.travis.yml index 25ab961ec4..d883410123 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,5 +4,6 @@ env: - TRAVIS_BUILD_TYPE=gcc/ia32 - TRAVIS_BUILD_TYPE=gcc/unittest - TRAVIS_BUILD_TYPE=clint + - TRAVIS_BUILD_TYPE=api/python script: - ./scripts/travis.sh diff --git a/.valgrind.supp b/.valgrind.supp index a0a96518ba..f788030151 100644 --- a/.valgrind.supp +++ b/.valgrind.supp @@ -5,3 +5,28 @@ fun:nss_parse_service_list fun:__nss_database_lookup } +{ + ex_function_1 + Memcheck:Leak + fun:malloc + fun:try_malloc + fun:xmalloc + fun:ex_function +} +{ + ex_function_2 + Memcheck:Leak + fun:realloc + fun:xrealloc + fun:ga_grow + fun:ex_function +} +{ + ex_function_3 + Memcheck:Leak + fun:malloc + fun:strdup + fun:xstrdup + fun:vim_strsave + fun:ex_function +} @@ -3,6 +3,7 @@ [Website](http://neovim.org) | [Google Group](https://groups.google.com/forum/#!forum/neovim) | [Twitter](http://twitter.com/Neovim) | +[Reddit](http://www.reddit.com/r/neovim) | [Bountysource](https://www.bountysource.com/teams/neovim) [](https://travis-ci.org/neovim/neovim) diff --git a/clint-files.txt b/clint-files.txt index 9518e7cb84..e05912d338 100644 --- a/clint-files.txt +++ b/clint-files.txt @@ -1,3 +1,18 @@ +src/nvim/api/buffer.c +src/nvim/api/buffer.h +src/nvim/api/private/defs.h +src/nvim/api/private/helpers.c +src/nvim/api/private/helpers.h +src/nvim/api/private/handle.c +src/nvim/api/private/handle.h +src/nvim/api/tabpage.c +src/nvim/api/tabpage.h +src/nvim/api/vim.c +src/nvim/api/vim.h +src/nvim/api/window.c +src/nvim/api/window.h +src/nvim/hashtab.c +src/nvim/hashtab.h src/nvim/indent.c src/nvim/indent.h src/nvim/log.c @@ -7,34 +22,27 @@ src/nvim/map.h src/nvim/map_defs.h src/nvim/os/env.c src/nvim/os/event.c -src/nvim/os/event_defs.h src/nvim/os/event.h +src/nvim/os/event_defs.h src/nvim/os/input.c src/nvim/os/input.h -src/nvim/os/rstream.c -src/nvim/os/rstream_defs.h -src/nvim/os/rstream.h src/nvim/os/job.c -src/nvim/os/job_defs.h src/nvim/os/job.h +src/nvim/os/job_defs.h src/nvim/os/mem.c +src/nvim/os/msgpack_rpc.c +src/nvim/os/msgpack_rpc.h src/nvim/os/os.h +src/nvim/os/rstream.c +src/nvim/os/rstream.h +src/nvim/os/rstream_defs.h src/nvim/os/shell.c src/nvim/os/shell.h src/nvim/os/signal.c src/nvim/os/signal.h src/nvim/os/time.c src/nvim/os/time.h -src/nvim/os/msgpack_rpc.h -src/nvim/os/msgpack_rpc.c -src/nvim/api/defs.h -src/nvim/api/buffer.h -src/nvim/api/buffer.c -src/nvim/api/helpers.h -src/nvim/api/helpers.c -src/nvim/api/tabpage.h -src/nvim/api/tabpage.c -src/nvim/api/window.h -src/nvim/api/window.c -src/nvim/api/vim.h -src/nvim/api/vim.c +src/nvim/os/server.c +src/nvim/os/server.h +src/nvim/os/channel.c +src/nvim/os/channel.h diff --git a/scripts/msgpack-gen.lua b/scripts/msgpack-gen.lua index d303fde2fc..3cc1558fd7 100644 --- a/scripts/msgpack-gen.lua +++ b/scripts/msgpack-gen.lua @@ -111,7 +111,7 @@ end output:write([[ }; -void msgpack_rpc_dispatch(msgpack_object *req, msgpack_packer *res) +void msgpack_rpc_dispatch(uint64_t id, msgpack_object *req, msgpack_packer *res) { Error error = { .set = false }; uint64_t method_id = (uint32_t)req->via.array.ptr[2].via.u64; @@ -119,7 +119,9 @@ void msgpack_rpc_dispatch(msgpack_object *req, msgpack_packer *res) switch (method_id) { case 0: msgpack_pack_nil(res); - // The result is the `msgpack_metadata` byte array + // The result is the [channel_id, metadata] array + msgpack_pack_array(res, 2); + msgpack_pack_uint64(res, id); msgpack_pack_raw(res, sizeof(msgpack_metadata)); msgpack_pack_raw_body(res, msgpack_metadata, sizeof(msgpack_metadata)); return; diff --git a/scripts/run-api-tests.exp b/scripts/run-api-tests.exp new file mode 100755 index 0000000000..6a568e17cb --- /dev/null +++ b/scripts/run-api-tests.exp @@ -0,0 +1,86 @@ +#!/usr/bin/env expect + +if {$argc < 2} { + puts "Need commands for running the tests and for starting nvim" + exit 1 +} + +set timeout 10 +set run_tests [split [lindex $argv 0] " "] +set run_nvim [split [lindex $argv 1] " "] + +# don't echo to stdout +log_user 0 +# set NEOVIM_LISTEN_ADDRESS, so nvim will listen on a known socket +set env(NEOVIM_LISTEN_ADDRESS) "/tmp/nvim-[exec date +%s%N].sock" +# start nvim +spawn {*}$run_nvim +# save the job descriptor +set nvim_id $spawn_id +# Reset function that can be invoked by test runners to put nvim in a cleaner +# state +send { +:function BeforeEachTest() + set all& + redir => groups + silent augroup + redir END + for group in split(groups) + exe 'augroup '.group + autocmd! + augroup NONE + exe 'augroup! '.group + endfor + tabnew + let curbufnum = eval(bufnr('%')) + redir => buflist + silent ls! + redir END + let bufnums = [] + for buf in split(buflist, '\n') + let bufnum = eval(split(buf, '[ u]')[0]) + if bufnum != curbufnum + call add(bufnums, bufnum) + endif + endfor + if len(bufnums) > 0 + exe 'silent bwipeout! '.join(bufnums, ' ') + endif + silent tabonly + for k in keys(g:) + exe 'unlet g:'.k + endfor + filetype plugin indent off + mapclear + mapclear! + abclear + comclear +endfunction +:echo "read"."y" +} +# wait until nvim is ready +expect "ready" +# run tests +spawn {*}$run_tests +set tests_id $spawn_id +set status 1 +# listen for test output in the background +expect_background { + * { + # show test output to the user + send_user -- $expect_out(buffer) + } + eof { + # collect the exit status code + set spawn_id $tests_id + catch wait result + set status [lindex $result 3] + set spawn_id $nvim_id + # quit nvim + send ":qa!\r" + } +} +# switch back nvim and wait until it exits +set spawn_id $nvim_id +expect eof +exit $status diff --git a/scripts/travis.sh b/scripts/travis.sh index 62c4fbe98e..2b97773b22 100755 --- a/scripts/travis.sh +++ b/scripts/travis.sh @@ -1,8 +1,45 @@ #!/bin/sh -e -check_and_report() { +tmpdir="$(pwd)/tmp" +rm -rf "$tmpdir" +mkdir -p "$tmpdir" +suppressions="$(pwd)/.valgrind.supp" + +valgrind_check() { ( - cd $tmpdir + cd $1 + set -- valgrind-[*] valgrind-* + case $1$2 in + 'valgrind-[*]valgrind-*') + ;; + *) + shift + local err='' + for valgrind_log in "$@"; do + # Remove useless warning + sed -i "$valgrind_log" \ + -e '/Warning: noted but unhandled ioctl/d' \ + -e '/could cause spurious value errors to appear/d' \ + -e '/See README_MISSING_SYSCALL_OR_IOCTL for guidance/d' + if [ "$(stat -c %s $valgrind_log)" != "0" ]; then + # if after removing the warning, the log still has errors, show its + # contents and set the flag so we exit with non-zero status + cat "$valgrind_log" + err=1 + fi + done + if [ -n "$err" ]; then + echo "Runtime errors detected" + exit 1 + fi + ;; + esac + ) +} + +asan_check() { + ( + cd $1 set -- [*]san.[*] *san.* case $1$2 in '[*]san.[*]*san.*') @@ -68,9 +105,6 @@ if [ "$TRAVIS_BUILD_TYPE" = "clang/asan" ]; then install_dir="$(pwd)/dist" # temporary directory for writing sanitizer logs - tmpdir="$(pwd)/tmp" - rm -rf "$tmpdir" - mkdir -p "$tmpdir" # need the symbolizer path for stack traces with source information if [ -n "$USE_CLANG_34" ]; then @@ -91,10 +125,10 @@ if [ "$TRAVIS_BUILD_TYPE" = "clang/asan" ]; then $MAKE_CMD if ! $MAKE_CMD test; then reset - check_and_report + asan_check "$tmpdir" exit 1 fi - check_and_report + asan_check "$tmpdir" coveralls --encoding iso-8859-1 || echo 'coveralls upload failed.' $MAKE_CMD install elif [ "$TRAVIS_BUILD_TYPE" = "gcc/unittest" ]; then @@ -129,4 +163,19 @@ elif [ "$TRAVIS_BUILD_TYPE" = "gcc/ia32" ]; then $MAKE_CMD test elif [ "$TRAVIS_BUILD_TYPE" = "clint" ]; then ./scripts/clint.sh +elif [ "$TRAVIS_BUILD_TYPE" = "api/python" ]; then + set_environment /opt/neovim-deps + $MAKE_CMD + sudo apt-get install expect valgrind + git clone --depth=1 -b master git://github.com/neovim/python-client + cd python-client + sudo pip install . + sudo pip install nose + test_cmd="nosetests --verbosity=2" + nvim_cmd="valgrind -q --track-origins=yes --leak-check=yes --suppressions=$suppressions --log-file=$tmpdir/valgrind-%p.log ../build/bin/nvim -u NONE" + if ! ../scripts/run-api-tests.exp "$test_cmd" "$nvim_cmd"; then + valgrind_check "$tmpdir" + exit 1 + fi + valgrind_check "$tmpdir" fi diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index d9ec65af86..bdb262731d 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -6,17 +6,6 @@ file(GLOB API_HEADERS api/*.h) set(MSGPACK_RPC_HEADER ${PROJECT_SOURCE_DIR}/src/nvim/os/msgpack_rpc.h) set(MSGPACK_DISPATCH ${GENERATED_DIR}/msgpack_dispatch.c) -# Remove helpers.h from API_HEADERS since it doesn't contain public API -# functions -foreach(sfile ${API_HEADERS}) - get_filename_component(f ${sfile} NAME) - if(${f} MATCHES "^(helpers.h)$") - list(APPEND to_remove ${sfile}) - endif() -endforeach() -list(REMOVE_ITEM API_HEADERS ${to_remove}) -set(to_remove) - file(MAKE_DIRECTORY ${GENERATED_DIR}) add_custom_command(OUTPUT ${MSGPACK_DISPATCH} @@ -42,11 +31,13 @@ list(APPEND NEOVIM_SOURCES "${MSGPACK_DISPATCH}") file( GLOB OS_SOURCES os/*.c ) file( GLOB API_SOURCES api/*.c ) +file( GLOB API_PRIV_SOURCES api/private/*.c ) set(CONV_SRCS api.c arabic.c garray.c + hashtab.c memory.c map.c os/env.c @@ -59,7 +50,8 @@ set(CONV_SRCS os/wstream.c os/msgpack_rpc.c api/buffer.c - api/helpers.c + api/private/helpers.c + api/private/handle.c api/tabpage.c api/window.c api/vim.h @@ -110,13 +102,14 @@ list(APPEND NVIM_LINK_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) if(NOT DEFINED ENV{SKIP_EXEC}) - add_executable(nvim ${NEOVIM_SOURCES} ${OS_SOURCES} ${API_SOURCES}) + add_executable(nvim ${NEOVIM_SOURCES} ${OS_SOURCES} ${API_SOURCES} + ${API_PRIV_SOURCES}) target_link_libraries(nvim ${NVIM_LINK_LIBRARIES}) install(TARGETS nvim RUNTIME DESTINATION bin) endif() if(NOT DEFINED ENV{SKIP_UNITTEST}) add_library(nvim-test MODULE EXCLUDE_FROM_ALL ${NEOVIM_SOURCES} - ${OS_SOURCES} ${API_SOURCES}) + ${OS_SOURCES} ${API_SOURCES} ${API_PRIV_SOURCES}) target_link_libraries(nvim-test ${NVIM_LINK_LIBRARIES}) endif() diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index e73823e5c3..4721045048 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -4,8 +4,8 @@ #include <stdlib.h> #include "nvim/api/buffer.h" -#include "nvim/api/helpers.h" -#include "nvim/api/defs.h" +#include "nvim/api/private/helpers.h" +#include "nvim/api/private/defs.h" #include "nvim/vim.h" #include "nvim/buffer.h" #include "nvim/memline.h" @@ -56,10 +56,12 @@ String buffer_get_line(Buffer buffer, Integer index, Error *err) String rv = {.size = 0}; StringArray slice = buffer_get_slice(buffer, index, index, true, true, err); - if (slice.size) { + if (!err->set && slice.size) { rv = slice.items[0]; } + free(slice.items); + return rv; } @@ -71,7 +73,7 @@ void buffer_set_line(Buffer buffer, Integer index, String line, Error *err) void buffer_del_line(Buffer buffer, Integer index, Error *err) { - StringArray array = {.size = 0}; + StringArray array = ARRAY_DICT_INIT; buffer_set_slice(buffer, index, index, true, true, array, err); } @@ -82,7 +84,7 @@ StringArray buffer_get_slice(Buffer buffer, Boolean include_end, Error *err) { - StringArray rv = {.size = 0}; + StringArray rv = ARRAY_DICT_INIT; buf_T *buf = find_buffer(buffer, err); if (!buf) { @@ -115,9 +117,7 @@ StringArray buffer_get_slice(Buffer buffer, end: if (err->set) { for (size_t i = 0; i < rv.size; i++) { - if (rv.items[i].data != NULL) { - free(rv.items[i].data); - } + free(rv.items[i].data); } free(rv.items); @@ -219,9 +219,9 @@ void buffer_set_slice(Buffer buffer, goto end; } - // Same as with replacing + // Same as with replacing, but we also need to free lines + free(lines[i]); lines[i] = NULL; - i++; extra++; } @@ -240,10 +240,8 @@ void buffer_set_slice(Buffer buffer, } end: - for (uint32_t i = 0; i < new_len; i++) { - if (lines[i] != NULL) { - free(lines[i]); - } + for (size_t i = 0; i < new_len; i++) { + free(lines[i]); } free(lines); @@ -298,9 +296,21 @@ void buffer_set_option(Buffer buffer, String name, Object value, Error *err) set_option_to(buf, SREQ_BUF, name, value, err); } +Integer buffer_get_number(Buffer buffer, Error *err) +{ + Integer rv = 0; + buf_T *buf = find_buffer(buffer, err); + + if (!buf) { + return rv; + } + + return buf->b_fnum; +} + String buffer_get_name(Buffer buffer, Error *err) { - String rv = {.size = 0, .data = ""}; + String rv = STRING_INIT; buf_T *buf = find_buffer(buffer, err); if (!buf || buf->b_ffname == NULL) { @@ -326,6 +336,7 @@ void buffer_set_name(Buffer buffer, String name, Error *err) // Using aucmd_*: autocommands will be executed by rename_buffer aucmd_prepbuf(&aco, buf); ren_ret = rename_buffer((char_u *)val); + free(val); aucmd_restbuf(&aco); if (try_end(err)) { @@ -357,7 +368,7 @@ Position buffer_get_mark(Buffer buffer, String name, Error *err) return rv; } - if (name.size != 0) { + if (name.size != 1) { set_api_error("mark name must be a single character", err); return rv; } diff --git a/src/nvim/api/buffer.h b/src/nvim/api/buffer.h index 5f39589679..52a3b7cdb3 100644 --- a/src/nvim/api/buffer.h +++ b/src/nvim/api/buffer.h @@ -4,7 +4,7 @@ #include <stdint.h> #include <stdbool.h> -#include "nvim/api/defs.h" +#include "nvim/api/private/defs.h" /// Gets the buffer line count /// @@ -104,6 +104,13 @@ Object buffer_get_option(Buffer buffer, String name, Error *err); /// @param[out] err Details of an error that may have occurred void buffer_set_option(Buffer buffer, String name, Object value, Error *err); +/// Gets the buffer number +/// +/// @param buffer The buffer handle +/// @param[out] err Details of an error that may have occurred +/// @return The buffer number +Integer buffer_get_number(Buffer buffer, Error *err); + /// Gets the full file name for the buffer /// /// @param buffer The buffer handle diff --git a/src/nvim/api/defs.h b/src/nvim/api/private/defs.h index 3ee50310fb..fbf9018043 100644 --- a/src/nvim/api/defs.h +++ b/src/nvim/api/private/defs.h @@ -1,10 +1,20 @@ -#ifndef NVIM_API_DEFS_H -#define NVIM_API_DEFS_H +#ifndef NVIM_API_PRIVATE_DEFS_H +#define NVIM_API_PRIVATE_DEFS_H #include <stdint.h> #include <stdbool.h> #include <string.h> +#define ARRAY_DICT_INIT {.size = 0, .items = NULL} +#define STRING_INIT {.data = NULL, .size = 0} +#define REMOTE_TYPE(type) typedef uint64_t type + +#define TYPED_ARRAY_OF(type) \ + typedef struct { \ + type *items; \ + size_t size; \ + } type##Array + // Basic types typedef struct { char msg[256]; @@ -20,16 +30,16 @@ typedef struct { size_t size; } String; -typedef Integer Buffer; -typedef Integer Window; -typedef Integer Tabpage; +REMOTE_TYPE(Buffer); +REMOTE_TYPE(Window); +REMOTE_TYPE(Tabpage); typedef struct object Object; -typedef struct { - String *items; - size_t size; -} StringArray; +TYPED_ARRAY_OF(Buffer); +TYPED_ARRAY_OF(Window); +TYPED_ARRAY_OF(Tabpage); +TYPED_ARRAY_OF(String); typedef struct { Integer row, col; @@ -75,5 +85,5 @@ struct key_value_pair { }; -#endif // NVIM_API_DEFS_H +#endif // NVIM_API_PRIVATE_DEFS_H diff --git a/src/nvim/api/private/handle.c b/src/nvim/api/private/handle.c new file mode 100644 index 0000000000..88d176fccb --- /dev/null +++ b/src/nvim/api/private/handle.c @@ -0,0 +1,40 @@ +#include <stdint.h> + +#include "nvim/vim.h" +#include "nvim/map.h" +#include "nvim/api/private/handle.h" + +#define HANDLE_INIT(name) name##_handles = map_new(uint64_t)() + +#define HANDLE_IMPL(type, name) \ + static Map(uint64_t) *name##_handles = NULL; \ + \ + type *handle_get_##name(uint64_t handle) \ + { \ + return map_get(uint64_t)(name##_handles, handle); \ + } \ + \ + void handle_register_##name(type *name) \ + { \ + assert(!name->handle); \ + name->handle = next_handle++; \ + map_put(uint64_t)(name##_handles, name->handle, name); \ + } \ + \ + void handle_unregister_##name(type *name) \ + { \ + map_del(uint64_t)(name##_handles, name->handle); \ + } + +static uint64_t next_handle = 1; + +HANDLE_IMPL(buf_T, buffer) +HANDLE_IMPL(win_T, window) +HANDLE_IMPL(tabpage_T, tabpage) + +void handle_init() +{ + HANDLE_INIT(buffer); + HANDLE_INIT(window); + HANDLE_INIT(tabpage); +} diff --git a/src/nvim/api/private/handle.h b/src/nvim/api/private/handle.h new file mode 100644 index 0000000000..1a196f6797 --- /dev/null +++ b/src/nvim/api/private/handle.h @@ -0,0 +1,20 @@ +#ifndef NVIM_API_PRIVATE_HANDLE_H +#define NVIM_API_PRIVATE_HANDLE_H + +#include "nvim/vim.h" +#include "nvim/buffer_defs.h" + +#define HANDLE_DECLS(type, name) \ + type *handle_get_##name(uint64_t handle); \ + void handle_register_##name(type *name); \ + void handle_unregister_##name(type *name); + +HANDLE_DECLS(buf_T, buffer) +HANDLE_DECLS(win_T, window) +HANDLE_DECLS(tabpage_T, tabpage) + +void handle_init(void); + + +#endif // NVIM_API_PRIVATE_HANDLE_H + diff --git a/src/nvim/api/helpers.c b/src/nvim/api/private/helpers.c index a193c8721e..861ac8cc1b 100644 --- a/src/nvim/api/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -2,8 +2,9 @@ #include <stdlib.h> #include <string.h> -#include "nvim/api/helpers.h" -#include "nvim/api/defs.h" +#include "nvim/api/private/helpers.h" +#include "nvim/api/private/defs.h" +#include "nvim/api/private/handle.h" #include "nvim/vim.h" #include "nvim/buffer.h" #include "nvim/window.h" @@ -66,7 +67,7 @@ bool try_end(Error *err) ET_ERROR, NULL, &should_free); - strncpy(err->msg, msg, sizeof(err->msg)); + xstrlcpy(err->msg, msg, sizeof(err->msg)); err->set = true; free_global_msglist(); @@ -266,6 +267,7 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) char *val = xstrndup(value.data.string.data, value.data.string.size); set_option_value_for(key, 0, val, opt_flags, type, to, err); + free(val); } cleanup: @@ -285,43 +287,29 @@ Object vim_to_object(typval_T *obj) buf_T *find_buffer(Buffer buffer, Error *err) { - if (buffer > INT_MAX || buffer < INT_MIN) { - set_api_error("Invalid buffer id", err); - return NULL; - } - - buf_T *buf = buflist_findnr((int)buffer); + buf_T *rv = handle_get_buffer(buffer); - if (buf == NULL) { + if (!rv) { set_api_error("Invalid buffer id", err); } - return buf; + return rv; } win_T * find_window(Window window, Error *err) { - tabpage_T *tp; - win_T *wp; + win_T *rv = handle_get_window(window); - FOR_ALL_TAB_WINDOWS(tp, wp) { - if (!--window) { - return wp; - } + if (!rv) { + set_api_error("Invalid window id", err); } - set_api_error("Invalid window id", err); - return NULL; + return rv; } tabpage_T * find_tab(Tabpage tabpage, Error *err) { - if (tabpage > INT_MAX || tabpage < INT_MIN) { - set_api_error("Invalid tabpage id", err); - return NULL; - } - - tabpage_T *rv = find_tabpage((int)tabpage); + tabpage_T *rv = handle_get_tabpage(tabpage); if (!rv) { set_api_error("Invalid tabpage id", err); @@ -332,7 +320,7 @@ tabpage_T * find_tab(Tabpage tabpage, Error *err) String cstr_to_string(const char *str) { if (str == NULL) { - return (String) { .data = NULL, .size = 0 }; + return (String) STRING_INIT; } size_t len = strlen(str); diff --git a/src/nvim/api/helpers.h b/src/nvim/api/private/helpers.h index f93487d62f..04b128d3f1 100644 --- a/src/nvim/api/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -1,14 +1,15 @@ -#ifndef NVIM_API_HELPERS_H -#define NVIM_API_HELPERS_H +#ifndef NVIM_API_PRIVATE_HELPERS_H +#define NVIM_API_PRIVATE_HELPERS_H #include <stdbool.h> -#include "nvim/api/defs.h" +#include "nvim/api/private/defs.h" #include "nvim/vim.h" +#include "nvim/memory.h" #define set_api_error(message, err) \ do { \ - strncpy(err->msg, message, sizeof(err->msg)); \ + xstrlcpy(err->msg, message, sizeof(err->msg)); \ err->set = true; \ } while (0) @@ -93,5 +94,5 @@ tabpage_T * find_tab(Tabpage tabpage, Error *err); /// empty String is returned String cstr_to_string(const char *str); -#endif // NVIM_API_HELPERS_H +#endif // NVIM_API_PRIVATE_HELPERS_H diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c index fc50723ba5..b7243c68a8 100644 --- a/src/nvim/api/tabpage.c +++ b/src/nvim/api/tabpage.c @@ -4,12 +4,13 @@ #include "nvim/api/tabpage.h" #include "nvim/api/vim.h" -#include "nvim/api/defs.h" -#include "nvim/api/helpers.h" +#include "nvim/api/private/defs.h" +#include "nvim/api/private/helpers.h" +#include "nvim/memory.h" -Integer tabpage_get_window_count(Tabpage tabpage, Error *err) +WindowArray tabpage_get_windows(Tabpage tabpage, Error *err) { - Integer rv = 0; + WindowArray rv = ARRAY_DICT_INIT; tabpage_T *tab = find_tab(tabpage, err); if (!tab) { @@ -23,7 +24,17 @@ Integer tabpage_get_window_count(Tabpage tabpage, Error *err) if (tp != tab) { break; } - rv++; + rv.size++; + } + + rv.items = xmalloc(sizeof(Window) * rv.size); + size_t i = 0; + + FOR_ALL_TAB_WINDOWS(tp, wp) { + if (tp != tab) { + break; + } + rv.items[i++] = wp->handle; } return rv; @@ -67,13 +78,11 @@ Window tabpage_get_window(Tabpage tabpage, Error *err) } else { tabpage_T *tp; win_T *wp; - rv = 1; FOR_ALL_TAB_WINDOWS(tp, wp) { if (tp == tab && wp == tab->tp_curwin) { - return rv; + return wp->handle; } - rv++; } // There should always be a current window for a tabpage abort(); diff --git a/src/nvim/api/tabpage.h b/src/nvim/api/tabpage.h index ef049fb644..dddcecbdbd 100644 --- a/src/nvim/api/tabpage.h +++ b/src/nvim/api/tabpage.h @@ -4,14 +4,14 @@ #include <stdint.h> #include <stdbool.h> -#include "nvim/api/defs.h" +#include "nvim/api/private/defs.h" /// Gets the number of windows in a tabpage /// /// @param tabpage The tabpage /// @param[out] err Details of an error that may have occurred /// @return The number of windows in `tabpage` -Integer tabpage_get_window_count(Tabpage tabpage, Error *err); +WindowArray tabpage_get_windows(Tabpage tabpage, Error *err); /// Gets a tabpage variable /// diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 505844e651..694781e0a3 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -4,8 +4,8 @@ #include <string.h> #include "nvim/api/vim.h" -#include "nvim/api/helpers.h" -#include "nvim/api/defs.h" +#include "nvim/api/private/helpers.h" +#include "nvim/api/private/defs.h" #include "nvim/api/buffer.h" #include "nvim/vim.h" #include "nvim/buffer.h" @@ -73,12 +73,15 @@ Integer vim_strwidth(String str, Error *err) return 0; } - return mb_string2cells((char_u *)str.data, (int)str.size); + char *buf = xstrndup(str.data, str.size); + Integer rv = mb_string2cells((char_u *)buf, -1); + free(buf); + return rv; } StringArray vim_list_runtime_paths(void) { - StringArray rv = {.size = 0}; + StringArray rv = ARRAY_DICT_INIT; uint8_t *rtp = p_rtp; if (*rtp == NUL) { @@ -94,14 +97,12 @@ StringArray vim_list_runtime_paths(void) rtp++; } - // index - uint32_t i = 0; // Allocate memory for the copies rv.items = xmalloc(sizeof(String) * rv.size); // reset the position rtp = p_rtp; // Start copying - while (*rtp != NUL) { + for (size_t i = 0; i < rv.size && *rtp != NUL; i++) { rv.items[i].data = xmalloc(MAXPATHL); // Copy the path from 'runtimepath' to rv.items[i] int length = copy_option_part(&rtp, @@ -110,7 +111,6 @@ StringArray vim_list_runtime_paths(void) ","); assert(length >= 0); rv.items[i].size = (size_t)length; - i++; } return rv; @@ -118,8 +118,14 @@ StringArray vim_list_runtime_paths(void) void vim_change_directory(String dir, Error *err) { + if (dir.size >= MAXPATHL) { + set_api_error("directory string is too long", err); + return; + } + char string[MAXPATHL]; strncpy(string, dir.data, dir.size); + string[dir.size] = NUL; try_start(); @@ -136,17 +142,17 @@ void vim_change_directory(String dir, Error *err) String vim_get_current_line(Error *err) { - return buffer_get_line(curbuf->b_fnum, curwin->w_cursor.lnum - 1, err); + return buffer_get_line(curbuf->handle, curwin->w_cursor.lnum - 1, err); } void vim_set_current_line(String line, Error *err) { - buffer_set_line(curbuf->b_fnum, curwin->w_cursor.lnum - 1, line, err); + buffer_set_line(curbuf->handle, curwin->w_cursor.lnum - 1, line, err); } void vim_del_current_line(Error *err) { - buffer_del_line(curbuf->b_fnum, curwin->w_cursor.lnum - 1, err); + buffer_del_line(curbuf->handle, curwin->w_cursor.lnum - 1, err); } Object vim_get_var(String name, Error *err) @@ -184,32 +190,43 @@ void vim_err_write(String str) write_msg(str, true); } -Integer vim_get_buffer_count(void) +BufferArray vim_get_buffers(void) { + BufferArray rv = ARRAY_DICT_INIT; buf_T *b = firstbuf; - Integer n = 0; while (b) { - n++; + rv.size++; b = b->b_next; } - return n; + rv.items = xmalloc(sizeof(Buffer) * rv.size); + size_t i = 0; + b = firstbuf; + + while (b) { + rv.items[i++] = b->handle; + b = b->b_next; + } + + return rv; } Buffer vim_get_current_buffer(void) { - return curbuf->b_fnum; + return curbuf->handle; } void vim_set_current_buffer(Buffer buffer, Error *err) { - if (!find_buffer(buffer, err)) { + buf_T *buf = find_buffer(buffer, err); + + if (!buf) { return; } try_start(); - if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, (int)buffer, 0) == FAIL) { + if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0) == FAIL) { if (try_end(err)) { return; } @@ -223,14 +240,21 @@ void vim_set_current_buffer(Buffer buffer, Error *err) try_end(err); } -Integer vim_get_window_count(void) +WindowArray vim_get_windows(void) { + WindowArray rv = ARRAY_DICT_INIT; tabpage_T *tp; win_T *wp; - Integer rv = 0; FOR_ALL_TAB_WINDOWS(tp, wp) { - rv++; + rv.size++; + } + + rv.items = xmalloc(sizeof(Window) * rv.size); + size_t i = 0; + + FOR_ALL_TAB_WINDOWS(tp, wp) { + rv.items[i++] = wp->handle; } return rv; @@ -238,20 +262,7 @@ Integer vim_get_window_count(void) Window vim_get_current_window(void) { - tabpage_T *tp; - win_T *wp; - Window rv = 1; - - FOR_ALL_TAB_WINDOWS(tp, wp) { - if (wp == curwin) { - return rv; - } - - rv++; - } - - // There should always be a current window - abort(); + return curwin->handle; } void vim_set_current_window(Window window, Error *err) @@ -263,7 +274,7 @@ void vim_set_current_window(Window window, Error *err) } try_start(); - win_goto(win); + goto_tabpage_win(win_find_tabpage(win), win); if (win != curwin) { if (try_end(err)) { @@ -276,14 +287,23 @@ void vim_set_current_window(Window window, Error *err) try_end(err); } -Integer vim_get_tabpage_count(void) +TabpageArray vim_get_tabpages(void) { + TabpageArray rv = ARRAY_DICT_INIT; tabpage_T *tp = first_tabpage; - Integer rv = 0; - while (tp != NULL) { + while (tp) { + rv.size++; + tp = tp->tp_next; + } + + rv.items = xmalloc(sizeof(Tabpage) * rv.size); + size_t i = 0; + tp = first_tabpage; + + while (tp) { + rv.items[i++] = tp->handle; tp = tp->tp_next; - rv++; } return rv; @@ -291,24 +311,19 @@ Integer vim_get_tabpage_count(void) Tabpage vim_get_current_tabpage(void) { - Tabpage rv = 1; - tabpage_T *t; - - for (t = first_tabpage; t != NULL && t != curtab; t = t->tp_next) { - rv++; - } - - return rv; + return curtab->handle; } void vim_set_current_tabpage(Tabpage tabpage, Error *err) { - if (!find_tab(tabpage, err)) { + tabpage_T *tp = find_tab(tabpage, err); + + if (!tp) { return; } try_start(); - goto_tabpage((int)tabpage); + goto_tabpage_tp(tp, true, true); try_end(err); } diff --git a/src/nvim/api/vim.h b/src/nvim/api/vim.h index 4ecc9fc2d0..acfab11cf7 100644 --- a/src/nvim/api/vim.h +++ b/src/nvim/api/vim.h @@ -4,7 +4,7 @@ #include <stdint.h> #include <stdbool.h> -#include "nvim/api/defs.h" +#include "nvim/api/private/defs.h" /// Send keys to vim input buffer, simulating user input. /// @@ -108,10 +108,10 @@ void vim_out_write(String str); /// @param str The message void vim_err_write(String str); -/// Gets the number of buffers +/// Gets the current list of buffer handles /// /// @return The number of buffers -Integer vim_get_buffer_count(void); +BufferArray vim_get_buffers(void); /// Return the current buffer /// @@ -124,10 +124,10 @@ Buffer vim_get_current_buffer(void); /// @param[out] err Details of an error that may have occurred void vim_set_current_buffer(Buffer buffer, Error *err); -/// Gets the number of windows +/// Gets the current list of window handles /// /// @return The number of windows -Integer vim_get_window_count(void); +WindowArray vim_get_windows(void); /// Return the current window /// @@ -139,10 +139,10 @@ Window vim_get_current_window(void); /// @param handle The window handle void vim_set_current_window(Window window, Error *err); -/// Gets the number of tab pages +/// Gets the current list of tabpage handles /// /// @return The number of tab pages -Integer vim_get_tabpage_count(void); +TabpageArray vim_get_tabpages(void); /// Return the current tab page /// diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index 8e21034c40..8bd8316477 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -3,8 +3,8 @@ #include <stdlib.h> #include "nvim/api/window.h" -#include "nvim/api/defs.h" -#include "nvim/api/helpers.h" +#include "nvim/api/private/defs.h" +#include "nvim/api/private/helpers.h" #include "nvim/vim.h" #include "nvim/window.h" #include "nvim/screen.h" @@ -19,7 +19,7 @@ Buffer window_get_buffer(Window window, Error *err) return 0; } - return win->w_buffer->b_fnum; + return win->w_buffer->handle; } Position window_get_cursor(Window window, Error *err) @@ -192,8 +192,14 @@ Position window_get_position(Window window, Error *err) Tabpage window_get_tabpage(Window window, Error *err) { - set_api_error("Not implemented", err); - return 0; + Tabpage rv = 0; + win_T *win = find_window(window, err); + + if (win) { + rv = win_find_tabpage(win)->handle; + } + + return rv; } Boolean window_is_valid(Window window) diff --git a/src/nvim/api/window.h b/src/nvim/api/window.h index 525b7f86c7..4c036ff5d7 100644 --- a/src/nvim/api/window.h +++ b/src/nvim/api/window.h @@ -4,7 +4,7 @@ #include <stdint.h> #include <stdbool.h> -#include "nvim/api/defs.h" +#include "nvim/api/private/defs.h" /// Gets the current buffer in a window /// diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 03dd972df1..7c50b1721c 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -26,6 +26,7 @@ #include <string.h> +#include "nvim/api/private/handle.h" #include "nvim/vim.h" #include "nvim/buffer.h" #include "nvim/charset.h" @@ -538,6 +539,7 @@ void buf_freeall(buf_T *buf, int flags) */ static void free_buffer(buf_T *buf) { + handle_unregister_buffer(buf); free_buffer_stuff(buf, TRUE); unref_var_dict(buf->b_vars); aubuflocal_remove(buf); @@ -1362,6 +1364,7 @@ buflist_new ( } if (buf != curbuf || curbuf == NULL) { buf = xcalloc(1, sizeof(buf_T)); + handle_register_buffer(buf); /* init b: variables */ buf->b_vars = dict_alloc(); init_var_dict(buf->b_vars, &buf->b_bufvar, VAR_SCOPE); @@ -2235,9 +2238,8 @@ setfname ( close_buffer(NULL, obuf, DOBUF_WIPE, FALSE); } sfname = vim_strsave(sfname); - if (ffname == NULL || sfname == NULL) { + if (ffname == NULL) { free(sfname); - free(ffname); return FAIL; } #ifdef USE_FNAME_CASE @@ -4114,8 +4116,6 @@ chk_modeline ( while (s[-1] != ':'); s = linecopy = vim_strsave(s); /* copy the line, it will change */ - if (linecopy == NULL) - return FAIL; save_sourcing_lnum = sourcing_lnum; save_sourcing_name = sourcing_name; diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index d658da9502..0a24280b4a 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -401,6 +401,7 @@ typedef struct { */ struct file_buffer { + uint64_t handle; // unique identifier for the buffer memline_T b_ml; /* associated memline (also contains line count) */ @@ -737,6 +738,7 @@ struct diffblock_S { */ typedef struct tabpage_S tabpage_T; struct tabpage_S { + uint64_t handle; tabpage_T *tp_next; /* next tabpage or NULL */ frame_T *tp_topframe; /* topframe for the windows */ win_T *tp_curwin; /* current window in this Tab page */ @@ -839,6 +841,7 @@ struct matchitem { * All row numbers are relative to the start of the window, except w_winrow. */ struct window_S { + uint64_t handle; buf_T *w_buffer; /* buffer we are a window into (used often, keep it the first item!) */ diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 6618a7c22d..ae5da557d5 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1910,10 +1910,8 @@ void backslash_halve(char_u *p) /// @return String with the number of backslashes halved. char_u* backslash_halve_save(char_u *p) { + // TODO(philix): simplify and improve backslash_halve_save algorithm char_u *res = vim_strsave(p); - if (res == NULL) { - return p; - } backslash_halve(res); return res; } diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 0e5d1c20b7..06416639bd 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -519,10 +519,6 @@ static void diff_check_unchanged(tabpage_T *tp, diff_T *dp) dp->df_lnum[i_org] + off_org, FALSE)); - if (line_org == NULL) { - return; - } - int i_new; for (i_new = i_org + 1; i_new < DB_COUNT; ++i_new) { if (tp->tp_diffbuf[i_new] == NULL) { @@ -972,10 +968,7 @@ void ex_diffpatch(exarg_T *eap) if (curbuf->b_fname != NULL) { newname = vim_strnsave(curbuf->b_fname, (int)(STRLEN(curbuf->b_fname) + 4)); - - if (newname != NULL) { - STRCAT(newname, ".new"); - } + STRCAT(newname, ".new"); } // don't use a new tab page, each tab page has its own diffs @@ -1580,9 +1573,6 @@ static int diff_equal_entry(diff_T *dp, int idx1, int idx2) char_u *line = vim_strsave(ml_get_buf(curtab->tp_diffbuf[idx1], dp->df_lnum[idx1] + i, FALSE)); - if (line == NULL) { - return FALSE; - } int cmp = diff_cmp(line, ml_get_buf(curtab->tp_diffbuf[idx2], dp->df_lnum[idx2] + i, FALSE)); free(line); @@ -1886,9 +1876,6 @@ int diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp) // Make a copy of the line, the next ml_get() will invalidate it. char_u *line_org = vim_strsave(ml_get_buf(wp->w_buffer, lnum, FALSE)); - if (line_org == NULL) { - return FALSE; - } int idx = diff_buf_idx(wp->w_buffer); if (idx == DB_COUNT) { @@ -2283,16 +2270,14 @@ void ex_diffgetput(exarg_T *eap) break; } p = vim_strsave(ml_get_buf(curtab->tp_diffbuf[idx_from], nr, FALSE)); - if (p != NULL) { - ml_append(lnum + i - 1, p, 0, FALSE); - free(p); - added++; - if (buf_empty && (curbuf->b_ml.ml_line_count == 2)) { - // Added the first line into an empty buffer, need to - // delete the dummy empty line. - buf_empty = FALSE; - ml_delete((linenr_T)2, FALSE); - } + ml_append(lnum + i - 1, p, 0, FALSE); + free(p); + added++; + if (buf_empty && (curbuf->b_ml.ml_line_count == 2)) { + // Added the first line into an empty buffer, need to + // delete the dummy empty line. + buf_empty = FALSE; + ml_delete((linenr_T)2, FALSE); } } new_count = dp->df_count[idx_to] + added; diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c index b7f0c40788..443640d23d 100644 --- a/src/nvim/digraph.c +++ b/src/nvim/digraph.c @@ -1738,28 +1738,24 @@ char_u* keymap_init(void) keymap_unload(); do_cmdline_cmd((char_u *)"unlet! b:keymap_name"); } else { - char_u *buf; + char *buf; size_t buflen; // Source the keymap file. It will contain a ":loadkeymap" command // which will call ex_loadkeymap() below. buflen = STRLEN(curbuf->b_p_keymap) + STRLEN(p_enc) + 14; - buf = alloc((unsigned)buflen); - - if (buf == NULL) { - return e_outofmem; - } + buf = xmalloc(buflen); // try finding "keymap/'keymap'_'encoding'.vim" in 'runtimepath' - vim_snprintf((char *)buf, buflen, "keymap/%s_%s.vim", + vim_snprintf(buf, buflen, "keymap/%s_%s.vim", curbuf->b_p_keymap, p_enc); - if (source_runtime(buf, FALSE) == FAIL) { + if (source_runtime((char_u *)buf, FALSE) == FAIL) { // try finding "keymap/'keymap'.vim" in 'runtimepath' - vim_snprintf((char *)buf, buflen, "keymap/%s.vim", + vim_snprintf(buf, buflen, "keymap/%s.vim", curbuf->b_p_keymap); - if (source_runtime(buf, FALSE) == FAIL) { + if (source_runtime((char_u *)buf, FALSE) == FAIL) { free(buf); return (char_u *)N_("E544: Keymap file not found"); } @@ -1818,12 +1814,10 @@ void ex_loadkeymap(exarg_T *eap) s = skiptowhite(p); kp->to = vim_strnsave(p, (int)(s - p)); - if ((kp->from == NULL) - || (kp->to == NULL) - || (STRLEN(kp->from) + STRLEN(kp->to) >= KMAP_LLEN) + if ((STRLEN(kp->from) + STRLEN(kp->to) >= KMAP_LLEN) || (*kp->from == NUL) || (*kp->to == NUL)) { - if ((kp->to != NULL) && (*kp->to == NUL)) { + if (*kp->to == NUL) { EMSG(_("E791: Empty keymap entry")); } free(kp->from); diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 440787643e..1dcc86b7db 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1727,8 +1727,6 @@ change_indent ( /* Save new line */ new_line = vim_strsave(ml_get_curline()); - if (new_line == NULL) - return; /* We only put back the new line up to the cursor */ new_line[curwin->w_cursor.col] = NUL; @@ -2128,10 +2126,7 @@ ins_compl_add ( match->cp_number = -1; if (flags & ORIGINAL_TEXT) match->cp_number = 0; - if ((match->cp_str = vim_strnsave(str, len)) == NULL) { - free(match); - return FAIL; - } + match->cp_str = vim_strnsave(str, len); match->cp_icase = icase; /* match-fname is: @@ -2210,18 +2205,16 @@ static void ins_compl_longest_match(compl_T *match) if (compl_leader == NULL) { /* First match, use it as a whole. */ compl_leader = vim_strsave(match->cp_str); - if (compl_leader != NULL) { - had_match = (curwin->w_cursor.col > compl_col); - ins_compl_delete(); - ins_bytes(compl_leader + ins_compl_len()); - ins_redraw(FALSE); + had_match = (curwin->w_cursor.col > compl_col); + ins_compl_delete(); + ins_bytes(compl_leader + ins_compl_len()); + ins_redraw(FALSE); - /* When the match isn't there (to avoid matching itself) remove it - * again after redrawing. */ - if (!had_match) - ins_compl_delete(); - compl_used_match = FALSE; - } + /* When the match isn't there (to avoid matching itself) remove it + * again after redrawing. */ + if (!had_match) + ins_compl_delete(); + compl_used_match = FALSE; } else { /* Reduce the text if this match differs from compl_leader. */ p = compl_leader; @@ -2328,9 +2321,10 @@ void set_completion(colnr_T startcol, list_T *list) compl_length = (int)curwin->w_cursor.col - (int)startcol; /* compl_pattern doesn't need to be set */ compl_orig_text = vim_strnsave(ml_get_curline() + compl_col, compl_length); - if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, - -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK) + if (ins_compl_add(compl_orig_text, -1, p_ic, NULL, NULL, 0, + ORIGINAL_TEXT, FALSE) != OK) { return; + } /* Handle like dictionary completion. */ ctrl_x_mode = CTRL_X_WHOLE_LINE; @@ -2873,14 +2867,12 @@ static int ins_compl_bs(void) free(compl_leader); compl_leader = vim_strnsave(line + compl_col, (int)(p - line) - compl_col); - if (compl_leader != NULL) { - ins_compl_new_leader(); - if (compl_shown_match != NULL) - /* Make sure current match is not a hidden item. */ - compl_curr_match = compl_shown_match; - return NUL; - } - return K_BS; + ins_compl_new_leader(); + if (compl_shown_match != NULL) + /* Make sure current match is not a hidden item. */ + compl_curr_match = compl_shown_match; + + return NUL; } /* @@ -2980,8 +2972,7 @@ static void ins_compl_addleader(int c) free(compl_leader); compl_leader = vim_strnsave(ml_get_curline() + compl_col, (int)(curwin->w_cursor.col - compl_col)); - if (compl_leader != NULL) - ins_compl_new_leader(); + ins_compl_new_leader(); } } @@ -3003,15 +2994,10 @@ static void ins_compl_restart(void) */ static void ins_compl_set_original_text(char_u *str) { - char_u *p; - /* Replace the original text entry. */ if (compl_first_match->cp_flags & ORIGINAL_TEXT) { /* safety check */ - p = vim_strsave(str); - if (p != NULL) { - free(compl_first_match->cp_str); - compl_first_match->cp_str = p; - } + free(compl_first_match->cp_str); + compl_first_match->cp_str = vim_strsave(str); } } @@ -4356,8 +4342,6 @@ static int ins_complete(int c) ) { /* Match any word of at least two chars */ compl_pattern = vim_strsave((char_u *)"\\<\\k\\k"); - if (compl_pattern == NULL) - return FAIL; compl_col += curs_col; compl_length = 0; } else { @@ -4432,8 +4416,6 @@ static int ins_complete(int c) return FAIL; } else if (ctrl_x_mode == CTRL_X_CMDLINE) { compl_pattern = vim_strnsave(line, curs_col); - if (compl_pattern == NULL) - return FAIL; set_cmd_context(&compl_xp, compl_pattern, (int)STRLEN(compl_pattern), curs_col); if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL @@ -4513,8 +4495,6 @@ static int ins_complete(int c) line = ml_get(curwin->w_cursor.lnum); compl_length = curs_col - compl_col; compl_pattern = vim_strnsave(line + compl_col, compl_length); - if (compl_pattern == NULL) - return FAIL; } else if (ctrl_x_mode == CTRL_X_SPELL) { if (spell_bad_len > 0) compl_col = curs_col - spell_bad_len; @@ -4530,8 +4510,6 @@ static int ins_complete(int c) /* Need to obtain "line" again, it may have become invalid. */ line = ml_get(curwin->w_cursor.lnum); compl_pattern = vim_strnsave(line + compl_col, compl_length); - if (compl_pattern == NULL) - return FAIL; } else { EMSG2(_(e_intern2), "ins_complete()"); return FAIL; @@ -4568,8 +4546,8 @@ static int ins_complete(int c) /* Always add completion for the original text. */ free(compl_orig_text); compl_orig_text = vim_strnsave(line + compl_col, compl_length); - if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, - -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK) { + if (ins_compl_add(compl_orig_text, -1, p_ic, NULL, NULL, 0, + ORIGINAL_TEXT, FALSE) != OK) { free(compl_pattern); compl_pattern = NULL; free(compl_orig_text); @@ -6227,11 +6205,10 @@ char_u *get_last_insert_save(void) if (last_insert == NULL) return NULL; s = vim_strsave(last_insert + last_insert_skip); - if (s != NULL) { - len = (int)STRLEN(s); - if (len > 0 && s[len - 1] == ESC) /* remove trailing ESC */ - s[len - 1] = NUL; - } + len = (int)STRLEN(s); + if (len > 0 && s[len - 1] == ESC) /* remove trailing ESC */ + s[len - 1] = NUL; + return s; } @@ -6265,37 +6242,33 @@ static int echeck_abbr(int c) * For a newline, there are two NUL headed lists. One contains the characters * that the NL replaced. The extra one stores the characters after the cursor * that were deleted (always white space). - * - * Replace_offset is normally 0, in which case replace_push will add a new - * character at the end of the stack. If replace_offset is not 0, that many - * characters will be left on the stack above the newly inserted character. */ static char_u *replace_stack = NULL; static ssize_t replace_stack_nr = 0; /* next entry in replace stack */ static ssize_t replace_stack_len = 0; /* max. number of entries */ -void -replace_push ( - int c /* character that is replaced (NUL is none) */ -) +/// Push character that is replaced onto the the replace stack. +/// +/// replace_offset is normally 0, in which case replace_push will add a new +/// character at the end of the stack. If replace_offset is not 0, that many +/// characters will be left on the stack above the newly inserted character. +/// +/// @param c character that is replaced (NUL is none) +void replace_push(int c) { - if (replace_stack_nr < replace_offset) /* nothing to do */ + if (replace_stack_nr < replace_offset) { // nothing to do return; + } - // TODO(philix): use xrealloc in replace_push() if (replace_stack_len <= replace_stack_nr) { replace_stack_len += 50; - void *aux = xmalloc(replace_stack_len); - if (replace_stack != NULL) { - memmove(aux, replace_stack, replace_stack_nr); - free(replace_stack); - } - replace_stack = aux; + replace_stack = xrealloc(replace_stack, replace_stack_len); } char_u *p = replace_stack + replace_stack_nr - replace_offset; - if (replace_offset) + if (replace_offset) { memmove(p + 1, p, replace_offset); + } *p = (char_u)c; ++replace_stack_nr; } @@ -6315,16 +6288,12 @@ int replace_push_mb(char_u *p) return l; } -/* - * Pop one item from the replace stack. - * return -1 if stack empty - * return replaced character or NUL otherwise - */ +/// Pop one item from the replace stack. +/// +/// @return -1 if stack is empty, replaced character or NUL otherwise static int replace_pop(void) { - if (replace_stack_nr == 0) - return -1; - return (int)replace_stack[--replace_stack_nr]; + return (replace_stack_nr == 0) ? -1 : (int)replace_stack[--replace_stack_nr]; } /* @@ -8006,8 +7975,6 @@ static int ins_tab(void) pos = curwin->w_cursor; cursor = &pos; saved_line = vim_strsave(ml_get_curline()); - if (saved_line == NULL) - return FALSE; ptr = saved_line + pos.col; } else { ptr = ml_get_cursor(); @@ -8411,7 +8378,6 @@ static colnr_T get_nolist_virtcol(void) */ static char_u *do_insert_char_pre(int c) { - char_u *res; char_u buf[MB_MAXBYTES + 1]; /* Return quickly when there is nothing to do. */ @@ -8429,7 +8395,7 @@ static char_u *do_insert_char_pre(int c) ++textlock; set_vim_var_string(VV_CHAR, buf, -1); /* set v:char */ - res = NULL; + char_u *res = NULL; if (apply_autocmds(EVENT_INSERTCHARPRE, NULL, NULL, FALSE, curbuf)) { /* Get the value of v:char. It may be empty or more than one * character. Only use it when changed, otherwise continue with the diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 6e0681420b..87054aa9df 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -12,7 +12,6 @@ #include <string.h> #include <stdlib.h> - #include "nvim/vim.h" #include "nvim/eval.h" #include "nvim/buffer.h" @@ -67,6 +66,7 @@ #include "nvim/os/rstream.h" #include "nvim/os/rstream_defs.h" #include "nvim/os/time.h" +#include "nvim/os/channel.h" #if defined(FEAT_FLOAT) # include <math.h> @@ -680,11 +680,6 @@ static void f_range(typval_T *argvars, typval_T *rettv); static void f_readfile(typval_T *argvars, typval_T *rettv); static void f_reltime(typval_T *argvars, typval_T *rettv); static void f_reltimestr(typval_T *argvars, typval_T *rettv); -static void f_remote_expr(typval_T *argvars, typval_T *rettv); -static void f_remote_foreground(typval_T *argvars, typval_T *rettv); -static void f_remote_peek(typval_T *argvars, typval_T *rettv); -static void f_remote_read(typval_T *argvars, typval_T *rettv); -static void f_remote_send(typval_T *argvars, typval_T *rettv); static void f_remove(typval_T *argvars, typval_T *rettv); static void f_rename(typval_T *argvars, typval_T *rettv); static void f_repeat(typval_T *argvars, typval_T *rettv); @@ -700,8 +695,7 @@ static void f_searchdecl(typval_T *argvars, typval_T *rettv); static void f_searchpair(typval_T *argvars, typval_T *rettv); static void f_searchpairpos(typval_T *argvars, typval_T *rettv); static void f_searchpos(typval_T *argvars, typval_T *rettv); -static void f_server2client(typval_T *argvars, typval_T *rettv); -static void f_serverlist(typval_T *argvars, typval_T *rettv); +static void f_send_event(typval_T *argvars, typval_T *rettv); static void f_setbufvar(typval_T *argvars, typval_T *rettv); static void f_setcmdpos(typval_T *argvars, typval_T *rettv); static void f_setline(typval_T *argvars, typval_T *rettv); @@ -1040,8 +1034,6 @@ var_redir_start ( /* Make a copy of the name, it is used in redir_lval until redir ends. */ redir_varname = vim_strsave(name); - if (redir_varname == NULL) - return FAIL; redir_lval = xcalloc(1, sizeof(lval_T)); @@ -1457,12 +1449,11 @@ int get_spellword(list_T *list, char_u **pp) */ typval_T *eval_expr(char_u *arg, char_u **nextcmd) { - typval_T *tv; + typval_T *tv = xmalloc(sizeof(typval_T)); - tv = (typval_T *)alloc(sizeof(typval_T)); - if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL) { + if (eval0(arg, tv, nextcmd, TRUE) == FAIL) { free(tv); - tv = NULL; + return NULL; } return tv; @@ -1485,7 +1476,6 @@ call_vim_function ( typval_T *rettv ) { - typval_T *argvars; long n; int len; int i; @@ -1493,9 +1483,7 @@ call_vim_function ( void *save_funccalp = NULL; int ret; - argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T))); - if (argvars == NULL) - return FAIL; + typval_T *argvars = xmalloc((argc + 1) * sizeof(typval_T)); for (i = 0; i < argc; i++) { /* Pass a NULL or empty argument as an empty string */ @@ -2541,8 +2529,6 @@ get_lval ( lp->ll_newkey = vim_strnsave(key, len); if (len == -1) clear_tv(&var1); - if (lp->ll_newkey == NULL) - p = NULL; break; } /* existing variable, need to check if it can be changed */ @@ -3429,20 +3415,19 @@ void del_menutrans_vars(void) static char_u *cat_prefix_varname(int prefix, char_u *name); static char_u *varnamebuf = NULL; -static int varnamebuflen = 0; +static size_t varnamebuflen = 0; /* * Function to concatenate a prefix and a variable name. */ static char_u *cat_prefix_varname(int prefix, char_u *name) { - int len; + size_t len = STRLEN(name) + 3; - len = (int)STRLEN(name) + 3; if (len > varnamebuflen) { free(varnamebuf); len += 10; /* some additional space */ - varnamebuf = alloc(len); + varnamebuf = xmalloc(len); if (varnamebuf == NULL) { varnamebuflen = 0; return NULL; @@ -4924,9 +4909,7 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate) * Copy the string into allocated memory, handling backslashed * characters. */ - name = alloc((unsigned)(p - *arg + extra)); - if (name == NULL) - return FAIL; + name = xmalloc(p - *arg + extra); rettv->v_type = VAR_STRING; rettv->vval.v_string = name; @@ -5041,9 +5024,7 @@ static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate) /* * Copy the string into allocated memory, handling '' to ' reduction. */ - str = alloc((unsigned)((p - *arg) - reduce)); - if (str == NULL) - return FAIL; + str = xmalloc((p - *arg) - reduce); rettv->v_type = VAR_STRING; rettv->vval.v_string = str; @@ -5192,7 +5173,7 @@ list_free ( */ listitem_T *listitem_alloc(void) { - return (listitem_T *)alloc(sizeof(listitem_T)); + return xmalloc(sizeof(listitem_T)); } /* @@ -6157,17 +6138,12 @@ dict_free ( * Allocate a Dictionary item. * The "key" is copied to the new item. * Note that the value of the item "di_tv" still needs to be initialized! - * Returns NULL when out of memory. */ dictitem_T *dictitem_alloc(char_u *key) { - dictitem_T *di; - - di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key))); - if (di != NULL) { - STRCPY(di->di_key, key); - di->di_flags = 0; - } + dictitem_T *di = xmalloc(sizeof(dictitem_T) + STRLEN(key)); + STRCPY(di->di_key, key); + di->di_flags = 0; return di; } @@ -6176,15 +6152,12 @@ dictitem_T *dictitem_alloc(char_u *key) */ static dictitem_T *dictitem_copy(dictitem_T *org) { - dictitem_T *di; + dictitem_T *di = xmalloc(sizeof(dictitem_T) + STRLEN(org->di_key)); + + STRCPY(di->di_key, org->di_key); + di->di_flags = 0; + copy_tv(&org->di_tv, &di->di_tv); - di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) - + STRLEN(org->di_key))); - if (di != NULL) { - STRCPY(di->di_key, org->di_key); - di->di_flags = 0; - copy_tv(&org->di_tv, &di->di_tv); - } return di; } @@ -6352,8 +6325,6 @@ dictitem_T *dict_find(dict_T *d, char_u *key, int len) akey = key; else if (len >= AKEYLEN) { tofree = akey = vim_strnsave(key, len); - if (akey == NULL) - return NULL; } else { /* Avoid a malloc/free by using buf[]. */ vim_strncpy(buf, key, len); @@ -6673,34 +6644,33 @@ static char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copy */ static char_u *string_quote(char_u *str, int function) { - unsigned len; char_u *p, *r, *s; - len = (function ? 13 : 3); + size_t len = (function ? 13 : 3); if (str != NULL) { - len += (unsigned)STRLEN(str); + len += STRLEN(str); for (p = str; *p != NUL; mb_ptr_adv(p)) if (*p == '\'') ++len; } - s = r = alloc(len); - if (r != NULL) { - if (function) { - STRCPY(r, "function('"); - r += 10; - } else - *r++ = '\''; - if (str != NULL) - for (p = str; *p != NUL; ) { - if (*p == '\'') - *r++ = '\''; - MB_COPY_CHAR(p, r); - } + s = r = xmalloc(len); + + if (function) { + STRCPY(r, "function('"); + r += 10; + } else *r++ = '\''; - if (function) - *r++ = ')'; - *r++ = NUL; - } + if (str != NULL) + for (p = str; *p != NUL; ) { + if (*p == '\'') + *r++ = '\''; + MB_COPY_CHAR(p, r); + } + *r++ = '\''; + if (function) + *r++ = ')'; + *r++ = NUL; + return s; } @@ -6960,11 +6930,6 @@ static struct fst { {"readfile", 1, 3, f_readfile}, {"reltime", 0, 2, f_reltime}, {"reltimestr", 1, 1, f_reltimestr}, - {"remote_expr", 2, 3, f_remote_expr}, - {"remote_foreground", 1, 1, f_remote_foreground}, - {"remote_peek", 1, 2, f_remote_peek}, - {"remote_read", 1, 1, f_remote_read}, - {"remote_send", 2, 3, f_remote_send}, {"remove", 2, 3, f_remove}, {"rename", 2, 2, f_rename}, {"repeat", 2, 2, f_repeat}, @@ -6980,8 +6945,7 @@ static struct fst { {"searchpair", 3, 7, f_searchpair}, {"searchpairpos", 3, 7, f_searchpairpos}, {"searchpos", 1, 4, f_searchpos}, - {"server2client", 2, 2, f_server2client}, - {"serverlist", 0, 0, f_serverlist}, + {"send_event", 3, 3, f_send_event}, {"setbufvar", 3, 3, f_setbufvar}, {"setcmdpos", 1, 1, f_setcmdpos}, {"setline", 2, 2, f_setline}, @@ -7262,8 +7226,6 @@ call_func ( /* Make a copy of the name, if it comes from a funcref variable it could * be changed or deleted in the called function. */ name = vim_strnsave(funcname, len); - if (name == NULL) - return ret; /* * In a script change <SID>name() and s:name() to K_SNR 123_name(). @@ -7288,13 +7250,9 @@ call_func ( STRCPY(fname_buf + i, name + llen); fname = fname_buf; } else { - fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); - if (fname == NULL) - error = ERROR_OTHER; - else { - memmove(fname, fname_buf, (size_t)i); - STRCPY(fname + i, name + llen); - } + fname = xmalloc(i + STRLEN(name + llen) + 1); + memmove(fname, fname_buf, (size_t)i); + STRCPY(fname + i, name + llen); } } else fname = name; @@ -9257,20 +9215,18 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv) } } txt = _("+-%s%3ld lines: "); - r = alloc((unsigned)(STRLEN(txt) - + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ - + 20 /* for %3ld */ - + STRLEN(s))); /* concatenated */ - if (r != NULL) { - sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, - (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr - - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); - len = (int)STRLEN(r); - STRCAT(r, s); - /* remove 'foldmarker' and 'commentstring' */ - foldtext_cleanup(r + len); - rettv->vval.v_string = r; - } + r = xmalloc(STRLEN(txt) + + STRLEN(vimvars[VV_FOLDDASHES].vv_str) // for %s + + 20 // for %3ld + + STRLEN(s)); // concatenated + sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, + (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr + - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); + len = (int)STRLEN(r); + STRCAT(r, s); + /* remove 'foldmarker' and 'commentstring' */ + foldtext_cleanup(r + len); + rettv->vval.v_string = r; } } @@ -9331,12 +9287,9 @@ static void f_function(typval_T *argvars, typval_T *rettv) * would also work, but some plugins depend on the name being * printable text. */ sprintf(sid_buf, "<SNR>%" PRId64 "_", (int64_t)current_SID); - rettv->vval.v_string = - alloc((int)(STRLEN(sid_buf) + STRLEN(s + off) + 1)); - if (rettv->vval.v_string != NULL) { - STRCPY(rettv->vval.v_string, sid_buf); - STRCAT(rettv->vval.v_string, s + off); - } + rettv->vval.v_string = xmalloc(STRLEN(sid_buf) + STRLEN(s + off) + 1); + STRCPY(rettv->vval.v_string, sid_buf); + STRCAT(rettv->vval.v_string, s + off); } else rettv->vval.v_string = vim_strsave(s); rettv->v_type = VAR_FUNC; @@ -9625,11 +9578,8 @@ static void f_getcmdpos(typval_T *argvars, typval_T *rettv) static void f_getcmdtype(typval_T *argvars, typval_T *rettv) { rettv->v_type = VAR_STRING; - rettv->vval.v_string = alloc(2); - if (rettv->vval.v_string != NULL) { - rettv->vval.v_string[0] = get_cmdline_type(); - rettv->vval.v_string[1] = NUL; - } + rettv->vval.v_string = xmallocz(1); + rettv->vval.v_string[0] = get_cmdline_type(); } /* @@ -9641,17 +9591,14 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; - cwd = alloc(MAXPATHL); - if (cwd != NULL) { - if (os_dirname(cwd, MAXPATHL) != FAIL) { - rettv->vval.v_string = vim_strsave(cwd); + cwd = xmalloc(MAXPATHL); + if (os_dirname(cwd, MAXPATHL) != FAIL) { + rettv->vval.v_string = vim_strsave(cwd); #ifdef BACKSLASH_IN_FILENAME - if (rettv->vval.v_string != NULL) - slash_adjust(rettv->vval.v_string); + slash_adjust(rettv->vval.v_string); #endif - } - free(cwd); } + free(cwd); } /* @@ -9675,11 +9622,9 @@ static void f_getfperm(typval_T *argvars, typval_T *rettv) int32_t file_perm = os_getperm(filename); if (file_perm >= 0) { perm = vim_strsave((char_u *)"---------"); - if (perm != NULL) { - for (int i = 0; i < 9; i++) { - if (file_perm & (1 << (8 - i))) - perm[i] = flags[i % 3]; - } + for (int i = 0; i < 9; i++) { + if (file_perm & (1 << (8 - i))) + perm[i] = flags[i % 3]; } } rettv->v_type = VAR_STRING; @@ -11758,8 +11703,6 @@ static int mkdir_recurse(char_u *dir, int prot) /* If the directory exists we're done. Otherwise: create it.*/ updir = vim_strnsave(dir, (int)(p - dir)); - if (updir == NULL) - return FAIL; if (os_isdir(updir)) r = OK; else if (mkdir_recurse(updir, prot) == OK) @@ -11971,7 +11914,6 @@ static void f_printf(typval_T *argvars, typval_T *rettv) { char_u buf[NUMBUFLEN]; int len; - char_u *s; int saved_did_emsg = did_emsg; char *fmt; @@ -11980,11 +11922,9 @@ static void f_printf(typval_T *argvars, typval_T *rettv) fmt = (char *)get_tv_string_buf(&argvars[0], buf); len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); if (!did_emsg) { - s = alloc(len + 1); - if (s != NULL) { - rettv->vval.v_string = s; - (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); - } + char *s = xmalloc(len + 1); + rettv->vval.v_string = (char_u *)s; + (void)vim_vsnprintf(s, len + 1, fmt, ap, argvars + 1); } did_emsg |= saved_did_emsg; } @@ -12104,17 +12044,11 @@ static void f_readfile(typval_T *argvars, typval_T *rettv) /* Change "prev" buffer to be the right size. This way * the bytes are only copied once, and very long lines are * allocated only once. */ - if ((s = xrealloc(prev, prevlen + len + 1)) != NULL) { - memmove(s + prevlen, start, len); - s[prevlen + len] = NUL; - prev = NULL; /* the list will own the string */ - prevlen = prevsize = 0; - } - } - if (s == NULL) { - do_outofmem_msg((long_u) prevlen + len + 1); - failed = TRUE; - break; + s = xrealloc(prev, prevlen + len + 1); + memcpy(s + prevlen, start, len); + s[prevlen + len] = NUL; + prev = NULL; /* the list will own the string */ + prevlen = prevsize = 0; } if ((li = listitem_alloc()) == NULL) { @@ -12174,8 +12108,6 @@ static void f_readfile(typval_T *argvars, typval_T *rettv) if (start < p) { /* There's part of a line in buf, store it in "prev". */ if (p - start + prevlen >= prevsize) { - /* need bigger "prev" buffer */ - char_u *newprev; /* A common use case is ordinary text files and "prev" gets a * fragment of a line, so the first allocation is made @@ -12188,14 +12120,7 @@ static void f_readfile(typval_T *argvars, typval_T *rettv) long growmin = (long)((p - start) * 2 + prevlen); prevsize = grow50pc > growmin ? grow50pc : growmin; } - newprev = prev == NULL ? alloc(prevsize) - : xrealloc(prev, prevsize); - if (newprev == NULL) { - do_outofmem_msg((long_u)prevsize); - failed = TRUE; - break; - } - prev = newprev; + prev = xrealloc(prev, prevsize); } /* Add the line part to end of "prev". */ memmove(prev + prevlen, start, p - start); @@ -12289,46 +12214,6 @@ static void f_reltimestr(typval_T *argvars, typval_T *rettv) rettv->vval.v_string = vim_strsave((char_u *)profile_msg(&tm)); } - - -/* - * "remote_expr()" function - */ -static void f_remote_expr(typval_T *argvars, typval_T *rettv) -{ - rettv->v_type = VAR_STRING; - rettv->vval.v_string = NULL; -} - -/* - * "remote_foreground()" function - */ -static void f_remote_foreground(typval_T *argvars, typval_T *rettv) -{ -} - -static void f_remote_peek(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = -1; -} - -static void f_remote_read(typval_T *argvars, typval_T *rettv) -{ - char_u *r = NULL; - - rettv->v_type = VAR_STRING; - rettv->vval.v_string = r; -} - -/* - * "remote_send()" function - */ -static void f_remote_send(typval_T *argvars, typval_T *rettv) -{ - rettv->v_type = VAR_STRING; - rettv->vval.v_string = NULL; -} - /* * "remove()" function */ @@ -12432,10 +12317,6 @@ static void f_repeat(typval_T *argvars, typval_T *rettv) { char_u *p; int n; - int slen; - int len; - char_u *r; - int i; n = get_tv_number(&argvars[1]); if (argvars[0].v_type == VAR_LIST) { @@ -12453,17 +12334,14 @@ static void f_repeat(typval_T *argvars, typval_T *rettv) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; - slen = (int)STRLEN(p); - len = slen * n; + int slen = (int)STRLEN(p); + int len = slen * n; if (len <= 0) return; - r = alloc(len + 1); - if (r != NULL) { - for (i = 0; i < n; i++) - memmove(r + i * slen, p, (size_t)slen); - r[len] = NUL; - } + char_u *r = xmallocz(len); + for (int i = 0; i < n; i++) + memmove(r + i * slen, p, (size_t)slen); rettv->vval.v_string = r; } @@ -12521,9 +12399,7 @@ static void f_resolve(typval_T *argvars, typval_T *rettv) q[-1] = NUL; } - buf = alloc(MAXPATHL + 1); - if (buf == NULL) - goto fail; + buf = xmallocz(MAXPATHL); for (;; ) { for (;; ) { @@ -12569,13 +12445,11 @@ static void f_resolve(typval_T *argvars, typval_T *rettv) } if (q > p && !path_is_absolute_path(buf)) { /* symlink is relative to directory of argument */ - cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); - if (cpy != NULL) { - STRCPY(cpy, p); - STRCPY(path_tail(cpy), buf); - free(p); - p = cpy; - } + cpy = xmalloc(STRLEN(p) + STRLEN(buf) + 1); + STRCPY(cpy, p); + STRCPY(path_tail(cpy), buf); + free(p); + p = cpy; } else { free(p); p = vim_strsave(buf); @@ -12589,11 +12463,10 @@ static void f_resolve(typval_T *argvars, typval_T *rettv) q = path_next_component(remain + 1); len = q - remain - (*q != NUL); cpy = vim_strnsave(p, STRLEN(p) + len); - if (cpy != NULL) { - STRNCAT(cpy, remain, len); - free(p); - p = cpy; - } + STRNCAT(cpy, remain, len); + free(p); + p = cpy; + /* Shorten "remain". */ if (*q != NUL) STRMOVE(remain, q - 1); @@ -13083,10 +12956,8 @@ do_searchpair ( /* Make two search patterns: start/end (pat2, for in nested pairs) and * start/middle/end (pat3, for the top pair). */ - pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); - pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); - if (pat2 == NULL || pat3 == NULL) - goto theend; + pat2 = xmalloc(STRLEN(spat) + STRLEN(epat) + 15); + pat3 = xmalloc(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23); sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); if (*mpat == NUL) STRCPY(pat3, pat2); @@ -13177,7 +13048,6 @@ do_searchpair ( if ((flags & SP_NOMOVE) || retval == 0) curwin->w_cursor = save_cursor; -theend: free(pat2); free(pat3); if (p_cpo == empty_option) @@ -13189,6 +13059,36 @@ theend: return retval; } +// "send_event()" function +static void f_send_event(typval_T *argvars, typval_T *rettv) +{ + rettv->v_type = VAR_NUMBER; + rettv->vval.v_number = 0; + + if (check_restricted() || check_secure()) { + return; + } + + if (argvars[0].v_type != VAR_NUMBER || argvars[0].vval.v_number <= 0) { + EMSG2(_(e_invarg2), "Channel id must be a positive integer"); + return; + } + + if (argvars[1].v_type != VAR_STRING) { + EMSG2(_(e_invarg2), "Event type must be a string"); + return; + } + + if (!channel_send_event((uint64_t)argvars[0].vval.v_number, + (char *)argvars[1].vval.v_string, + &argvars[2])) { + EMSG2(_(e_invarg2), "Channel doesn't exist"); + return; + } + + rettv->vval.v_number = 1; +} + /* * "searchpos()" function */ @@ -13214,20 +13114,6 @@ static void f_searchpos(typval_T *argvars, typval_T *rettv) list_append_number(rettv->vval.v_list, (varnumber_T)n); } - -static void f_server2client(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = -1; -} - -static void f_serverlist(typval_T *argvars, typval_T *rettv) -{ - char_u *r = NULL; - - rettv->v_type = VAR_STRING; - rettv->vval.v_string = r; -} - /* * "setbufvar()" function */ @@ -13261,13 +13147,11 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv) if (!error && strval != NULL) set_option_value(varname, numval, strval, OPT_LOCAL); } else { - bufvarname = alloc((unsigned)STRLEN(varname) + 3); - if (bufvarname != NULL) { - STRCPY(bufvarname, "b:"); - STRCPY(bufvarname + 2, varname); - set_var(bufvarname, varp, TRUE); - free(bufvarname); - } + bufvarname = xmalloc(STRLEN(varname) + 3); + STRCPY(bufvarname, "b:"); + STRCPY(bufvarname + 2, varname); + set_var(bufvarname, varp, TRUE); + free(bufvarname); } /* reset notion of buffer */ @@ -13573,13 +13457,11 @@ static void f_settabvar(typval_T *argvars, typval_T *rettv) save_curtab = curtab; goto_tabpage_tp(tp, FALSE, FALSE); - tabvarname = alloc((unsigned)STRLEN(varname) + 3); - if (tabvarname != NULL) { - STRCPY(tabvarname, "t:"); - STRCPY(tabvarname + 2, varname); - set_var(tabvarname, varp, TRUE); - free(tabvarname); - } + tabvarname = xmalloc(STRLEN(varname) + 3); + STRCPY(tabvarname, "t:"); + STRCPY(tabvarname + 2, varname); + set_var(tabvarname, varp, TRUE); + free(tabvarname); /* Restore current tabpage */ if (valid_tabpage(save_curtab)) @@ -13643,13 +13525,11 @@ static void setwinvar(typval_T *argvars, typval_T *rettv, int off) if (!error && strval != NULL) set_option_value(varname, numval, strval, OPT_LOCAL); } else { - winvarname = alloc((unsigned)STRLEN(varname) + 3); - if (winvarname != NULL) { - STRCPY(winvarname, "w:"); - STRCPY(winvarname + 2, varname); - set_var(winvarname, varp, TRUE); - free(winvarname); - } + winvarname = xmalloc(STRLEN(varname) + 3); + STRCPY(winvarname, "w:"); + STRCPY(winvarname + 2, varname); + set_var(winvarname, varp, TRUE); + free(winvarname); } restore_win(save_curwin, save_curtab, TRUE); @@ -14831,7 +14711,7 @@ static void f_tagfiles(typval_T *argvars, typval_T *rettv) tagname_T tn; rettv_list_alloc(rettv); - fname = alloc(MAXPATHL); + fname = xmalloc(MAXPATHL); int first = TRUE; while (get_tagfname(&tn, first, fname) == OK) { @@ -14924,33 +14804,30 @@ static void f_tanh(typval_T *argvars, typval_T *rettv) */ static void f_tolower(typval_T *argvars, typval_T *rettv) { - char_u *p; - - p = vim_strsave(get_tv_string(&argvars[0])); + char_u *p = vim_strsave(get_tv_string(&argvars[0])); rettv->v_type = VAR_STRING; rettv->vval.v_string = p; - if (p != NULL) - while (*p != NUL) { - int l; - - if (enc_utf8) { - int c, lc; - - c = utf_ptr2char(p); - lc = utf_tolower(c); - l = utf_ptr2len(p); - /* TODO: reallocate string when byte count changes. */ - if (utf_char2len(lc) == l) - utf_char2bytes(lc, p); - p += l; - } else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) - p += l; /* skip multi-byte character */ - else { - *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ - ++p; - } + while (*p != NUL) { + int l; + + if (enc_utf8) { + int c, lc; + + c = utf_ptr2char(p); + lc = utf_tolower(c); + l = utf_ptr2len(p); + /* TODO: reallocate string when byte count changes. */ + if (utf_char2len(lc) == l) + utf_char2bytes(lc, p); + p += l; + } else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) + p += l; /* skip multi-byte character */ + else { + *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ + ++p; } + } } /* @@ -15773,13 +15650,11 @@ static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u * temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE); if (temp_result != NULL && nextcmd == NULL) { - retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) - + (in_end - expr_end) + 1)); - if (retval != NULL) { - STRCPY(retval, in_start); - STRCAT(retval, temp_result); - STRCAT(retval, expr_end + 1); - } + retval = xmalloc(STRLEN(temp_result) + (expr_start - in_start) + + (in_end - expr_end) + 1); + STRCPY(retval, in_start); + STRCAT(retval, temp_result); + STRCAT(retval, expr_end + 1); } free(temp_result); @@ -15970,7 +15845,6 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg) { char_u *oldval; char_u *newval; - unsigned len; oldval = vimvars[VV_CMDARG].vv_str; if (eap == NULL) { @@ -15979,26 +15853,23 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg) return NULL; } + size_t len = 0; if (eap->force_bin == FORCE_BIN) len = 6; else if (eap->force_bin == FORCE_NOBIN) len = 8; - else - len = 0; if (eap->read_edit) len += 7; if (eap->force_ff != 0) - len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; + len += STRLEN(eap->cmd + eap->force_ff) + 6; if (eap->force_enc != 0) - len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; + len += STRLEN(eap->cmd + eap->force_enc) + 7; if (eap->bad_char != 0) len += 7 + 4; /* " ++bad=" + "keep" or "drop" */ - newval = alloc(len + 1); - if (newval == NULL) - return NULL; + newval = xmalloc(len + 1); if (eap->force_bin == FORCE_BIN) sprintf((char *)newval, " ++bin"); @@ -16753,10 +16624,7 @@ set_var ( if (!valid_varname(varname)) return; - v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) - + STRLEN(varname))); - if (v == NULL) - return; + v = xmalloc(sizeof(dictitem_T) + STRLEN(varname)); STRCPY(v->di_key, varname); if (hash_add(ht, DI2HIKEY(v)) == FAIL) { free(v); @@ -17412,8 +17280,6 @@ void ex_function(exarg_T *eap) c = *p; *p = NUL; arg = vim_strsave(arg); - if (arg == NULL) - goto erret; /* Check for duplicate argument name. */ for (i = 0; i < newargs.ga_len; ++i) @@ -17605,11 +17471,9 @@ void ex_function(exarg_T *eap) * allocates 250 bytes per line, this saves 80% on average. The cost * is an extra alloc/free. */ p = vim_strsave(theline); - if (p != NULL) { - if (line_arg == NULL) - free(theline); - theline = p; - } + if (line_arg == NULL) + free(theline); + theline = p; ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline; @@ -17678,8 +17542,6 @@ void ex_function(exarg_T *eap) free(name); sprintf(numbuf, "%d", ++func_nr); name = vim_strsave((char_u *)numbuf); - if (name == NULL) - goto erret; } if (fp == NULL) { @@ -17709,9 +17571,7 @@ void ex_function(exarg_T *eap) } } - fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); - if (fp == NULL) - goto erret; + fp = xmalloc(sizeof(ufunc_T) + STRLEN(name)); if (fudi.fd_dict != NULL) { if (fudi.fd_di == NULL) { @@ -17939,18 +17799,16 @@ trans_function_name ( } } - name = alloc((unsigned)(len + lead + 1)); - if (name != NULL) { - if (lead > 0) { - name[0] = K_SPECIAL; - name[1] = KS_EXTRA; - name[2] = (int)KE_SNR; - if (lead > 3) /* If it's "<SID>" */ - STRCPY(name + 3, sid_buf); - } - memmove(name + lead, lv.ll_name, (size_t)len); - name[lead + len] = NUL; + name = xmalloc(len + lead + 1); + if (lead > 0){ + name[0] = K_SPECIAL; + name[1] = KS_EXTRA; + name[2] = (int)KE_SNR; + if (lead > 3) /* If it's "<SID>" */ + STRCPY(name + 3, sid_buf); } + memmove(name + lead, lv.ll_name, (size_t)len); + name[lead + len] = NUL; *pp = end; theend: @@ -18160,7 +18018,7 @@ void func_dump_profile(FILE *fd) if (todo == 0) return; /* nothing to dump */ - sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); + sorttab = xmalloc(sizeof(ufunc_T) * todo); for (hi = func_hashtab.ht_array; todo > 0; ++hi) { if (!HASHITEM_EMPTY(hi)) { @@ -18338,9 +18196,7 @@ static char_u *autoload_name(char_u *name) char_u *scriptname; /* Get the script file name: replace '#' with '/', append ".vim". */ - scriptname = alloc((unsigned)(STRLEN(name) + 14)); - if (scriptname == NULL) - return FALSE; + scriptname = xmalloc(STRLEN(name) + 14); STRCPY(scriptname, "autoload/"); STRCAT(scriptname, name); *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; @@ -18555,7 +18411,7 @@ call_user_func ( line_breakcheck(); /* check for CTRL-C hit */ - fc = (funccall_T *)alloc(sizeof(funccall_T)); + fc = xmalloc(sizeof(funccall_T)); fc->caller = current_funccal; current_funccal = fc; fc->func = fp; @@ -18636,10 +18492,7 @@ call_user_func ( v = &fc->fixvar[fixvar_idx++].var; v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; } else { - v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) - + STRLEN(name))); - if (v == NULL) - break; + v = xmalloc(sizeof(dictitem_T) + STRLEN(name)); v->di_flags = DI_FLAGS_RO; } STRCPY(v->di_key, name); @@ -18662,10 +18515,9 @@ call_user_func ( save_sourcing_name = sourcing_name; save_sourcing_lnum = sourcing_lnum; sourcing_lnum = 1; - sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 - : STRLEN(save_sourcing_name)) + - STRLEN(fp->uf_name) + 13)); - if (sourcing_name != NULL) { + sourcing_name = xmalloc((save_sourcing_name == NULL ? 0 : STRLEN(save_sourcing_name)) + + STRLEN(fp->uf_name) + 13); + { if (save_sourcing_name != NULL && STRNCMP(save_sourcing_name, "function ", 9) == 0) sprintf((char *)sourcing_name, "%s..", save_sourcing_name); @@ -19522,11 +19374,9 @@ repeat: /* Only replace it when it starts with '~' */ if (*dirname == '~') { s = vim_strsave(dirname); - if (s != NULL) { - *fnamep = s; - free(*bufp); - *bufp = s; - } + *fnamep = s; + free(*bufp); + *bufp = s; } } free(pbuf); @@ -19547,11 +19397,8 @@ repeat: *fnamelen = (int)(tail - *fnamep); if (*fnamelen == 0) { /* Result is empty. Turn it into "." to make ":cd %:h" work. */ - p = vim_strsave((char_u *)"."); - if (p == NULL) - return -1; free(*bufp); - *bufp = *fnamep = tail = p; + *bufp = *fnamep = tail = vim_strsave((char_u *)"."); *fnamelen = 1; } else { while (tail > s && !after_pathsep(s, tail)) @@ -19625,29 +19472,23 @@ repeat: p = vim_strchr(s, sep); if (p != NULL) { pat = vim_strnsave(s, (int)(p - s)); - if (pat != NULL) { - s = p + 1; - /* find end of substitution */ - p = vim_strchr(s, sep); - if (p != NULL) { - sub = vim_strnsave(s, (int)(p - s)); - str = vim_strnsave(*fnamep, *fnamelen); - if (sub != NULL && str != NULL) { - *usedlen = (int)(p + 1 - src); - s = do_string_sub(str, pat, sub, flags); - if (s != NULL) { - *fnamep = s; - *fnamelen = (int)STRLEN(s); - free(*bufp); - *bufp = s; - didit = TRUE; - } - } - free(sub); - free(str); - } - free(pat); + s = p + 1; + /* find end of substitution */ + p = vim_strchr(s, sep); + if (p != NULL) { + sub = vim_strnsave(s, (int)(p - s)); + str = vim_strnsave(*fnamep, *fnamelen); + *usedlen = (int)(p + 1 - src); + s = do_string_sub(str, pat, sub, flags); + *fnamep = s; + *fnamelen = (int)STRLEN(s); + free(*bufp); + *bufp = s; + didit = TRUE; + free(sub); + free(str); } + free(pat); } /* after using ":s", repeat all the modifiers */ if (didit) @@ -19679,7 +19520,6 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *flags) int do_all; char_u *tail; garray_T ga; - char_u *ret; char_u *save_cpo; char_u *zero_width = NULL; @@ -19738,7 +19578,7 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *flags) vim_regfree(regmatch.regprog); } - ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); + char_u *ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); ga_clear(&ga); if (p_cpo == empty_option) p_cpo = save_cpo; diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 0918e73b8a..fa17986028 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -695,12 +695,10 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest) return FAIL; for (extra = 0, l = line1; l <= line2; l++) { str = vim_strsave(ml_get(l + extra)); - if (str != NULL) { - ml_append(dest + l - line1, str, (colnr_T)0, FALSE); - free(str); - if (dest < line1) - extra++; - } + ml_append(dest + l - line1, str, (colnr_T)0, FALSE); + free(str); + if (dest < line1) + extra++; } /* @@ -803,10 +801,9 @@ void ex_copy(linenr_T line1, linenr_T line2, linenr_T n) /* need to use vim_strsave() because the line will be unlocked within * ml_append() */ p = vim_strsave(ml_get(line1)); - if (p != NULL) { - ml_append(curwin->w_cursor.lnum, p, (colnr_T)0, FALSE); - free(p); - } + ml_append(curwin->w_cursor.lnum, p, (colnr_T)0, FALSE); + free(p); + /* situation 2: skip already copied lines */ if (line1 == n) line1 = curwin->w_cursor.lnum; @@ -1454,8 +1451,6 @@ read_viminfo ( return FAIL; fname = viminfo_filename(file); /* get file name in allocated buffer */ - if (fname == NULL) - return FAIL; fp = mch_fopen((char *)fname, READBIN); if (p_verbose > 0) { @@ -1502,8 +1497,6 @@ void write_viminfo(char_u *file, int forceit) return; fname = viminfo_filename(file); /* may set to default if NULL */ - if (fname == NULL) - return; fp_in = mch_fopen((char *)fname, READBIN); if (fp_in == NULL) { @@ -1670,7 +1663,7 @@ end: * cmdline functions). * Otherwise use "-i file_name", value from 'viminfo' or the default, and * expand environment variables. - * Returns an allocated string. NULL when out of memory. + * Returns an allocated string. */ static char_u *viminfo_filename(char_u *file) { @@ -1886,8 +1879,6 @@ viminfo_readstring ( s = retval + 1; /* Skip the leading '<' */ } else { retval = vim_strsave(virp->vir_line + off); - if (retval == NULL) - return NULL; s = retval; } @@ -3937,17 +3928,14 @@ void do_sub(exarg_T *eap) * what matches. Temporarily replace the line * and change it back afterwards. */ orig_line = vim_strsave(ml_get(lnum)); - if (orig_line != NULL) { - char_u *new_line = concat_str(new_start, - sub_firstline + copycol); - - // Position the cursor relative to the end of the line, the - // previous substitute may have inserted or deleted characters - // before the cursor. - len_change = (int)STRLEN(new_line) - (int)STRLEN(orig_line); - curwin->w_cursor.col += len_change; - ml_replace(lnum, new_line, FALSE); - } + char_u *new_line = concat_str(new_start, sub_firstline + copycol); + + // Position the cursor relative to the end of the line, the + // previous substitute may have inserted or deleted characters + // before the cursor. + len_change = (int)STRLEN(new_line) - (int)STRLEN(orig_line); + curwin->w_cursor.col += len_change; + ml_replace(lnum, new_line, FALSE); } search_match_lines = regmatch.endpos[0].lnum @@ -5769,11 +5757,6 @@ void ex_sign(exarg_T *eap) next_sign_typenr = 1; /* wrap around */ sp->sn_name = vim_strsave(arg); - if (sp->sn_name == NULL) /* out of memory */ - { - free(sp); - return; - } /* add the new sign to the list of signs */ if (sp_prev == NULL) @@ -5837,7 +5820,7 @@ void ex_sign(exarg_T *eap) len = (int)(p - arg + ((cells == 1) ? 1 : 0)); sp->sn_text = vim_strnsave(arg, len); - if (sp->sn_text != NULL && cells == 1) + if (cells == 1) STRCPY(sp->sn_text + len - 1, " "); } else if (STRNCMP(arg, "linehl=", 7) == 0) diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 3f20c59b2b..b4155b417d 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -1920,8 +1920,6 @@ void ex_argedit(exarg_T *eap) if (i == ARGCOUNT) { /* Can't find it, add it to the argument list. */ s = vim_strsave(eap->arg); - if (s == NULL) - return; i = alist_add_list(1, &s, eap->addr_count > 0 ? (int)eap->line2 : curwin->w_arg_idx + 1); curwin->w_arg_idx = i; @@ -2252,8 +2250,8 @@ void *cookie; /* Make a copy of 'runtimepath'. Invoking the callback may change the * value. */ rtp_copy = vim_strsave(p_rtp); - buf = xmalloc(MAXPATHL); - if (rtp_copy != NULL) { + buf = xmallocz(MAXPATHL); + { if (p_verbose > 1 && name != NULL) { verbose_enter(); smsg((char_u *)_("Searching for \"%s\" in \"%s\""), @@ -2594,10 +2592,8 @@ do_source ( p = string_convert(&cookie.conv, firstline + 3, NULL); if (p == NULL) p = vim_strsave(firstline + 3); - if (p != NULL) { - free(firstline); - firstline = p; - } + free(firstline); + firstline = p; } #ifdef STARTUPTIME @@ -3483,8 +3479,6 @@ static char_u **find_locales(void) while (loc != NULL) { ga_grow(&locales_ga, 1); loc = vim_strsave(loc); - if (loc == NULL) - break; ((char_u **)locales_ga.ga_data)[locales_ga.ga_len++] = loc; loc = (char_u *)strtok(NULL, "\n"); diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 7007cd3e22..0ff62a3726 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -718,11 +718,6 @@ int flags; /* 3. Make a copy of the command so we can mess with it. */ else if (cmdline_copy == NULL) { next_cmdline = vim_strsave(next_cmdline); - if (next_cmdline == NULL) { - EMSG(_(e_outofmem)); - retval = FAIL; - break; - } } cmdline_copy = next_cmdline; @@ -4296,10 +4291,6 @@ static int uc_add_command(char_u *name, size_t name_len, char_u *rep, long argt, if (rep_buf == NULL) { /* Can't replace termcodes - try using the string as is */ rep_buf = vim_strsave(rep); - - /* Give up if out of memory */ - if (rep_buf == NULL) - return FAIL; } /* get address of growarray: global or in curbuf */ @@ -4346,8 +4337,7 @@ static int uc_add_command(char_u *name, size_t name_len, char_u *rep, long argt, if (cmp != 0) { ga_grow(gap, 1); - if ((p = vim_strnsave(name, (int)name_len)) == NULL) - goto fail; + p = vim_strnsave(name, (int)name_len); cmd = USER_CMD_GA(gap, i); memmove(cmd + 1, cmd, (gap->ga_len - i) * sizeof(ucmd_T)); @@ -5253,12 +5243,11 @@ static void ex_colorscheme(exarg_T *eap) char_u *expr = vim_strsave((char_u *)"g:colors_name"); char_u *p = NULL; - if (expr != NULL) { - ++emsg_off; - p = eval_to_string(expr, NULL, FALSE); - --emsg_off; - free(expr); - } + ++emsg_off; + p = eval_to_string(expr, NULL, FALSE); + --emsg_off; + free(expr); + if (p != NULL) { MSG(p); free(p); @@ -7388,6 +7377,7 @@ static void ex_normal(exarg_T *eap) * ends with half a command. */ save_typeahead(&tabuf); + // TODO(philix): after save_typeahead() this is always TRUE if (tabuf.typebuf_valid) { /* * Repeat the :normal command for each line in the range. When no @@ -7991,8 +7981,6 @@ char_u *expand_sfile(char_u *arg) char_u *p; result = vim_strsave(arg); - if (result == NULL) - return NULL; for (p = result; *p; ) { if (STRNCMP(p, "<sfile>", 7) != 0) diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index cc2d4b6405..929ff4211f 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -244,17 +244,10 @@ int cause_errthrow(char_u *mesg, int severe, int *ignore) while (*plist != NULL) plist = &(*plist)->next; - elem = (struct msglist *)alloc((unsigned)sizeof(struct msglist)); - if (elem == NULL) { - suppress_errthrow = TRUE; - EMSG(_(e_outofmem)); - } else { + elem = xmalloc(sizeof(struct msglist)); + { elem->msg = vim_strsave(mesg); - if (elem->msg == NULL) { - free(elem); - suppress_errthrow = TRUE; - EMSG(_(e_outofmem)); - } else { + { elem->next = NULL; elem->throw_msg = NULL; *plist = elem; @@ -402,15 +395,11 @@ char_u *get_exception_string(void *value, int type, char_u *cmdname, int *should cmdlen = (int)STRLEN(cmdname); ret = vim_strnsave((char_u *)"Vim(", 4 + cmdlen + 2 + (int)STRLEN(mesg)); - if (ret == NULL) - return ret; STRCPY(&ret[4], cmdname); STRCPY(&ret[4 + cmdlen], "):"); val = ret + 4 + cmdlen + 2; } else { ret = vim_strnsave((char_u *)"Vim:", 4 + (int)STRLEN(mesg)); - if (ret == NULL) - return ret; val = ret + 4; } @@ -477,9 +466,7 @@ static int throw_exception(void *value, int type, char_u *cmdname) } } - excp = (except_T *)alloc((unsigned)sizeof(except_T)); - if (excp == NULL) - goto nomem; + excp = xmalloc(sizeof(except_T)); if (type == ET_ERROR) /* Store the original message and prefix the exception value with @@ -493,11 +480,6 @@ static int throw_exception(void *value, int type, char_u *cmdname) excp->type = type; excp->throw_name = vim_strsave(sourcing_name == NULL ? (char_u *)"" : sourcing_name); - if (excp->throw_name == NULL) { - if (should_free) - free(excp->value); - goto nomem; - } excp->throw_lnum = sourcing_lnum; if (p_verbose >= 13 || debug_break_level > 0) { @@ -1302,18 +1284,12 @@ void ex_try(exarg_T *eap) * to save the value. */ if (emsg_silent) { - eslist_T *elem; - - elem = (eslist_T *)alloc((unsigned)sizeof(struct eslist_elem)); - if (elem == NULL) - EMSG(_(e_outofmem)); - else { - elem->saved_emsg_silent = emsg_silent; - elem->next = cstack->cs_emsg_silent_list; - cstack->cs_emsg_silent_list = elem; - cstack->cs_flags[cstack->cs_idx] |= CSF_SILENT; - emsg_silent = 0; - } + eslist_T *elem = xmalloc(sizeof(struct eslist_elem)); + elem->saved_emsg_silent = emsg_silent; + elem->next = cstack->cs_emsg_silent_list; + cstack->cs_emsg_silent_list = elem; + cstack->cs_flags[cstack->cs_idx] |= CSF_SILENT; + emsg_silent = 0; } } diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 99915525ae..278886cf5e 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -118,7 +118,7 @@ static void set_cmdspos(void); static void set_cmdspos_cursor(void); static void correct_cmdspos(int idx, int cells); static void alloc_cmdbuff(int len); -static int realloc_cmdbuff(int len); +static void realloc_cmdbuff(int len); static void draw_cmdline(int start, int len); static void save_cmdline(struct cmdline_info *ccp); static void restore_cmdline(struct cmdline_info *ccp); @@ -232,8 +232,6 @@ getcmdline ( /* alloc initial ccline.cmdbuff */ alloc_cmdbuff(exmode_active ? 250 : indent + 1); - if (ccline.cmdbuff == NULL) - return NULL; /* out of memory */ ccline.cmdlen = ccline.cmdpos = 0; ccline.cmdbuff[0] = NUL; @@ -616,22 +614,21 @@ getcmdline ( if (p != NULL) { len = (int)STRLEN(p); - if (realloc_cmdbuff(len + 1) == OK) { - ccline.cmdlen = len; - STRCPY(ccline.cmdbuff, p); - free(p); - - /* Restore the cursor or use the position set with - * set_cmdline_pos(). */ - if (new_cmdpos > ccline.cmdlen) - ccline.cmdpos = ccline.cmdlen; - else - ccline.cmdpos = new_cmdpos; - - KeyTyped = FALSE; /* Don't do p_wc completion. */ - redrawcmd(); - goto cmdline_changed; - } + realloc_cmdbuff(len + 1); + ccline.cmdlen = len; + STRCPY(ccline.cmdbuff, p); + free(p); + + /* Restore the cursor or use the position set with + * set_cmdline_pos(). */ + if (new_cmdpos > ccline.cmdlen) + ccline.cmdpos = ccline.cmdlen; + else + ccline.cmdpos = new_cmdpos; + + KeyTyped = FALSE; /* Don't do p_wc completion. */ + redrawcmd(); + goto cmdline_changed; } } beep_flush(); @@ -1196,8 +1193,7 @@ getcmdline ( /* save current command string so it can be restored later */ if (lookfor == NULL) { - if ((lookfor = vim_strsave(ccline.cmdbuff)) == NULL) - goto cmdline_not_changed; + lookfor = vim_strsave(ccline.cmdbuff); lookfor[ccline.cmdpos] = NUL; } @@ -1286,15 +1282,11 @@ getcmdline ( } if (i == 0) { alloc_cmdbuff(len); - if (ccline.cmdbuff == NULL) - goto returncmd; } } ccline.cmdbuff[len] = NUL; } else { alloc_cmdbuff((int)STRLEN(p)); - if (ccline.cmdbuff == NULL) - goto returncmd; STRCPY(ccline.cmdbuff, p); } @@ -1994,27 +1986,21 @@ static void alloc_cmdbuff(int len) else len += 20; - ccline.cmdbuff = alloc(len); /* caller should check for out-of-memory */ + ccline.cmdbuff = xmalloc(len); ccline.cmdbufflen = len; } /* * Re-allocate the command line to length len + something extra. - * return FAIL for failure, OK otherwise */ -static int realloc_cmdbuff(int len) +static void realloc_cmdbuff(int len) { - char_u *p; - - if (len < ccline.cmdbufflen) - return OK; /* no need to resize */ + if (len < ccline.cmdbufflen) { + return; // no need to resize + } - p = ccline.cmdbuff; + char_u *p = ccline.cmdbuff; alloc_cmdbuff(len); /* will get some more */ - if (ccline.cmdbuff == NULL) { /* out of memory */ - ccline.cmdbuff = p; /* keep the old one */ - return FAIL; - } /* There isn't always a NUL after the command, but it may need to be * there, thus copy up to the NUL and add a NUL. */ memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen); @@ -2032,8 +2018,6 @@ static int realloc_cmdbuff(int len) if (i >= 0 && i <= ccline.cmdlen) ccline.xpc->xp_pattern = ccline.cmdbuff + i; } - - return OK; } static char_u *arshape_buf = NULL; @@ -2082,9 +2066,7 @@ static void draw_cmdline(int start, int len) * alloc()/free() calls. */ free(arshape_buf); buflen = len * 2 + 2; - arshape_buf = alloc(buflen); - if (arshape_buf == NULL) - return; /* out of memory */ + arshape_buf = xmalloc(buflen); } if (utf_iscomposing(utf_ptr2char(ccline.cmdbuff + start))) { @@ -2188,9 +2170,8 @@ void unputcmdline(void) * twice in a row, then 'redraw' should be FALSE and redrawcmd() should be * called afterwards. */ -int put_on_cmdline(char_u *str, int len, int redraw) +void put_on_cmdline(char_u *str, int len, int redraw) { - int retval; int i; int m; int c; @@ -2198,121 +2179,116 @@ int put_on_cmdline(char_u *str, int len, int redraw) if (len < 0) len = (int)STRLEN(str); - /* Check if ccline.cmdbuff needs to be longer */ - if (ccline.cmdlen + len + 1 >= ccline.cmdbufflen) - retval = realloc_cmdbuff(ccline.cmdlen + len + 1); - else - retval = OK; - if (retval == OK) { - if (!ccline.overstrike) { - memmove(ccline.cmdbuff + ccline.cmdpos + len, - ccline.cmdbuff + ccline.cmdpos, - (size_t)(ccline.cmdlen - ccline.cmdpos)); - ccline.cmdlen += len; - } else { - if (has_mbyte) { - /* Count nr of characters in the new string. */ - m = 0; - for (i = 0; i < len; i += (*mb_ptr2len)(str + i)) - ++m; - /* Count nr of bytes in cmdline that are overwritten by these - * characters. */ - for (i = ccline.cmdpos; i < ccline.cmdlen && m > 0; - i += (*mb_ptr2len)(ccline.cmdbuff + i)) - --m; - if (i < ccline.cmdlen) { - memmove(ccline.cmdbuff + ccline.cmdpos + len, - ccline.cmdbuff + i, (size_t)(ccline.cmdlen - i)); - ccline.cmdlen += ccline.cmdpos + len - i; - } else - ccline.cmdlen = ccline.cmdpos + len; - } else if (ccline.cmdpos + len > ccline.cmdlen) + realloc_cmdbuff(ccline.cmdlen + len + 1); + + if (!ccline.overstrike) { + memmove(ccline.cmdbuff + ccline.cmdpos + len, + ccline.cmdbuff + ccline.cmdpos, + (size_t)(ccline.cmdlen - ccline.cmdpos)); + ccline.cmdlen += len; + } else { + if (has_mbyte) { + /* Count nr of characters in the new string. */ + m = 0; + for (i = 0; i < len; i += (*mb_ptr2len)(str + i)) + ++m; + /* Count nr of bytes in cmdline that are overwritten by these + * characters. */ + for (i = ccline.cmdpos; i < ccline.cmdlen && m > 0; + i += (*mb_ptr2len)(ccline.cmdbuff + i)) + --m; + if (i < ccline.cmdlen) { + memmove(ccline.cmdbuff + ccline.cmdpos + len, + ccline.cmdbuff + i, (size_t)(ccline.cmdlen - i)); + ccline.cmdlen += ccline.cmdpos + len - i; + } else ccline.cmdlen = ccline.cmdpos + len; - } - memmove(ccline.cmdbuff + ccline.cmdpos, str, (size_t)len); - ccline.cmdbuff[ccline.cmdlen] = NUL; + } else if (ccline.cmdpos + len > ccline.cmdlen) + ccline.cmdlen = ccline.cmdpos + len; + } + memmove(ccline.cmdbuff + ccline.cmdpos, str, (size_t)len); + ccline.cmdbuff[ccline.cmdlen] = NUL; - if (enc_utf8) { - /* When the inserted text starts with a composing character, - * backup to the character before it. There could be two of them. - */ - i = 0; + if (enc_utf8) { + /* When the inserted text starts with a composing character, + * backup to the character before it. There could be two of them. + */ + i = 0; + c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos); + while (ccline.cmdpos > 0 && utf_iscomposing(c)) { + i = (*mb_head_off)(ccline.cmdbuff, + ccline.cmdbuff + ccline.cmdpos - 1) + 1; + ccline.cmdpos -= i; + len += i; c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos); - while (ccline.cmdpos > 0 && utf_iscomposing(c)) { - i = (*mb_head_off)(ccline.cmdbuff, - ccline.cmdbuff + ccline.cmdpos - 1) + 1; + } + if (i == 0 && ccline.cmdpos > 0 && arabic_maycombine(c)) { + /* Check the previous character for Arabic combining pair. */ + i = (*mb_head_off)(ccline.cmdbuff, + ccline.cmdbuff + ccline.cmdpos - 1) + 1; + if (arabic_combine(utf_ptr2char(ccline.cmdbuff + + ccline.cmdpos - i), c)) { ccline.cmdpos -= i; len += i; - c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos); - } - if (i == 0 && ccline.cmdpos > 0 && arabic_maycombine(c)) { - /* Check the previous character for Arabic combining pair. */ - i = (*mb_head_off)(ccline.cmdbuff, - ccline.cmdbuff + ccline.cmdpos - 1) + 1; - if (arabic_combine(utf_ptr2char(ccline.cmdbuff - + ccline.cmdpos - i), c)) { - ccline.cmdpos -= i; - len += i; - } else - i = 0; - } - if (i != 0) { - /* Also backup the cursor position. */ - i = ptr2cells(ccline.cmdbuff + ccline.cmdpos); - ccline.cmdspos -= i; - msg_col -= i; - if (msg_col < 0) { - msg_col += Columns; - --msg_row; - } + } else + i = 0; + } + if (i != 0) { + /* Also backup the cursor position. */ + i = ptr2cells(ccline.cmdbuff + ccline.cmdpos); + ccline.cmdspos -= i; + msg_col -= i; + if (msg_col < 0) { + msg_col += Columns; + --msg_row; } } + } - if (redraw && !cmd_silent) { - msg_no_more = TRUE; - i = cmdline_row; - cursorcmd(); - draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos); - /* Avoid clearing the rest of the line too often. */ - if (cmdline_row != i || ccline.overstrike) - msg_clr_eos(); - msg_no_more = FALSE; - } - /* - * If we are in Farsi command mode, the character input must be in - * Insert mode. So do not advance the cmdpos. - */ - if (!cmd_fkmap) { - if (KeyTyped) { - m = Columns * Rows; - if (m < 0) /* overflow, Columns or Rows at weird value */ - m = MAXCOL; - } else + if (redraw && !cmd_silent) { + msg_no_more = TRUE; + i = cmdline_row; + cursorcmd(); + draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos); + /* Avoid clearing the rest of the line too often. */ + if (cmdline_row != i || ccline.overstrike) + msg_clr_eos(); + msg_no_more = FALSE; + } + /* + * If we are in Farsi command mode, the character input must be in + * Insert mode. So do not advance the cmdpos. + */ + if (!cmd_fkmap) { + if (KeyTyped) { + m = Columns * Rows; + if (m < 0) /* overflow, Columns or Rows at weird value */ m = MAXCOL; - for (i = 0; i < len; ++i) { - c = cmdline_charsize(ccline.cmdpos); - /* count ">" for a double-wide char that doesn't fit. */ - if (has_mbyte) - correct_cmdspos(ccline.cmdpos, c); - /* Stop cursor at the end of the screen, but do increment the - * insert position, so that entering a very long command - * works, even though you can't see it. */ - if (ccline.cmdspos + c < m) - ccline.cmdspos += c; - if (has_mbyte) { - c = (*mb_ptr2len)(ccline.cmdbuff + ccline.cmdpos) - 1; - if (c > len - i - 1) - c = len - i - 1; - ccline.cmdpos += c; - i += c; - } - ++ccline.cmdpos; + } else + m = MAXCOL; + for (i = 0; i < len; ++i) { + c = cmdline_charsize(ccline.cmdpos); + /* count ">" for a double-wide char that doesn't fit. */ + if (has_mbyte) + correct_cmdspos(ccline.cmdpos, c); + /* Stop cursor at the end of the screen, but do increment the + * insert position, so that entering a very long command + * works, even though you can't see it. */ + if (ccline.cmdspos + c < m) + ccline.cmdspos += c; + if (has_mbyte) { + c = (*mb_ptr2len)(ccline.cmdbuff + ccline.cmdpos) - 1; + if (c > len - i - 1) + c = len - i - 1; + ccline.cmdpos += c; + i += c; } + ++ccline.cmdpos; } } + if (redraw) msg_check(); - return retval; } static struct cmdline_info prev_ccline; @@ -2348,15 +2324,11 @@ static void restore_cmdline(struct cmdline_info *ccp) /* * Save the command line into allocated memory. Returns a pointer to be * passed to restore_cmdline_alloc() later. - * Returns NULL when failed. */ char_u *save_cmdline_alloc(void) { - struct cmdline_info *p; - - p = (struct cmdline_info *)alloc((unsigned)sizeof(struct cmdline_info)); - if (p != NULL) - save_cmdline(p); + struct cmdline_info *p = xmalloc(sizeof(struct cmdline_info)); + save_cmdline(p); return (char_u *)p; } @@ -2649,7 +2621,6 @@ nextwild ( char_u *p1; char_u *p2; int difflen; - int v; if (xp->xp_numfiles == -1) { set_expand_context(xp); @@ -2712,18 +2683,15 @@ nextwild ( if (p2 != NULL && !got_int) { difflen = (int)STRLEN(p2) - xp->xp_pattern_len; if (ccline.cmdlen + difflen + 4 > ccline.cmdbufflen) { - v = realloc_cmdbuff(ccline.cmdlen + difflen + 4); + realloc_cmdbuff(ccline.cmdlen + difflen + 4); xp->xp_pattern = ccline.cmdbuff + i; - } else - v = OK; - if (v == OK) { - memmove(&ccline.cmdbuff[ccline.cmdpos + difflen], - &ccline.cmdbuff[ccline.cmdpos], - (size_t)(ccline.cmdlen - ccline.cmdpos + 1)); - memmove(&ccline.cmdbuff[i], p2, STRLEN(p2)); - ccline.cmdlen += difflen; - ccline.cmdpos += difflen; } + memmove(&ccline.cmdbuff[ccline.cmdpos + difflen], + &ccline.cmdbuff[ccline.cmdpos], + (size_t)(ccline.cmdlen - ccline.cmdpos + 1)); + memmove(&ccline.cmdbuff[i], p2, STRLEN(p2)); + ccline.cmdlen += difflen; + ccline.cmdpos += difflen; } free(p2); @@ -3104,15 +3072,11 @@ char_u *vim_strsave_fnameescape(char_u *fname, int shell) */ static void escape_fname(char_u **pp) { - char_u *p; - - p = alloc((unsigned)(STRLEN(*pp) + 2)); - if (p != NULL) { - p[0] = '\\'; - STRCPY(p + 1, *pp); - free(*pp); - *pp = p; - } + char_u *p = xmalloc(STRLEN(*pp) + 2); + p[0] = '\\'; + STRCPY(p + 1, *pp); + free(*pp); + *pp = p; } /* @@ -3246,8 +3210,7 @@ static int showmatches(expand_T *xp, int wildmenu) exp_path = expand_env_save_opt(files_found[k], TRUE); halved_slash = backslash_halve_save( exp_path != NULL ? exp_path : files_found[k]); - j = os_isdir(halved_slash != NULL ? halved_slash - : files_found[k]); + j = os_isdir(halved_slash); free(exp_path); free(halved_slash); } else @@ -3403,8 +3366,8 @@ addstar ( || context == EXPAND_USER_LIST) && fname[i] == '\\') new_len++; /* '\' becomes "\\" */ } - retval = alloc(new_len); - if (retval != NULL) { + retval = xmalloc(new_len); + { retval[0] = '^'; j = 1; for (i = 0; i < len; i++, j++) { @@ -3437,7 +3400,7 @@ addstar ( } } } else { - retval = alloc(len + 4); + retval = xmalloc(len + 4); if (retval != NULL) { vim_strncpy(retval, fname, len); @@ -3831,7 +3794,7 @@ ExpandFromContext ( * obtain strings, one by one. The strings are matched against a regexp * program. Matching strings are copied into an array, which is returned. * - * Returns OK when no problems encountered, FAIL for error (out of memory). + * Returns OK when no problems encountered, FAIL for error. */ int ExpandGeneric(xp, regmatch, num_file, file, func, escaped) expand_T *xp; @@ -3860,11 +3823,7 @@ int escaped; if (count == 0) return OK; *num_file = count; - *file = (char_u **)alloc((unsigned)(count * sizeof(char_u *))); - if (*file == NULL) { - *file = (char_u **)""; - return FAIL; - } + *file = (char_u **)xmalloc(count * sizeof(char_u *)); // copy the matching names into allocated memory count = 0; @@ -3925,15 +3884,12 @@ expand_shellcmd ( char_u *path; int mustfree = FALSE; garray_T ga; - char_u *buf = alloc(MAXPATHL); + char_u *buf = xmalloc(MAXPATHL); size_t l; char_u *s, *e; int flags = flagsarg; int ret; - if (buf == NULL) - return FAIL; - /* for ":set path=" and ":set tags=" halve backslashes for escaped * space */ pat = vim_strsave(filepat); @@ -4157,11 +4113,7 @@ static int ExpandRTDir(char_u *pat, int *num_file, char_u ***file, char *dirname ga_init(&ga, (int)sizeof(char *), 10); for (i = 0; dirnames[i] != NULL; ++i) { - s = alloc((unsigned)(STRLEN(dirnames[i]) + pat_len + 7)); - if (s == NULL) { - ga_clear_strings(&ga); - return FAIL; - } + s = xmalloc(STRLEN(dirnames[i]) + pat_len + 7); sprintf((char *)s, "%s/%s*.vim", dirnames[i], pat); matches = globpath(p_rtp, s, 0); free(s); @@ -4208,7 +4160,6 @@ static int ExpandRTDir(char_u *pat, int *num_file, char_u ***file, char *dirname char_u *globpath(char_u *path, char_u *file, int expand_options) { expand_T xpc; - char_u *buf; garray_T ga; int i; int len; @@ -4216,9 +4167,7 @@ char_u *globpath(char_u *path, char_u *file, int expand_options) char_u **p; char_u *cur = NULL; - buf = alloc(MAXPATHL); - if (buf == NULL) - return NULL; + char_u *buf = xmalloc(MAXPATHL); ExpandInit(&xpc); xpc.xp_context = EXPAND_FILES; @@ -4510,8 +4459,7 @@ add_to_history ( /* Store the separator after the NUL of the string. */ len = (int)STRLEN(new_entry); hisptr->hisstr = vim_strnsave(new_entry, len + 2); - if (hisptr->hisstr != NULL) - hisptr->hisstr[len + 1] = sep; + hisptr->hisstr[len + 1] = sep; hisptr->hisnum = ++hisnum[histype]; hisptr->viminfo = FALSE; diff --git a/src/nvim/ex_getln.h b/src/nvim/ex_getln.h index 61a0fcaeb3..d2ebb7a82f 100644 --- a/src/nvim/ex_getln.h +++ b/src/nvim/ex_getln.h @@ -14,7 +14,7 @@ char_u *getexmodeline(int promptc, void *cookie, int indent); void free_cmdline_buf(void); void putcmdline(int c, int shift); void unputcmdline(void); -int put_on_cmdline(char_u *str, int len, int redraw); +void put_on_cmdline(char_u *str, int len, int redraw); char_u *save_cmdline_alloc(void); void restore_cmdline_alloc(char_u *p); void cmdline_paste_str(char_u *s, int literally); diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index dbef8b422d..0ff02b85bf 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -278,8 +278,7 @@ vim_findfile_init ( if (search_ctx_arg != NULL) search_ctx = search_ctx_arg; else { - search_ctx = (ff_search_ctx_T*)alloc((unsigned)sizeof(ff_search_ctx_T)); - memset(search_ctx, 0, sizeof(ff_search_ctx_T)); + search_ctx = xcalloc(1, sizeof(ff_search_ctx_T)); } search_ctx->ffsc_find_what = find_what; search_ctx->ffsc_tagfile = tagfile; @@ -305,7 +304,7 @@ vim_findfile_init ( } if (ff_expand_buffer == NULL) { - ff_expand_buffer = (char_u*)alloc(MAXPATHL); + ff_expand_buffer = xmalloc(MAXPATHL); } /* Store information on starting dir now if path is relative. @@ -322,8 +321,6 @@ vim_findfile_init ( search_ctx->ffsc_start_dir = FullName_save(ff_expand_buffer, FALSE); } else search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len); - if (search_ctx->ffsc_start_dir == NULL) - goto error_return; if (*++path != NUL) ++path; } else if (*path == NUL || !vim_isAbsName(path)) { @@ -344,8 +341,6 @@ vim_findfile_init ( goto error_return; search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer); - if (search_ctx->ffsc_start_dir == NULL) - goto error_return; #ifdef BACKSLASH_IN_FILENAME /* A path that starts with "/dir" is relative to the drive, not to the @@ -374,8 +369,7 @@ vim_findfile_init ( walker++; dircount = 1; - search_ctx->ffsc_stopdirs_v = - (char_u **)alloc((unsigned)sizeof(char_u *)); + search_ctx->ffsc_stopdirs_v = xmalloc(sizeof(char_u *)); do { char_u *helper; @@ -458,9 +452,6 @@ vim_findfile_init ( } ff_expand_buffer[len] = NUL; search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer); - - if (search_ctx->ffsc_wc_path == NULL) - goto error_return; } else search_ctx->ffsc_fix_path = vim_strsave(path); @@ -469,8 +460,6 @@ vim_findfile_init ( * This is needed if the parameter path is fully qualified. */ search_ctx->ffsc_start_dir = vim_strsave(search_ctx->ffsc_fix_path); - if (search_ctx->ffsc_start_dir == NULL) - goto error_return; search_ctx->ffsc_fix_path[0] = NUL; } @@ -483,9 +472,8 @@ vim_findfile_init ( STRCPY(ff_expand_buffer, search_ctx->ffsc_start_dir); add_pathsep(ff_expand_buffer); { - int eb_len = (int)STRLEN(ff_expand_buffer); - char_u *buf = alloc(eb_len - + (int)STRLEN(search_ctx->ffsc_fix_path) + 1); + size_t eb_len = STRLEN(ff_expand_buffer); + char_u *buf = xmalloc(eb_len + STRLEN(search_ctx->ffsc_fix_path) + 1); STRCPY(buf, ff_expand_buffer); STRCPY(buf + eb_len, search_ctx->ffsc_fix_path); @@ -507,9 +495,9 @@ vim_findfile_init ( if (search_ctx->ffsc_wc_path != NULL) { wc_path = vim_strsave(search_ctx->ffsc_wc_path); - temp = alloc((int)(STRLEN(search_ctx->ffsc_wc_path) - + STRLEN(search_ctx->ffsc_fix_path + len) - + 1)); + temp = xmalloc(STRLEN(search_ctx->ffsc_wc_path) + + STRLEN(search_ctx->ffsc_fix_path + len) + + 1); } if (temp == NULL || wc_path == NULL) { @@ -532,15 +520,8 @@ vim_findfile_init ( search_ctx->ffsc_wc_path, level, 0); - if (sptr == NULL) - goto error_return; - ff_push(search_ctx, sptr); - search_ctx->ffsc_file_to_search = vim_strsave(filename); - if (search_ctx->ffsc_file_to_search == NULL) - goto error_return; - return search_ctx; error_return: @@ -623,8 +604,7 @@ char_u *vim_findfile(void *search_ctx_arg) * filepath is used as buffer for various actions and as the storage to * return a found filename. */ - if ((file_path = alloc((int)MAXPATHL)) == NULL) - return NULL; + file_path = xmalloc(MAXPATHL); /* store the end of the start dir -- needed for upward search */ if (search_ctx->ffsc_start_dir != NULL) @@ -776,12 +756,9 @@ char_u *vim_findfile(void *search_ctx_arg) * If the path is a URL don't try this. */ if (path_with_url(dirptrs[0])) { - stackp->ffs_filearray = (char_u **) - alloc((unsigned)sizeof(char *)); - if ((stackp->ffs_filearray[0] = vim_strsave(dirptrs[0])) != NULL) - stackp->ffs_filearray_size = 1; - else - stackp->ffs_filearray_size = 0; + stackp->ffs_filearray = (char_u **)xmalloc(sizeof(char *)); + stackp->ffs_filearray[0] = vim_strsave(dirptrs[0]); + stackp->ffs_filearray_size = 1; } else /* Add EW_NOTWILD because the expanded path may contain * wildcard characters that are to be taken literally. @@ -969,8 +946,6 @@ char_u *vim_findfile(void *search_ctx_arg) /* create a new stack entry */ sptr = ff_create_stack_element(file_path, search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0); - if (sptr == NULL) - break; ff_push(search_ctx, sptr); } else break; @@ -1066,14 +1041,10 @@ static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, ff_visited_l /* * if we reach this we didn't find a list and we have to allocate new list */ - retptr = (ff_visited_list_hdr_T*)alloc((unsigned)sizeof(*retptr)); + retptr = xmalloc(sizeof(*retptr)); retptr->ffvl_visited_list = NULL; retptr->ffvl_filename = vim_strsave(filename); - if (retptr->ffvl_filename == NULL) { - free(retptr); - return NULL; - } retptr->ffvl_next = *list_headp; *list_headp = retptr; @@ -1156,8 +1127,7 @@ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u * /* * New file/dir. Add it to the list of visited files/dirs. */ - vp = (ff_visited_T *)alloc((unsigned)(sizeof(ff_visited_T) - + STRLEN(ff_expand_buffer))); + vp = xmalloc(sizeof(ff_visited_T) + STRLEN(ff_expand_buffer)); if (!url) { vp->ffv_dev_valid = TRUE; @@ -1185,9 +1155,7 @@ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u * */ static ff_stack_T *ff_create_stack_element(char_u *fix_part, char_u *wc_part, int level, int star_star_empty) { - ff_stack_T *new; - - new = (ff_stack_T *)alloc((unsigned)sizeof(ff_stack_T)); + ff_stack_T *new = xmalloc(sizeof(ff_stack_T)); new->ffs_prev = NULL; new->ffs_filearray = NULL; @@ -1206,13 +1174,6 @@ static ff_stack_T *ff_create_stack_element(char_u *fix_part, char_u *wc_part, in wc_part = (char_u *)""; new->ffs_wc_path = vim_strsave(wc_part); - if (new->ffs_fix_path == NULL - || new->ffs_wc_path == NULL - ) { - ff_free_stack_element(new); - new = NULL; - } - return new; } @@ -1429,10 +1390,6 @@ find_file_in_path_option ( free(ff_file_to_find); ff_file_to_find = vim_strsave(NameBuff); - if (ff_file_to_find == NULL) { /* out of memory */ - file_name = NULL; - goto theend; - } } rel_to_curdir = (ff_file_to_find[0] == '.' @@ -1525,7 +1482,7 @@ find_file_in_path_option ( break; } - buf = alloc((int)(MAXPATHL)); + buf = xmalloc(MAXPATHL); /* copy next path */ buf[0] = 0; diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 214b38dea7..027c7b07d5 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -2070,11 +2070,9 @@ static char_u *next_fenc(char_u **pp) } else { r = vim_strnsave(*pp, (int)(p - *pp)); *pp = p + 1; - if (r != NULL) { - p = enc_canonize(r); - free(r); - r = p; - } + p = enc_canonize(r); + free(r); + r = p; } if (r == NULL) { /* out of memory */ r = (char_u *)""; @@ -3438,7 +3436,7 @@ restore_backup: "E513: write error, conversion failed (make 'fenc' empty to override)"); else { errmsg_allocated = TRUE; - errmsg = alloc(300); + errmsg = xmalloc(300); vim_snprintf((char *)errmsg, 300, _("E513: write error, conversion failed in line %" PRId64 " (make 'fenc' empty to override)"), @@ -4373,7 +4371,7 @@ modname ( * (we need the full path in case :cd is used). */ if (fname == NULL || *fname == NUL) { - retval = alloc((unsigned)(MAXPATHL + extlen + 3)); + retval = xmalloc(MAXPATHL + extlen + 3); if (os_dirname(retval, MAXPATHL) == FAIL || (fnamelen = (int)STRLEN(retval)) == 0) { free(retval); @@ -4386,7 +4384,7 @@ modname ( prepend_dot = FALSE; /* nothing to prepend a dot to */ } else { fnamelen = (int)STRLEN(fname); - retval = alloc((unsigned)(fnamelen + extlen + 3)); + retval = xmalloc(fnamelen + extlen + 3); STRCPY(retval, fname); } @@ -4759,7 +4757,7 @@ static int move_lines(buf_T *frombuf, buf_T *tobuf) curbuf = tobuf; for (lnum = 1; lnum <= frombuf->b_ml.ml_line_count; ++lnum) { p = vim_strsave(ml_get_buf(frombuf, lnum, FALSE)); - if (p == NULL || ml_append(lnum - 1, p, 0, FALSE) == FAIL) { + if (ml_append(lnum - 1, p, 0, FALSE) == FAIL) { free(p); retval = FAIL; break; @@ -4936,8 +4934,7 @@ buf_check_timestamp ( if (path != NULL) { if (!helpmesg) mesg2 = ""; - tbuf = alloc((unsigned)(STRLEN(path) + STRLEN(mesg) - + STRLEN(mesg2) + 2)); + tbuf = xmalloc(STRLEN(path) + STRLEN(mesg) + STRLEN(mesg2) + 2); sprintf((char *)tbuf, mesg, path); /* Set warningmsg here, before the unimportant and output-specific * mesg2 has been appended. */ @@ -5759,8 +5756,6 @@ static int au_new_group(char_u *name) } AUGROUP_NAME(i) = vim_strsave(name); - if (AUGROUP_NAME(i) == NULL) - return AUGROUP_ERROR; if (i == augroups.ga_len) ++augroups.ga_len; } @@ -5964,18 +5959,14 @@ char_u *au_event_disable(char *what) char_u *save_ei; save_ei = vim_strsave(p_ei); - if (save_ei != NULL) { - new_ei = vim_strnsave(p_ei, (int)(STRLEN(p_ei) + STRLEN(what))); - if (new_ei != NULL) { - if (*what == ',' && *p_ei == NUL) - STRCPY(new_ei, what + 1); - else - STRCAT(new_ei, what); - set_string_option_direct((char_u *)"ei", -1, new_ei, - OPT_FREE, SID_NONE); - free(new_ei); - } - } + new_ei = vim_strnsave(p_ei, (int)(STRLEN(p_ei) + STRLEN(what))); + if (*what == ',' && *p_ei == NUL) + STRCPY(new_ei, what + 1); + else + STRCAT(new_ei, what); + set_string_option_direct((char_u *)"ei", -1, new_ei, OPT_FREE, SID_NONE); + free(new_ei); + return save_ei; } @@ -6126,7 +6117,7 @@ void do_autocmd(char_u *arg, int forceit) * Find the group ID in a ":autocmd" or ":doautocmd" argument. * The "argp" argument is advanced to the following argument. * - * Returns the group ID, AUGROUP_ERROR for error (out of memory). + * Returns the group ID or AUGROUP_ALL. */ static int au_get_grouparg(char_u **argp) { @@ -6138,8 +6129,6 @@ static int au_get_grouparg(char_u **argp) p = skiptowhite(arg); if (p > arg) { group_name = vim_strnsave(arg, (int)(p - arg)); - if (group_name == NULL) /* out of memory */ - return AUGROUP_ERROR; group = au_find_group(group_name); if (group == AUGROUP_ERROR) group = AUGROUP_ALL; /* no match, use all groups */ @@ -6306,13 +6295,9 @@ static int do_autocmd_event(event_T event, char_u *pat, int nested, char_u *cmd, return FAIL; } - ap = (AutoPat *)alloc((unsigned)sizeof(AutoPat)); + ap = xmalloc(sizeof(AutoPat)); ap->pat = vim_strnsave(pat, patlen); ap->patlen = patlen; - if (ap->pat == NULL) { - free(ap); - return FAIL; - } if (is_buflocal) { ap->buflocal_nr = buflocal_nr; @@ -6347,13 +6332,9 @@ static int do_autocmd_event(event_T event, char_u *pat, int nested, char_u *cmd, prev_ac = &(ap->cmds); while ((ac = *prev_ac) != NULL) prev_ac = &ac->next; - ac = (AutoCmd *)alloc((unsigned)sizeof(AutoCmd)); + ac = xmalloc(sizeof(AutoCmd)); ac->cmd = vim_strsave(cmd); ac->scriptID = current_SID; - if (ac->cmd == NULL) { - free(ac); - return FAIL; - } ac->next = NULL; *prev_ac = ac; ac->nested = nested; @@ -7160,8 +7141,7 @@ auto_next_pat ( : ap->buflocal_nr == apc->arg_bufnr) { name = event_nr2name(apc->event); s = _("%s Auto commands for \"%s\""); - sourcing_name = alloc((unsigned)(STRLEN(s) - + STRLEN(name) + ap->patlen + 1)); + sourcing_name = xmalloc(STRLEN(s) + STRLEN(name) + ap->patlen + 1); sprintf((char *)sourcing_name, s, (char *)name, (char *)ap->pat); if (p_verbose >= 8) { @@ -7264,8 +7244,7 @@ int has_autocmd(event_T event, char_u *sfname, buf_T *buf) * autocommand patterns portable between Unix and MS-DOS. */ sfname = vim_strsave(sfname); - if (sfname != NULL) - forward_slash(sfname); + forward_slash(sfname); forward_slash(fname); #endif @@ -7403,8 +7382,6 @@ int au_exists(char_u *arg) /* Make a copy so that we can change the '#' chars to a NUL. */ arg_save = vim_strsave(arg); - if (arg_save == NULL) - return FALSE; p = vim_strchr(arg_save, '#'); if (p != NULL) *p++ = NUL; diff --git a/src/nvim/fold.c b/src/nvim/fold.c index d12d364f49..1215d5b24d 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -1610,7 +1610,7 @@ static void foldAddMarker(linenr_T lnum, char_u *marker, int markerlen) line_len = (int)STRLEN(line); if (u_save(lnum - 1, lnum + 1) == OK) { - newline = alloc((unsigned)(line_len + markerlen + STRLEN(cms) + 1)); + newline = xmalloc(line_len + markerlen + STRLEN(cms) + 1); STRCPY(newline, line); if (p == NULL) vim_strncpy(newline + line_len, marker, markerlen); @@ -1681,7 +1681,7 @@ static void foldDelMarker(linenr_T lnum, char_u *marker, int markerlen) } if (u_save(lnum - 1, lnum + 1) == OK) { /* Make new line: text-before-marker + text-after-marker */ - newline = alloc((unsigned)(STRLEN(line) - len + 1)); + newline = xmalloc(STRLEN(line) - len + 1); STRNCPY(newline, line, p - line); STRCPY(newline + (p - line), p + len); ml_replace(lnum, newline, FALSE); diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index efa63f2682..52322244e1 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -891,14 +891,8 @@ int ins_typebuf(char_u *str, int noremap, int offset, int nottyped, int silent) setcursor(); return FAIL; } - s1 = alloc(newlen); - if (s1 == NULL) /* out of memory */ - return FAIL; - s2 = alloc(newlen); - if (s2 == NULL) { /* out of memory */ - free(s1); - return FAIL; - } + s1 = xmalloc(newlen); + s2 = xmalloc(newlen); typebuf.tb_buflen = newlen; /* copy the old chars, before the insertion point */ @@ -1147,16 +1141,11 @@ static void may_sync_undo(void) /* * Make "typebuf" empty and allocate new buffers. - * Returns FAIL when out of memory. */ -int alloc_typebuf(void) +void alloc_typebuf(void) { - typebuf.tb_buf = alloc(TYPELEN_INIT); - typebuf.tb_noremap = alloc(TYPELEN_INIT); - if (typebuf.tb_buf == NULL || typebuf.tb_noremap == NULL) { - free_typebuf(); - return FAIL; - } + typebuf.tb_buf = xmalloc(TYPELEN_INIT); + typebuf.tb_noremap = xmalloc(TYPELEN_INIT); typebuf.tb_buflen = TYPELEN_INIT; typebuf.tb_off = 0; typebuf.tb_len = 0; @@ -1165,7 +1154,6 @@ int alloc_typebuf(void) typebuf.tb_no_abbr_cnt = 0; if (++typebuf.tb_change_cnt == 0) typebuf.tb_change_cnt = 1; - return OK; } /* @@ -1189,16 +1177,11 @@ void free_typebuf(void) */ static typebuf_T saved_typebuf[NSCRIPT]; -int save_typebuf(void) +void save_typebuf(void) { init_typebuf(); saved_typebuf[curscript] = typebuf; - /* If out of memory: restore typebuf and close file. */ - if (alloc_typebuf() == FAIL) { - closescript(); - return FAIL; - } - return OK; + alloc_typebuf(); } static int old_char = -1; /* character put back by vungetc() */ @@ -1213,10 +1196,8 @@ static int old_mouse_col; /* mouse_col related to old_char */ void save_typeahead(tasave_T *tp) { tp->save_typebuf = typebuf; - tp->typebuf_valid = (alloc_typebuf() == OK); - if (!tp->typebuf_valid) - typebuf = tp->save_typebuf; - + alloc_typebuf(); + tp->typebuf_valid = TRUE; tp->old_char = old_char; tp->old_mod_mask = old_mod_mask; old_char = -1; @@ -1280,8 +1261,7 @@ openscript ( --curscript; return; } - if (save_typebuf() == FAIL) - return; + save_typebuf(); /* * Execute the commands from the file right now when using ":source!" @@ -2636,7 +2616,6 @@ do_map ( char_u *p; int n; int len = 0; /* init for GCC */ - char_u *newstr; int hasarg; int haskey; int did_it = FALSE; @@ -2979,13 +2958,8 @@ do_map ( } else { /* new rhs for existing entry */ mp->m_mode &= ~mode; /* remove mode bits */ if (mp->m_mode == 0 && !did_it) { /* reuse entry */ - newstr = vim_strsave(rhs); - if (newstr == NULL) { - retval = 4; /* no mem */ - goto theend; - } free(mp->m_str); - mp->m_str = newstr; + mp->m_str = vim_strsave(rhs); free(mp->m_orig_str); mp->m_orig_str = vim_strsave(orig_rhs); mp->m_noremap = noremap; @@ -3044,11 +3018,7 @@ do_map ( /* * Get here when adding a new entry to the maphash[] list or abbrlist. */ - mp = (mapblock_T *)alloc((unsigned)sizeof(mapblock_T)); - if (mp == NULL) { - retval = 4; /* no mem */ - goto theend; - } + mp = xmalloc(sizeof(mapblock_T)); /* If CTRL-C has been mapped, don't always use it for Interrupting */ if (*keys == Ctrl_C) @@ -3057,14 +3027,6 @@ do_map ( mp->m_keys = vim_strsave(keys); mp->m_str = vim_strsave(rhs); mp->m_orig_str = vim_strsave(orig_rhs); - if (mp->m_keys == NULL || mp->m_str == NULL) { - free(mp->m_keys); - free(mp->m_str); - free(mp->m_orig_str); - free(mp); - retval = 4; /* no mem */ - goto theend; - } mp->m_keylen = (int)STRLEN(mp->m_keys); mp->m_noremap = noremap; mp->m_nowait = nowait; @@ -3328,11 +3290,9 @@ showmap ( /* Remove escaping of CSI, because "m_str" is in a format to be used * as typeahead. */ char_u *s = vim_strsave(mp->m_str); - if (s != NULL) { - vim_unescape_csi(s); - msg_outtrans_special(s, FALSE); - free(s); - } + vim_unescape_csi(s); + msg_outtrans_special(s, FALSE); + free(s); } if (p_verbose > 0) last_set_msg(mp->m_script_ID); @@ -3564,9 +3524,7 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file) break; /* for (round) */ if (round == 1) { - *file = (char_u **)alloc((unsigned)(count * sizeof(char_u *))); - if (*file == NULL) - return FAIL; + *file = (char_u **)xmalloc(count * sizeof(char_u *)); } } /* for (round) */ @@ -3778,8 +3736,6 @@ eval_map_expr ( /* Remove escaping of CSI, because "str" is in a format to be used as * typeahead. */ expr = vim_strsave(str); - if (expr == NULL) - return NULL; vim_unescape_csi(expr); save_cmd = save_cmdline_alloc(); @@ -3831,7 +3787,7 @@ char_u *vim_strsave_escape_csi(char_u *p) char_u *s, *d; /* Need a buffer to hold up to three times as much. */ - res = alloc((unsigned)(STRLEN(p) * 3) + 1); + res = xmalloc(STRLEN(p) * 3 + 1); d = res; for (s = p; *s != NUL; ) { if (s[0] == K_SPECIAL && s[1] != NUL && s[2] != NUL) { @@ -4325,10 +4281,8 @@ void add_map(char_u *map, int mode) p_cpo = (char_u *)""; /* Allow <> notation */ s = vim_strsave(map); - if (s != NULL) { - (void)do_map(0, s, mode, FALSE); - free(s); - } + (void)do_map(0, s, mode, FALSE); + free(s); p_cpo = cpo_save; } #endif diff --git a/src/nvim/getchar.h b/src/nvim/getchar.h index 527573bdab..c34efc8d0c 100644 --- a/src/nvim/getchar.h +++ b/src/nvim/getchar.h @@ -31,9 +31,9 @@ int typebuf_changed(int tb_change_cnt); int typebuf_typed(void); int typebuf_maplen(void); void del_typebuf(int len, int offset); -int alloc_typebuf(void); +void alloc_typebuf(void); void free_typebuf(void); -int save_typebuf(void); +void save_typebuf(void); void save_typeahead(tasave_T *tp); void restore_typeahead(tasave_T *tp); void openscript(char_u *name, int directly); diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c index 4918a0226f..4e4274bfa1 100644 --- a/src/nvim/hashtab.c +++ b/src/nvim/hashtab.c @@ -2,22 +2,23 @@ /// /// Handling of a hashtable with Vim-specific properties. /// -/// Each item in a hashtable has a NUL terminated string key. A key can appear +/// Each item in a hashtable has a NUL terminated string key. A key can appear /// only once in the table. /// -/// A hash number is computed from the key for quick lookup. When the hashes +/// A hash number is computed from the key for quick lookup. When the hashes /// of two different keys point to the same entry an algorithm is used to /// iterate over other entries in the table until the right one is found. /// To make the iteration work removed keys are different from entries where a /// key was never present. /// /// The mechanism has been partly based on how Python Dictionaries are -/// implemented. The algorithm is from Knuth Vol. 3, Sec. 6.4. +/// implemented. The algorithm is from Knuth Vol. 3, Sec. 6.4. /// -/// The hashtable grows to accommodate more entries when needed. At least 1/3 +/// The hashtable grows to accommodate more entries when needed. At least 1/3 /// of the entries is empty to keep the lookup efficient (at the cost of extra /// memory). +#include <stdbool.h> #include <string.h> #include "nvim/vim.h" @@ -29,12 +30,9 @@ // Magic value for algorithm that walks through the array. #define PERTURB_SHIFT 5 -static int hash_may_resize(hashtab_T *ht, int minitems); - +static int hash_may_resize(hashtab_T *ht, size_t minitems); /// Initialize an empty hash table. -/// -/// @param ht void hash_init(hashtab_T *ht) { // This zeroes all "ht_" entries and all the "hi_key" in "ht_smallarray". @@ -43,10 +41,10 @@ void hash_init(hashtab_T *ht) ht->ht_mask = HT_INIT_SIZE - 1; } -/// Free the array of a hash table. Does not free the items it contains! -/// If "ht" is not freed then you should call hash_init() next! +/// Free the array of a hash table without freeing contained values. /// -/// @param ht +/// If "ht" is not freed (after calling this) then you should call hash_init() +/// right next! void hash_clear(hashtab_T *ht) { if (ht->ht_array != ht->ht_smallarray) { @@ -54,20 +52,13 @@ void hash_clear(hashtab_T *ht) } } -/// Free the array of a hash table and all the keys it contains. The keys must -/// have been allocated. "off" is the offset from the start of the allocate -/// memory to the location of the key (it's always positive). +/// Free the array of a hash table and all contained values. /// -/// @param ht -/// @param off -void hash_clear_all(hashtab_T *ht, int off) +/// @param off the offset from start of value to start of key (@see hashitem_T). +void hash_clear_all(hashtab_T *ht, unsigned int off) { - long todo; - hashitem_T *hi; - - todo = (long)ht->ht_used; - - for (hi = ht->ht_array; todo > 0; ++hi) { + size_t todo = ht->ht_used; + for (hashitem_T *hi = ht->ht_array; todo > 0; ++hi) { if (!HASHITEM_EMPTY(hi)) { free(hi->hi_key - off); todo--; @@ -76,17 +67,15 @@ void hash_clear_all(hashtab_T *ht, int off) hash_clear(ht); } -/// Find "key" in hashtable "ht". "key" must not be NULL. -/// Always returns a pointer to a hashitem. If the item was not found then -/// HASHITEM_EMPTY() is TRUE. The pointer is then the place where the key -/// would be added. -/// WARNING: The returned pointer becomes invalid when the hashtable is changed -/// (adding, setting or removing an item)! +/// Find item for given "key" in hashtable "ht". /// -/// @param ht -/// @param key +/// @param key The key of the looked-for item. Must not be NULL. /// -/// @return Pointer to the hashitem stored with the given key. +/// @return Pointer to the hash item corresponding to the given key. +/// If not found, then return pointer to the empty item that would be +/// used for that key. +/// WARNING: Returned pointer becomes invalid as soon as the hash table +/// is changed in any way. hashitem_T* hash_find(hashtab_T *ht, char_u *key) { return hash_lookup(ht, key, hash_hash(key)); @@ -94,18 +83,16 @@ hashitem_T* hash_find(hashtab_T *ht, char_u *key) /// Like hash_find(), but caller computes "hash". /// -/// @param ht -/// @param key -/// @param hash +/// @param key The key of the looked-for item. Must not be NULL. +/// @param hash The precomputed hash for the key. /// -/// @return Pointer to the hashitem stored with the given key. +/// @return Pointer to the hashitem corresponding to the given key. +/// If not found, then return pointer to the empty item that would be +/// used for that key. +/// WARNING: Returned pointer becomes invalid as soon as the hash table +/// is changed in any way. hashitem_T* hash_lookup(hashtab_T *ht, char_u *key, hash_T hash) { - hash_T perturb; - hashitem_T *freeitem; - hashitem_T *hi; - unsigned idx; - #ifdef HT_DEBUG hash_count_lookup++; #endif // ifdef HT_DEBUG @@ -114,29 +101,28 @@ hashitem_T* hash_lookup(hashtab_T *ht, char_u *key, hash_T hash) // - return if there is no item at all // - skip over a removed item // - return if the item matches - idx = (unsigned)(hash & ht->ht_mask); - hi = &ht->ht_array[idx]; + hash_T idx = hash & ht->ht_mask; + hashitem_T *hi = &ht->ht_array[idx]; if (hi->hi_key == NULL) { return hi; } + hashitem_T *freeitem = NULL; if (hi->hi_key == HI_KEY_REMOVED) { freeitem = hi; } else if ((hi->hi_hash == hash) && (STRCMP(hi->hi_key, key) == 0)) { return hi; - } else { - freeitem = NULL; } - // Need to search through the table to find the key. The algorithm + // Need to search through the table to find the key. The algorithm // to step through the table starts with large steps, gradually becoming - // smaller down to (1/4 table size + 1). This means it goes through all + // smaller down to (1/4 table size + 1). This means it goes through all // table entries in the end. // When we run into a NULL key it's clear that the key isn't there. // Return the first available slot found (can be a slot of a removed // item). - for (perturb = hash;; perturb >>= PERTURB_SHIFT) { + for (hash_T perturb = hash;; perturb >>= PERTURB_SHIFT) { #ifdef HT_DEBUG // count a "miss" for hashtab lookup hash_count_perturb++; @@ -161,6 +147,7 @@ hashitem_T* hash_lookup(hashtab_T *ht, char_u *key, hash_T hash) } /// Print the efficiency of hashtable lookups. +/// /// Useful when trying different hash algorithms. /// Called when exiting. void hash_debug_results(void) @@ -176,12 +163,13 @@ void hash_debug_results(void) #endif // ifdef HT_DEBUG } -/// Add item with key "key" to hashtable "ht". +/// Add item for key "key" to hashtable "ht". /// -/// @param ht -/// @param key +/// @param key Pointer to the key for the new item. The key has to be contained +/// in the new item (@see hashitem_T). Must not be NULL. /// -/// @returns FAIL when out of memory or the key is already present. +/// @return OK if success. +/// FAIL if key already present, or out of memory. int hash_add(hashtab_T *ht, char_u *key) { hash_T hash = hash_hash(key); @@ -193,16 +181,16 @@ int hash_add(hashtab_T *ht, char_u *key) return hash_add_item(ht, hi, key, hash); } -/// Add item "hi" with "key" to hashtable "ht". "key" must not be NULL and -/// "hi" must have been obtained with hash_lookup() and point to an empty item. -/// "hi" is invalid after this! +/// Add item "hi" for key "key" to hashtable "ht". /// -/// @param ht -/// @param hi -/// @param key -/// @param hash +/// @param hi The hash item to be used. Must have been obtained through +/// hash_lookup() and point to an empty item. +/// @param key Pointer to the key for the new item. The key has to be contained +/// in the new item (@see hashitem_T). Must not be NULL. +/// @param hash The precomputed hash value for the key. /// -/// @returns OK or FAIL (out of memory). +/// @return OK if success. +/// FAIL if out of memory. int hash_add_item(hashtab_T *ht, hashitem_T *hi, char_u *key, hash_T hash) { // If resizing failed before and it fails again we can't add an item. @@ -221,13 +209,12 @@ int hash_add_item(hashtab_T *ht, hashitem_T *hi, char_u *key, hash_T hash) return hash_may_resize(ht, 0); } -/// Remove item "hi" from hashtable "ht". "hi" must have been obtained with -/// hash_lookup(). +/// Remove item "hi" from hashtable "ht". /// -/// The caller must take care of freeing the item itself. +/// Caller must take care of freeing the item itself. /// -/// @param ht -/// @param hi +/// @param hi The hash item to be removed. +/// It must have been obtained with hash_lookup(). void hash_remove(hashtab_T *ht, hashitem_T *hi) { ht->ht_used--; @@ -235,44 +222,37 @@ void hash_remove(hashtab_T *ht, hashitem_T *hi) hash_may_resize(ht, 0); } -/// Lock a hashtable: prevent that ht_array changes. +/// Lock hashtable (prevent changes in ht_array). +/// /// Don't use this when items are to be added! /// Must call hash_unlock() later. -/// -/// @param ht void hash_lock(hashtab_T *ht) { ht->ht_locked++; } -/// Unlock a hashtable: allow ht_array changes again. -/// Table will be resized (shrink) when necessary. +/// Unlock hashtable (allow changes in ht_array again). +/// +/// Table will be resized (shrunk) when necessary. /// This must balance a call to hash_lock(). void hash_unlock(hashtab_T *ht) { ht->ht_locked--; - (void)hash_may_resize(ht, 0); + hash_may_resize(ht, 0); } -/// Shrink a hashtable when there is too much empty space. -/// Grow a hashtable when there is not enough empty space. +/// Resize hastable (new size can be given or automatically computed). /// -/// @param ht -/// @param minitems minimal number of items +/// @param minitems Minimum number of items the new table should hold. +/// If zero, new size will depend on currently used items: +/// - Shrink when too much empty space. +/// - Grow when not enough empty space. +/// If non-zero, passed minitems will be used. /// -/// @returns OK or FAIL (out of memory). -static int hash_may_resize(hashtab_T *ht, int minitems) +/// @return OK if success. +/// FAIL if out of memory. +static int hash_may_resize(hashtab_T *ht, size_t minitems) { - hashitem_T temparray[HT_INIT_SIZE]; - hashitem_T *oldarray, *newarray; - hashitem_T *olditem, *newitem; - unsigned newi; - int todo; - long_u oldsize, newsize; - long_u minsize; - long_u newmask; - hash_T perturb; - // Don't resize a locked table. if (ht->ht_locked > 0) { return OK; @@ -288,8 +268,9 @@ static int hash_may_resize(hashtab_T *ht, int minitems) } #endif // ifdef HT_DEBUG + size_t minsize; if (minitems == 0) { - // Return quickly for small tables with at least two NULL items. NULL + // Return quickly for small tables with at least two NULL items. // items are required for the lookup to decide a key isn't there. if ((ht->ht_filled < HT_INIT_SIZE - 1) && (ht->ht_array == ht->ht_smallarray)) { @@ -298,9 +279,9 @@ static int hash_may_resize(hashtab_T *ht, int minitems) // Grow or refill the array when it's more than 2/3 full (including // removed items, so that they get cleaned up). - // Shrink the array when it's less than 1/5 full. When growing it is + // Shrink the array when it's less than 1/5 full. When growing it is // at least 1/4 full (avoids repeated grow-shrink operations) - oldsize = ht->ht_mask + 1; + size_t oldsize = ht->ht_mask + 1; if ((ht->ht_filled * 3 < oldsize * 2) && (ht->ht_used > oldsize / 5)) { return OK; } @@ -314,16 +295,15 @@ static int hash_may_resize(hashtab_T *ht, int minitems) } } else { // Use specified size. - if ((long_u)minitems < ht->ht_used) { + if (minitems < ht->ht_used) { // just in case... - minitems = (int)ht->ht_used; + minitems = ht->ht_used; } // array is up to 2/3 full minsize = minitems * 3 / 2; } - newsize = HT_INIT_SIZE; - + size_t newsize = HT_INIT_SIZE; while (newsize < minsize) { // make sure it's always a power of 2 newsize <<= 1; @@ -333,51 +313,37 @@ static int hash_may_resize(hashtab_T *ht, int minitems) } } - if (newsize == HT_INIT_SIZE) { - // Use the small array inside the hashdict structure. - newarray = ht->ht_smallarray; - if (ht->ht_array == newarray) { - // Moving from ht_smallarray to ht_smallarray! Happens when there - // are many removed items. Copy the items to be able to clean up - // removed items. - memmove(temparray, newarray, sizeof(temparray)); - oldarray = temparray; - } else { - oldarray = ht->ht_array; - } - } else { - // Allocate an array. - newarray = (hashitem_T *)alloc((unsigned)(sizeof(hashitem_T) * newsize)); - - if (newarray == NULL) { - // Out of memory. When there are NULL items still return OK. - // Otherwise set ht_error, because lookup may result in a hang if - // we add another item. - if (ht->ht_filled < ht->ht_mask) { - return OK; - } - ht->ht_error = TRUE; - return FAIL; - } - oldarray = ht->ht_array; - } - memset(newarray, 0, (size_t)(sizeof(hashitem_T) * newsize)); + bool newarray_is_small = newsize == HT_INIT_SIZE; + bool keep_smallarray = newarray_is_small + && ht->ht_array == ht->ht_smallarray; + + // Make sure that oldarray and newarray do not overlap, + // so that copying is possible. + hashitem_T temparray[HT_INIT_SIZE]; + hashitem_T *oldarray = keep_smallarray + ? memcpy(temparray, ht->ht_smallarray, sizeof(temparray)) + : ht->ht_array; + hashitem_T *newarray = newarray_is_small + ? ht->ht_smallarray + : xmalloc(sizeof(hashitem_T) * newsize); + + memset(newarray, 0, sizeof(hashitem_T) * newsize); // Move all the items from the old array to the new one, placing them in - // the right spot. The new array won't have any removed items, thus this + // the right spot. The new array won't have any removed items, thus this // is also a cleanup action. - newmask = newsize - 1; - todo = (int)ht->ht_used; + hash_T newmask = newsize - 1; + size_t todo = ht->ht_used; - for (olditem = oldarray; todo > 0; ++olditem) { + for (hashitem_T *olditem = oldarray; todo > 0; ++olditem) { if (!HASHITEM_EMPTY(olditem)) { // The algorithm to find the spot to add the item is identical to - // the algorithm to find an item in hash_lookup(). But we only + // the algorithm to find an item in hash_lookup(). But we only // need to search for a NULL key, thus it's simpler. - newi = (unsigned)(olditem->hi_hash & newmask); - newitem = &newarray[newi]; + hash_T newi = olditem->hi_hash & newmask; + hashitem_T *newitem = &newarray[newi]; if (newitem->hi_key != NULL) { - for (perturb = olditem->hi_hash;; perturb >>= PERTURB_SHIFT) { + for (hash_T perturb = olditem->hi_hash;; perturb >>= PERTURB_SHIFT) { newi = 5 * newi + perturb + 1; newitem = &newarray[newi & newmask]; if (newitem->hi_key == NULL) { @@ -396,33 +362,29 @@ static int hash_may_resize(hashtab_T *ht, int minitems) ht->ht_array = newarray; ht->ht_mask = newmask; ht->ht_filled = ht->ht_used; - ht->ht_error = FALSE; + ht->ht_error = false; return OK; } /// Get the hash number for a key. +/// /// If you think you know a better hash function: Compile with HT_DEBUG set and -/// run a script that uses hashtables a lot. Vim will then print statistics -/// when exiting. Try that with the current hash algorithm and yours. The +/// run a script that uses hashtables a lot. Vim will then print statistics +/// when exiting. Try that with the current hash algorithm and yours. The /// lower the percentage the better. -/// -/// @param key -/// -/// @return Hash number for the key. hash_T hash_hash(char_u *key) { - hash_T hash; - char_u *p; + hash_T hash = *key; - if ((hash = *key) == 0) { + if (hash == 0) { // Empty keys are not allowed, but we don't want to crash if we get one. return (hash_T) 0; } - p = key + 1; // A simplistic algorithm that appears to do very well. // Suggested by George Reilly. + char_u *p = key + 1; while (*p != NUL) { hash = hash * 101 + *p++; } diff --git a/src/nvim/hashtab.h b/src/nvim/hashtab.h index 118795efe6..bd64984ac8 100644 --- a/src/nvim/hashtab.h +++ b/src/nvim/hashtab.h @@ -1,56 +1,83 @@ #ifndef NVIM_HASHTAB_H #define NVIM_HASHTAB_H -/* Item for a hashtable. "hi_key" can be one of three values: - * NULL: Never been used - * HI_KEY_REMOVED: Entry was removed - * Otherwise: Used item, pointer to the actual key; this usually is - * inside the item, subtract an offset to locate the item. - * This reduces the size of hashitem by 1/3. - */ -typedef struct hashitem_S { - long_u hi_hash; /* cached hash number of hi_key */ - char_u *hi_key; -} hashitem_T; +#include <stdbool.h> +#include "nvim/vim.h" -/* The address of "hash_removed" is used as a magic number for hi_key to - * indicate a removed item. */ +/// Type for hash number (hash calculation result). +typedef size_t hash_T; + +/// The address of "hash_removed" is used as a magic number +/// for hi_key to indicate a removed item. #define HI_KEY_REMOVED &hash_removed -#define HASHITEM_EMPTY(hi) ((hi)->hi_key == NULL || (hi)->hi_key == \ - &hash_removed) +#define HASHITEM_EMPTY(hi) ((hi)->hi_key == NULL \ + || (hi)->hi_key == &hash_removed) + +/// A hastable item. +/// +/// Each item has a NUL terminated string key. +/// A key can appear only once in the table. +/// +/// A hash number is computed from the key for quick lookup. When the hashes +/// of two different keys point to the same entry an algorithm is used to +/// iterate over other entries in the table until the right one is found. +/// To make the iteration work removed keys are different from entries where a +/// key was never present. +/// +/// Note that this does not contain a pointer to the key and another pointer to +/// the value. Instead, it is assumed that the key is contained within the +/// value, so that you can get a pointer to the value subtracting an offset from +/// the pointer to the key. +/// This reduces the size of this item by 1/3. +typedef struct hashitem_S { + /// Cached hash number for hi_key. + hash_T hi_hash; + + /// Item key. + /// + /// Possible values mean the following: + /// NULL : Item was never used. + /// HI_KEY_REMOVED : Item was removed. + /// (Any other pointer value) : Item is currently being used. + char_u *hi_key; +} hashitem_T; -/* Initial size for a hashtable. Our items are relatively small and growing - * is expensive, thus use 16 as a start. Must be a power of 2. */ +/// Initial size for a hashtable. +/// Our items are relatively small and growing is expensive, thus start with 16. +/// Must be a power of 2. #define HT_INIT_SIZE 16 +/// An array-based hashtable. +/// +/// Keys are NUL terminated strings. They cannot be repeated within a table. +/// Values are of any type. +/// +/// The hashtable grows to accommodate more entries when needed. typedef struct hashtable_S { - long_u ht_mask; /* mask used for hash value (nr of items in - * array is "ht_mask" + 1) */ - long_u ht_used; /* number of items used */ - long_u ht_filled; /* number of items used + removed */ - int ht_locked; /* counter for hash_lock() */ - int ht_error; /* when set growing failed, can't add more - items before growing works */ - hashitem_T *ht_array; /* points to the array, allocated when it's - not "ht_smallarray" */ - hashitem_T ht_smallarray[HT_INIT_SIZE]; /* initial array */ + hash_T ht_mask; /// mask used for hash value + /// (nr of items in array is "ht_mask" + 1) + size_t ht_used; /// number of items used + size_t ht_filled; /// number of items used or removed + int ht_locked; /// counter for hash_lock() + bool ht_error; /// when set growing failed, can't add more + /// items before growing works + hashitem_T *ht_array; /// points to the array, allocated when it's + /// not "ht_smallarray" + hashitem_T ht_smallarray[HT_INIT_SIZE]; /// initial array } hashtab_T; -typedef long_u hash_T; /* Type for hi_hash */ - -/* hashtab.c */ +// hashtab.c void hash_init(hashtab_T *ht); void hash_clear(hashtab_T *ht); -void hash_clear_all(hashtab_T *ht, int off); +void hash_clear_all(hashtab_T *ht, unsigned int off); hashitem_T *hash_find(hashtab_T *ht, char_u *key); hashitem_T *hash_lookup(hashtab_T *ht, char_u *key, hash_T hash); void hash_debug_results(void); int hash_add(hashtab_T *ht, char_u *key); -int hash_add_item(hashtab_T *ht, hashitem_T *hi, char_u *key, - hash_T hash); +int hash_add_item(hashtab_T *ht, hashitem_T *hi, char_u *key, hash_T hash); void hash_remove(hashtab_T *ht, hashitem_T *hi); void hash_lock(hashtab_T *ht); void hash_unlock(hashtab_T *ht); hash_T hash_hash(char_u *key); -#endif /* NVIM_HASHTAB_H */ +#endif // NVIM_HASHTAB_H diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index 8b52fb521f..7549e77223 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -459,7 +459,7 @@ static int cs_add(exarg_T *eap) static void cs_stat_emsg(char *fname) { char *stat_emsg = _("E563: stat(%s) error: %d"); - char *buf = (char *)alloc((unsigned)strlen(stat_emsg) + MAXPATHL + 10); + char *buf = xmalloc(strlen(stat_emsg) + MAXPATHL + 10); (void)sprintf(buf, stat_emsg, fname, errno); (void)EMSG(buf); @@ -490,7 +490,7 @@ cs_add_common ( char_u *fbuf = NULL; /* get the filename (arg1), expand it, and try to stat it */ - fname = (char *)alloc(MAXPATHL + 1); + fname = xmalloc(MAXPATHL + 1); expand_env((char_u *)arg1, (char_u *)fname, MAXPATHL); len = (int)STRLEN(fname); @@ -512,7 +512,7 @@ staterr: // get the prepend path (arg2), expand it, and see if it exists if (arg2 != NULL) { - ppath = (char *)alloc(MAXPATHL + 1); + ppath = xmalloc(MAXPATHL + 1); expand_env((char_u *)arg2, (char_u *)ppath, MAXPATHL); if (!os_file_exists((char_u *)ppath)) goto staterr; @@ -520,7 +520,7 @@ staterr: /* if filename is a directory, append the cscope database name to it */ if ((file_info.stat.st_mode & S_IFMT) == S_IFDIR) { - fname2 = (char *)alloc((unsigned)(strlen(CSCOPE_DBFILE) + strlen(fname) + 2)); + fname2 = (char *)xmalloc(strlen(CSCOPE_DBFILE) + strlen(fname) + 2); while (fname[strlen(fname)-1] == '/' ) { @@ -625,10 +625,9 @@ cs_reading_emsg ( static int cs_cnt_matches(int idx) { char *stok; - char *buf; int nlines; - buf = (char *)alloc(CSREAD_BUFSIZE); + char *buf = xmalloc(CSREAD_BUFSIZE); for (;; ) { if (!fgets(buf, CSREAD_BUFSIZE, csinfo[idx].fr_fp)) { if (feof(csinfo[idx].fr_fp)) @@ -721,7 +720,7 @@ static char *cs_create_cmd(char *csoption, char *pattern) while (vim_iswhite(*pat)) ++pat; - cmd = (char *)alloc((unsigned)(strlen(pat) + 2)); + cmd = xmalloc(strlen(pat) + 2); (void)sprintf(cmd, "%d%s", search, pat); @@ -801,14 +800,14 @@ err_closing: } #endif /* expand the cscope exec for env var's */ - prog = (char *)alloc(MAXPATHL + 1); + prog = xmalloc(MAXPATHL + 1); expand_env((char_u *)p_csprg, (char_u *)prog, MAXPATHL); /* alloc space to hold the cscope command */ len = (int)(strlen(prog) + strlen(csinfo[i].fname) + 32); if (csinfo[i].ppath) { /* expand the prepend path for env var's */ - ppath = (char *)alloc(MAXPATHL + 1); + ppath = xmalloc(MAXPATHL + 1); expand_env((char_u *)csinfo[i].ppath, (char_u *)ppath, MAXPATHL); len += (int)strlen(ppath); @@ -817,7 +816,7 @@ err_closing: if (csinfo[i].flags) len += (int)strlen(csinfo[i].flags); - cmd = (char *)alloc(len); + cmd = xmalloc(len); /* run the cscope command; is there execl for non-unix systems? */ #if defined(UNIX) @@ -1009,7 +1008,7 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, int us if (strchr(CSQF_FLAGS, *qfpos) == NULL) { char *nf = _("E469: invalid cscopequickfix flag %c for %c"); /* strlen will be enough because we use chars */ - char *buf = (char *)alloc((unsigned)strlen(nf)); + char *buf = xmalloc(strlen(nf)); sprintf(buf, nf, *qfpos, *(qfpos-1)); (void)EMSG(buf); @@ -1030,7 +1029,7 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, int us if (cmd == NULL) return FALSE; - nummatches = (int *)alloc(sizeof(int)*csinfo_size); + nummatches = xmalloc(sizeof(int) * csinfo_size); /* Send query to all open connections, then count the total number * of matches so we can alloc all in one swell foop. */ @@ -1064,7 +1063,7 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, int us return FALSE; } - buf = (char *)alloc((unsigned)(strlen(opt) + strlen(pat) + strlen(nf))); + buf = xmalloc(strlen(opt) + strlen(pat) + strlen(nf)); sprintf(buf, nf, opt, pat); (void)EMSG(buf); free(buf); @@ -1249,18 +1248,18 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags, clear_csinfo(j); } - csinfo[i].fname = (char *)alloc((unsigned)strlen(fname)+1); + csinfo[i].fname = xmalloc(strlen(fname) + 1); (void)strcpy(csinfo[i].fname, (const char *)fname); if (ppath != NULL) { - csinfo[i].ppath = (char *)alloc((unsigned)strlen(ppath) + 1); + csinfo[i].ppath = xmalloc(strlen(ppath) + 1); (void)strcpy(csinfo[i].ppath, (const char *)ppath); } else csinfo[i].ppath = NULL; if (flags != NULL) { - csinfo[i].flags = (char *)alloc((unsigned)strlen(flags) + 1); + csinfo[i].flags = xmalloc(strlen(flags) + 1); (void)strcpy(csinfo[i].flags, (const char *)flags); } else csinfo[i].flags = NULL; @@ -1553,13 +1552,12 @@ static char *cs_parse_results(int cnumber, char *buf, int bufsize, char **contex static void cs_file_results(FILE *f, int *nummatches_a) { int i, j; - char *buf; char *search, *slno; char *fullname; char *cntx; char *context; - buf = (char *)alloc(CSREAD_BUFSIZE); + char *buf = xmalloc(CSREAD_BUFSIZE); for (i = 0; i < csinfo_size; i++) { if (nummatches_a[i] < 1) @@ -1570,7 +1568,7 @@ static void cs_file_results(FILE *f, int *nummatches_a) &slno, &search)) == NULL) continue; - context = (char *)alloc((unsigned)strlen(cntx)+5); + context = xmalloc(strlen(cntx) + 5); if (strcmp(cntx, "<global>")==0) strcpy(context, "<<global>>"); @@ -1633,10 +1631,7 @@ static void cs_fill_results(char *tagstr, int totmatches, int *nummatches_a, cha if (strcmp(cntx, "<global>") == 0) cntxts[totsofar] = NULL; else { - /* note: if vim_strsave returns NULL, then the context - * will be "<global>", which is misleading. - */ - cntxts[totsofar] = (char *)vim_strsave((char_u *)cntx); + cntxts[totsofar] = xstrdup(cntx); } totsofar++; @@ -1689,9 +1684,6 @@ static char *cs_pathcomponents(char *path) */ static void cs_print_tags_priv(char **matches, char **cntxts, int num_matches) { - char *buf = NULL; - int bufsize = 0; /* Track available bufsize */ - int newsize = 0; char *ptag; char *fname, *lno, *extra, *tbuf; int i, idx, num; @@ -1703,14 +1695,14 @@ static void cs_print_tags_priv(char **matches, char **cntxts, int num_matches) assert (num_matches > 0); - tbuf = (char *)alloc((unsigned)strlen(matches[0]) + 1); + tbuf = xmalloc(strlen(matches[0]) + 1); strcpy(tbuf, matches[0]); ptag = strtok(tbuf, "\t"); - newsize = (int)(strlen(cstag_msg) + strlen(ptag)); - buf = (char *)alloc(newsize); - bufsize = newsize; + size_t newsize = strlen(cstag_msg) + strlen(ptag); + char *buf = xmalloc(newsize); + size_t bufsize = newsize; // Track available bufsize (void)sprintf(buf, cstag_msg, ptag); MSG_PUTS_ATTR(buf, hl_attr(HLF_T)); @@ -1728,7 +1720,7 @@ static void cs_print_tags_priv(char **matches, char **cntxts, int num_matches) * by parsing matches[i] on the fly and placing stuff into buf * directly, but that's too much of a hassle */ - tbuf = (char *)alloc((unsigned)strlen(matches[idx]) + 1); + tbuf = xmalloc(strlen(matches[idx]) + 1); (void)strcpy(tbuf, matches[idx]); if (strtok(tbuf, (const char *)"\t") == NULL) @@ -1742,9 +1734,9 @@ static void cs_print_tags_priv(char **matches, char **cntxts, int num_matches) lno[strlen(lno)-2] = '\0'; /* ignore ;" at the end */ /* hopefully 'num' (num of matches) will be less than 10^16 */ - newsize = (int)(strlen(csfmt_str) + 16 + strlen(lno)); + newsize = strlen(csfmt_str) + 16 + strlen(lno); if (bufsize < newsize) { - buf = (char *)xrealloc(buf, newsize); + buf = xrealloc(buf, newsize); bufsize = newsize; } if (buf != NULL) { @@ -1759,10 +1751,10 @@ static void cs_print_tags_priv(char **matches, char **cntxts, int num_matches) context = cntxts[idx]; else context = globalcntx; - newsize = (int)(strlen(context) + strlen(cntxformat)); + newsize = strlen(context) + strlen(cntxformat); if (bufsize < newsize) { - buf = (char *)xrealloc(buf, newsize); + buf = xrealloc(buf, newsize); bufsize = newsize; } if (buf != NULL) { @@ -1822,9 +1814,11 @@ static int cs_read_prompt(int i) while ((ch = getc(csinfo[i].fr_fp)) != EOF && ch != CSCOPE_PROMPT[0]) /* if there is room and char is printable */ if (bufpos < maxlen - 1 && vim_isprintc(ch)) { - if (buf == NULL) /* lazy buffer allocation */ - buf = (char *)alloc(maxlen); - if (buf != NULL) { + // lazy buffer allocation + if (buf == NULL) { + buf = xmalloc(maxlen); + } + { /* append character to the message */ buf[bufpos++] = ch; buf[bufpos] = NUL; @@ -2075,7 +2069,6 @@ static int cs_reset(exarg_T *eap) static char *cs_resolve_file(int i, char *name) { char *fullname; - int len; char_u *csdir = NULL; /* @@ -2083,17 +2076,17 @@ static char *cs_resolve_file(int i, char *name) * Fullname is freed after cs_make_vim_style_matches, after it's been * copied into the tag buffer used by Vim. */ - len = (int)(strlen(name) + 2); + size_t len = strlen(name) + 2; if (csinfo[i].ppath != NULL) - len += (int)strlen(csinfo[i].ppath); + len += strlen(csinfo[i].ppath); else if (p_csre && csinfo[i].fname != NULL) { /* If 'cscoperelative' is set and ppath is not set, use cscope.out * path in path resolution. */ - csdir = alloc(MAXPATHL); + csdir = xmalloc(MAXPATHL); vim_strncpy(csdir, (char_u *)csinfo[i].fname, path_tail((char_u *)csinfo[i].fname) - (char_u *)csinfo[i].fname); - len += (int)STRLEN(csdir); + len += STRLEN(csdir); } /* Note/example: this won't work if the cscope output already starts @@ -2110,7 +2103,7 @@ static char *cs_resolve_file(int i, char *name) * cscope output. */ fullname = (char *)concat_fnames(csdir, (char_u *)name, TRUE); } else { - fullname = (char *)vim_strsave((char_u *)name); + fullname = xstrdup(name); } free(csdir); diff --git a/src/nvim/indent.c b/src/nvim/indent.c index aa02efe5b2..06273e98c2 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -182,7 +182,7 @@ int set_indent(int size, int flags) // characters and allocate accordingly. We will fill the rest with spaces // after the if (!curbuf->b_p_et) below. if (orig_char_len != -1) { - newline = alloc(orig_char_len + size - ind_done + line_len); + newline = xmalloc(orig_char_len + size - ind_done + line_len); todo = size - ind_done; // Set total length of indent in characters, which may have been @@ -203,7 +203,7 @@ int set_indent(int size, int flags) } } else { todo = size; - newline = alloc(ind_len + line_len); + newline = xmalloc(ind_len + line_len); s = newline; } @@ -368,7 +368,7 @@ int copy_indent(int size, char_u *src) // Allocate memory for the result: the copied indent, new indent // and the rest of the line. line_len = (int)STRLEN(ml_get_curline()) + 1; - line = alloc(ind_len + line_len); + line = xmalloc(ind_len + line_len); p = line; } } diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c index 6f9a72ea47..8979635823 100644 --- a/src/nvim/indent_c.c +++ b/src/nvim/indent_c.c @@ -122,7 +122,7 @@ int cin_is_cinword(char_u *line) int len; cinw_len = (int)STRLEN(curbuf->b_p_cinw) + 1; - cinw_buf = alloc((unsigned)cinw_len); + cinw_buf = xmalloc(cinw_len); line = skipwhite(line); for (cinw = curbuf->b_p_cinw; *cinw; ) { len = copy_option_part(&cinw, cinw_buf, cinw_len, ","); diff --git a/src/nvim/lib/khash.h b/src/nvim/lib/khash.h index ce2862a1f1..51a666733b 100644 --- a/src/nvim/lib/khash.h +++ b/src/nvim/lib/khash.h @@ -197,7 +197,7 @@ static const double __ac_HASH_UPPER = 0.77; extern void kh_destroy_##name(kh_##name##_t *h); \ extern void kh_clear_##name(kh_##name##_t *h); \ extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \ - extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \ + extern void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \ extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \ extern void kh_del_##name(kh_##name##_t *h, khint_t x); @@ -240,9 +240,9 @@ static const double __ac_HASH_UPPER = 0.77; return __ac_iseither(h->flags, i)? h->n_buckets : i; \ } else return 0; \ } \ - SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ + SCOPE void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ FUNC_ATTR_UNUSED; \ - SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ + SCOPE void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ { /* This function uses 0.25*n_buckets bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \ khint32_t *new_flags = 0; \ khint_t j = 1; \ @@ -252,15 +252,12 @@ static const double __ac_HASH_UPPER = 0.77; if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; /* requested size is too small */ \ else { /* hash table size to be changed (shrink or expand); rehash */ \ new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ - if (!new_flags) return -1; \ memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ if (h->n_buckets < new_n_buckets) { /* expand */ \ khkey_t *new_keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ - if (!new_keys) return -1; \ h->keys = new_keys; \ if (kh_is_map) { \ khval_t *new_vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ - if (!new_vals) return -1; \ h->vals = new_vals; \ } \ } /* otherwise shrink */ \ @@ -303,7 +300,6 @@ static const double __ac_HASH_UPPER = 0.77; h->n_occupied = h->size; \ h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \ } \ - return 0; \ } \ SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \ FUNC_ATTR_UNUSED; \ @@ -312,11 +308,9 @@ static const double __ac_HASH_UPPER = 0.77; khint_t x; \ if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \ if (h->n_buckets > (h->size<<1)) { \ - if (kh_resize_##name(h, h->n_buckets - 1) < 0) { /* clear "deleted" elements */ \ - *ret = -1; return h->n_buckets; \ - } \ - } else if (kh_resize_##name(h, h->n_buckets + 1) < 0) { /* expand the hash table */ \ - *ret = -1; return h->n_buckets; \ + kh_resize_##name(h, h->n_buckets - 1); /* clear "deleted" elements */ \ + } else { \ + kh_resize_##name(h, h->n_buckets + 1); /* expand the hash table */ \ } \ } /* TODO: to implement automatically shrinking; resize() already support shrinking */ \ { \ diff --git a/src/nvim/main.c b/src/nvim/main.c index 8d7fbe0a02..91e879cbe0 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1308,7 +1308,7 @@ static void command_line_scan(mparm_T *parmp) --argv; } else a = argv[0]; - p = alloc((unsigned)(STRLEN(a) + 4)); + p = xmalloc(STRLEN(a) + 4); sprintf((char *)p, "so %s", a); parmp->cmds_tofree[parmp->n_commands] = TRUE; parmp->commands[parmp->n_commands++] = p; @@ -1352,8 +1352,7 @@ scripterror: mch_errmsg("\"\n"); mch_exit(2); } - if (save_typebuf() == FAIL) - mch_exit(2); /* out of memory */ + save_typebuf(); break; case 't': /* "-t {tag}" */ @@ -1415,8 +1414,8 @@ scripterror: /* Add the file to the global argument list. */ ga_grow(&global_alist.al_ga, 1); - if ((p = vim_strsave((char_u *)argv[0])) == NULL) - mch_exit(2); + p = vim_strsave((char_u *)argv[0]); + if (parmp->diff_mode && os_isdir(p) && GARGCOUNT > 0 && !os_isdir(alist_name(&GARGLIST[0]))) { char_u *r; @@ -1456,7 +1455,7 @@ scripterror: /* If there is a "+123" or "-c" command, set v:swapcommand to the first * one. */ if (parmp->n_commands > 0) { - p = alloc((unsigned)STRLEN(parmp->commands[0]) + 3); + p = xmalloc(STRLEN(parmp->commands[0]) + 3); sprintf((char *)p, ":%s\r", parmp->commands[0]); set_vim_var_string(VV_SWAPCOMMAND, p, -1); free(p); @@ -1502,7 +1501,7 @@ static void init_startuptime(mparm_T *paramp) */ static void allocate_generic_buffers(void) { - NameBuff = alloc(MAXPATHL); + NameBuff = xmalloc(MAXPATHL); TIME_MSG("Allocated generic buffers"); } diff --git a/src/nvim/map.c b/src/nvim/map.c index 28fd0af61c..559a5f261a 100644 --- a/src/nvim/map.c +++ b/src/nvim/map.c @@ -85,3 +85,4 @@ MAP_IMPL(cstr_t) MAP_IMPL(ptr_t) +MAP_IMPL(uint64_t) diff --git a/src/nvim/map.h b/src/nvim/map.h index ae47561deb..dba56dc5aa 100644 --- a/src/nvim/map.h +++ b/src/nvim/map.h @@ -21,6 +21,7 @@ MAP_DECLS(cstr_t) MAP_DECLS(ptr_t) +MAP_DECLS(uint64_t) #define map_new(T) map_##T##_new #define map_free(T) map_##T##_free diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 16d360d093..23e7355e9c 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -606,8 +606,7 @@ static char_u *mark_line(pos_T *mp, int lead_len) if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count) return vim_strsave((char_u *)"-invalid-"); s = vim_strnsave(skipwhite(ml_get(mp->lnum)), (int)Columns); - if (s == NULL) - return NULL; + /* Truncate the line to fit it in the window */ len = 0; for (p = s; *p != NUL; mb_ptr_adv(p)) { @@ -844,8 +843,6 @@ void ex_changes(exarg_T *eap) curbuf->b_changelist[i].col); msg_outtrans(IObuff); name = mark_line(&curbuf->b_changelist[i], 17); - if (name == NULL) - break; msg_outtrans_attr(name, hl_attr(HLF_D)); free(name); ui_breakcheck(); @@ -1418,7 +1415,7 @@ void copy_viminfo_marks(vir_T *virp, FILE *fp_out, int count, int eof, int flags pos_T pos; list_T *list = NULL; - name_buf = alloc(LSIZE); + name_buf = xmalloc(LSIZE); *name_buf = NUL; if (fp_out == NULL && (flags & (VIF_GET_OLDFILES | VIF_FORCEIT))) { diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 97509040df..10e94d7ced 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -3333,7 +3333,7 @@ char_u * enc_canonize(char_u *enc) } /* copy "enc" to allocated memory, with room for two '-' */ - r = alloc((unsigned)(STRLEN(enc) + 3)); + r = xmalloc(STRLEN(enc) + 3); /* Make it all lower case and replace '_' with '-'. */ p = r; for (s = enc; *s != NUL; ++s) { @@ -3534,7 +3534,7 @@ static char_u * iconv_string(vimconv_T *vcp, char_u *str, int slen, int *unconvl /* Allocate enough room for most conversions. When re-allocating * increase the buffer size. */ len = len + fromlen * 2 + 40; - p = alloc((unsigned)len); + p = xmalloc(len); if (done > 0) memmove(p, result, done); free(result); @@ -3852,7 +3852,7 @@ int convert_input_safe(ptr, len, maxlen, restp, restlenp) if (dlen <= maxlen) { if (unconvertlen > 0) { /* Move the unconverted characters to allocated memory. */ - *restp = alloc(unconvertlen); + *restp = xmalloc(unconvertlen); memmove(*restp, ptr + len - unconvertlen, unconvertlen); *restlenp = unconvertlen; } @@ -3908,7 +3908,7 @@ char_u * string_convert_ext(vcp, ptr, lenp, unconvlenp) switch (vcp->vc_type) { case CONV_TO_UTF8: /* latin1 to utf-8 conversion */ - retval = alloc(len * 2 + 1); + retval = xmalloc(len * 2 + 1); d = retval; for (i = 0; i < len; ++i) { c = ptr[i]; @@ -3925,7 +3925,7 @@ char_u * string_convert_ext(vcp, ptr, lenp, unconvlenp) break; case CONV_9_TO_UTF8: /* latin9 to utf-8 conversion */ - retval = alloc(len * 3 + 1); + retval = xmalloc(len * 3 + 1); d = retval; for (i = 0; i < len; ++i) { c = ptr[i]; @@ -3948,7 +3948,7 @@ char_u * string_convert_ext(vcp, ptr, lenp, unconvlenp) case CONV_TO_LATIN1: /* utf-8 to latin1 conversion */ case CONV_TO_LATIN9: /* utf-8 to latin9 conversion */ - retval = alloc(len + 1); + retval = xmalloc(len + 1); d = retval; for (i = 0; i < len; ++i) { l = utf_ptr2len_len(ptr + i, len - i); diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c index bf40d27502..f6bd8d7983 100644 --- a/src/nvim/memfile.c +++ b/src/nvim/memfile.c @@ -104,11 +104,9 @@ static void mf_hash_grow(mf_hashtab_T *); */ memfile_T *mf_open(char_u *fname, int flags) { - memfile_T *mfp; off_t size; - if ((mfp = (memfile_T *)alloc((unsigned)sizeof(memfile_T))) == NULL) - return NULL; + memfile_T *mfp = xmalloc(sizeof(memfile_T)); if (fname == NULL) { /* no file for this memfile, use memory only */ mfp->mf_fname = NULL; @@ -316,14 +314,14 @@ bhdr_T *mf_new(memfile_T *mfp, int negative, int page_count) * just use the number and free the bhdr_T from the free list */ if (freep->bh_page_count > page_count) { - if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL) - return NULL; + if (hp == NULL) { + hp = mf_alloc_bhdr(mfp, page_count); + } hp->bh_bnum = freep->bh_bnum; freep->bh_bnum += page_count; freep->bh_page_count -= page_count; } else if (hp == NULL) { /* need to allocate memory for this block */ - if ((p = (char_u *)alloc(mfp->mf_page_size * page_count)) == NULL) - return NULL; + p = xmalloc(mfp->mf_page_size * page_count); hp = mf_rem_free(mfp); hp->bh_data = p; } else { /* use the number, remove entry from free list */ @@ -332,8 +330,9 @@ bhdr_T *mf_new(memfile_T *mfp, int negative, int page_count) free(freep); } } else { /* get a new number */ - if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL) - return NULL; + if (hp == NULL) { + hp = mf_alloc_bhdr(mfp, page_count); + } if (negative) { hp->bh_bnum = mfp->mf_blocknr_min--; mfp->mf_neg_count++; @@ -386,8 +385,9 @@ bhdr_T *mf_get(memfile_T *mfp, blocknr_T nr, int page_count) * If not, allocate a new block. */ hp = mf_release(mfp, page_count); - if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL) - return NULL; + if (hp == NULL) { + hp = mf_alloc_bhdr(mfp, page_count); + } hp->bh_bnum = nr; hp->bh_flags = 0; @@ -689,10 +689,7 @@ static bhdr_T *mf_release(memfile_T *mfp, int page_count) */ if (hp->bh_page_count != page_count) { free(hp->bh_data); - if ((hp->bh_data = alloc(mfp->mf_page_size * page_count)) == NULL) { - free(hp); - return NULL; - } + hp->bh_data = xmalloc(mfp->mf_page_size * page_count); hp->bh_page_count = page_count; } return hp; @@ -743,16 +740,10 @@ int mf_release_all(void) */ static bhdr_T *mf_alloc_bhdr(memfile_T *mfp, int page_count) { - bhdr_T *hp; + bhdr_T *hp = xmalloc(sizeof(bhdr_T)); + hp->bh_data = xmalloc(mfp->mf_page_size * page_count); + hp->bh_page_count = page_count; - if ((hp = (bhdr_T *)alloc((unsigned)sizeof(bhdr_T))) != NULL) { - if ((hp->bh_data = (char_u *)alloc(mfp->mf_page_size * page_count)) - == NULL) { - free(hp); /* not enough memory */ - return NULL; - } - hp->bh_page_count = page_count; - } return hp; } @@ -911,14 +902,12 @@ static int mf_trans_add(memfile_T *mfp, bhdr_T *hp) { bhdr_T *freep; blocknr_T new_bnum; - NR_TRANS *np; int page_count; if (hp->bh_bnum >= 0) /* it's already positive */ return OK; - if ((np = (NR_TRANS *)alloc((unsigned)sizeof(NR_TRANS))) == NULL) - return FAIL; + NR_TRANS *np = xmalloc(sizeof(NR_TRANS)); /* * Get a new number for the block. diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 8d0bd9a6d0..dc6823c8fa 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -313,8 +313,7 @@ int ml_open(buf_T *buf) /* * fill block0 struct and write page 0 */ - if ((hp = mf_new(mfp, FALSE, 1)) == NULL) - goto error; + hp = mf_new(mfp, FALSE, 1); if (hp->bh_bnum != 0) { EMSG(_("E298: Didn't get block nr 0?")); goto error; @@ -373,8 +372,7 @@ int ml_open(buf_T *buf) /* * Allocate first data block and create an empty line 1. */ - if ((hp = ml_new_data(mfp, FALSE, 1)) == NULL) - goto error; + hp = ml_new_data(mfp, FALSE, 1); if (hp->bh_bnum != 2) { EMSG(_("E298: Didn't get block nr 2?")); goto error; @@ -857,7 +855,7 @@ void ml_recover(void) * Allocate a buffer structure for the swap file that is used for recovery. * Only the memline in it is really used. */ - buf = (buf_T *)alloc((unsigned)sizeof(buf_T)); + buf = xmalloc(sizeof(buf_T)); /* * init fields in memline struct @@ -956,7 +954,7 @@ void ml_recover(void) mfp->mf_infile_count = mfp->mf_blocknr_max; /* need to reallocate the memory used to store the data */ - p = alloc(mfp->mf_page_size); + p = xmalloc(mfp->mf_page_size); memmove(p, hp->bh_data, previous_page_size); free(hp->bh_data); hp->bh_data = p; @@ -1334,7 +1332,7 @@ recover_names ( * Do the loop for every directory in 'directory'. * First allocate some memory to put the directory name in. */ - dir_name = alloc((unsigned)STRLEN(p_dir) + 1); + dir_name = xmalloc(STRLEN(p_dir) + 1); dirp = p_dir; while (dir_name != NULL && *dirp) { /* @@ -1408,7 +1406,7 @@ recover_names ( char_u *swapname = modname(fname_res, (char_u *)".swp", TRUE); if (swapname != NULL) { if (os_file_exists(swapname)) { - files = (char_u **)alloc((unsigned)sizeof(char_u *)); + files = (char_u **)xmalloc(sizeof(char_u *)); files[0] = swapname; swapname = NULL; num_files = 1; @@ -2118,12 +2116,7 @@ ml_append_int ( } page_count = ((space_needed + HEADER_SIZE) + page_size - 1) / page_size; - if ((hp_new = ml_new_data(mfp, newfile, page_count)) == NULL) { - /* correct line counts in pointer blocks */ - --(buf->b_ml.ml_locked_lineadd); - --(buf->b_ml.ml_locked_high); - return FAIL; - } + hp_new = ml_new_data(mfp, newfile, page_count); if (db_idx < 0) { /* left block is new */ hp_left = hp_new; hp_right = hp; @@ -2403,8 +2396,9 @@ int ml_replace(linenr_T lnum, char_u *line, int copy) if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL) return FAIL; - if (copy && (line = vim_strsave(line)) == NULL) /* allocate memory */ - return FAIL; + if (copy) { + line = vim_strsave(line); + } if (curbuf->b_ml.ml_line_lnum != lnum) /* other line buffered */ ml_flush_line(curbuf); /* flush it */ else if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) /* same line allocated */ @@ -2777,13 +2771,8 @@ static void ml_flush_line(buf_T *buf) */ static bhdr_T *ml_new_data(memfile_T *mfp, int negative, int page_count) { - bhdr_T *hp; - DATA_BL *dp; - - if ((hp = mf_new(mfp, negative, page_count)) == NULL) - return NULL; - - dp = (DATA_BL *)(hp->bh_data); + bhdr_T *hp = mf_new(mfp, negative, page_count); + DATA_BL *dp = (DATA_BL *)(hp->bh_data); dp->db_id = DATA_ID; dp->db_txt_start = dp->db_txt_end = page_count * mfp->mf_page_size; dp->db_free = dp->db_txt_start - HEADER_SIZE; @@ -2797,13 +2786,8 @@ static bhdr_T *ml_new_data(memfile_T *mfp, int negative, int page_count) */ static bhdr_T *ml_new_ptr(memfile_T *mfp) { - bhdr_T *hp; - PTR_BL *pp; - - if ((hp = mf_new(mfp, FALSE, 1)) == NULL) - return NULL; - - pp = (PTR_BL *)(hp->bh_data); + bhdr_T *hp = mf_new(mfp, FALSE, 1); + PTR_BL *pp = (PTR_BL *)(hp->bh_data); pp->pb_id = PTR_ID; pp->pb_count = 0; pp->pb_count_max = (mfp->mf_page_size - sizeof(PTR_BL)) / sizeof(PTR_EN) + 1; @@ -3335,7 +3319,7 @@ findswapname ( * Isolate a directory name from *dirp and put it in dir_name. * First allocate some memory to put the directory name in. */ - dir_name = alloc((unsigned)STRLEN(*dirp) + 1); + dir_name = xmalloc(STRLEN(*dirp) + 1); (void)copy_option_part(dirp, dir_name, 31000, ","); /* @@ -3462,9 +3446,9 @@ findswapname ( if (swap_exists_action != SEA_NONE && choice == 0) { char_u *name; - name = alloc((unsigned)(STRLEN(fname) - + STRLEN(_("Swap file \"")) - + STRLEN(_("\" already exists!")) + 5)); + name = xmalloc(STRLEN(fname) + + STRLEN(_("Swap file \"")) + + STRLEN(_("\" already exists!")) + 5); STRCPY(name, _("Swap file \"")); home_replace(NULL, fname, name + STRLEN(name), 1000, TRUE); diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 215eac2a33..238a6791c0 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -43,14 +43,6 @@ static void try_to_free_memory(); -/* - * Note: if unsigned is 16 bits we can only allocate up to 64K with alloc(). - */ -char_u *alloc(unsigned size) -{ - return xmalloc(size); -} - /// Try to free memory. Used when trying to recover from out of memory errors. /// @see {xmalloc} static void try_to_free_memory() @@ -92,7 +84,7 @@ void *verbose_try_malloc(size_t size) { void *ret = try_malloc(size); if (!ret) { - do_outofmem_msg((long_u)size); + do_outofmem_msg(size); } return ret; } @@ -191,7 +183,20 @@ char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen) } } -char * xstrdup(const char *str) +size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t size) +{ + size_t ret = strlen(src); + + if (size) { + size_t len = (ret >= size) ? size - 1 : ret; + memcpy(dst, src, len); + dst[len] = '\0'; + } + + return ret; +} + +char *xstrdup(const char *str) { char *ret = strdup(str); @@ -222,7 +227,7 @@ void *xmemdup(const void *data, size_t len) * Avoid repeating the error message many times (they take 1 second each). * Did_outofmem_msg is reset when a character is read. */ -void do_outofmem_msg(long_u size) +void do_outofmem_msg(size_t size) { if (!did_outofmem_msg) { /* Don't hide this message */ diff --git a/src/nvim/memory.h b/src/nvim/memory.h index c37ec56adc..accf293176 100644 --- a/src/nvim/memory.h +++ b/src/nvim/memory.h @@ -5,8 +5,6 @@ #include "nvim/types.h" #include "nvim/vim.h" -char_u *alloc(unsigned size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); - /// malloc() wrapper /// /// try_malloc() is a malloc() wrapper that tries to free some memory before @@ -127,6 +125,19 @@ char *xstpcpy(char *restrict dst, const char *restrict src); /// @param maxlen char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen); +/// xstrlcpy - Copy a %NUL terminated string into a sized buffer +/// +/// Compatible with *BSD strlcpy: the result is always a valid +/// NUL-terminated string that fits in the buffer (unless, +/// of course, the buffer size is zero). It does not pad +/// out the result like strncpy() does. +/// +/// @param dst Where to copy the string to +/// @param src Where to copy the string from +/// @param size Size of destination buffer +/// @return Length of the source string (i.e.: strlen(src)) +size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t size); + /// Duplicates a chunk of memory using xmalloc /// /// @see {xmalloc} @@ -136,7 +147,7 @@ char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen); void *xmemdup(const void *data, size_t len) FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET; -void do_outofmem_msg(long_u size); +void do_outofmem_msg(size_t size); void free_all_mem(void); #endif diff --git a/src/nvim/menu.c b/src/nvim/menu.c index 7fa813c5b3..d9b84eae71 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -308,8 +308,6 @@ add_menu_path ( /* Make a copy so we can stuff around with it, since it could be const */ path_name = vim_strsave(menu_path); - if (path_name == NULL) - return FAIL; menup = &root_menu; parent = NULL; name = path_name; @@ -464,7 +462,7 @@ add_menu_path ( } if (c != 0) { - menu->strings[i] = alloc((unsigned)(STRLEN(call_data) + 5 )); + menu->strings[i] = xmalloc(STRLEN(call_data) + 5 ); menu->strings[i][0] = c; if (d == 0) STRCPY(menu->strings[i] + 1, call_data); @@ -728,8 +726,6 @@ static int show_menus(char_u *path_name, int modes) menu = root_menu; name = path_name = vim_strsave(path_name); - if (path_name == NULL) - return FAIL; /* First, find the (sub)menu with the given name */ while (*name) { @@ -1168,7 +1164,7 @@ get_menu_cmd_modes ( /* * Modify a menu name starting with "PopUp" to include the mode character. - * Returns the name in allocated memory (NULL for failure). + * Returns the name in allocated memory. */ static char_u *popup_mode_name(char_u *name, int idx) { @@ -1176,10 +1172,9 @@ static char_u *popup_mode_name(char_u *name, int idx) int len = (int)STRLEN(name); p = vim_strnsave(name, len + 1); - if (p != NULL) { - memmove(p + 6, p + 5, (size_t)(len - 4)); - p[5] = menu_mode_chars[idx]; - } + memmove(p + 6, p + 5, (size_t)(len - 4)); + p[5] = menu_mode_chars[idx]; + return p; } @@ -1305,8 +1300,6 @@ void ex_emenu(exarg_T *eap) char_u *mode; saved_name = vim_strsave(eap->arg); - if (saved_name == NULL) - return; menu = root_menu; name = saved_name; @@ -1419,8 +1412,6 @@ vimmenu_T *gui_find_menu(char_u *path_name) menu = root_menu; saved_name = vim_strsave(path_name); - if (saved_name == NULL) - return NULL; name = saved_name; while (*name) { @@ -1513,23 +1504,21 @@ void ex_menutranslate(exarg_T *eap) ga_grow(&menutrans_ga, 1); tp = (menutrans_T *)menutrans_ga.ga_data; from = vim_strsave(from); - if (from != NULL) { - from_noamp = menu_text(from, NULL, NULL); - to = vim_strnsave(to, (int)(arg - to)); - if (from_noamp != NULL && to != NULL) { - menu_translate_tab_and_shift(from); - menu_translate_tab_and_shift(to); - menu_unescape_name(from); - menu_unescape_name(to); - tp[menutrans_ga.ga_len].from = from; - tp[menutrans_ga.ga_len].from_noamp = from_noamp; - tp[menutrans_ga.ga_len].to = to; - ++menutrans_ga.ga_len; - } else { - free(from); - free(from_noamp); - free(to); - } + from_noamp = menu_text(from, NULL, NULL); + to = vim_strnsave(to, (int)(arg - to)); + if (from_noamp != NULL) { + menu_translate_tab_and_shift(from); + menu_translate_tab_and_shift(to); + menu_unescape_name(from); + menu_unescape_name(to); + tp[menutrans_ga.ga_len].from = from; + tp[menutrans_ga.ga_len].from_noamp = from_noamp; + tp[menutrans_ga.ga_len].to = to; + ++menutrans_ga.ga_len; + } else { + free(from); + free(from_noamp); + free(to); } } } diff --git a/src/nvim/message.c b/src/nvim/message.c index 5f2d1226de..9bdcbf6c78 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -267,7 +267,7 @@ msg_strtrunc ( len = (room + 2) * 2; else len = room + 2; - buf = alloc(len); + buf = xmalloc(len); trunc_string(s, buf, room, len); } } @@ -421,7 +421,7 @@ static char_u *get_emsg_source(void) if (sourcing_name != NULL && other_sourcing_name()) { p = (char_u *)_("Error detected while processing %s:"); - Buf = alloc((unsigned)(STRLEN(sourcing_name) + STRLEN(p))); + Buf = xmalloc(STRLEN(sourcing_name) + STRLEN(p)); sprintf((char *)Buf, (char *)p, sourcing_name); return Buf; } @@ -443,7 +443,7 @@ static char_u *get_emsg_lnum(void) && (other_sourcing_name() || sourcing_lnum != last_sourcing_lnum) && sourcing_lnum != 0) { p = (char_u *)_("line %4ld:"); - Buf = alloc((unsigned)(STRLEN(p) + 20)); + Buf = xmalloc(STRLEN(p) + 20); sprintf((char *)Buf, (char *)p, (long)sourcing_lnum); return Buf; } @@ -680,8 +680,6 @@ add_msg_hist ( int attr ) { - struct msg_hist *p; - if (msg_hist_off || msg_silent != 0) return; @@ -690,7 +688,7 @@ add_msg_hist ( (void)delete_first_msg(); /* allocate an entry and add the message at the end of the history */ - p = (struct msg_hist *)alloc((int)sizeof(struct msg_hist)); + struct msg_hist *p = xmalloc(sizeof(struct msg_hist)); if (len < 0) len = (int)STRLEN(s); /* remove leading and trailing newlines */ @@ -1841,7 +1839,7 @@ static void inc_msg_scrolled(void) p = (char_u *)_("Unknown"); else { len = (int)STRLEN(p) + 40; - tofree = alloc(len); + tofree = xmalloc(len); vim_snprintf((char *)tofree, len, _("%s line %" PRId64), p, (int64_t)sourcing_lnum); p = tofree; @@ -1893,7 +1891,7 @@ store_sb_text ( } if (s > *sb_str) { - mp = (msgchunk_T *)alloc((int)(sizeof(msgchunk_T) + (s - *sb_str))); + mp = xmalloc((sizeof(msgchunk_T) + (s - *sb_str))); mp->sb_eol = finish; mp->sb_msg_col = *sb_col; mp->sb_attr = attr; diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index e0d62f9b24..d83c03c9fd 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -120,8 +120,6 @@ open_line ( * make a copy of the current line so we can mess with it */ saved_line = vim_strsave(ml_get_curline()); - if (saved_line == NULL) /* out of memory! */ - return FALSE; if (State & VREPLACE_FLAG) { /* @@ -137,8 +135,6 @@ open_line ( next_line = vim_strsave(ml_get(curwin->w_cursor.lnum + 1)); else next_line = vim_strsave((char_u *)""); - if (next_line == NULL) /* out of memory! */ - goto theend; /* * In VREPLACE mode, a NL replaces the rest of the line, and starts @@ -505,7 +501,7 @@ open_line ( } if (lead_len) { /* allocate buffer (may concatenate p_extra later) */ - leader = alloc(lead_len + lead_repl_len + extra_space + extra_len + leader = xmalloc(lead_len + lead_repl_len + extra_space + extra_len + (second_line_indent > 0 ? second_line_indent : 0) + 1); allocated = leader; /* remember to free it later */ @@ -918,8 +914,6 @@ open_line ( if (State & VREPLACE_FLAG) { /* Put new line in p_extra */ p_extra = vim_strsave(ml_get_curline()); - if (p_extra == NULL) - goto theend; /* Put back original line */ ml_replace(curwin->w_cursor.lnum, next_line, FALSE); @@ -1708,9 +1702,7 @@ del_bytes ( if (was_alloced) newp = oldp; /* use same allocated memory */ else { /* need to allocate a new line */ - newp = alloc((unsigned)(oldlen + 1 - count)); - if (newp == NULL) - return FAIL; + newp = xmalloc(oldlen + 1 - count); memmove(newp, oldp, (size_t)col); } memmove(newp + col, oldp + col + count, (size_t)movelen); @@ -1726,10 +1718,8 @@ del_bytes ( /* * Delete from cursor to end of line. * Caller must have prepared for undo. - * - * return FAIL for failure, OK otherwise */ -int +void truncate_line ( int fixpos /* if TRUE fix the cursor position when done */ ) @@ -1743,9 +1733,6 @@ truncate_line ( else newp = vim_strnsave(ml_get(lnum), col); - if (newp == NULL) - return FAIL; - ml_replace(lnum, newp, FALSE); /* mark the buffer as changed and prepare for displaying */ @@ -1756,8 +1743,6 @@ truncate_line ( */ if (fixpos && curwin->w_cursor.col > 0) --curwin->w_cursor.col; - - return OK; } /* @@ -2409,7 +2394,7 @@ int get_keystroke(void) * bytes. */ maxlen = (buflen - 6 - len) / 3; if (buf == NULL) - buf = alloc(buflen); + buf = xmalloc(buflen); else if (maxlen < 10) { /* Need some more space. This might happen when receiving a long * escape sequence. */ @@ -2729,9 +2714,7 @@ char_u *expand_env_save(char_u *src) */ char_u *expand_env_save_opt(char_u *src, int one) { - char_u *p; - - p = alloc(MAXPATHL); + char_u *p = xmalloc(MAXPATHL); expand_env_esc(src, p, MAXPATHL, FALSE, one, NULL); return p; } @@ -2879,13 +2862,12 @@ expand_env_esc ( if (p_ssl && var != NULL && vim_strchr(var, '\\') != NULL) { char_u *p = vim_strsave(var); - if (p != NULL) { - if (mustfree) - free(var); - var = p; - mustfree = TRUE; - forward_slash(var); + if (mustfree) { + free(var); } + var = p; + mustfree = TRUE; + forward_slash(var); } #endif @@ -3038,7 +3020,7 @@ char_u *vim_getenv(char_u *name, int *mustfree) /* check that the result is a directory name */ p = vim_strnsave(p, (int)(pend - p)); - if (p != NULL && !os_isdir(p)) { + if (!os_isdir(p)) { free(p); p = NULL; } else { @@ -3337,13 +3319,12 @@ home_replace_save ( ) { char_u *dst; - unsigned len; - len = 3; /* space for "~/" and trailing NUL */ + size_t len = 3; /* space for "~/" and trailing NUL */ if (src != NULL) /* just in case */ - len += (unsigned)STRLEN(src); - dst = alloc(len); - home_replace(buf, src, dst, len, TRUE); + len += STRLEN(src); + dst = xmalloc(len); + home_replace(buf, src, dst, (int)len, TRUE); return dst; } @@ -3504,7 +3485,7 @@ get_cmd_output ( len = ftell(fd); /* get size of temp file */ fseek(fd, 0L, SEEK_SET); - buffer = alloc(len + 1); + buffer = xmalloc(len + 1); i = (int)fread((char *)buffer, (size_t)1, (size_t)len, fd); fclose(fd); os_remove((char *)tempname); diff --git a/src/nvim/misc1.h b/src/nvim/misc1.h index 7d9cd4ab63..df1d630621 100644 --- a/src/nvim/misc1.h +++ b/src/nvim/misc1.h @@ -22,7 +22,7 @@ void ins_str(char_u *s); int del_char(int fixpos); int del_chars(long count, int fixpos); int del_bytes(long count, int fixpos_arg, int use_delcombine); -int truncate_line(int fixpos); +void truncate_line(int fixpos); void del_lines(long nlines, int undo); int gchar_pos(pos_T *pos); int gchar_cursor(void); diff --git a/src/nvim/misc2.c b/src/nvim/misc2.c index b9b68c5d0b..d49898815f 100644 --- a/src/nvim/misc2.c +++ b/src/nvim/misc2.c @@ -229,7 +229,7 @@ coladvance2 ( if (line[idx] == NUL) { /* Append spaces */ int correct = wcol - col; - char_u *newline = alloc(idx + correct + 1); + char_u *newline = xmalloc(idx + correct + 1); int t; for (t = 0; t < idx; ++t) @@ -255,7 +255,7 @@ coladvance2 ( if (-correct > csize) return FAIL; - newline = alloc(linelen + csize); + newline = xmalloc(linelen + csize); for (t = 0; t < linelen; t++) { if (t != idx) diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 714607e913..bdd6a2a266 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -3382,7 +3382,7 @@ find_decl ( int retval = OK; int incll; - pat = alloc(len + 7); + pat = xmalloc(len + 7); /* Put "\V" before the pattern to avoid that the special meaning of "." * and "~" causes trouble. */ @@ -4356,7 +4356,7 @@ static void nv_ident(cmdarg_T *cap) kp = (*curbuf->b_p_kp == NUL ? p_kp : curbuf->b_p_kp); kp_help = (*kp == NUL || STRCMP(kp, ":he") == 0 || STRCMP(kp, ":help") == 0); - buf = alloc((unsigned)(n * 2 + 30 + STRLEN(kp))); + buf = xmalloc(n * 2 + 30 + STRLEN(kp)); buf[0] = NUL; switch (cmdchar) { diff --git a/src/nvim/ops.c b/src/nvim/ops.c index dff9822dd0..dccc3e6324 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -689,8 +689,6 @@ char_u *get_expr_line(void) /* Make a copy of the expression, because evaluating it may cause it to be * changed. */ expr_copy = vim_strsave(expr_line); - if (expr_copy == NULL) - return NULL; /* When we are invoked recursively limit the evaluation to 10 levels. * Then return the string as-is. */ @@ -907,7 +905,7 @@ static int stuff_yank(int regname, char_u *p) *pp = lp; } else { free_yank_all(); - y_current->y_array = (char_u **)alloc((unsigned)sizeof(char_u *)); + y_current->y_array = (char_u **)xmalloc(sizeof(char_u *)); y_current->y_array[0] = p; y_current->y_size = 1; y_current->y_type = MCHAR; /* used to be MLINE, why? */ @@ -2154,17 +2152,15 @@ void op_insert(oparg_T *oap, long count1) if (pre_textlen >= 0 && (ins_len = (long)STRLEN(firstline) - pre_textlen) > 0) { ins_text = vim_strnsave(firstline, (int)ins_len); - if (ins_text != NULL) { - /* block handled here */ - if (u_save(oap->start.lnum, - (linenr_T)(oap->end.lnum + 1)) == OK) - block_insert(oap, ins_text, (oap->op_type == OP_INSERT), - &bd); - - curwin->w_cursor.col = oap->start.col; - check_cursor(); - free(ins_text); - } + /* block handled here */ + if (u_save(oap->start.lnum, + (linenr_T)(oap->end.lnum + 1)) == OK) + block_insert(oap, ins_text, (oap->op_type == OP_INSERT), + &bd); + + curwin->w_cursor.col = oap->start.col; + check_cursor(); + free(ins_text); } } } @@ -2414,9 +2410,7 @@ int op_yank(oparg_T *oap, int deleting, int mess) break; case MLINE: - if ((y_current->y_array[y_idx] = - vim_strsave(ml_get(lnum))) == NULL) - goto fail; + y_current->y_array[y_idx] = vim_strsave(ml_get(lnum)); break; case MCHAR: @@ -2547,13 +2541,7 @@ int op_yank(oparg_T *oap, int deleting, int mess) curbuf->b_op_end.col = MAXCOL; } - return OK; - -fail: /* free the allocated lines */ - free_yank(y_idx + 1); - y_current = curr; - return FAIL; } static void yank_copy_line(struct block_def *bd, long y_idx) @@ -2676,8 +2664,7 @@ do_put ( } if (y_array != NULL) break; - y_array = (char_u **)alloc((unsigned) - (y_size * sizeof(char_u *))); + y_array = (char_u **)xmalloc(y_size * sizeof(char_u *)); } } else { y_size = 1; /* use fake one-line yank register */ @@ -2699,14 +2686,10 @@ do_put ( if (u_save_cursor() == FAIL) goto end; ptr = vim_strsave(ml_get_cursor()); - if (ptr == NULL) - goto end; ml_append(curwin->w_cursor.lnum, ptr, (colnr_T)0, FALSE); free(ptr); ptr = vim_strnsave(ml_get_curline(), curwin->w_cursor.col); - if (ptr == NULL) - goto end; ml_replace(curwin->w_cursor.lnum, ptr, FALSE); ++nr_lines; dir = FORWARD; @@ -3628,20 +3611,19 @@ static int same_leader(linenr_T lnum, int leader1_len, char_u *leader1_flags, in * The first line has to be saved, only one line can be locked at a time. */ line1 = vim_strsave(ml_get(lnum)); - if (line1 != NULL) { - for (idx1 = 0; vim_iswhite(line1[idx1]); ++idx1) - ; - line2 = ml_get(lnum + 1); - for (idx2 = 0; idx2 < leader2_len; ++idx2) { - if (!vim_iswhite(line2[idx2])) { - if (line1[idx1++] != line2[idx2]) - break; - } else - while (vim_iswhite(line1[idx1])) - ++idx1; - } - free(line1); + for (idx1 = 0; vim_iswhite(line1[idx1]); ++idx1) + ; + line2 = ml_get(lnum + 1); + for (idx2 = 0; idx2 < leader2_len; ++idx2) { + if (!vim_iswhite(line2[idx2])) { + if (line1[idx1++] != line2[idx2]) + break; + } else + while (vim_iswhite(line1[idx1])) + ++idx1; } + free(line1); + return idx2 == leader2_len && idx1 == leader1_len; } @@ -4401,7 +4383,7 @@ int do_addsub(int command, linenr_T Prenum1) * When there are many leading zeros it could be very long. Allocate * a bit too much. */ - buf1 = alloc((unsigned)length + NUMBUFLEN); + buf1 = xmalloc(length + NUMBUFLEN); ptr = buf1; if (negative) { *ptr++ = '-'; @@ -4491,7 +4473,7 @@ int read_viminfo_register(vir_T *virp, int force) y_previous = y_current; free(y_current->y_array); array = y_current->y_array = - (char_u **)alloc((unsigned)(limit * sizeof(char_u *))); + (char_u **)xmalloc(limit * sizeof(char_u *)); str = skipwhite(skiptowhite(str)); if (STRNCMP(str, "CHAR", 4) == 0) y_current->y_type = MCHAR; @@ -4508,8 +4490,7 @@ int read_viminfo_register(vir_T *virp, int force) && (virp->vir_line[0] == TAB || virp->vir_line[0] == '<')) { if (do_it) { if (size >= limit) { - y_current->y_array = (char_u **) - alloc((unsigned)(limit * 2 * sizeof(char_u *))); + y_current->y_array = (char_u **)xmalloc(limit * 2 * sizeof(char_u *)); for (i = 0; i < limit; i++) y_current->y_array[i] = array[i]; free(array); @@ -4529,7 +4510,7 @@ int read_viminfo_register(vir_T *virp, int force) y_current->y_array = NULL; } else if (size < limit) { y_current->y_array = - (char_u **)alloc((unsigned)(size * sizeof(char_u *))); + (char_u **)xmalloc(size * sizeof(char_u *)); for (i = 0; i < size; i++) y_current->y_array[i] = array[i]; free(array); @@ -4773,8 +4754,7 @@ void write_reg_contents_ex(int name, char_u *str, int maxlen, int must_append, i char_u *p, *s; p = vim_strnsave(str, (int)len); - if (p == NULL) - return; + if (must_append) { s = concat_str(get_expr_line_src(), p); free(p); @@ -4885,7 +4865,7 @@ str_to_reg ( extra = (int)STRLEN(y_ptr->y_array[lnum]); } else extra = 0; - s = alloc((unsigned)(i + extra + 1)); + s = xmalloc(i + extra + 1); if (extra) memmove(s, y_ptr->y_array[lnum], (size_t)extra); if (append) diff --git a/src/nvim/option.c b/src/nvim/option.c index 49abc62c89..33d146161b 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2089,7 +2089,8 @@ void set_init_1(void) p = (char_u *)_(*(char **)options[opt_idx].var); else p = option_expand(opt_idx, NULL); - if (p != NULL && (p = vim_strsave(p)) != NULL) { + if (p != NULL) { + p = vim_strsave(p); *(char_u **)options[opt_idx].var = p; /* VIMEXP * Defaults for all expanded options are currently the same for Vi @@ -2278,14 +2279,12 @@ void set_string_default(char *name, char_u *val) int opt_idx; p = vim_strsave(val); - if (p != NULL) { /* we don't want a NULL */ - opt_idx = findoption((char_u *)name); - if (opt_idx >= 0) { - if (options[opt_idx].flags & P_DEF_ALLOCED) - free(options[opt_idx].def_val[VI_DEFAULT]); - options[opt_idx].def_val[VI_DEFAULT] = p; - options[opt_idx].flags |= P_DEF_ALLOCED; - } + opt_idx = findoption((char_u *)name); + if (opt_idx >= 0) { + if (options[opt_idx].flags & P_DEF_ALLOCED) + free(options[opt_idx].def_val[VI_DEFAULT]); + options[opt_idx].def_val[VI_DEFAULT] = p; + options[opt_idx].flags |= P_DEF_ALLOCED; } } @@ -2450,7 +2449,7 @@ void set_init_3(void) p1 = p2 + 1; p = vim_strnsave(p1, (int)(p - p1)); } - if (p != NULL) { + { /* * Default for p_sp is "| tee", for p_srr is ">". * For known shells it is changed here to include stderr. @@ -2506,16 +2505,12 @@ void set_helplang_default(char_u *lang) if (options[idx].flags & P_ALLOCED) free_string_option(p_hlg); p_hlg = vim_strsave(lang); - if (p_hlg == NULL) - p_hlg = empty_option; - else { - /* zh_CN becomes "cn", zh_TW becomes "tw". */ - if (STRNICMP(p_hlg, "zh_", 3) == 0 && STRLEN(p_hlg) >= 5) { - p_hlg[0] = TOLOWER_ASC(p_hlg[3]); - p_hlg[1] = TOLOWER_ASC(p_hlg[4]); - } - p_hlg[2] = NUL; + /* zh_CN becomes "cn", zh_TW becomes "tw". */ + if (STRNICMP(p_hlg, "zh_", 3) == 0 && STRLEN(p_hlg) >= 5) { + p_hlg[0] = TOLOWER_ASC(p_hlg[3]); + p_hlg[1] = TOLOWER_ASC(p_hlg[4]); } + p_hlg[2] = NUL; options[idx].flags |= P_ALLOCED; } } @@ -3075,7 +3070,7 @@ do_set ( newlen = (unsigned)STRLEN(arg) + 1; if (adding || prepending || removing) newlen += (unsigned)STRLEN(origval) + 1; - newval = alloc(newlen); + newval = xmalloc(newlen); s = newval; /* @@ -3121,7 +3116,7 @@ do_set ( newlen = (unsigned)STRLEN(s) + 1; if (adding || prepending || removing) newlen += (unsigned)STRLEN(origval) + 1; - newval = alloc(newlen); + newval = xmalloc(newlen); STRCPY(newval, s); } } @@ -3739,7 +3734,7 @@ set_string_option_direct ( return; s = vim_strsave(val); - if (s != NULL) { + { varp = (char_u **)get_varp_scope(&(options[idx]), both ? OPT_LOCAL : opt_flags); if ((opt_flags & OPT_FREE) && (options[idx].flags & P_ALLOCED)) @@ -3780,9 +3775,8 @@ set_string_option_global ( p = (char_u **)GLOBAL_WO(varp); else p = (char_u **)options[opt_idx].var; - if (options[opt_idx].indir != PV_NONE - && p != varp - && (s = vim_strsave(*varp)) != NULL) { + if (options[opt_idx].indir != PV_NONE && p != varp) { + s = vim_strsave(*varp); free_string_option(*p); *p = s; } @@ -3809,18 +3803,17 @@ set_string_option ( return NULL; s = vim_strsave(value); - if (s != NULL) { - varp = (char_u **)get_varp_scope(&(options[opt_idx]), - (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0 - ? (((int)options[opt_idx].indir & PV_BOTH) - ? OPT_GLOBAL : OPT_LOCAL) - : opt_flags); - oldval = *varp; - *varp = s; - if ((r = did_set_string_option(opt_idx, varp, TRUE, oldval, NULL, - opt_flags)) == NULL) - did_set_option(opt_idx, opt_flags, TRUE); - } + varp = (char_u **)get_varp_scope(&(options[opt_idx]), + (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0 + ? (((int)options[opt_idx].indir & PV_BOTH) + ? OPT_GLOBAL : OPT_LOCAL) + : opt_flags); + oldval = *varp; + *varp = s; + if ((r = did_set_string_option(opt_idx, varp, TRUE, oldval, NULL, + opt_flags)) == NULL) + did_set_option(opt_idx, opt_flags, TRUE); + return r; } @@ -4768,7 +4761,7 @@ skip: if (count == 0) wp->w_p_cc_cols = NULL; else { - wp->w_p_cc_cols = (int *)alloc((unsigned)sizeof(int) * (count + 1)); + wp->w_p_cc_cols = xmalloc(sizeof(int) * (count + 1)); /* sort the columns for faster usage on screen redraw inside * win_line() */ qsort(color_cols, count, sizeof(int), int_cmp); @@ -6139,7 +6132,6 @@ showoptions ( int col; int isterm; char_u *varp; - struct vimoption **items; int item_count; int run; int row, rows; @@ -6150,8 +6142,7 @@ showoptions ( #define INC 20 #define GAP 3 - items = (struct vimoption **)alloc((unsigned)(sizeof(struct vimoption *) * - PARAM_COUNT)); + struct vimoption **items = xmalloc(sizeof(struct vimoption *) * PARAM_COUNT); /* Highlight title */ if (all == 2) @@ -6440,7 +6431,7 @@ static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, int e if (put_escstr(fd, str2special(&s, FALSE), 2) == FAIL) return FAIL; } else if (expand) { - buf = alloc(MAXPATHL); + buf = xmalloc(MAXPATHL); home_replace(NULL, *valuep, buf, MAXPATHL, FALSE); if (put_escstr(fd, buf, 2) == FAIL) { free(buf); @@ -7454,11 +7445,7 @@ int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u *** *num_file = num_term; else return OK; - *file = (char_u **)alloc((unsigned)(*num_file * sizeof(char_u *))); - if (*file == NULL) { - *file = (char_u **)""; - return FAIL; - } + *file = (char_u **)xmalloc(*num_file * sizeof(char_u *)); } } return OK; @@ -7470,7 +7457,7 @@ int ExpandOldSetting(int *num_file, char_u ***file) char_u *buf; *num_file = 0; - *file = (char_u **)alloc((unsigned)sizeof(char_u *)); + *file = (char_u **)xmalloc(sizeof(char_u *)); /* * For a terminal key code expand_option_idx is < 0. diff --git a/src/nvim/os/channel.c b/src/nvim/os/channel.c index 10766ca76e..f275c70805 100644 --- a/src/nvim/os/channel.c +++ b/src/nvim/os/channel.c @@ -3,7 +3,7 @@ #include <uv.h> #include <msgpack.h> -#include "nvim/lib/klist.h" +#include "nvim/api/private/helpers.h" #include "nvim/os/channel.h" #include "nvim/os/channel_defs.h" #include "nvim/os/rstream.h" @@ -15,8 +15,10 @@ #include "nvim/os/msgpack_rpc.h" #include "nvim/vim.h" #include "nvim/memory.h" +#include "nvim/map.h" typedef struct { + uint64_t id; ChannelProtocol protocol; bool is_job; union { @@ -30,22 +32,26 @@ typedef struct { struct { RStream *read; WStream *write; + uv_stream_t *uv; } streams; } data; } Channel; -#define _destroy_channel(x) +static uint64_t next_id = 1; +static Map(uint64_t) *channels = NULL; +static msgpack_sbuffer msgpack_event_buffer; -KLIST_INIT(Channel, Channel *, _destroy_channel) - -static klist_t(Channel) *channels = NULL; static void on_job_stdout(RStream *rstream, void *data, bool eof); static void on_job_stderr(RStream *rstream, void *data, bool eof); static void parse_msgpack(RStream *rstream, void *data, bool eof); +static void send_msgpack(Channel *channel, String type, Object data); +static void close_channel(Channel *channel); +static void close_cb(uv_handle_t *handle); void channel_init() { - channels = kl_init(Channel); + channels = map_new(uint64_t)(); + msgpack_sbuffer_init(&msgpack_event_buffer); } void channel_teardown() @@ -56,24 +62,9 @@ void channel_teardown() Channel *channel; - while (kl_shift(Channel, channels, &channel) == 0) { - - switch (channel->protocol) { - case kChannelProtocolMsgpack: - msgpack_sbuffer_free(channel->proto.msgpack.sbuffer); - msgpack_unpacker_free(channel->proto.msgpack.unpacker); - break; - default: - abort(); - } - - if (channel->is_job) { - job_stop(channel->data.job_id); - } else { - rstream_free(channel->data.streams.read); - wstream_free(channel->data.streams.write); - } - } + map_foreach_value(channels, channel, { + close_channel(channel); + }); } void channel_from_job(char **argv, ChannelProtocol prot) @@ -92,10 +83,11 @@ void channel_from_job(char **argv, ChannelProtocol prot) abort(); } + channel->id = next_id++; channel->protocol = prot; channel->is_job = true; channel->data.job_id = job_start(argv, channel, rcb, on_job_stderr, NULL); - *kl_pushp(Channel, channels) = channel; + map_put(uint64_t)(channels, channel->id, channel); } void channel_from_stream(uv_stream_t *stream, ChannelProtocol prot) @@ -115,6 +107,7 @@ void channel_from_stream(uv_stream_t *stream, ChannelProtocol prot) } stream->data = NULL; + channel->id = next_id++; channel->protocol = prot; channel->is_job = false; // read stream @@ -124,8 +117,32 @@ void channel_from_stream(uv_stream_t *stream, ChannelProtocol prot) // write stream channel->data.streams.write = wstream_new(1024 * 1024); wstream_set_stream(channel->data.streams.write, stream); - // push to channel list - *kl_pushp(Channel, channels) = channel; + channel->data.streams.uv = stream; + map_put(uint64_t)(channels, channel->id, channel); +} + +bool channel_send_event(uint64_t id, char *type, typval_T *data) +{ + Channel *channel = map_get(uint64_t)(channels, id); + + if (!channel) { + return false; + } + + String event_type = {.size = strnlen(type, 1024), .data = type}; + Object event_data = vim_to_object(data); + + switch (channel->protocol) { + case kChannelProtocolMsgpack: + send_msgpack(channel, event_type, event_data); + break; + default: + abort(); + } + + msgpack_rpc_free_object(event_data); + + return true; } static void on_job_stdout(RStream *rstream, void *data, bool eof) @@ -141,8 +158,13 @@ static void on_job_stderr(RStream *rstream, void *data, bool eof) static void parse_msgpack(RStream *rstream, void *data, bool eof) { - msgpack_unpacked unpacked; Channel *channel = data; + + if (eof) { + close_channel(channel); + return; + } + uint32_t count = rstream_available(rstream); // Feed the unpacker with data @@ -152,17 +174,18 @@ static void parse_msgpack(RStream *rstream, void *data, bool eof) count); msgpack_unpacker_buffer_consumed(channel->proto.msgpack.unpacker, count); + msgpack_unpacked unpacked; msgpack_unpacked_init(&unpacked); - // Deserialize everything we can. + // Deserialize everything we can. while (msgpack_unpacker_next(channel->proto.msgpack.unpacker, &unpacked)) { - // Each object is a new msgpack-rpc request and requires an empty response + // Each object is a new msgpack-rpc request and requires an empty response msgpack_packer response; msgpack_packer_init(&response, channel->proto.msgpack.sbuffer, msgpack_sbuffer_write); // Perform the call - msgpack_rpc_call(&unpacked.data, &response); + msgpack_rpc_call(channel->id, &unpacked.data, &response); wstream_write(channel->data.streams.write, xmemdup(channel->proto.msgpack.sbuffer->data, channel->proto.msgpack.sbuffer->size), @@ -173,3 +196,49 @@ static void parse_msgpack(RStream *rstream, void *data, bool eof) msgpack_sbuffer_clear(channel->proto.msgpack.sbuffer); } } + +static void send_msgpack(Channel *channel, String type, Object data) +{ + msgpack_packer packer; + msgpack_packer_init(&packer, &msgpack_event_buffer, msgpack_sbuffer_write); + msgpack_rpc_notification(type, data, &packer); + char *bytes = xmemdup(msgpack_event_buffer.data, msgpack_event_buffer.size); + + wstream_write(channel->data.streams.write, + bytes, + msgpack_event_buffer.size, + true); + + msgpack_sbuffer_clear(&msgpack_event_buffer); +} + +static void close_channel(Channel *channel) +{ + map_del(uint64_t)(channels, channel->id); + + switch (channel->protocol) { + case kChannelProtocolMsgpack: + msgpack_sbuffer_free(channel->proto.msgpack.sbuffer); + msgpack_unpacker_free(channel->proto.msgpack.unpacker); + break; + default: + abort(); + } + + if (channel->is_job) { + job_stop(channel->data.job_id); + } else { + rstream_free(channel->data.streams.read); + wstream_free(channel->data.streams.write); + uv_close((uv_handle_t *)channel->data.streams.uv, close_cb); + } + + free(channel); +} + +static void close_cb(uv_handle_t *handle) +{ + free(handle->data); + free(handle); +} + diff --git a/src/nvim/os/channel.h b/src/nvim/os/channel.h index 4a3962575d..543b91dd89 100644 --- a/src/nvim/os/channel.h +++ b/src/nvim/os/channel.h @@ -3,6 +3,7 @@ #include <uv.h> +#include "nvim/vim.h" #include "nvim/os/channel_defs.h" /// Initializes the module @@ -25,5 +26,13 @@ void channel_from_stream(uv_stream_t *stream, ChannelProtocol prot); /// @param prot The rpc protocol used void channel_from_job(char **argv, ChannelProtocol prot); +/// Sends event/data to channel +/// +/// @param id The channel id +/// @param type The event type, an arbitrary string +/// @param obj The event data +/// @return True if the data was sent successfully, false otherwise. +bool channel_send_event(uint64_t id, char *type, typval_T *data); + #endif // NVIM_OS_CHANNEL_H diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 47bf2fd933..861e1b46c5 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -89,8 +89,8 @@ static bool is_executable_in_path(const char_u *name) return false; } - int buf_len = STRLEN(name) + STRLEN(path) + 2; - char_u *buf = alloc((unsigned)(buf_len)); + size_t buf_len = STRLEN(name) + STRLEN(path) + 2; + char_u *buf = xmalloc(buf_len); // Walk through all entries in $PATH to check if "name" exists there and // is an executable file. @@ -103,7 +103,7 @@ static bool is_executable_in_path(const char_u *name) // Glue together the given directory from $PATH with name and save into // buf. vim_strncpy(buf, (char_u *) path, e - path); - append_path((char *) buf, (const char *) name, buf_len); + append_path((char *) buf, (const char *) name, (int)buf_len); if (is_executable(buf)) { // Found our executable. Free buf and return. diff --git a/src/nvim/os/msgpack_rpc.c b/src/nvim/os/msgpack_rpc.c index 45832070b1..423c5d584d 100644 --- a/src/nvim/os/msgpack_rpc.c +++ b/src/nvim/os/msgpack_rpc.c @@ -1,10 +1,61 @@ +#include <stdint.h> +#include <stdbool.h> + #include <msgpack.h> #include "nvim/os/msgpack_rpc.h" #include "nvim/vim.h" #include "nvim/memory.h" -void msgpack_rpc_call(msgpack_object *req, msgpack_packer *res) +#define REMOTE_FUNCS_IMPL(t, lt) \ + bool msgpack_rpc_to_##lt(msgpack_object *obj, t *arg) \ + { \ + *arg = obj->via.u64; \ + return obj->type == MSGPACK_OBJECT_POSITIVE_INTEGER; \ + } \ + \ + void msgpack_rpc_from_##lt(t result, msgpack_packer *res) \ + { \ + msgpack_pack_uint64(res, result); \ + } + +#define TYPED_ARRAY_IMPL(t, lt) \ + bool msgpack_rpc_to_##lt##array(msgpack_object *obj, t##Array *arg) \ + { \ + if (obj->type != MSGPACK_OBJECT_ARRAY) { \ + return false; \ + } \ + \ + arg->size = obj->via.array.size; \ + arg->items = xcalloc(obj->via.array.size, sizeof(t)); \ + \ + for (size_t i = 0; i < obj->via.array.size; i++) { \ + if (!msgpack_rpc_to_##lt(obj->via.array.ptr + i, &arg->items[i])) { \ + return false; \ + } \ + } \ + \ + return true; \ + } \ + \ + void msgpack_rpc_from_##lt##array(t##Array result, msgpack_packer *res) \ + { \ + msgpack_pack_array(res, result.size); \ + \ + for (size_t i = 0; i < result.size; i++) { \ + msgpack_rpc_from_##lt(result.items[i], res); \ + } \ + } \ + \ + void msgpack_rpc_free_##lt##array(t##Array value) { \ + for (size_t i = 0; i < value.size; i++) { \ + msgpack_rpc_free_##lt(value.items[i]); \ + } \ + \ + free(value.items); \ + } + +void msgpack_rpc_call(uint64_t id, msgpack_object *req, msgpack_packer *res) { // The initial response structure is the same no matter what happens, // we set it up here @@ -59,7 +110,16 @@ void msgpack_rpc_call(msgpack_object *req, msgpack_packer *res) } // dispatch the message - msgpack_rpc_dispatch(req, res); + msgpack_rpc_dispatch(id, req, res); +} + +void msgpack_rpc_notification(String type, Object data, msgpack_packer *pac) +{ + msgpack_pack_array(pac, 3); + msgpack_pack_int(pac, 2); + msgpack_pack_raw(pac, type.size); + msgpack_pack_raw_body(pac, type.data, type.size); + msgpack_rpc_from_object(data, pac); } void msgpack_rpc_error(char *msg, msgpack_packer *res) @@ -99,24 +159,13 @@ bool msgpack_rpc_to_float(msgpack_object *obj, Float *arg) bool msgpack_rpc_to_string(msgpack_object *obj, String *arg) { - arg->data = (char *)obj->via.raw.ptr; - arg->size = obj->via.raw.size; - return obj->type == MSGPACK_OBJECT_RAW; -} - -bool msgpack_rpc_to_buffer(msgpack_object *obj, Buffer *arg) -{ - return msgpack_rpc_to_integer(obj, arg); -} - -bool msgpack_rpc_to_window(msgpack_object *obj, Window *arg) -{ - return msgpack_rpc_to_integer(obj, arg); -} + if (obj->type != MSGPACK_OBJECT_RAW) { + return false; + } -bool msgpack_rpc_to_tabpage(msgpack_object *obj, Tabpage *arg) -{ - return msgpack_rpc_to_integer(obj, arg); + arg->data = xmemdup(obj->via.raw.ptr, obj->via.raw.size); + arg->size = obj->via.raw.size; + return true; } bool msgpack_rpc_to_object(msgpack_object *obj, Object *arg) @@ -156,24 +205,6 @@ bool msgpack_rpc_to_object(msgpack_object *obj, Object *arg) } } -bool msgpack_rpc_to_stringarray(msgpack_object *obj, StringArray *arg) -{ - if (obj->type != MSGPACK_OBJECT_ARRAY) { - return false; - } - - arg->size = obj->via.array.size; - arg->items = xcalloc(obj->via.array.size, sizeof(String)); - - for (uint32_t i = 0; i < obj->via.array.size; i++) { - if (!msgpack_rpc_to_string(obj->via.array.ptr + i, &arg->items[i])) { - return false; - } - } - - return true; -} - bool msgpack_rpc_to_position(msgpack_object *obj, Position *arg) { return obj->type == MSGPACK_OBJECT_ARRAY @@ -251,21 +282,6 @@ void msgpack_rpc_from_string(String result, msgpack_packer *res) msgpack_pack_raw_body(res, result.data, result.size); } -void msgpack_rpc_from_buffer(Buffer result, msgpack_packer *res) -{ - msgpack_rpc_from_integer(result, res); -} - -void msgpack_rpc_from_window(Window result, msgpack_packer *res) -{ - msgpack_rpc_from_integer(result, res); -} - -void msgpack_rpc_from_tabpage(Tabpage result, msgpack_packer *res) -{ - msgpack_rpc_from_integer(result, res); -} - void msgpack_rpc_from_object(Object result, msgpack_packer *res) { switch (result.type) { @@ -302,15 +318,6 @@ void msgpack_rpc_from_object(Object result, msgpack_packer *res) } } -void msgpack_rpc_from_stringarray(StringArray result, msgpack_packer *res) -{ - msgpack_pack_array(res, result.size); - - for (size_t i = 0; i < result.size; i++) { - msgpack_rpc_from_string(result.items[i], res); - } -} - void msgpack_rpc_from_position(Position result, msgpack_packer *res) { msgpack_pack_array(res, 2);; @@ -337,6 +344,15 @@ void msgpack_rpc_from_dictionary(Dictionary result, msgpack_packer *res) } } +void msgpack_rpc_free_string(String value) +{ + if (!value.data) { + return; + } + + free(value.data); +} + void msgpack_rpc_free_object(Object value) { switch (value.type) { @@ -363,14 +379,6 @@ void msgpack_rpc_free_object(Object value) } } -void msgpack_rpc_free_stringarray(StringArray value) { - for (uint32_t i = 0; i < value.size; i++) { - msgpack_rpc_free_string(value.items[i]); - } - - free(value.items); -} - void msgpack_rpc_free_array(Array value) { for (uint32_t i = 0; i < value.size; i++) { @@ -390,3 +398,12 @@ void msgpack_rpc_free_dictionary(Dictionary value) free(value.items); } +REMOTE_FUNCS_IMPL(Buffer, buffer) +REMOTE_FUNCS_IMPL(Window, window) +REMOTE_FUNCS_IMPL(Tabpage, tabpage) + +TYPED_ARRAY_IMPL(Buffer, buffer) +TYPED_ARRAY_IMPL(Window, window) +TYPED_ARRAY_IMPL(Tabpage, tabpage) +TYPED_ARRAY_IMPL(String, string) + diff --git a/src/nvim/os/msgpack_rpc.h b/src/nvim/os/msgpack_rpc.h index 0e9d474d8d..4d8d51699b 100644 --- a/src/nvim/os/msgpack_rpc.h +++ b/src/nvim/os/msgpack_rpc.h @@ -6,14 +6,25 @@ #include <msgpack.h> -#include "nvim/api/defs.h" +#include "nvim/func_attr.h" +#include "nvim/api/private/defs.h" /// Validates the basic structure of the msgpack-rpc call and fills `res` /// with the basic response structure. /// +/// @param id The channel id /// @param req The parsed request object /// @param res A packer that contains the response -void msgpack_rpc_call(msgpack_object *req, msgpack_packer *res); +void msgpack_rpc_call(uint64_t id, msgpack_object *req, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_NONNULL_ARG(3); + +/// Packs a notification message +/// +/// @param type The message type, an arbitrary string +/// @param data The notification data +/// @param packer Where the notification will be packed to +void msgpack_rpc_notification(String type, Object data, msgpack_packer *pac) + FUNC_ATTR_NONNULL_ARG(3); /// Dispatches to the actual API function after basic payload validation by /// `msgpack_rpc_call`. It is responsible for validating/converting arguments @@ -21,15 +32,20 @@ void msgpack_rpc_call(msgpack_object *req, msgpack_packer *res); /// The implementation is generated at compile time with metadata extracted /// from the api/*.h headers, /// +/// @param id The channel id /// @param req The parsed request object /// @param res A packer that contains the response -void msgpack_rpc_dispatch(msgpack_object *req, msgpack_packer *res); +void msgpack_rpc_dispatch(uint64_t id, + msgpack_object *req, + msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_NONNULL_ARG(3); /// Finishes the msgpack-rpc call with an error message. /// /// @param msg The error message /// @param res A packer that contains the response -void msgpack_rpc_error(char *msg, msgpack_packer *res); +void msgpack_rpc_error(char *msg, msgpack_packer *res) + FUNC_ATTR_NONNULL_ALL; /// Functions for validating and converting from msgpack types to C types. /// These are used by `msgpack_rpc_dispatch` to validate and convert each @@ -38,18 +54,36 @@ void msgpack_rpc_error(char *msg, msgpack_packer *res); /// @param obj The object to convert /// @param[out] arg A pointer to the avalue /// @return true if the convertion succeeded, false otherwise -bool msgpack_rpc_to_boolean(msgpack_object *obj, Boolean *arg); -bool msgpack_rpc_to_integer(msgpack_object *obj, Integer *arg); -bool msgpack_rpc_to_float(msgpack_object *obj, Float *arg); -bool msgpack_rpc_to_position(msgpack_object *obj, Position *arg); -bool msgpack_rpc_to_string(msgpack_object *obj, String *arg); -bool msgpack_rpc_to_buffer(msgpack_object *obj, Buffer *arg); -bool msgpack_rpc_to_window(msgpack_object *obj, Window *arg); -bool msgpack_rpc_to_tabpage(msgpack_object *obj, Tabpage *arg); -bool msgpack_rpc_to_object(msgpack_object *obj, Object *arg); -bool msgpack_rpc_to_stringarray(msgpack_object *obj, StringArray *arg); -bool msgpack_rpc_to_array(msgpack_object *obj, Array *arg); -bool msgpack_rpc_to_dictionary(msgpack_object *obj, Dictionary *arg); +bool msgpack_rpc_to_boolean(msgpack_object *obj, Boolean *arg) + FUNC_ATTR_NONNULL_ALL; +bool msgpack_rpc_to_integer(msgpack_object *obj, Integer *arg) + FUNC_ATTR_NONNULL_ALL; +bool msgpack_rpc_to_float(msgpack_object *obj, Float *arg) + FUNC_ATTR_NONNULL_ALL; +bool msgpack_rpc_to_position(msgpack_object *obj, Position *arg) + FUNC_ATTR_NONNULL_ALL; +bool msgpack_rpc_to_string(msgpack_object *obj, String *arg) + FUNC_ATTR_NONNULL_ALL; +bool msgpack_rpc_to_buffer(msgpack_object *obj, Buffer *arg) + FUNC_ATTR_NONNULL_ALL; +bool msgpack_rpc_to_window(msgpack_object *obj, Window *arg) + FUNC_ATTR_NONNULL_ALL; +bool msgpack_rpc_to_tabpage(msgpack_object *obj, Tabpage *arg) + FUNC_ATTR_NONNULL_ALL; +bool msgpack_rpc_to_object(msgpack_object *obj, Object *arg) + FUNC_ATTR_NONNULL_ALL; +bool msgpack_rpc_to_stringarray(msgpack_object *obj, StringArray *arg) + FUNC_ATTR_NONNULL_ALL; +bool msgpack_rpc_to_bufferarray(msgpack_object *obj, BufferArray *arg) + FUNC_ATTR_NONNULL_ALL; +bool msgpack_rpc_to_windowarray(msgpack_object *obj, WindowArray *arg) + FUNC_ATTR_NONNULL_ALL; +bool msgpack_rpc_to_tabpagearray(msgpack_object *obj, TabpageArray *arg) + FUNC_ATTR_NONNULL_ALL; +bool msgpack_rpc_to_array(msgpack_object *obj, Array *arg) + FUNC_ATTR_NONNULL_ALL; +bool msgpack_rpc_to_dictionary(msgpack_object *obj, Dictionary *arg) + FUNC_ATTR_NONNULL_ALL; /// Functions for converting from C types to msgpack types. /// These are used by `msgpack_rpc_dispatch` to convert return values @@ -57,32 +91,53 @@ bool msgpack_rpc_to_dictionary(msgpack_object *obj, Dictionary *arg); /// /// @param result A pointer to the result /// @param res A packer that contains the response -void msgpack_rpc_from_boolean(Boolean result, msgpack_packer *res); -void msgpack_rpc_from_integer(Integer result, msgpack_packer *res); -void msgpack_rpc_from_float(Float result, msgpack_packer *res); -void msgpack_rpc_from_position(Position result, msgpack_packer *res); -void msgpack_rpc_from_string(String result, msgpack_packer *res); -void msgpack_rpc_from_buffer(Buffer result, msgpack_packer *res); -void msgpack_rpc_from_window(Window result, msgpack_packer *res); -void msgpack_rpc_from_tabpage(Tabpage result, msgpack_packer *res); -void msgpack_rpc_from_object(Object result, msgpack_packer *res); -void msgpack_rpc_from_stringarray(StringArray result, msgpack_packer *res); -void msgpack_rpc_from_array(Array result, msgpack_packer *res); -void msgpack_rpc_from_dictionary(Dictionary result, msgpack_packer *res); +void msgpack_rpc_from_boolean(Boolean result, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2); +void msgpack_rpc_from_integer(Integer result, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2); +void msgpack_rpc_from_float(Float result, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2); +void msgpack_rpc_from_position(Position result, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2); +void msgpack_rpc_from_string(String result, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2); +void msgpack_rpc_from_buffer(Buffer result, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2); +void msgpack_rpc_from_window(Window result, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2); +void msgpack_rpc_from_tabpage(Tabpage result, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2); +void msgpack_rpc_from_object(Object result, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2); +void msgpack_rpc_from_stringarray(StringArray result, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2); +void msgpack_rpc_from_bufferarray(BufferArray result, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2); +void msgpack_rpc_from_windowarray(WindowArray result, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2); +void msgpack_rpc_from_tabpagearray(TabpageArray result, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2); +void msgpack_rpc_from_array(Array result, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2); +void msgpack_rpc_from_dictionary(Dictionary result, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(2); /// Helpers for initializing types that may be freed later #define msgpack_rpc_init_boolean #define msgpack_rpc_init_integer #define msgpack_rpc_init_float #define msgpack_rpc_init_position -#define msgpack_rpc_init_string +#define msgpack_rpc_init_string = STRING_INIT #define msgpack_rpc_init_buffer #define msgpack_rpc_init_window #define msgpack_rpc_init_tabpage #define msgpack_rpc_init_object = {.type = kObjectTypeNil} -#define msgpack_rpc_init_stringarray = {.items = NULL, .size = 0} -#define msgpack_rpc_init_array = {.items = NULL, .size = 0} -#define msgpack_rpc_init_dictionary = {.items = NULL, .size = 0} +#define msgpack_rpc_init_stringarray = ARRAY_DICT_INIT +#define msgpack_rpc_init_bufferarray = ARRAY_DICT_INIT +#define msgpack_rpc_init_windowarray = ARRAY_DICT_INIT +#define msgpack_rpc_init_tabpagearray = ARRAY_DICT_INIT +#define msgpack_rpc_init_array = ARRAY_DICT_INIT +#define msgpack_rpc_init_dictionary = ARRAY_DICT_INIT /// Helpers for freeing arguments/return value /// @@ -91,17 +146,17 @@ void msgpack_rpc_from_dictionary(Dictionary result, msgpack_packer *res); #define msgpack_rpc_free_integer(value) #define msgpack_rpc_free_float(value) #define msgpack_rpc_free_position(value) -// Strings are not copied from msgpack and so don't need to be freed(they -// probably "live" in the msgpack streaming buffer) -#define msgpack_rpc_free_string(value) +void msgpack_rpc_free_string(String value); #define msgpack_rpc_free_buffer(value) #define msgpack_rpc_free_window(value) #define msgpack_rpc_free_tabpage(value) void msgpack_rpc_free_object(Object value); void msgpack_rpc_free_stringarray(StringArray value); +void msgpack_rpc_free_bufferarray(BufferArray value); +void msgpack_rpc_free_windowarray(WindowArray value); +void msgpack_rpc_free_tabpagearray(TabpageArray value); void msgpack_rpc_free_array(Array value); void msgpack_rpc_free_dictionary(Dictionary value); - #endif // NVIM_OS_MSGPACK_RPC_H diff --git a/src/nvim/os/server.c b/src/nvim/os/server.c index 9b5410c323..7b2326556c 100644 --- a/src/nvim/os/server.c +++ b/src/nvim/os/server.c @@ -85,7 +85,11 @@ void server_start(char *endpoint, ChannelProtocol prot) char addr[ADDRESS_MAX_SIZE]; // Trim to `ADDRESS_MAX_SIZE` - strncpy(addr, endpoint, sizeof(addr)); + if (xstrlcpy(addr, endpoint, sizeof(addr)) >= sizeof(addr)) { + // TODO(aktau): since this is not what the user wanted, perhaps we + // should return an error here + EMSG2("Address was too long, truncated to %s", addr); + } // Check if the server already exists if (map_has(cstr_t)(servers, addr)) { @@ -111,7 +115,7 @@ void server_start(char *endpoint, ChannelProtocol prot) } // Extract the address part - strncpy(ip, addr, addr_len); + xstrlcpy(ip, addr, addr_len); int port = NEOVIM_DEFAULT_TCP_PORT; @@ -119,8 +123,8 @@ void server_start(char *endpoint, ChannelProtocol prot) char *port_end; // Extract the port port = strtol(ip_end + 1, &port_end, 10); - errno = 0; + if (errno != 0 || port == 0 || port > 0xffff) { // Invalid port, treat as named pipe or unix socket server_type = kServerTypePipe; @@ -152,7 +156,7 @@ void server_start(char *endpoint, ChannelProtocol prot) } } else { // Listen on named pipe or unix socket - strcpy(server->socket.pipe.addr, addr); + xstrlcpy(server->socket.pipe.addr, addr, sizeof(server->socket.pipe.addr)); uv_pipe_init(uv_default_loop(), &server->socket.pipe.handle, 0); server->socket.pipe.handle.data = server; uv_pipe_bind(&server->socket.pipe.handle, server->socket.pipe.addr); @@ -183,7 +187,7 @@ void server_stop(char *endpoint) char addr[ADDRESS_MAX_SIZE]; // Trim to `ADDRESS_MAX_SIZE` - strncpy(addr, endpoint, sizeof(addr)); + xstrlcpy(addr, endpoint, sizeof(addr)); if ((server = map_get(cstr_t)(servers, addr)) == NULL) { EMSG2("Not listening on %s", addr); diff --git a/src/nvim/os/server.h b/src/nvim/os/server.h index 541746eb5f..73c6bd1fea 100644 --- a/src/nvim/os/server.h +++ b/src/nvim/os/server.h @@ -10,7 +10,7 @@ void server_init(); void server_teardown(); /// Starts listening on arbitrary tcp/unix addresses specified by -/// `endpoint` for API calls. The type of socket used(tcp or unix/pipe) will +/// `endpoint` for API calls. The type of socket used(tcp or unix/pipe) will /// be determined by parsing `endpoint`: If it's a valid tcp address in the /// 'ip:port' format, then it will be tcp socket, else it will be a unix /// socket or named pipe. diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c index 1b302098dd..707a2f5ee9 100644 --- a/src/nvim/os/users.c +++ b/src/nvim/os/users.c @@ -4,6 +4,7 @@ #include "nvim/os/os.h" #include "nvim/garray.h" +#include "nvim/memory.h" #include "nvim/misc2.h" #include "nvim/strings.h" #ifdef HAVE_PWD_H @@ -28,10 +29,7 @@ int os_get_usernames(garray_T *users) // pw->pw_name shouldn't be NULL but just in case... if (pw->pw_name != NULL) { ga_grow(users, 1); - user = (char *)vim_strsave((char_u*)pw->pw_name); - if (user == NULL) { - return FAIL; - } + user = xstrdup(pw->pw_name); ((char **)(users->ga_data))[users->ga_len++] = user; } } @@ -79,8 +77,7 @@ char *os_get_user_directory(const char *name) pw = getpwnam(name); if (pw != NULL) { // save the string from the static passwd entry into malloced memory - char *user_directory = (char *)vim_strsave((char_u *)pw->pw_dir); - return user_directory; + return xstrdup(pw->pw_dir); } #endif return NULL; diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 1669a7cf77..e0b838ed26 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -27,6 +27,7 @@ #include <string.h> +#include "nvim/api/private/handle.h" #include "nvim/vim.h" #include "nvim/os_unix.h" #include "nvim/buffer.h" @@ -542,6 +543,7 @@ int mch_nodetype(char_u *name) void mch_early_init() { + handle_init(); time_init(); } @@ -1120,7 +1122,7 @@ int flags; /* EW_* flags */ ++len; } } - command = alloc(len); + command = xmalloc(len); /* * Build the shell command: @@ -1269,7 +1271,7 @@ int flags; /* EW_* flags */ fseek(fd, 0L, SEEK_END); len = ftell(fd); /* get size of temp file */ fseek(fd, 0L, SEEK_SET); - buffer = alloc(len + 1); + buffer = xmalloc(len + 1); i = fread((char *)buffer, 1, len, fd); fclose(fd); os_remove((char *)tempname); @@ -1353,7 +1355,7 @@ int flags; /* EW_* flags */ goto notfound; } *num_file = i; - *file = (char_u **)alloc(sizeof(char_u *) * i); + *file = (char_u **)xmalloc(sizeof(char_u *) * i); /* * Isolate the individual file names. @@ -1397,7 +1399,7 @@ int flags; /* EW_* flags */ if (!dir && (flags & EW_EXEC) && !os_can_exe((*file)[i])) continue; - p = alloc((unsigned)(STRLEN((*file)[i]) + 1 + dir)); + p = xmalloc(STRLEN((*file)[i]) + 1 + dir); STRCPY(p, (*file)[i]); if (dir) add_pathsep(p); /* add '/' to a directory name */ @@ -1437,10 +1439,9 @@ char_u ***file; for (i = 0; i < num_pat; i++) { s = vim_strsave(pat[i]); - if (s != NULL) - /* Be compatible with expand_filename(): halve the number of - * backslashes. */ - backslash_halve(s); + /* Be compatible with expand_filename(): halve the number of + * backslashes. */ + backslash_halve(s); (*file)[i] = s; } *num_file = num_pat; diff --git a/src/nvim/path.c b/src/nvim/path.c index 7a3c644499..5a1c9cd1c3 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -296,7 +296,7 @@ void add_pathsep(char_u *p) /* * FullName_save - Make an allocated copy of a full file name. - * Returns NULL when out of memory. + * Returns NULL when fname is NULL. */ char_u * FullName_save ( @@ -305,20 +305,20 @@ FullName_save ( * like a full path name */ ) { - char_u *buf; char_u *new_fname = NULL; if (fname == NULL) return NULL; - buf = alloc((unsigned)MAXPATHL); - if (buf != NULL) { - if (vim_FullName(fname, buf, MAXPATHL, force) != FAIL) - new_fname = vim_strsave(buf); - else - new_fname = vim_strsave(fname); - free(buf); + char_u *buf = xmalloc(MAXPATHL); + + if (vim_FullName(fname, buf, MAXPATHL, force) != FAIL) { + new_fname = vim_strsave(buf); + } else { + new_fname = vim_strsave(fname); } + free(buf); + return new_fname; } @@ -380,7 +380,7 @@ unix_expandpath ( } /* make room for file name */ - buf = alloc((int)STRLEN(path) + BASENAMELEN + 5); + buf = xmalloc(STRLEN(path) + BASENAMELEN + 5); /* * Find the first part in the path name that contains a wildcard. @@ -609,7 +609,7 @@ static void expand_path_option(char_u *curdir, garray_T *gap) char_u *p; int len; - buf = alloc((int)MAXPATHL); + buf = xmalloc(MAXPATHL); while (*path_option != NUL) { copy_option_part(&path_option, buf, MAXPATHL, " ,"); @@ -650,8 +650,6 @@ static void expand_path_option(char_u *curdir, garray_T *gap) ga_grow(gap, 1); p = vim_strsave(buf); - if (p == NULL) - break; ((char_u **)gap->ga_data)[gap->ga_len++] = p; } @@ -723,7 +721,7 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern) * possible patterns? */ len = (int)STRLEN(pattern); - file_pattern = alloc(len + 2); + file_pattern = xmalloc(len + 2); file_pattern[0] = '*'; file_pattern[1] = NUL; STRCAT(file_pattern, pattern); @@ -738,7 +736,7 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern) if (regmatch.regprog == NULL) return; - curdir = alloc((int)(MAXPATHL)); + curdir = xmalloc(MAXPATHL); os_dirname(curdir, MAXPATHL); expand_path_option(curdir, &path_ga); @@ -814,7 +812,7 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern) continue; } - rel_path = alloc((int)(STRLEN(short_name) + STRLEN(PATHSEPSTR) + 2)); + rel_path = xmalloc(STRLEN(short_name) + STRLEN(PATHSEPSTR) + 2); STRCPY(rel_path, "."); add_pathsep(rel_path); STRCAT(rel_path, short_name); @@ -887,7 +885,7 @@ expand_in_path ( char_u *e; /* end */ char_u *paths = NULL; - curdir = alloc((unsigned)MAXPATHL); + curdir = xmalloc(MAXPATHL); os_dirname(curdir, MAXPATHL); ga_init(&path_ga, (int)sizeof(char_u *), 1); @@ -1137,8 +1135,6 @@ expand_backtick ( /* Create the command: lop off the backticks. */ cmd = vim_strnsave(pat + 1, (int)STRLEN(pat) - 2); - if (cmd == NULL) - return 0; if (*cmd == '=') /* `={expr}`: Expand expression */ buffer = eval_to_string(cmd + 1, &p, TRUE); @@ -1211,7 +1207,7 @@ addfile ( /* Make room for another item in the file list. */ ga_grow(gap, 1); - p = alloc((unsigned)(STRLEN(f) + 1 + isdir)); + p = xmalloc(STRLEN(f) + 1 + isdir); STRCPY(p, f); #ifdef BACKSLASH_IN_FILENAME @@ -1563,9 +1559,7 @@ char_u *fix_fname(char_u *fname) fname = vim_strsave(fname); # ifdef USE_FNAME_CASE - if (fname != NULL) { - fname_case(fname, 0); /* set correct case for file name */ - } + fname_case(fname, 0); // set correct case for file name # endif return fname; diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index 7408ce292b..4c31e9e0ae 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -345,32 +345,27 @@ void pum_redraw(void) *p = saved; if (curwin->w_p_rl) { - char_u *rt = reverse_text(st); - - if (rt != NULL) { - char_u *rt_start = rt; - int size; - - size = vim_strsize(rt); - - if (size > pum_width) { - do { - size -= has_mbyte ? (*mb_ptr2cells)(rt) : 1; - mb_ptr_adv(rt); - } while (size > pum_width); - - if (size < pum_width) { - // Most left character requires 2-cells but only 1 cell - // is available on screen. Put a '<' on the left of the - // pum item - *(--rt) = '<'; - size++; - } + char_u *rt = reverse_text(st); + char_u *rt_start = rt; + int size = vim_strsize(rt); + + if (size > pum_width) { + do { + size -= has_mbyte ? (*mb_ptr2cells)(rt) : 1; + mb_ptr_adv(rt); + } while (size > pum_width); + + if (size < pum_width) { + // Most left character requires 2-cells but only 1 cell + // is available on screen. Put a '<' on the left of the + // pum item + *(--rt) = '<'; + size++; } - screen_puts_len(rt, (int)STRLEN(rt), row, col - size + 1, - attr); - free(rt_start); } + screen_puts_len(rt, (int)STRLEN(rt), row, col - size + 1, + attr); + free(rt_start); free(st); col -= width; diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 299a0a38db..269a33edcc 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -283,9 +283,9 @@ qf_init_ext ( {'s', ".\\+"} }; - namebuf = alloc(CMDBUFFSIZE + 1); - errmsg = alloc(CMDBUFFSIZE + 1); - pattern = alloc(CMDBUFFSIZE + 1); + namebuf = xmalloc(CMDBUFFSIZE + 1); + errmsg = xmalloc(CMDBUFFSIZE + 1); + pattern = xmalloc(CMDBUFFSIZE + 1); if (efile != NULL && (fd = mch_fopen((char *)efile, "r")) == NULL) { EMSG2(_(e_openerrf), efile); @@ -321,7 +321,7 @@ qf_init_ext ( #else i += 2; /* "%f" can become two chars longer */ #endif - fmtstr = alloc(i); + fmtstr = xmalloc(i); while (efm[0] != NUL) { /* @@ -719,13 +719,10 @@ restofline: if (qfprev == NULL) goto error2; if (*errmsg && !multiignore) { - len = (int)STRLEN(qfprev->qf_text); - ptr = alloc((unsigned)(len + STRLEN(errmsg) + 2)); - STRCPY(ptr, qfprev->qf_text); - free(qfprev->qf_text); - qfprev->qf_text = ptr; - *(ptr += len) = '\n'; - STRCPY(++ptr, errmsg); + size_t len = STRLEN(qfprev->qf_text); + qfprev->qf_text = xrealloc(qfprev->qf_text, len + STRLEN(errmsg) + 2); + qfprev->qf_text[len] = '\n'; + STRCPY(qfprev->qf_text + len + 1, errmsg); } if (qfprev->qf_nr == -1) qfprev->qf_nr = enr; @@ -856,7 +853,7 @@ static void qf_new_list(qf_info_T *qi, char_u *qf_title) qi->qf_curlist = qi->qf_listcount++; memset(&qi->qf_lists[qi->qf_curlist], 0, (size_t)(sizeof(qf_list_T))); if (qf_title != NULL) { - char_u *p = alloc((int)STRLEN(qf_title) + 2); + char_u *p = xmalloc(STRLEN(qf_title) + 2); qi->qf_lists[qi->qf_curlist].qf_title = p; sprintf((char *)p, ":%s", (char *)qf_title); @@ -921,27 +918,20 @@ qf_add_entry ( int valid /* valid entry */ ) { - qfline_T *qfp; - - qfp = (qfline_T *)alloc((unsigned)sizeof(qfline_T)); + qfline_T *qfp = xmalloc(sizeof(qfline_T)); if (bufnum != 0) qfp->qf_fnum = bufnum; else qfp->qf_fnum = qf_get_fnum(dir, fname); - if ((qfp->qf_text = vim_strsave(mesg)) == NULL) { - free(qfp); - return FAIL; - } + qfp->qf_text = vim_strsave(mesg); qfp->qf_lnum = lnum; qfp->qf_col = col; qfp->qf_viscol = vis_col; - if (pattern == NULL || *pattern == NUL) + if (pattern == NULL || *pattern == NUL) { qfp->qf_pattern = NULL; - else if ((qfp->qf_pattern = vim_strsave(pattern)) == NULL) { - free(qfp->qf_text); - free(qfp); - return FAIL; + } else { + qfp->qf_pattern = vim_strsave(pattern); } qfp->qf_nr = nr; if (type != 1 && !vim_isprintc(type)) /* only printable chars allowed */ @@ -1145,11 +1135,10 @@ static int qf_get_fnum(char_u *directory, char_u *fname) */ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr) { - struct dir_stack_T *ds_new; struct dir_stack_T *ds_ptr; /* allocate new stack element and hook it in */ - ds_new = (struct dir_stack_T *)alloc((unsigned)sizeof(struct dir_stack_T)); + struct dir_stack_T *ds_new = xmalloc(sizeof(struct dir_stack_T)); ds_new->next = *stackptr; *stackptr = ds_new; @@ -2521,7 +2510,7 @@ void ex_make(exarg_T *eap) len = (unsigned)STRLEN(p_shq) * 2 + (unsigned)STRLEN(eap->arg) + 1; if (*p_sp != NUL) len += (unsigned)STRLEN(p_sp) + (unsigned)STRLEN(fname) + 3; - cmd = alloc(len); + cmd = xmalloc(len); sprintf((char *)cmd, "%s%s%s", (char *)p_shq, (char *)eap->arg, (char *)p_shq); if (*p_sp != NUL) @@ -2596,7 +2585,7 @@ static char_u *get_mef_name(void) else off += 19; - name = alloc((unsigned)STRLEN(p_mef) + 30); + name = xmalloc(STRLEN(p_mef) + 30); STRCPY(name, p_mef); sprintf((char *)name + (p - p_mef), "%d%d", start, off); STRCAT(name, p + 2); @@ -2843,8 +2832,8 @@ void ex_vimgrep(exarg_T *eap) goto theend; } - dirname_start = alloc(MAXPATHL); - dirname_now = alloc(MAXPATHL); + dirname_start = xmalloc(MAXPATHL); + dirname_now = xmalloc(MAXPATHL); /* Remember the current directory, because a BufRead autocommand that does * ":lcd %:p:h" changes the meaning of short path names. */ @@ -3112,7 +3101,7 @@ char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags) */ static void restore_start_dir(char_u *dirname_start) { - char_u *dirname_now = alloc(MAXPATHL); + char_u *dirname_now = xmalloc(MAXPATHL); os_dirname(dirname_now, MAXPATHL); if (STRCMP(dirname_start, dirname_now) != 0) { diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index cade4bd1c1..de4220f93a 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -1141,8 +1141,7 @@ char_u *skip_regexp(char_u *startp, int dirc, int magic, char_u **newp) /* change "\?" to "?", make a copy first. */ if (*newp == NULL) { *newp = vim_strsave(startp); - if (*newp != NULL) - p = *newp + (p - startp); + p = *newp + (p - startp); } if (*newp != NULL) STRMOVE(p, p + 1); @@ -5654,7 +5653,7 @@ static int match_with_backref(linenr_T start_lnum, colnr_T start_col, linenr_T e if (reg_tofree == NULL || len >= (int)reg_tofreelen) { len += 50; /* get some extra */ free(reg_tofree); - reg_tofree = alloc(len); + reg_tofree = xmalloc(len); reg_tofreelen = len; } STRCPY(reg_tofree, regline); @@ -6405,7 +6404,7 @@ char_u *regtilde(char_u *source, int magic) if (reg_prev_sub != NULL) { /* length = len(newsub) - 1 + len(prev_sub) + 1 */ prevlen = (int)STRLEN(reg_prev_sub); - tmpsub = alloc((unsigned)(STRLEN(newsub) + prevlen)); + tmpsub = xmalloc(STRLEN(newsub) + prevlen); /* copy prefix */ len = (int)(p - newsub); /* not including ~ */ memmove(tmpsub, newsub, (size_t)len); diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 9855092ab4..d263a000d7 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -516,7 +516,7 @@ static char_u *nfa_get_match_text(nfa_state_T *start) if (p->c != NFA_MCLOSE || p->out->c != NFA_MATCH) return NULL; - ret = alloc(len); + ret = xmalloc(len); p = start->out->out; /* skip first char, it goes into regstart */ s = ret; while (p->c > 0) { @@ -4193,10 +4193,9 @@ addstate_here ( if (l->n + count - 1 >= l->len) { /* not enough space to move the new states, reallocate the list * and move the states to the right position */ - nfa_thread_T *newl; l->len = l->len * 3 / 2 + 50; - newl = (nfa_thread_T *)alloc(l->len * sizeof(nfa_thread_T)); + nfa_thread_T *newl = xmalloc(l->len * sizeof(nfa_thread_T)); memmove(&(newl[0]), &(l->t[0]), sizeof(nfa_thread_T) * listidx); diff --git a/src/nvim/screen.c b/src/nvim/screen.c index f65fa1066f..f4616d3b8e 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -4691,10 +4691,7 @@ win_redr_status_matches ( if (matches == NULL) /* interrupted completion? */ return; - if (has_mbyte) - buf = alloc((unsigned)Columns * MB_MAXBYTES + 1); - else - buf = alloc((unsigned)Columns + 1); + buf = xmalloc(has_mbyte ? Columns * MB_MAXBYTES + 1 : Columns + 1); if (match == -1) { /* don't show match but original text */ match = 0; @@ -6291,7 +6288,7 @@ retry: || outofmem) { if (ScreenLines != NULL || !done_outofmem_msg) { /* guess the size */ - do_outofmem_msg((long_u)((Rows + 1) * Columns)); + do_outofmem_msg((Rows + 1) * Columns); /* Remember we did this to avoid getting outofmem messages over * and over again. */ diff --git a/src/nvim/search.c b/src/nvim/search.c index 22dca0b22f..9d37aa3339 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -230,35 +230,29 @@ char_u *get_search_pat(void) /* * Reverse text into allocated memory. - * Returns the allocated string, NULL when out of memory. + * Returns the allocated string. + * + * TODO(philix): move reverse_text() to strings.c */ char_u *reverse_text(char_u *s) { - unsigned len; - unsigned s_i, rev_i; - char_u *rev; - /* * Reverse the pattern. */ - len = (unsigned)STRLEN(s); - rev = alloc(len + 1); - if (rev != NULL) { - rev_i = len; - for (s_i = 0; s_i < len; ++s_i) { - if (has_mbyte) { - int mb_len; - - mb_len = (*mb_ptr2len)(s + s_i); - rev_i -= mb_len; - memmove(rev + rev_i, s + s_i, mb_len); - s_i += mb_len - 1; - } else - rev[--rev_i] = s[s_i]; - - } - rev[len] = NUL; + size_t len = STRLEN(s); + char_u *rev = xmalloc(len + 1); + size_t rev_i = len; + for (size_t s_i = 0; s_i < len; ++s_i) { + if (has_mbyte) { + int mb_len = (*mb_ptr2len)(s + s_i); + rev_i -= mb_len; + memmove(rev + rev_i, s + s_i, mb_len); + s_i += mb_len - 1; + } else + rev[--rev_i] = s[s_i]; } + rev[len] = NUL; + return rev; } @@ -1056,8 +1050,8 @@ proftime_T *tm; /* timeout limit or NULL */ p = spats[last_idx].pat; else p = searchstr; - msgbuf = alloc((unsigned)(STRLEN(p) + 40)); - if (msgbuf != NULL) { + msgbuf = xmalloc(STRLEN(p) + 40); + { msgbuf[0] = dirc; if (enc_utf8 && utf_iscomposing(utf_ptr2char(p))) { /* Use a space to draw the composing char on. */ @@ -1088,13 +1082,9 @@ proftime_T *tm; /* timeout limit or NULL */ * it would be blanked out again very soon. Show it on the * left, but do reverse the text. */ if (curwin->w_p_rl && *curwin->w_p_rlc == 's') { - char_u *r; - - r = reverse_text(trunc != NULL ? trunc : msgbuf); - if (r != NULL) { - free(trunc); - trunc = r; - } + char_u *r = reverse_text(trunc != NULL ? trunc : msgbuf); + free(trunc); + trunc = r; } if (trunc != NULL) { msg_outtrans(trunc); @@ -3257,14 +3247,8 @@ again: curwin->w_cursor = old_pos; goto theend; } - spat = alloc(len + 31); - epat = alloc(len + 9); - if (spat == NULL || epat == NULL) { - free(spat); - free(epat); - curwin->w_cursor = old_pos; - goto theend; - } + spat = xmalloc(len + 31); + epat = xmalloc(len + 9); sprintf((char *)spat, "<%.*s\\>\\%%(\\s\\_[^>]\\{-}[^/]>\\|>\\)\\c", len, p); sprintf((char *)epat, "</%.*s>\\c", len, p); @@ -4024,18 +4008,14 @@ find_pattern_in_path ( incl_regmatch.regprog = NULL; def_regmatch.regprog = NULL; - file_line = alloc(LSIZE); - if (file_line == NULL) - return; + file_line = xmalloc(LSIZE); if (type != CHECK_PATH && type != FIND_DEFINE /* when CONT_SOL is set compare "ptr" with the beginning of the line * is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo */ && !(compl_cont_status & CONT_SOL) ) { - pat = alloc(len + 5); - if (pat == NULL) - goto fpip_end; + pat = xmalloc(len + 5); sprintf((char *)pat, whole ? "\\<%.*s\\>" : "%.*s", len, ptr); /* ignore case according to p_ic, p_scs and pat */ regmatch.rm_ic = ignorecase(pat); diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 6b229f7498..1fe957d17c 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -2010,7 +2010,7 @@ spell_move_to ( if (buflen < len + MAXWLEN + 2) { free(buf); buflen = len + MAXWLEN + 2; - buf = alloc(buflen); + buf = xmalloc(buflen); } // In first line check first word for Capital. @@ -2479,8 +2479,6 @@ spell_load_file ( // Remember the file name, used to reload the file when it's updated. lp->sl_fname = vim_strsave(fname); - if (lp->sl_fname == NULL) - goto endFAIL; // Check for .add.spl. lp->sl_add = strstr((char *)path_tail(fname), SPL_FNAME_ADD) != NULL; @@ -2856,7 +2854,7 @@ static int read_sal_section(FILE *fd, slang_T *slang) ccnt = getc(fd); // <salfromlen> if (ccnt < 0) return SP_TRUNCERROR; - p = alloc(ccnt + 2); + p = xmalloc(ccnt + 2); smp->sm_lead = p; // Read up to the first special char into sm_lead. @@ -2919,7 +2917,7 @@ static int read_sal_section(FILE *fd, slang_T *slang) // Add one extra entry to mark the end with an empty sm_lead. Avoids // that we need to check the index every time. smp = &((salitem_T *)gap->ga_data)[gap->ga_len]; - p = alloc(1); + p = xmalloc(1); p[0] = NUL; smp->sm_lead = p; smp->sm_leadlen = 0; @@ -2996,7 +2994,7 @@ count_common_word ( hash = hash_hash(p); hi = hash_lookup(&lp->sl_wordcount, p, hash); if (HASHITEM_EMPTY(hi)) { - wc = (wordcount_T *)alloc((unsigned)(sizeof(wordcount_T) + STRLEN(p))); + wc = xmalloc(sizeof(wordcount_T) + STRLEN(p)); STRCPY(wc->wc_word, p); wc->wc_count = count; hash_add_item(&lp->sl_wordcount, hi, wc->wc_word, hash); @@ -3146,22 +3144,22 @@ static int read_compound(FILE *fd, slang_T *slang, int len) c = todo * 2 + 7; if (enc_utf8) c += todo * 2; - pat = alloc((unsigned)c); + pat = xmalloc(c); // We also need a list of all flags that can appear at the start and one // for all flags. - cp = alloc(todo + 1); + cp = xmalloc(todo + 1); slang->sl_compstartflags = cp; *cp = NUL; - ap = alloc(todo + 1); + ap = xmalloc(todo + 1); slang->sl_compallflags = ap; *ap = NUL; // And a list of all patterns in their original form, for checking whether // compounding may work in match_compoundrule(). This is freed when we // encounter a wildcard, the check doesn't work then. - crp = alloc(todo + 1); + crp = xmalloc(todo + 1); slang->sl_comprules = crp; pp = pat; @@ -3378,7 +3376,7 @@ static int set_sofo(slang_T *lp, char_u *from, char_u *to) // Allocate the lists. for (i = 0; i < 256; ++i) if (lp->sl_sal_first[i] > 0) { - p = alloc(sizeof(int) * (lp->sl_sal_first[i] * 2 + 1)); + p = xmalloc(sizeof(int) * (lp->sl_sal_first[i] * 2 + 1)); ((int **)gap->ga_data)[i] = (int *)p; *(int *)p = 0; } @@ -3669,8 +3667,6 @@ char_u *did_set_spelllang(win_T *wp) // Make a copy of 'spelllang', the SpellFileMissing autocommands may change // it under our fingers. spl_copy = vim_strsave(wp->w_s->b_p_spl); - if (spl_copy == NULL) - goto theend; wp->w_s->b_cjk = 0; @@ -3936,11 +3932,9 @@ static void use_midword(slang_T *lp, win_T *wp) // Append multi-byte chars to "b_spell_ismw_mb". n = (int)STRLEN(wp->w_s->b_spell_ismw_mb); bp = vim_strnsave(wp->w_s->b_spell_ismw_mb, n + l); - if (bp != NULL) { - free(wp->w_s->b_spell_ismw_mb); - wp->w_s->b_spell_ismw_mb = bp; - vim_strncpy(bp + n, p, l); - } + free(wp->w_s->b_spell_ismw_mb); + wp->w_s->b_spell_ismw_mb = bp; + vim_strncpy(bp + n, p, l); } p += l; } else @@ -5175,8 +5169,6 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) if (HASHITEM_EMPTY(hash_find(&spin->si_commonwords, items[i]))) { p = vim_strsave(items[i]); - if (p == NULL) - break; hash_add(&spin->si_commonwords, p); } } @@ -7382,7 +7374,7 @@ static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname) // Write the .sug file. // Make the file name by changing ".spl" to ".sug". - fname = alloc(MAXPATHL); + fname = xmalloc(MAXPATHL); vim_strncpy(fname, wfname, MAXPATHL - 1); len = (int)STRLEN(fname); fname[len - 2] = 'u'; @@ -7789,7 +7781,7 @@ mkspell ( innames = &fnames[1]; incount = fcount - 1; - wfname = alloc(MAXPATHL); + wfname = xmalloc(MAXPATHL); if (fcount >= 1) { len = (int)STRLEN(fnames[0]); @@ -7840,7 +7832,7 @@ mkspell ( goto theend; } - fname = alloc(MAXPATHL); + fname = xmalloc(MAXPATHL); // Init the aff and dic pointers. // Get the region names if there are more than 2 arguments. @@ -8032,7 +8024,7 @@ spell_add_word ( EMSG2(_(e_notset), "spellfile"); return; } - fnamebuf = alloc(MAXPATHL); + fnamebuf = xmalloc(MAXPATHL); for (spf = curwin->w_s->b_p_spf, i = 1; *spf != NUL; ++i) { copy_option_part(&spf, fnamebuf, MAXPATHL, ","); @@ -8151,7 +8143,7 @@ static void init_spellfile(void) char_u *lstart = curbuf->b_s.b_p_spl; if (*curwin->w_s->b_p_spl != NUL && !GA_EMPTY(&curwin->w_s->b_langp)) { - buf = alloc(MAXPATHL); + buf = xmalloc(MAXPATHL); // Find the end of the language name. Exclude the region. If there // is a path separator remember the start of the tail. @@ -8678,8 +8670,6 @@ void spell_suggest(int count) // Make a copy of current line since autocommands may free the line. line = vim_strsave(ml_get_curline()); - if (line == NULL) - goto skip; // Get the list of suggestions. Limit to 'lines' - 2 or the number in // 'spellsuggest', whatever is smaller. @@ -8796,8 +8786,7 @@ void spell_suggest(int count) } // Replace the word. - p = alloc((unsigned)STRLEN(line) - stp->st_orglen - + stp->st_wordlen + 1); + p = xmalloc(STRLEN(line) - stp->st_orglen + stp->st_wordlen + 1); c = (int)(sug.su_badptr - line); memmove(p, line, c); STRCPY(p + c, stp->st_word); @@ -8818,8 +8807,6 @@ void spell_suggest(int count) curwin->w_cursor = prev_cursor; spell_find_cleanup(&sug); -skip: - free(line); } // Check if the word at line "lnum" column "col" is required to start with a @@ -8897,7 +8884,7 @@ void ex_spellrepall(exarg_T *eap) } addlen = (int)(STRLEN(repl_to) - STRLEN(repl_from)); - frompat = alloc((unsigned)STRLEN(repl_from) + 7); + frompat = xmalloc(STRLEN(repl_from) + 7); sprintf((char *)frompat, "\\V\\<%s\\>", repl_from); p_ws = FALSE; @@ -8914,7 +8901,7 @@ void ex_spellrepall(exarg_T *eap) line = ml_get_curline(); if (addlen <= 0 || STRNCMP(line + curwin->w_cursor.col, repl_to, STRLEN(repl_to)) != 0) { - p = alloc((unsigned)STRLEN(line) + addlen + 1); + p = xmalloc(STRLEN(line) + addlen + 1); memmove(p, line, curwin->w_cursor.col); STRCPY(p + curwin->w_cursor.col, repl_to); STRCAT(p, line + curwin->w_cursor.col + STRLEN(repl_from)); @@ -8966,8 +8953,8 @@ spell_suggest_list ( // The suggested word may replace only part of "word", add the not // replaced part. - wcopy = alloc(stp->st_wordlen - + (unsigned)STRLEN(sug.su_badptr + stp->st_orglen) + 1); + wcopy = xmalloc(stp->st_wordlen + + STRLEN(sug.su_badptr + stp->st_orglen) + 1); STRCPY(wcopy, stp->st_word); STRCPY(wcopy + stp->st_wordlen, sug.su_badptr + stp->st_orglen); ((char_u **)gap->ga_data)[gap->ga_len++] = wcopy; @@ -9063,8 +9050,6 @@ spell_find_suggest ( // Make a copy of 'spellsuggest', because the expression may change it. sps_copy = vim_strsave(p_sps); - if (sps_copy == NULL) - return; // Loop over the items in 'spellsuggest'. for (p = sps_copy; *p != NUL; ) { @@ -11024,13 +11009,11 @@ static void score_comp_sal(suginfo_T *su) // Add the suggestion. sstp = &SUG(su->su_sga, su->su_sga.ga_len); sstp->st_word = vim_strsave(stp->st_word); - if (sstp->st_word != NULL) { - sstp->st_wordlen = stp->st_wordlen; - sstp->st_score = score; - sstp->st_altscore = 0; - sstp->st_orglen = stp->st_orglen; - ++su->su_sga.ga_len; - } + sstp->st_wordlen = stp->st_wordlen; + sstp->st_score = score; + sstp->st_altscore = 0; + sstp->st_orglen = stp->st_orglen; + ++su->su_sga.ga_len; } } break; @@ -11313,8 +11296,7 @@ add_sound_suggest ( hash = hash_hash(goodword); hi = hash_lookup(&slang->sl_sounddone, goodword, hash); if (HASHITEM_EMPTY(hi)) { - sft = (sftword_T *)alloc((unsigned)(sizeof(sftword_T) - + STRLEN(goodword))); + sft = xmalloc(sizeof(sftword_T) + STRLEN(goodword)); sft->sft_score = score; STRCPY(sft->sft_word, goodword); hash_add_item(&slang->sl_sounddone, hi, sft->sft_word, hash); @@ -11578,7 +11560,7 @@ static void set_map_str(slang_T *lp, char_u *map) hash_T hash; hashitem_T *hi; - b = alloc((unsigned)(cl + headcl + 2)); + b = xmalloc(cl + headcl + 2); mb_char2bytes(c, b); b[cl] = NUL; mb_char2bytes(headc, b + cl + 1); @@ -11730,25 +11712,23 @@ add_suggestion ( // Add a suggestion. stp = &SUG(*gap, gap->ga_len); stp->st_word = vim_strnsave(goodword, goodlen); - if (stp->st_word != NULL) { - stp->st_wordlen = goodlen; - stp->st_score = score; - stp->st_altscore = altscore; - stp->st_had_bonus = had_bonus; - stp->st_orglen = badlen; - stp->st_slang = slang; - ++gap->ga_len; - - // If we have too many suggestions now, sort the list and keep - // the best suggestions. - if (gap->ga_len > SUG_MAX_COUNT(su)) { - if (maxsf) - su->su_sfmaxscore = cleanup_suggestions(gap, - su->su_sfmaxscore, SUG_CLEAN_COUNT(su)); - else - su->su_maxscore = cleanup_suggestions(gap, - su->su_maxscore, SUG_CLEAN_COUNT(su)); - } + stp->st_wordlen = goodlen; + stp->st_score = score; + stp->st_altscore = altscore; + stp->st_had_bonus = had_bonus; + stp->st_orglen = badlen; + stp->st_slang = slang; + ++gap->ga_len; + + // If we have too many suggestions now, sort the list and keep + // the best suggestions. + if (gap->ga_len > SUG_MAX_COUNT(su)) { + if (maxsf) + su->su_sfmaxscore = cleanup_suggestions(gap, + su->su_sfmaxscore, SUG_CLEAN_COUNT(su)); + else + su->su_maxscore = cleanup_suggestions(gap, + su->su_maxscore, SUG_CLEAN_COUNT(su)); } } } @@ -11799,8 +11779,7 @@ static void add_banned(suginfo_T *su, char_u *word) hi = hash_lookup(&su->su_banned, word, hash); if (HASHITEM_EMPTY(hi)) { s = vim_strsave(word); - if (s != NULL) - hash_add_item(&su->su_banned, hi, s, hash); + hash_add_item(&su->su_banned, hi, s, hash); } } diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 50669dfcfb..d8a14c1883 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -45,14 +45,7 @@ */ char_u *vim_strsave(char_u *string) { - char_u *p; - unsigned len; - - len = (unsigned)STRLEN(string) + 1; - p = alloc(len); - if (p != NULL) - memmove(p, string, (size_t)len); - return p; + return (char_u *)xstrdup((char *)string); } /* @@ -63,12 +56,7 @@ char_u *vim_strsave(char_u *string) */ char_u *vim_strnsave(char_u *string, int len) { - char_u *p; - - p = alloc((unsigned)(len + 1)); - STRNCPY(p, string, len); - p[len] = NUL; - return p; + return (char_u *)strncpy(xmallocz(len), (char *)string, len); } /* @@ -108,7 +96,7 @@ char_u *vim_strsave_escaped_ext(char_u *string, char_u *esc_chars, int cc, int b ++length; /* count a backslash */ ++length; /* count an ordinary char */ } - escaped_string = alloc(length); + escaped_string = xmalloc(length); p2 = escaped_string; for (p = string; *p; p++) { if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) { @@ -169,7 +157,7 @@ char_u *vim_strsave_shellescape(char_u *string, bool do_special, bool do_newline } /* Allocate memory for the result and fill it. */ - escaped_string = alloc(length); + escaped_string = xmalloc(length); d = escaped_string; /* add opening quote */ @@ -253,49 +241,45 @@ void vim_strup(char_u *p) /* * Make string "s" all upper-case and return it in allocated memory. * Handles multi-byte characters as well as possible. - * Returns NULL when out of memory. */ char_u *strup_save(char_u *orig) { - char_u *p; - char_u *res; + char_u *res = vim_strsave(orig); - res = p = vim_strsave(orig); - - if (res != NULL) - while (*p != NUL) { - int l; - - if (enc_utf8) { - int c, uc; - int newl; - char_u *s; - - c = utf_ptr2char(p); - uc = utf_toupper(c); - - /* Reallocate string when byte count changes. This is rare, - * thus it's OK to do another malloc()/free(). */ - l = utf_ptr2len(p); - newl = utf_char2len(uc); - if (newl != l) { - s = alloc((unsigned)STRLEN(res) + 1 + newl - l); - memmove(s, res, p - res); - STRCPY(s + (p - res) + newl, p + l); - p = s + (p - res); - free(res); - res = s; - } - - utf_char2bytes(uc, p); - p += newl; - } else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) - p += l; /* skip multi-byte character */ - else { - *p = TOUPPER_LOC(*p); /* note that toupper() can be a macro */ - p++; + char_u *p = res; + while (*p != NUL) { + int l; + + if (enc_utf8) { + int c, uc; + int newl; + char_u *s; + + c = utf_ptr2char(p); + uc = utf_toupper(c); + + /* Reallocate string when byte count changes. This is rare, + * thus it's OK to do another malloc()/free(). */ + l = utf_ptr2len(p); + newl = utf_char2len(uc); + if (newl != l) { + s = xmalloc(STRLEN(res) + 1 + newl - l); + memmove(s, res, p - res); + STRCPY(s + (p - res) + newl, p + l); + p = s + (p - res); + free(res); + res = s; } + + utf_char2bytes(uc, p); + p += newl; + } else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) + p += l; /* skip multi-byte character */ + else { + *p = TOUPPER_LOC(*p); /* note that toupper() can be a macro */ + p++; } + } return res; } diff --git a/src/nvim/strings.h b/src/nvim/strings.h index 831191b517..aec9e4d06d 100644 --- a/src/nvim/strings.h +++ b/src/nvim/strings.h @@ -1,7 +1,10 @@ #ifndef NVIM_STRINGS_H #define NVIM_STRINGS_H -char_u *vim_strsave(char_u *string); -char_u *vim_strnsave(char_u *string, int len); + +#include "func_attr.h" + +char_u *vim_strsave(char_u *string) FUNC_ATTR_NONNULL_RET; +char_u *vim_strnsave(char_u *string, int len) FUNC_ATTR_NONNULL_RET; char_u *vim_strsave_escaped(char_u *string, char_u *esc_chars); char_u *vim_strsave_escaped_ext(char_u *string, char_u *esc_chars, int cc, diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index a72bd2bec6..ccc6752793 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -3924,7 +3924,6 @@ add_keyword ( int conceal_char ) { - keyentry_T *kp; hashtab_T *ht; hashitem_T *hi; char_u *name_ic; @@ -3936,7 +3935,7 @@ add_keyword ( name_folded, MAXKEYWLEN + 1); else name_ic = name; - kp = (keyentry_T *)alloc((int)(sizeof(keyentry_T) + STRLEN(name_ic))); + keyentry_T *kp = xmalloc(sizeof(keyentry_T) + STRLEN(name_ic)); STRCPY(kp->keyword, name_ic); kp->k_syn.id = id; kp->k_syn.inc_tag = current_syn_inc_tag; @@ -4113,8 +4112,6 @@ get_syn_options ( if (gname_start == arg) return NULL; gname = vim_strnsave(gname_start, (int)(arg - gname_start)); - if (gname == NULL) - return NULL; if (STRCMP(gname, "NONE") == 0) *opt->sync_idx = NONE_IDX; else { @@ -4156,7 +4153,7 @@ static void syn_incl_toplevel(int id, int *flagsp) *flagsp |= HL_CONTAINED; if (curwin->w_s->b_syn_topgrp >= SYNID_CLUSTER) { /* We have to alloc this, because syn_combine_list() will free it. */ - short *grp_list = (short *)alloc((unsigned)(2 * sizeof(short))); + short *grp_list = xmalloc(2 * sizeof(short)); int tlg_id = curwin->w_s->b_syn_topgrp - SYNID_CLUSTER; grp_list[0] = id; @@ -4257,7 +4254,7 @@ static void syn_cmd_keyword(exarg_T *eap, int syncing) syn_id = syn_check_group(arg, (int)(group_name_end - arg)); if (syn_id != 0) /* allocate a buffer, for removing backslashes in the keyword */ - keyword_copy = alloc((unsigned)STRLEN(rest) + 1); + keyword_copy = xmalloc(STRLEN(rest) + 1); syn_opt_arg.flags = 0; syn_opt_arg.keyword = TRUE; syn_opt_arg.sync_idx = NULL; @@ -4558,7 +4555,7 @@ syn_cmd_region ( * syn_patterns for this item, at the start (because the list is * used from end to start). */ - ppp = (struct pat_ptr *)alloc((unsigned)sizeof(struct pat_ptr)); + ppp = xmalloc(sizeof(struct pat_ptr)); ppp->pp_next = pat_ptrs[item]; pat_ptrs[item] = ppp; ppp->pp_synp = xcalloc(1, sizeof(synpat_T)); @@ -4784,7 +4781,7 @@ static void syn_combine_list(short **clstr1, short **clstr2, int list_op) clstr = NULL; break; } - clstr = (short *)alloc((unsigned)((count + 1) * sizeof(short))); + clstr = xmalloc((count + 1) * sizeof(short)); clstr[count] = 0; } } @@ -4823,14 +4820,10 @@ static int syn_scl_name2id(char_u *name) */ static int syn_scl_namen2id(char_u *linep, int len) { - char_u *name; - int id = 0; + char_u *name = vim_strnsave(linep, len); + int id = syn_scl_name2id(name); + free(name); - name = vim_strnsave(linep, len); - if (name != NULL) { - id = syn_scl_name2id(name); - free(name); - } return id; } @@ -4846,8 +4839,6 @@ static int syn_check_cluster(char_u *pp, int len) char_u *name; name = vim_strnsave(pp, len); - if (name == NULL) - return 0; id = syn_scl_name2id(name); if (id == 0) /* doesn't exist yet */ @@ -4996,8 +4987,7 @@ static char_u *get_syn_pattern(char_u *arg, synpat_T *ci) return NULL; } /* store the pattern and compiled regexp program */ - if ((ci->sp_pattern = vim_strnsave(arg + 1, (int)(end - arg - 1))) == NULL) - return NULL; + ci->sp_pattern = vim_strnsave(arg + 1, (int)(end - arg - 1)); /* Make 'cpoptions' empty, to avoid the 'l' flag */ cpo_save = p_cpo; @@ -5139,11 +5129,8 @@ static void syn_cmd_sync(exarg_T *eap, int syncing) if (!eap->skip) { /* store the pattern and compiled regexp program */ - if ((curwin->w_s->b_syn_linecont_pat = vim_strnsave(next_arg + 1, - (int)(arg_end - next_arg - 1))) == NULL) { - finished = TRUE; - break; - } + curwin->w_s->b_syn_linecont_pat = + vim_strnsave(next_arg + 1, (int)(arg_end - next_arg - 1)); curwin->w_s->b_syn_linecont_ic = curwin->w_s->b_syn_ic; /* Make 'cpoptions' empty, to avoid the 'l' flag */ @@ -5243,7 +5230,7 @@ get_id_list ( while (!ends_excmd(*p)) { for (end = p; *end && !vim_iswhite(*end) && *end != ','; ++end) ; - name = alloc((int)(end - p + 3)); /* leave room for "^$" */ + name = xmalloc((int)(end - p + 3)); /* leave room for "^$" */ vim_strncpy(name + 1, p, end - p); if ( STRCMP(name + 1, "ALLBUT") == 0 || STRCMP(name + 1, "ALL") == 0 @@ -5337,7 +5324,7 @@ get_id_list ( if (failed) break; if (round == 1) { - retval = (short *)alloc((unsigned)((count + 1) * sizeof(short))); + retval = xmalloc((count + 1) * sizeof(short)); retval[count] = 0; /* zero means end of the list */ total_count = count; } @@ -5372,7 +5359,7 @@ static short *copy_id_list(short *list) for (count = 0; list[count]; ++count) ; len = (count + 1) * sizeof(short); - retval = (short *)alloc((unsigned)len); + retval = xmalloc(len); memmove(retval, list, (size_t)len); return retval; @@ -5518,24 +5505,22 @@ void ex_syntax(exarg_T *eap) for (subcmd_end = arg; ASCII_ISALPHA(*subcmd_end); ++subcmd_end) ; subcmd_name = vim_strnsave(arg, (int)(subcmd_end - arg)); - if (subcmd_name != NULL) { - if (eap->skip) /* skip error messages for all subcommands */ - ++emsg_skip; - for (i = 0;; ++i) { - if (subcommands[i].name == NULL) { - EMSG2(_("E410: Invalid :syntax subcommand: %s"), subcmd_name); - break; - } - if (STRCMP(subcmd_name, (char_u *)subcommands[i].name) == 0) { - eap->arg = skipwhite(subcmd_end); - (subcommands[i].func)(eap, FALSE); - break; - } + if (eap->skip) /* skip error messages for all subcommands */ + ++emsg_skip; + for (i = 0;; ++i) { + if (subcommands[i].name == NULL) { + EMSG2(_("E410: Invalid :syntax subcommand: %s"), subcmd_name); + break; + } + if (STRCMP(subcmd_name, (char_u *)subcommands[i].name) == 0) { + eap->arg = skipwhite(subcmd_end); + (subcommands[i].func)(eap, FALSE); + break; } - free(subcmd_name); - if (eap->skip) - --emsg_skip; } + free(subcmd_name); + if (eap->skip) + --emsg_skip; } void ex_ownsyntax(exarg_T *eap) @@ -5544,7 +5529,7 @@ void ex_ownsyntax(exarg_T *eap) char_u *new_value; if (curwin->w_s == &curwin->w_buffer->b_s) { - curwin->w_s = (synblock_T *)alloc(sizeof(synblock_T)); + curwin->w_s = xmalloc(sizeof(synblock_T)); memset(curwin->w_s, 0, sizeof(synblock_T)); curwin->w_p_spell = FALSE; /* No spell checking */ clear_string_option(&curwin->w_s->b_p_spc); @@ -6184,7 +6169,7 @@ int load_colors(char_u *name) return OK; recursive = TRUE; - buf = alloc((unsigned)(STRLEN(name) + 12)); + buf = xmalloc(STRLEN(name) + 12); sprintf((char *)buf, "colors/%s.vim", name); retval = source_runtime(buf, FALSE); free(buf); @@ -6392,10 +6377,6 @@ do_highlight ( ++linep; free(key); key = vim_strnsave_up(key_start, (int)(linep - key_start)); - if (key == NULL) { - error = TRUE; - break; - } linep = skipwhite(linep); if (STRCMP(key, "NONE") == 0) { @@ -6440,10 +6421,7 @@ do_highlight ( } free(arg); arg = vim_strnsave(arg_start, (int)(linep - arg_start)); - if (arg == NULL) { - error = TRUE; - break; - } + if (*linep == '\'') ++linep; @@ -6725,10 +6703,6 @@ do_highlight ( arg[off + len] != ','; ++len) ; tname = vim_strnsave(arg + off, len); - if (tname == NULL) { /* out of memory */ - error = TRUE; - break; - } /* lookup the escape sequence for the item */ p = get_term_code(tname); free(tname); @@ -7410,14 +7384,10 @@ char_u *syn_id2name(int id) */ int syn_namen2id(char_u *linep, int len) { - char_u *name; - int id = 0; + char_u *name = vim_strnsave(linep, len); + int id = syn_name2id(name); + free(name); - name = vim_strnsave(linep, len); - if (name != NULL) { - id = syn_name2id(name); - free(name); - } return id; } @@ -7433,8 +7403,6 @@ int syn_check_group(char_u *pp, int len) char_u *name; name = vim_strnsave(pp, len); - if (name == NULL) - return 0; id = syn_name2id(name); if (id == 0) /* doesn't exist yet */ diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 0e01350537..a87210cbb8 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -236,8 +236,7 @@ do_tag ( cur_fnum = ptag_entry.cur_fnum; } else { free(ptag_entry.tagname); - if ((ptag_entry.tagname = vim_strsave(tag)) == NULL) - goto end_do_tag; + ptag_entry.tagname = vim_strsave(tag); } } else { /* @@ -256,13 +255,9 @@ do_tag ( --tagstackidx; } - /* - * put the tag name in the tag stack - */ - if ((tagstack[tagstackidx].tagname = vim_strsave(tag)) == NULL) { - curwin->w_tagstacklen = tagstacklen - 1; - goto end_do_tag; - } + // put the tag name in the tag stack + tagstack[tagstackidx].tagname = vim_strsave(tag); + curwin->w_tagstacklen = tagstacklen; save_pos = TRUE; /* save the cursor position below */ @@ -562,10 +557,9 @@ do_tag ( /* Find out the actual file name. If it is long, truncate * it and put "..." in the middle */ p = tag_full_fname(&tagp); - if (p != NULL) { - msg_puts_long_attr(p, hl_attr(HLF_D)); - free(p); - } + msg_puts_long_attr(p, hl_attr(HLF_D)); + free(p); + if (msg_col > 0) msg_putchar('\n'); if (got_int) @@ -684,8 +678,8 @@ do_tag ( * window. */ - fname = alloc(MAXPATHL + 1); - cmd = alloc(CMDBUFFSIZE + 1); + fname = xmalloc(MAXPATHL + 1); + cmd = xmalloc(CMDBUFFSIZE + 1); list = list_alloc(); for (i = 0; i < num_matches; ++i) { @@ -704,8 +698,6 @@ do_tag ( /* Save the tag file name */ p = tag_full_fname(&tagp); - if (p == NULL) - continue; vim_strncpy(fname, p, MAXPATHL); free(p); @@ -1190,8 +1182,8 @@ find_tags ( /* * Allocate memory for the buffers that are used */ - lbuf = alloc(lbuf_size); - tag_fname = alloc(MAXPATHL + 1); + lbuf = xmalloc(lbuf_size); + tag_fname = xmalloc(MAXPATHL + 1); for (mtt = 0; mtt < MT_COUNT; ++mtt) ga_init(&ga_match[mtt], (int)sizeof(struct match_found *), 100); @@ -1211,11 +1203,9 @@ find_tags ( && ASCII_ISALPHA(pat[orgpat.len - 2]) && ASCII_ISALPHA(pat[orgpat.len - 1])) { saved_pat = vim_strnsave(pat, orgpat.len - 3); - if (saved_pat != NULL) { - help_lang_find = &pat[orgpat.len - 2]; - orgpat.pat = saved_pat; - orgpat.len -= 3; - } + help_lang_find = &pat[orgpat.len - 2]; + orgpat.pat = saved_pat; + orgpat.len -= 3; } } if (p_tl != 0 && orgpat.len > p_tl) /* adjust for 'taglength' */ @@ -1821,9 +1811,7 @@ parse_line: */ *tagp.tagname_end = NUL; len = (int)(tagp.tagname_end - tagp.tagname); - mfp = (struct match_found *) - alloc((int)sizeof(struct match_found) + len - + 10 + ML_EXTRA); + mfp = xmalloc(sizeof(struct match_found) + len + 10 + ML_EXTRA); /* "len" includes the language and the NUL, but * not the priority. */ mfp->len = len + ML_EXTRA + 1; @@ -1851,8 +1839,7 @@ parse_line: if (tagp.command + 2 < temp_end) { len = (int)(temp_end - tagp.command - 2); - mfp = (struct match_found *)alloc( - (int)sizeof(struct match_found) + len); + mfp = xmalloc(sizeof(struct match_found) + len); mfp->len = len + 1; /* include the NUL */ p = mfp->match; vim_strncpy(p, tagp.command + 2, len); @@ -1861,8 +1848,7 @@ parse_line: get_it_again = FALSE; } else { len = (int)(tagp.tagname_end - tagp.tagname); - mfp = (struct match_found *)alloc( - (int)sizeof(struct match_found) + len); + mfp = xmalloc(sizeof(struct match_found) + len); mfp->len = len + 1; /* include the NUL */ p = mfp->match; vim_strncpy(p, tagp.tagname, len); @@ -1879,8 +1865,7 @@ parse_line: */ len = (int)STRLEN(tag_fname) + (int)STRLEN(lbuf) + 3; - mfp = (struct match_found *)alloc( - (int)sizeof(struct match_found) + len); + mfp = xmalloc(sizeof(struct match_found) + len); mfp->len = len; p = mfp->match; p[0] = mtt; @@ -2099,8 +2084,6 @@ get_tagfname ( * the value without notifying us. */ tnp->tn_tags = vim_strsave((*curbuf->b_p_tags != NUL) ? curbuf->b_p_tags : p_tags); - if (tnp->tn_tags == NULL) - return FAIL; tnp->tn_np = tnp->tn_tags; } @@ -2335,19 +2318,13 @@ parse_match ( /* * Find out the actual file name of a tag. Concatenate the tags file name * with the matching tag file name. - * Returns an allocated string or NULL (out of memory). + * Returns an allocated string. */ static char_u *tag_full_fname(tagptrs_T *tagp) { - char_u *fullname; - int c; - - { - c = *tagp->fname_end; - *tagp->fname_end = NUL; - } - fullname = expand_tag_fname(tagp->fname, tagp->tag_fname, FALSE); - + int c = *tagp->fname_end; + *tagp->fname_end = NUL; + char_u *fullname = expand_tag_fname(tagp->fname, tagp->tag_fname, FALSE); *tagp->fname_end = c; return fullname; @@ -2384,7 +2361,7 @@ jumpto_tag ( char_u *full_fname = NULL; int old_KeyTyped = KeyTyped; /* getting the file may reset it */ - pbuf = alloc(LSIZE); + pbuf = xmalloc(LSIZE); /* parse the match line into the tagp structure */ if (parse_match(lbuf, &tagp) == FAIL) { @@ -2420,8 +2397,6 @@ jumpto_tag ( * If 'tagrelative' option set, may change file name. */ fname = expand_tag_fname(fname, tagp.tag_fname, TRUE); - if (fname == NULL) - goto erret; tofree_fname = fname; /* free() it later */ /* @@ -2435,8 +2410,6 @@ jumpto_tag ( retval = NOTAGFILE; free(nofile_fname); nofile_fname = vim_strsave(fname); - if (nofile_fname == NULL) - nofile_fname = empty_option; goto erret; } @@ -2653,12 +2626,11 @@ erret: * If "expand" is TRUE, expand wildcards in fname. * If 'tagrelative' option set, change fname (name of file containing tag) * according to tag_fname (name of tag file containing fname). - * Returns a pointer to allocated memory (or NULL when out of memory). + * Returns a pointer to allocated memory. */ static char_u *expand_tag_fname(char_u *fname, char_u *tag_fname, int expand) { char_u *p; - char_u *retval; char_u *expanded_fname = NULL; expand_T xpc; @@ -2674,10 +2646,11 @@ static char_u *expand_tag_fname(char_u *fname, char_u *tag_fname, int expand) fname = expanded_fname; } + char_u *retval; if ((p_tr || curbuf->b_help) && !vim_isAbsName(fname) && (p = path_tail(tag_fname)) != tag_fname) { - retval = alloc(MAXPATHL); + retval = xmalloc(MAXPATHL); STRCPY(retval, tag_fname); vim_strncpy(retval + (p - tag_fname), fname, MAXPATHL - (p - tag_fname) - 1); @@ -2711,10 +2684,8 @@ static int test_for_current(char_u *fname, char_u *fname_end, char_u *tag_fname, *fname_end = NUL; } fullname = expand_tag_fname(fname, tag_fname, TRUE); - if (fullname != NULL) { - retval = (path_full_compare(fullname, buf_ffname, TRUE) & kEqualFiles); - free(fullname); - } + retval = (path_full_compare(fullname, buf_ffname, TRUE) & kEqualFiles); + free(fullname); *fname_end = c; } @@ -2816,7 +2787,6 @@ add_tag_field ( char_u *end /* after the value; can be NULL */ ) { - char_u *buf; int len = 0; int retval; @@ -2829,7 +2799,7 @@ add_tag_field ( } return FAIL; } - buf = alloc(MAXPATHL); + char_u *buf = xmalloc(MAXPATHL); if (start != NULL) { if (end == NULL) { end = start + STRLEN(start); diff --git a/src/nvim/term.c b/src/nvim/term.c index 7a44b52f36..073ed30052 100644 --- a/src/nvim/term.c +++ b/src/nvim/term.c @@ -1198,15 +1198,13 @@ static void parse_builtin_tcap(char_u *term) char_u *s, *t; s = vim_strsave((char_u *)p->bt_string); - if (s != NULL) { - for (t = s; *t; ++t) - if (term_7to8bit(t)) { - *t = term_7to8bit(t); - STRCPY(t + 1, t + 2); - } - term_strings[p->bt_entry] = s; - set_term_option_alloced(&term_strings[p->bt_entry]); - } + for (t = s; *t; ++t) + if (term_7to8bit(t)) { + *t = term_7to8bit(t); + STRCPY(t + 1, t + 2); + } + term_strings[p->bt_entry] = s; + set_term_option_alloced(&term_strings[p->bt_entry]); } else term_strings[p->bt_entry] = (char_u *)p->bt_string; } @@ -2970,8 +2968,6 @@ void add_termcode(char_u *name, char_u *string, int flags) } s = vim_strsave(string); - if (s == NULL) - return; /* Change leading <Esc>[ to CSI, change <Esc>O to <M-O>. */ if (flags != 0 && flags != ATC_FROM_TERM && term_7to8bit(string) != 0) { @@ -2987,8 +2983,7 @@ void add_termcode(char_u *name, char_u *string, int flags) */ if (tc_len == tc_max_len) { tc_max_len += 20; - new_tc = (struct termcode *)alloc( - (unsigned)(tc_max_len * sizeof(struct termcode))); + new_tc = xmalloc(tc_max_len * sizeof(struct termcode)); for (i = 0; i < tc_len; ++i) new_tc[i] = termcodes[i]; free(termcodes); @@ -4174,7 +4169,7 @@ replace_termcodes ( * Allocate space for the translation. Worst case a single character is * replaced by 6 bytes (shifted special key), plus a NUL at the end. */ - result = alloc((unsigned)STRLEN(from) * 6 + 1); + result = xmalloc(STRLEN(from) * 6 + 1); src = from; @@ -4309,14 +4304,9 @@ replace_termcodes ( } result[dlen] = NUL; - /* - * Copy the new string to allocated memory. - * If this fails, just return from. - */ - if ((*bufp = vim_strsave(result)) != NULL) - from = *bufp; - free(result); - return from; + *bufp = xrealloc(result, dlen + 1); + + return *bufp; } /* @@ -4380,7 +4370,7 @@ void show_termcodes(void) if (tc_len == 0) /* no terminal codes (must be GUI) */ return; - items = (int *)alloc((unsigned)(sizeof(int) * tc_len)); + items = xmalloc(sizeof(int) * tc_len); /* Highlight title */ MSG_PUTS_TITLE(_("\n--- Terminal keys ---")); diff --git a/src/nvim/ui.c b/src/nvim/ui.c index a1254ea04f..6d27822bc0 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -272,12 +272,10 @@ int vim_is_input_buf_empty(void) */ char_u *get_input_buf(void) { - garray_T *gap; - /* We use a growarray to store the data pointer and the length. */ - gap = (garray_T *)alloc((unsigned)sizeof(garray_T)); + garray_T *gap = xmalloc(sizeof(garray_T)); /* Add one to avoid a zero size. */ - gap->ga_data = alloc((unsigned)inbufcount + 1); + gap->ga_data = xmalloc(inbufcount + 1); if (gap->ga_data != NULL) memmove(gap->ga_data, inbuf, (size_t)inbufcount); gap->ga_len = inbufcount; diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 844ade790f..805dfa547c 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -594,10 +594,7 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) u_freeentry(uep, i); return FAIL; } - if ((uep->ue_array[i] = u_save_line(lnum++)) == NULL) { - u_freeentry(uep, i); - goto nomem; - } + uep->ue_array[i] = u_save_line(lnum++); } } else uep->ue_array = NULL; @@ -610,16 +607,6 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) u_check(FALSE); #endif return OK; - -nomem: - msg_silent = 0; /* must display the prompt */ - if (ask_yesno((char_u *)_("No undo possible; continue anyway"), TRUE) - == 'y') { - undo_off = TRUE; /* will be reset when character typed */ - return OK; - } - do_outofmem_msg((long_u)0); - return FAIL; } @@ -695,8 +682,6 @@ char_u *u_get_undo_file_name(char_u *buf_ffname, int reading) /* Use same directory as the ffname, * "dir/name" -> "dir/.name.un~" */ undo_file_name = vim_strnsave(ffname, (int)(STRLEN(ffname) + 5)); - if (undo_file_name == NULL) - break; p = path_tail(undo_file_name); memmove(p + 1, p, STRLEN(p) + 1); *p = '.'; @@ -706,8 +691,6 @@ char_u *u_get_undo_file_name(char_u *buf_ffname, int reading) if (os_isdir(dir_name)) { if (munged_name == NULL) { munged_name = vim_strsave(ffname); - if (munged_name == NULL) - return NULL; for (p = munged_name; *p != NUL; mb_ptr_adv(p)) if (vim_ispathsep(*p)) *p = '%'; @@ -2034,8 +2017,7 @@ static void u_undoredo(int undo) /* delete backwards, it goes faster in most cases */ for (lnum = bot - 1, i = oldsize; --i >= 0; --lnum) { /* what can we do when we run out of memory? */ - if ((newarray[i] = u_save_line(lnum)) == NULL) - do_outofmem_msg((long_u)0); + newarray[i] = u_save_line(lnum); /* remember we deleted the last line in the buffer, and a * dummy empty line will be inserted */ if (curbuf->b_ml.ml_line_count == 1) @@ -2666,8 +2648,7 @@ void u_saveline(linenr_T lnum) curbuf->b_u_line_colnr = curwin->w_cursor.col; else curbuf->b_u_line_colnr = 0; - if ((curbuf->b_u_line_ptr = u_save_line(lnum)) == NULL) - do_outofmem_msg((long_u)0); + curbuf->b_u_line_ptr = u_save_line(lnum); } /* @@ -2708,10 +2689,6 @@ void u_undoline(void) curbuf->b_u_line_lnum + 1, (linenr_T)0, FALSE) == FAIL) return; oldp = u_save_line(curbuf->b_u_line_lnum); - if (oldp == NULL) { - do_outofmem_msg((long_u)0); - return; - } ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, TRUE); changed_bytes(curbuf->b_u_line_lnum, 0); free(curbuf->b_u_line_ptr); @@ -2737,7 +2714,6 @@ void u_blockfree(buf_T *buf) /* * u_save_line(): allocate memory and copy line 'lnum' into it. - * Returns NULL when out of memory. */ static char_u *u_save_line(linenr_T lnum) { diff --git a/src/nvim/window.c b/src/nvim/window.c index 8270ccc7ea..534805b766 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -6,6 +6,7 @@ * See README.txt for an overview of the Vim source code. */ +#include "nvim/api/private/handle.h" #include "nvim/vim.h" #include "nvim/window.h" #include "nvim/buffer.h" @@ -2844,6 +2845,7 @@ void win_init_size(void) static tabpage_T *alloc_tabpage(void) { tabpage_T *tp = xcalloc(1, sizeof(tabpage_T)); + handle_register_tabpage(tp); /* init t: variables */ tp->tp_vars = dict_alloc(); @@ -2858,6 +2860,7 @@ void free_tabpage(tabpage_T *tp) { int idx; + handle_unregister_tabpage(tp); diff_clear(tp); for (idx = 0; idx < SNAP_COUNT; ++idx) clear_snapshot(tp, idx); @@ -3568,6 +3571,7 @@ static win_T *win_alloc(win_T *after, int hidden) * allocate window structure and linesizes arrays */ win_T *new_wp = xcalloc(1, sizeof(win_T)); + handle_register_window(new_wp); win_alloc_lines(new_wp); /* init w: variables */ @@ -3583,6 +3587,7 @@ static win_T *win_alloc(win_T *after, int hidden) */ if (!hidden) win_append(after, new_wp); + new_wp->w_wincol = 0; new_wp->w_width = Columns; @@ -3618,6 +3623,7 @@ win_free ( buf_T *buf; wininfo_T *wip; + handle_unregister_window(wp); clearFolding(wp); /* reduce the reference count to the argument list. */ @@ -5263,7 +5269,7 @@ int match_add(win_T *wp, char_u *grp, char_u *pat, int prio, int id) } /* Build new match. */ - m = (matchitem_T *)alloc(sizeof(matchitem_T)); + m = xmalloc(sizeof(matchitem_T)); m->id = id; m->priority = prio; m->pattern = vim_strsave(pat); |