aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/main.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-29 21:52:58 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-29 21:52:58 +0000
commit931bffbda3668ddc609fc1da8f9eb576b170aa52 (patch)
treed8c1843a95da5ea0bb4acc09f7e37843d9995c86 /src/nvim/main.c
parent142d9041391780ac15b89886a54015fdc5c73995 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-userreg.tar.gz
rneovim-userreg.tar.bz2
rneovim-userreg.zip
Merge remote-tracking branch 'upstream/master' into userreguserreg
Diffstat (limited to 'src/nvim/main.c')
-rw-r--r--src/nvim/main.c332
1 files changed, 188 insertions, 144 deletions
diff --git a/src/nvim/main.c b/src/nvim/main.c
index bbe877356d..6585bd1df7 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -1,7 +1,9 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
-#define EXTERN
+// Make sure extern symbols are exported on Windows
+#ifdef WIN32
+# define EXTERN __declspec(dllexport)
+#else
+# define EXTERN
+#endif
#include <assert.h>
#include <limits.h>
#include <msgpack/pack.h>
@@ -10,10 +12,18 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifdef ENABLE_ASAN_UBSAN
+# include <sanitizer/asan_interface.h>
+# include <sanitizer/ubsan_interface.h>
+#endif
-#include "auto/config.h"
+#include "auto/config.h" // IWYU pragma: keep
+#include "nvim/api/extmark.h"
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/ui.h"
#include "nvim/arglist.h"
-#include "nvim/ascii.h"
+#include "nvim/ascii_defs.h"
#include "nvim/autocmd.h"
#include "nvim/buffer.h"
#include "nvim/buffer_defs.h"
@@ -24,14 +34,17 @@
#include "nvim/drawscreen.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
-#include "nvim/eval/typval_defs.h"
+#include "nvim/eval/userfunc.h"
+#include "nvim/event/loop.h"
#include "nvim/event/multiqueue.h"
+#include "nvim/event/process.h"
#include "nvim/event/stream.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/func_attr.h"
#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/gettext.h"
@@ -41,60 +54,52 @@
#include "nvim/highlight.h"
#include "nvim/highlight_group.h"
#include "nvim/keycodes.h"
-#include "nvim/locale.h"
#include "nvim/log.h"
#include "nvim/lua/executor.h"
-#include "nvim/macros.h"
+#include "nvim/lua/secure.h"
+#include "nvim/macros_defs.h"
#include "nvim/main.h"
#include "nvim/mark.h"
-#include "nvim/memfile_defs.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/mouse.h"
#include "nvim/move.h"
+#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/msgpack_rpc/helpers.h"
+#include "nvim/msgpack_rpc/server.h"
#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
-#include "nvim/option_defs.h"
+#include "nvim/option_vars.h"
#include "nvim/optionstr.h"
#include "nvim/os/fileio.h"
+#include "nvim/os/fs.h"
#include "nvim/os/input.h"
+#include "nvim/os/lang.h"
#include "nvim/os/os.h"
+#include "nvim/os/signal.h"
#include "nvim/os/stdpaths_defs.h"
-#include "nvim/os/time.h"
#include "nvim/path.h"
#include "nvim/popupmenu.h"
-#include "nvim/pos.h"
#include "nvim/profile.h"
#include "nvim/quickfix.h"
#include "nvim/runtime.h"
#include "nvim/shada.h"
-#include "nvim/sign.h"
#include "nvim/statusline.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/terminal.h"
-#include "nvim/types.h"
+#include "nvim/types_defs.h"
#include "nvim/ui.h"
#include "nvim/ui_client.h"
#include "nvim/ui_compositor.h"
#include "nvim/version.h"
-#include "nvim/vim.h"
+#include "nvim/vim_defs.h"
#include "nvim/window.h"
#ifdef MSWIN
# include "nvim/os/os_win_console.h"
#endif
-#include "nvim/api/extmark.h"
-#include "nvim/api/private/defs.h"
-#include "nvim/api/private/helpers.h"
-#include "nvim/api/ui.h"
-#include "nvim/event/loop.h"
-#include "nvim/event/process.h"
-#include "nvim/msgpack_rpc/channel.h"
-#include "nvim/msgpack_rpc/helpers.h"
-#include "nvim/msgpack_rpc/server.h"
-#include "nvim/os/signal.h"
// values for "window_layout"
enum {
@@ -167,10 +172,9 @@ bool event_teardown(void)
/// Performs early initialization.
///
-/// Needed for unit tests. Must be called after `time_init()`.
+/// Needed for unit tests.
void early_init(mparm_T *paramp)
{
- env_init();
estack_init();
cmdline_init();
eval_init(); // init global variables
@@ -182,19 +186,24 @@ void early_init(mparm_T *paramp)
#ifdef MSWIN
OSVERSIONINFO ovi;
ovi.dwOSVersionInfoSize = sizeof(ovi);
+ // Disable warning about GetVersionExA being deprecated. There doesn't seem to be a convenient
+ // replacement that doesn't add a ton of extra code as of writing this.
+# ifdef _MSC_VER
+# pragma warning(suppress : 4996)
+ GetVersionEx(&ovi);
+# else
GetVersionEx(&ovi);
+# endif
snprintf(windowsVersion, sizeof(windowsVersion), "%d.%d",
(int)ovi.dwMajorVersion, (int)ovi.dwMinorVersion);
#endif
TIME_MSG("early init");
-#if defined(HAVE_LOCALE_H)
// Setup to use the current locale (for ctype() and many other things).
// NOTE: Translated messages with encodings other than latin1 will not
// work until set_init_1() has been called!
init_locale();
-#endif
// tabpage local options (p_ch) must be set before allocating first tabpage.
set_init_tablocal();
@@ -214,8 +223,6 @@ void early_init(mparm_T *paramp)
TIME_MSG("inits 1");
set_lang_var(); // set v:lang and v:ctype
-
- init_signs();
}
#ifdef MAKE_LIB
@@ -239,20 +246,28 @@ int main(int argc, char **argv)
argv0 = argv[0];
+ if (!appname_is_valid()) {
+ os_errmsg("$NVIM_APPNAME must be a name or relative path.\n");
+ exit(1);
+ }
+
+ if (argc > 1 && STRICMP(argv[1], "-ll") == 0) {
+ if (argc == 2) {
+ print_mainerr(err_arg_missing, argv[1]);
+ exit(1);
+ }
+ nlua_run_script(argv, argc, 3);
+ }
+
char *fname = NULL; // file name from command line
mparm_T params; // various parameters passed between
// main() and other functions.
char *cwd = NULL; // current working dir on startup
- time_init();
// Many variables are in `params` so that we can pass them around easily.
// `argc` and `argv` are also copied, so that they can be changed.
init_params(&params, argc, argv);
- // Since os_open is called during the init_startuptime, we need to call
- // fs_init before it.
- fs_init();
-
init_startuptime(&params);
// Need to find "--clean" before actually parsing arguments.
@@ -286,6 +301,16 @@ int main(int argc, char **argv)
}
}
+ if (GARGCOUNT > 0) {
+ fname = get_fname(&params, cwd);
+ }
+
+ // Recovery mode without a file name: List swap files.
+ // In this case, no UI is needed.
+ if (recoverymode && fname == NULL) {
+ headless_mode = true;
+ }
+
#ifdef MSWIN
// on windows we use CONIN special file, thus we don't know this yet.
bool has_term = true;
@@ -312,21 +337,11 @@ int main(int argc, char **argv)
uint64_t rv = ui_client_start_server(params.argc, params.argv);
if (!rv) {
os_errmsg("Failed to start Nvim server!\n");
- getout(1);
+ os_exit(1);
}
ui_client_channel_id = rv;
}
- if (GARGCOUNT > 0) {
- fname = get_fname(&params, cwd);
- }
-
- // Recovery mode without a file name: List swap files.
- // In this case, no UI is needed.
- if (recoverymode && fname == NULL) {
- headless_mode = true;
- }
-
TIME_MSG("expanding arguments");
if (params.diff_mode && params.window_count == -1) {
@@ -335,7 +350,7 @@ int main(int argc, char **argv)
// Don't redraw until much later.
RedrawingDisabled++;
- setbuf(stdout, NULL);
+ setbuf(stdout, NULL); // NOLINT(bugprone-unsafe-functions)
full_screen = !silent_mode;
@@ -348,7 +363,7 @@ int main(int argc, char **argv)
}
assert(p_ch >= 0 && Rows >= p_ch && Rows - p_ch <= INT_MAX);
- cmdline_row = (int)(Rows - p_ch);
+ cmdline_row = Rows - (int)p_ch;
msg_row = cmdline_row;
default_grid_alloc(); // allocate screen buffers
set_init_2(headless_mode);
@@ -372,13 +387,15 @@ int main(int argc, char **argv)
if (ui_client_channel_id) {
ui_client_run(remote_ui); // NORETURN
}
+ assert(!ui_client_channel_id && !use_builtin_ui);
// Wait for UIs to set up Nvim or show early messages
// and prompts (--cmd, swapfile dialog, …).
bool use_remote_ui = (embedded_mode && !headless_mode);
+ bool listen_and_embed = params.listen_addr != NULL;
if (use_remote_ui) {
TIME_MSG("waiting for UI");
- remote_ui_wait_for_attach();
+ remote_ui_wait_for_attach(!listen_and_embed);
TIME_MSG("done waiting for UI");
firstwin->w_prev_height = firstwin->w_height; // may have changed
}
@@ -396,19 +413,9 @@ int main(int argc, char **argv)
open_script_files(&params);
- // Default mappings (incl. menus)
- Error err = ERROR_INIT;
- Object o = NLUA_EXEC_STATIC("return vim._init_default_mappings()",
- (Array)ARRAY_DICT_INIT, &err);
- assert(!ERROR_SET(&err));
- api_clear_error(&err);
- assert(o.type == kObjectTypeNil);
- api_free_object(o);
-
- TIME_MSG("init default mappings");
+ nlua_init_defaults();
- init_default_autocmds();
- TIME_MSG("init default autocommands");
+ TIME_MSG("init default mappings & autocommands");
bool vimrc_none = strequal(params.use_vimrc, "NONE");
@@ -432,8 +439,7 @@ int main(int argc, char **argv)
// If using the runtime (-u is not NONE), enable syntax & filetype plugins.
if (!vimrc_none || params.clean) {
- // Sources filetype.lua and filetype.vim unless the user explicitly disabled it with :filetype
- // off.
+ // Sources filetype.lua unless the user explicitly disabled it with :filetype off.
filetype_maybe_enable();
// Sources syntax/syntax.vim. We do this *after* the user startup scripts so that users can
// disable syntax highlighting with `:syntax off` if they wish.
@@ -449,7 +455,7 @@ int main(int argc, char **argv)
// Recovery mode without a file name: List swap files.
// Uses the 'dir' option, therefore it must be after the initializations.
if (recoverymode && fname == NULL) {
- recover_names(NULL, true, 0, NULL);
+ recover_names(NULL, true, NULL, 0, NULL);
os_exit(0);
}
@@ -572,16 +578,16 @@ int main(int argc, char **argv)
// 'autochdir' has been postponed.
do_autochdir();
- set_vim_var_nr(VV_VIM_DID_ENTER, 1L);
+ set_vim_var_nr(VV_VIM_DID_ENTER, 1);
apply_autocmds(EVENT_VIMENTER, NULL, NULL, false, curbuf);
TIME_MSG("VimEnter autocommands");
- if (use_remote_ui || use_builtin_ui) {
- do_autocmd_uienter(use_remote_ui ? CHAN_STDIO : 0, true);
+ if (use_remote_ui) {
+ do_autocmd_uienter_all();
TIME_MSG("UIEnter autocommands");
}
#ifdef MSWIN
- if (use_builtin_ui) {
+ if (use_remote_ui) {
os_icon_init();
}
os_title_save();
@@ -597,7 +603,7 @@ int main(int argc, char **argv)
// scrollbind, sync the scrollbind now.
if (curwin->w_p_diff && curwin->w_p_scb) {
update_topline(curwin);
- check_scrollbind((linenr_T)0, 0L);
+ check_scrollbind(0, 0);
TIME_MSG("diff scrollbinding");
}
@@ -613,8 +619,14 @@ int main(int argc, char **argv)
}
if (params.luaf != NULL) {
+ // Like "--cmd", "+", "-c" and "-S", don't truncate messages.
+ msg_scroll = true;
bool lua_ok = nlua_exec_file(params.luaf);
TIME_MSG("executing Lua -l script");
+ if (msg_didout) {
+ msg_putchar('\n');
+ msg_didout = false;
+ }
getout(lua_ok ? 0 : 1);
}
@@ -637,6 +649,9 @@ void os_exit(int r)
if (ui_client_channel_id) {
ui_client_stop();
+ if (r == 0) {
+ r = ui_client_exit_status;
+ }
} else {
ui_flush();
ui_call_stop();
@@ -663,6 +678,7 @@ void os_exit(int r)
void getout(int exitval)
FUNC_ATTR_NORETURN
{
+ assert(!ui_client_channel_id);
exiting = true;
// On error during Ex mode, exit with a non-zero code.
@@ -673,8 +689,8 @@ void getout(int exitval)
set_vim_var_nr(VV_EXITING, exitval);
- // Position the cursor on the last screen line, below all the text
- ui_cursor_goto(Rows - 1, 0);
+ // Invoked all deferred functions in the function stack.
+ invoke_all_defer();
// Optionally print hashtable efficiency.
hash_debug_results();
@@ -686,7 +702,7 @@ void getout(int exitval)
for (const tabpage_T *tp = first_tabpage; tp != NULL; tp = next_tp) {
next_tp = tp->tp_next;
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
- if (wp->w_buffer == NULL) {
+ if (wp->w_buffer == NULL || !buf_valid(wp->w_buffer)) {
// Autocmd must have close the buffer already, skip.
continue;
}
@@ -761,9 +777,6 @@ void getout(int exitval)
wait_return(false);
}
- // Position the cursor again, the autocommands may have moved it
- ui_cursor_goto(Rows - 1, 0);
-
// Apply 'titleold'.
if (p_title && *p_titleold != NUL) {
ui_call_set_title(cstr_as_string(p_titleold));
@@ -782,10 +795,11 @@ void getout(int exitval)
os_exit(exitval);
}
-/// Preserve files, print contents of `IObuff`, and exit 1.
+/// Preserve files, print contents of `errmsg`, and exit 1.
+/// @param errmsg If NULL, this function will not print anything.
///
/// May be called from deadly_signal().
-void preserve_exit(void)
+void preserve_exit(const char *errmsg)
FUNC_ATTR_NORETURN
{
// 'true' when we are sure to exit, e.g., after a deadly signal
@@ -803,16 +817,26 @@ void preserve_exit(void)
really_exiting = true;
// Ignore SIGHUP while we are already exiting. #9274
signal_reject_deadly();
- os_errmsg(IObuff);
- os_errmsg("\n");
- ui_flush();
+
+ if (ui_client_channel_id) {
+ // For TUI: exit alternate screen so that the error messages can be seen.
+ ui_client_stop();
+ }
+ if (errmsg != NULL) {
+ os_errmsg(errmsg);
+ os_errmsg("\n");
+ }
+ if (ui_client_channel_id) {
+ os_exit(1);
+ }
ml_close_notmod(); // close all not-modified buffers
FOR_ALL_BUFFERS(buf) {
if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL) {
- os_errmsg("Vim: preserving files...\r\n");
- ui_flush();
+ if (errmsg != NULL) {
+ os_errmsg("Vim: preserving files...\r\n");
+ }
ml_sync_all(false, false, true); // preserve all swap files
break;
}
@@ -820,7 +844,9 @@ void preserve_exit(void)
ml_close_all(false); // close all memfiles, without deleting
- os_errmsg("Vim: Finished.\r\n");
+ if (errmsg != NULL) {
+ os_errmsg("Vim: Finished.\r\n");
+ }
getout(1);
}
@@ -840,7 +866,7 @@ void preserve_exit(void)
static int get_number_arg(const char *p, int *idx, int def)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
- if (ascii_isdigit(p[*idx])) { // -V522
+ if (ascii_isdigit(p[*idx])) {
def = atoi(&(p[*idx]));
while (ascii_isdigit(p[*idx])) {
*idx = *idx + 1;
@@ -888,6 +914,11 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr,
os_errmsg(connect_error);
os_errmsg("\n");
os_exit(1);
+ } else if (strequal(server_addr, os_getenv("NVIM"))) {
+ os_errmsg("Cannot attach UI of :terminal child to its parent. ");
+ os_errmsg("(Unset $NVIM to skip this check)");
+ os_errmsg("\n");
+ os_exit(1);
}
ui_client_channel_id = chan;
@@ -895,9 +926,8 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr,
}
Array args = ARRAY_DICT_INIT;
- String arg_s;
for (int t_argc = remote_args; t_argc < argc; t_argc++) {
- arg_s = cstr_to_string(argv[t_argc]);
+ String arg_s = cstr_to_string(argv[t_argc]);
ADD(args, STRING_OBJ(arg_s));
}
@@ -927,7 +957,7 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr,
TriState tabbed = kNone;
for (size_t i = 0; i < rvobj.data.dictionary.size; i++) {
- if (strcmp(rvobj.data.dictionary.items[i].key.data, "errmsg") == 0) {
+ if (strequal(rvobj.data.dictionary.items[i].key.data, "errmsg")) {
if (rvobj.data.dictionary.items[i].value.type != kObjectTypeString) {
os_errmsg("vim._cs_remote returned an unexpected type for 'errmsg'\n");
os_exit(2);
@@ -935,13 +965,19 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr,
os_errmsg(rvobj.data.dictionary.items[i].value.data.string.data);
os_errmsg("\n");
os_exit(2);
- } else if (strcmp(rvobj.data.dictionary.items[i].key.data, "tabbed") == 0) {
+ } else if (strequal(rvobj.data.dictionary.items[i].key.data, "result")) {
+ if (rvobj.data.dictionary.items[i].value.type != kObjectTypeString) {
+ os_errmsg("vim._cs_remote returned an unexpected type for 'result'\n");
+ os_exit(2);
+ }
+ os_msg(rvobj.data.dictionary.items[i].value.data.string.data);
+ } else if (strequal(rvobj.data.dictionary.items[i].key.data, "tabbed")) {
if (rvobj.data.dictionary.items[i].value.type != kObjectTypeBoolean) {
os_errmsg("vim._cs_remote returned an unexpected type for 'tabbed'\n");
os_exit(2);
}
tabbed = rvobj.data.dictionary.items[i].value.data.boolean ? kTrue : kFalse;
- } else if (strcmp(rvobj.data.dictionary.items[i].key.data, "should_exit") == 0) {
+ } else if (strequal(rvobj.data.dictionary.items[i].key.data, "should_exit")) {
if (rvobj.data.dictionary.items[i].value.type != kObjectTypeBoolean) {
os_errmsg("vim._cs_remote returned an unexpected type for 'should_exit'\n");
os_exit(2);
@@ -984,7 +1020,7 @@ static void command_line_scan(mparm_T *parmp)
int argv_idx; // index in argv[n][]
bool had_minmin = false; // found "--" argument
int want_argument; // option argument with argument
- long n;
+ int n;
argc--;
argv++;
@@ -1035,6 +1071,10 @@ static void command_line_scan(mparm_T *parmp)
version();
os_exit(0);
} else if (STRICMP(argv[0] + argv_idx, "api-info") == 0) {
+#ifdef MSWIN
+ // set stdout to binary to avoid crlf in --api-info output
+ _setmode(STDOUT_FILENO, _O_BINARY);
+#endif
FileDescriptor fp;
const int fof_ret = file_open_fd(&fp, STDOUT_FILENO,
kFileWriteOnly);
@@ -1082,7 +1122,7 @@ static void command_line_scan(mparm_T *parmp)
} else if (STRNICMP(argv[0] + argv_idx, "clean", 5) == 0) {
parmp->use_vimrc = "NONE";
parmp->clean = true;
- set_option_value_give_err("shadafile", 0L, "NONE", 0);
+ set_option_value_give_err("shadafile", STATIC_CSTR_AS_OPTVAL("NONE"), 0);
} else if (STRNICMP(argv[0] + argv_idx, "luamod-dev", 9) == 0) {
nlua_disable_preload = true;
} else {
@@ -1096,7 +1136,7 @@ static void command_line_scan(mparm_T *parmp)
}
break;
case 'A': // "-A" start in Arabic mode.
- set_option_value_give_err("arabic", 1L, NULL, 0);
+ set_option_value_give_err("arabic", BOOLEAN_OPTVAL(true), 0);
break;
case 'b': // "-b" binary mode.
// Needs to be effective before expanding file names, because
@@ -1125,9 +1165,9 @@ static void command_line_scan(mparm_T *parmp)
case 'h': // "-h" give help message
usage();
os_exit(0);
- case 'H': // "-H" start in Hebrew mode: rl + hkmap set.
- p_hkmap = true;
- set_option_value_give_err("rl", 1L, NULL, 0);
+ case 'H': // "-H" start in Hebrew mode: rl + keymap=hebrew set.
+ set_option_value_give_err("keymap", STATIC_CSTR_AS_OPTVAL("hebrew"), 0);
+ set_option_value_give_err("rl", BOOLEAN_OPTVAL(true), 0);
break;
case 'M': // "-M" no changes or writing of files
reset_modifiable();
@@ -1207,7 +1247,7 @@ static void command_line_scan(mparm_T *parmp)
// default is 10: a little bit verbose
p_verbose = get_number_arg(argv[0], &argv_idx, 10);
if (argv[0][argv_idx] != NUL) {
- set_option_value_give_err("verbosefile", 0L, argv[0] + argv_idx, 0);
+ set_option_value_give_err("verbosefile", CSTR_AS_OPTVAL(argv[0] + argv_idx), 0);
argv_idx = (int)strlen(argv[0]);
}
break;
@@ -1215,7 +1255,7 @@ static void command_line_scan(mparm_T *parmp)
// "-w {scriptout}" write to script
if (ascii_isdigit((argv[0])[argv_idx])) {
n = get_number_arg(argv[0], &argv_idx, 10);
- set_option_value_give_err("window", n, NULL, 0);
+ set_option_value_give_err("window", NUMBER_OPTVAL((OptInt)n), 0);
break;
}
want_argument = true;
@@ -1311,7 +1351,7 @@ static void command_line_scan(mparm_T *parmp)
break;
case 'i': // "-i {shada}" use for shada
- set_option_value_give_err("shadafile", 0L, argv[0], 0);
+ set_option_value_give_err("shadafile", CSTR_AS_OPTVAL(argv[0]), 0);
break;
case 'l': // "-l" Lua script: args after "-l".
@@ -1321,11 +1361,11 @@ static void command_line_scan(mparm_T *parmp)
parmp->no_swap_file = true;
parmp->use_vimrc = parmp->use_vimrc ? parmp->use_vimrc : "NONE";
if (p_shadafile == NULL || *p_shadafile == NUL) {
- set_option_value_give_err("shadafile", 0L, "NONE", 0);
+ set_option_value_give_err("shadafile", STATIC_CSTR_AS_OPTVAL("NONE"), 0);
}
parmp->luaf = argv[0];
argc--;
- if (argc > 0) { // Lua args after "-l <file>".
+ if (argc >= 0) { // Lua args after "-l <file>".
parmp->lua_arg0 = parmp->argc - argc;
argc = 0;
}
@@ -1357,7 +1397,7 @@ scripterror:
if (ascii_isdigit(*(argv[0]))) {
argv_idx = 0;
n = get_number_arg(argv[0], &argv_idx, 10);
- set_option_value_give_err("window", n, NULL, 0);
+ set_option_value_give_err("window", NUMBER_OPTVAL((OptInt)n), 0);
argv_idx = -1;
break;
}
@@ -1448,7 +1488,7 @@ static void init_startuptime(mparm_T *paramp)
{
for (int i = 1; i < paramp->argc - 1; i++) {
if (STRICMP(paramp->argv[i], "--startuptime") == 0) {
- time_fd = os_fopen(paramp->argv[i + 1], "a");
+ time_fd = fopen(paramp->argv[i + 1], "a");
time_start("--- NVIM STARTING ---");
break;
}
@@ -1532,6 +1572,7 @@ static void handle_tag(char *tagname)
// If the user doesn't want to edit the file then we quit here.
if (swap_exists_did_quit) {
+ ui_call_error_exit(1);
getout(1);
}
}
@@ -1570,7 +1611,7 @@ static void open_script_files(mparm_T *parmp)
scriptin[0] = file_open_new(&error, parmp->scriptin,
kFileReadOnly|kFileNonBlocking, 0);
if (scriptin[0] == NULL) {
- vim_snprintf((char *)IObuff, IOSIZE,
+ vim_snprintf(IObuff, IOSIZE,
_("Cannot open for reading: \"%s\": %s\n"),
parmp->scriptin, os_strerror(error));
os_errmsg(IObuff);
@@ -1595,9 +1636,6 @@ static void open_script_files(mparm_T *parmp)
// Also does recovery if "recoverymode" set.
static void create_windows(mparm_T *parmp)
{
- int dorewind;
- int done = 0;
-
// Create the number of windows that was requested.
if (parmp->window_count == -1) { // was not set
parmp->window_count = 1;
@@ -1633,6 +1671,7 @@ static void create_windows(mparm_T *parmp)
}
do_modelines(0); // do modelines
} else {
+ int done = 0;
// Open a buffer for windows that don't have one yet.
// Commands in the vimrc might have loaded a file or split the window.
// Watch out for autocommands that delete a window.
@@ -1640,7 +1679,7 @@ static void create_windows(mparm_T *parmp)
// Don't execute Win/Buf Enter/Leave autocommands here
autocmd_no_enter++;
autocmd_no_leave++;
- dorewind = true;
+ int dorewind = true;
while (done++ < 1000) {
if (dorewind) {
if (parmp->window_layout == WIN_TABS) {
@@ -1677,6 +1716,7 @@ static void create_windows(mparm_T *parmp)
if (got_int || only_one_window()) {
// abort selected or quit and only one window
did_emsg = false; // avoid hit-enter prompt
+ ui_call_error_exit(1);
getout(1);
}
// We can't close the window, it would disturb what
@@ -1712,7 +1752,6 @@ static void create_windows(mparm_T *parmp)
static void edit_buffers(mparm_T *parmp, char *cwd)
{
int arg_idx; // index in argument list
- int i;
bool advance = true;
win_T *win;
char *p_shm_save = NULL;
@@ -1728,7 +1767,7 @@ static void edit_buffers(mparm_T *parmp, char *cwd)
}
arg_idx = 1;
- for (i = 1; i < parmp->window_count; i++) {
+ for (int i = 1; i < parmp->window_count; i++) {
if (cwd != NULL) {
os_chdir(cwd);
}
@@ -1754,7 +1793,7 @@ static void edit_buffers(mparm_T *parmp, char *cwd)
p_shm_save = xstrdup(p_shm);
snprintf(buf, sizeof(buf), "F%s", p_shm);
- set_option_value_give_err("shm", 0L, buf, 0);
+ set_option_value_give_err("shm", CSTR_AS_OPTVAL(buf), 0);
}
} else {
if (curwin->w_next == NULL) { // just checking
@@ -1780,6 +1819,7 @@ static void edit_buffers(mparm_T *parmp, char *cwd)
if (got_int || only_one_window()) {
// abort selected and only one window
did_emsg = false; // avoid hit-enter prompt
+ ui_call_error_exit(1);
getout(1);
}
win_close(curwin, true, false);
@@ -1798,7 +1838,7 @@ static void edit_buffers(mparm_T *parmp, char *cwd)
}
if (p_shm_save != NULL) {
- set_option_value_give_err("shm", 0L, p_shm_save, 0);
+ set_option_value_give_err("shm", CSTR_AS_OPTVAL(p_shm_save), 0);
xfree(p_shm_save);
}
@@ -1831,7 +1871,6 @@ static void exe_pre_commands(mparm_T *parmp)
{
char **cmds = parmp->pre_commands;
int cnt = parmp->n_pre_commands;
- int i;
if (cnt <= 0) {
return;
@@ -1840,7 +1879,7 @@ static void exe_pre_commands(mparm_T *parmp)
curwin->w_cursor.lnum = 0; // just in case..
estack_push(ETYPE_ARGS, _("pre-vimrc command line"), 0);
current_sctx.sc_sid = SID_CMDARG;
- for (i = 0; i < cnt; i++) {
+ for (int i = 0; i < cnt; i++) {
do_cmdline_cmd(cmds[i]);
}
estack_pop();
@@ -1851,8 +1890,6 @@ static void exe_pre_commands(mparm_T *parmp)
// Execute "+", "-c" and "-S" arguments.
static void exe_commands(mparm_T *parmp)
{
- int i;
-
// We start commands on line 0, make "vim +/pat file" match a
// pattern on line 1. But don't move the cursor when an autocommand
// with g`" was used.
@@ -1863,7 +1900,7 @@ static void exe_commands(mparm_T *parmp)
estack_push(ETYPE_ARGS, "command line", 0);
current_sctx.sc_sid = SID_CARG;
current_sctx.sc_seq = 0;
- for (i = 0; i < parmp->n_commands; i++) {
+ for (int i = 0; i < parmp->n_commands; i++) {
do_cmdline_cmd(parmp->commands[i]);
if (parmp->cmds_tofree[i]) {
xfree(parmp->commands[i]);
@@ -1915,7 +1952,7 @@ static void do_system_initialization(void)
dir_len += 1;
}
memcpy(vimrc + dir_len, path_tail, sizeof(path_tail));
- if (do_source(vimrc, false, DOSO_NONE) != FAIL) {
+ if (do_source(vimrc, false, DOSO_NONE, NULL) != FAIL) {
xfree(vimrc);
xfree(config_dirs);
return;
@@ -1927,7 +1964,7 @@ static void do_system_initialization(void)
#ifdef SYS_VIMRC_FILE
// Get system wide defaults, if the file name is defined.
- (void)do_source(SYS_VIMRC_FILE, false, DOSO_NONE);
+ (void)do_source(SYS_VIMRC_FILE, false, DOSO_NONE, NULL);
#endif
}
@@ -1956,7 +1993,7 @@ static bool do_user_initialization(void)
// init.lua
if (os_path_exists(init_lua_path)
- && do_source(init_lua_path, true, DOSO_VIMRC)) {
+ && do_source(init_lua_path, true, DOSO_VIMRC, NULL)) {
if (os_path_exists(user_vimrc)) {
semsg(_("E5422: Conflicting configs: \"%s\" \"%s\""), init_lua_path,
user_vimrc);
@@ -1970,7 +2007,7 @@ static bool do_user_initialization(void)
xfree(init_lua_path);
// init.vim
- if (do_source(user_vimrc, true, DOSO_VIMRC) != FAIL) {
+ if (do_source(user_vimrc, true, DOSO_VIMRC, NULL) != FAIL) {
do_exrc = p_exrc;
if (do_exrc) {
do_exrc = (path_full_compare(VIMRC_FILE, user_vimrc, false, true) != kEqualFiles);
@@ -1996,7 +2033,7 @@ static bool do_user_initialization(void)
memmove(vimrc, dir, dir_len);
vimrc[dir_len] = PATHSEP;
memmove(vimrc + dir_len + 1, path_tail, sizeof(path_tail));
- if (do_source(vimrc, true, DOSO_VIMRC) != FAIL) {
+ if (do_source(vimrc, true, DOSO_VIMRC, NULL) != FAIL) {
do_exrc = p_exrc;
if (do_exrc) {
do_exrc = (path_full_compare(VIMRC_FILE, vimrc, false, true) != kEqualFiles);
@@ -2062,7 +2099,7 @@ static void source_startup_scripts(const mparm_T *const parmp)
|| strequal(parmp->use_vimrc, "NORC")) {
// Do nothing.
} else {
- if (do_source(parmp->use_vimrc, false, DOSO_NONE) != OK) {
+ if (do_source(parmp->use_vimrc, false, DOSO_NONE, NULL) != OK) {
semsg(_("E282: Cannot read from \"%s\""), parmp->use_vimrc);
}
}
@@ -2095,7 +2132,7 @@ static int execute_env(char *env)
current_sctx.sc_sid = SID_ENV;
current_sctx.sc_seq = 0;
current_sctx.sc_lnum = 0;
- do_cmdline_cmd((char *)initstr);
+ do_cmdline_cmd(initstr);
estack_pop();
current_sctx = save_current_sctx;
@@ -2111,6 +2148,12 @@ static int execute_env(char *env)
static void mainerr(const char *errstr, const char *str)
FUNC_ATTR_NORETURN
{
+ print_mainerr(errstr, str);
+ os_exit(1);
+}
+
+static void print_mainerr(const char *errstr, const char *str)
+{
char *prgname = path_tail(argv0);
signal_stop(); // kill us with CTRL-C here, if you like
@@ -2120,14 +2163,12 @@ static void mainerr(const char *errstr, const char *str)
os_errmsg(_(errstr));
if (str != NULL) {
os_errmsg(": \"");
- os_errmsg((char *)str);
+ os_errmsg(str);
os_errmsg("\"");
}
os_errmsg(_("\nMore info with \""));
os_errmsg(prgname);
os_errmsg(" -h\"\n");
-
- os_exit(1);
}
/// Prints version information for "nvim -v" or "nvim --version".
@@ -2147,43 +2188,33 @@ static void usage(void)
signal_stop(); // kill us with CTRL-C here, if you like
os_msg(_("Usage:\n"));
- os_msg(_(" nvim [options] [file ...] Edit file(s)\n"));
- os_msg(_(" nvim [options] -t <tag> Edit file where tag is defined\n"));
- os_msg(_(" nvim [options] -q [errorfile] Edit file with first error\n"));
+ os_msg(_(" nvim [options] [file ...]\n"));
os_msg(_("\nOptions:\n"));
- os_msg(_(" -- Only file names after this\n"));
- os_msg(_(" + Start at end of file\n"));
os_msg(_(" --cmd <cmd> Execute <cmd> before any config\n"));
os_msg(_(" +<cmd>, -c <cmd> Execute <cmd> after config and first file\n"));
os_msg(_(" -l <script> [args...] Execute Lua <script> (with optional args)\n"));
+ os_msg(_(" -S <session> Source <session> after loading the first file\n"));
+ os_msg(_(" -s <scriptin> Read Normal mode commands from <scriptin>\n"));
+ os_msg(_(" -u <config> Use this config file\n"));
os_msg("\n");
- os_msg(_(" -b Binary mode\n"));
os_msg(_(" -d Diff mode\n"));
- os_msg(_(" -e, -E Ex mode\n"));
os_msg(_(" -es, -Es Silent (batch) mode\n"));
os_msg(_(" -h, --help Print this help message\n"));
os_msg(_(" -i <shada> Use this shada file\n"));
- os_msg(_(" -m Modifications (writing files) not allowed\n"));
- os_msg(_(" -M Modifications in text not allowed\n"));
os_msg(_(" -n No swap file, use memory only\n"));
os_msg(_(" -o[N] Open N windows (default: one per file)\n"));
os_msg(_(" -O[N] Open N vertical windows (default: one per file)\n"));
os_msg(_(" -p[N] Open N tab pages (default: one per file)\n"));
- os_msg(_(" -r, -L List swap files\n"));
- os_msg(_(" -r <file> Recover edit state for this file\n"));
- os_msg(_(" -R Read-only mode\n"));
- os_msg(_(" -S <session> Source <session> after loading the first file\n"));
- os_msg(_(" -s <scriptin> Read Normal mode commands from <scriptin>\n"));
- os_msg(_(" -u <config> Use this config file\n"));
+ os_msg(_(" -R Read-only (view) mode\n"));
os_msg(_(" -v, --version Print version information\n"));
os_msg(_(" -V[N][file] Verbose [level][file]\n"));
os_msg("\n");
+ os_msg(_(" -- Only file names after this\n"));
os_msg(_(" --api-info Write msgpack-encoded API metadata to stdout\n"));
os_msg(_(" --clean \"Factory defaults\" (skip user config and plugins, shada)\n"));
os_msg(_(" --embed Use stdin/stdout as a msgpack-rpc channel\n"));
os_msg(_(" --headless Don't start a user interface\n"));
os_msg(_(" --listen <address> Serve RPC API from this address\n"));
- os_msg(_(" --noplugin Don't load plugins\n"));
os_msg(_(" --remote[-subcommand] Execute commands remotely on a server\n"));
os_msg(_(" --server <address> Specify RPC server to send commands to\n"));
os_msg(_(" --startuptime <file> Write startup timing messages to <file>\n"));
@@ -2196,7 +2227,20 @@ static void usage(void)
static void check_swap_exists_action(void)
{
if (swap_exists_action == SEA_QUIT) {
+ ui_call_error_exit(1);
getout(1);
}
handle_swap_exists(NULL);
}
+
+#ifdef ENABLE_ASAN_UBSAN
+const char *__ubsan_default_options(void)
+{
+ return "print_stacktrace=1";
+}
+
+const char *__asan_default_options(void)
+{
+ return "handle_abort=1,handle_sigill=1";
+}
+#endif