aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/nvim/CMakeLists.txt25
-rw-r--r--src/nvim/charset.c2
-rw-r--r--src/nvim/cmdexpand.c2
-rw-r--r--src/nvim/eval.c2
-rw-r--r--src/nvim/eval/decode.c4
-rw-r--r--src/nvim/fileio.c10
-rw-r--r--src/nvim/generators/gen_ex_cmds.lua2
-rw-r--r--src/nvim/locale.c377
-rw-r--r--src/nvim/locale.h10
-rw-r--r--src/nvim/lua/treesitter.c6
-rw-r--r--src/nvim/main.c4
-rw-r--r--src/nvim/mbyte.c10
-rw-r--r--src/nvim/msgpack_rpc/helpers.c8
-rw-r--r--src/nvim/option.c1
-rw-r--r--src/nvim/os/lang.c343
-rw-r--r--src/nvim/os/lang.h3
-rw-r--r--src/nvim/os/os_defs.h5
-rw-r--r--src/nvim/os/shell.c4
-rw-r--r--src/nvim/os/users.c10
-rw-r--r--src/nvim/tui/tui.c17
20 files changed, 371 insertions, 474 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 8c23b501f9..10f44c428c 100755
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -87,14 +87,14 @@ if(MSVC)
target_sources(main_lib INTERFACE ${CMAKE_CURRENT_LIST_DIR}/os/nvim.manifest)
else()
target_compile_options(main_lib INTERFACE -Wall -Wextra -pedantic -Wno-unused-parameter
- -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion
+ -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wvla
-Wdouble-promotion
-Wmissing-noreturn
-Wmissing-format-attribute
-Wmissing-prototypes)
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
- target_compile_options(main_lib INTERFACE
+ target_compile_options(main_lib INTERFACE -fno-common
$<$<CONFIG:Release>:-Wno-unused-result>
$<$<CONFIG:RelWithDebInfo>:-Wno-unused-result>
$<$<CONFIG:MinSizeRel>:-Wno-unused-result>)
@@ -144,17 +144,6 @@ if(WIN32)
target_compile_definitions(main_lib INTERFACE _WIN32_WINNT=0x0602 MSWIN)
endif()
-# OpenBSD's GCC (4.2.1) doesn't have -Wvla
-check_c_compiler_flag(-Wvla HAS_WVLA_FLAG)
-if(HAS_WVLA_FLAG)
- target_compile_options(main_lib INTERFACE -Wvla)
-endif()
-
-check_c_compiler_flag(-fno-common HAVE_FNO_COMMON)
-if (HAVE_FNO_COMMON)
- target_compile_options(main_lib INTERFACE -fno-common)
-endif()
-
check_c_compiler_flag(-fdiagnostics-color=auto HAS_DIAG_COLOR_FLAG)
if(HAS_DIAG_COLOR_FLAG)
if(CMAKE_GENERATOR MATCHES "Ninja")
@@ -240,13 +229,15 @@ endif()
if(UNIX)
# -fstack-protector breaks non Unix builds even in Mingw-w64
check_c_compiler_flag(-fstack-protector-strong HAS_FSTACK_PROTECTOR_STRONG_FLAG)
- check_c_compiler_flag(-fstack-protector HAS_FSTACK_PROTECTOR_FLAG)
if(HAS_FSTACK_PROTECTOR_STRONG_FLAG)
target_compile_options(main_lib INTERFACE -fstack-protector-strong)
target_link_libraries(main_lib INTERFACE -fstack-protector-strong)
- elseif(HAS_FSTACK_PROTECTOR_FLAG)
- target_compile_options(main_lib INTERFACE -fstack-protector --param ssp-buffer-size=4)
- target_link_libraries(main_lib INTERFACE -fstack-protector --param ssp-buffer-size=4)
+ else()
+ check_c_compiler_flag(-fstack-protector HAS_FSTACK_PROTECTOR_FLAG)
+ if(HAS_FSTACK_PROTECTOR_FLAG)
+ target_compile_options(main_lib INTERFACE -fstack-protector --param ssp-buffer-size=4)
+ target_link_libraries(main_lib INTERFACE -fstack-protector --param ssp-buffer-size=4)
+ endif()
endif()
endif()
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 1cfb5350f3..bf18d110c0 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -1446,7 +1446,7 @@ long getdigits_long(char **pp, bool strict, long def)
int32_t getdigits_int32(char **pp, bool strict, long def)
{
intmax_t number = getdigits(pp, strict, def);
-#if SIZEOF_INTMAX_T > SIZEOF_INT32_T
+#if SIZEOF_INTMAX_T > 4
if (strict) {
assert(number >= INT32_MIN && number <= INT32_MAX);
} else if (!(number >= INT32_MIN && number <= INT32_MAX)) {
diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c
index fcd6a73b2d..18d35e1e20 100644
--- a/src/nvim/cmdexpand.c
+++ b/src/nvim/cmdexpand.c
@@ -40,7 +40,6 @@
#include "nvim/highlight_defs.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"
@@ -50,6 +49,7 @@
#include "nvim/menu.h"
#include "nvim/message.h"
#include "nvim/option.h"
+#include "nvim/os/lang.h"
#include "nvim/os/os.h"
#include "nvim/path.h"
#include "nvim/popupmenu.h"
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 0fbf31a8cd..da2a88346a 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -45,7 +45,6 @@
#include "nvim/insexpand.h"
#include "nvim/keycodes.h"
#include "nvim/lib/queue.h"
-#include "nvim/locale.h"
#include "nvim/lua/executor.h"
#include "nvim/macros.h"
#include "nvim/main.h"
@@ -62,6 +61,7 @@
#include "nvim/optionstr.h"
#include "nvim/os/fileio.h"
#include "nvim/os/fs_defs.h"
+#include "nvim/os/lang.h"
#include "nvim/os/os.h"
#include "nvim/os/shell.h"
#include "nvim/os/stdpaths_defs.h"
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c
index cd1479f150..f57d06c83b 100644
--- a/src/nvim/eval/decode.c
+++ b/src/nvim/eval/decode.c
@@ -987,12 +987,8 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
}
break;
-#ifdef NVIM_MSGPACK_HAS_FLOAT32
case MSGPACK_OBJECT_FLOAT32:
case MSGPACK_OBJECT_FLOAT64:
-#else
- case MSGPACK_OBJECT_FLOAT:
-#endif
*rettv = (typval_T) {
.v_type = VAR_FLOAT,
.v_lock = VAR_UNLOCKED,
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 755b8e0834..c93df43cff 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -68,7 +68,7 @@
# include "nvim/charset.h"
#endif
-#if defined(HAVE_FLOCK) && defined(HAVE_DIRFD)
+#ifdef HAVE_DIRFD_AND_FLOCK
# include <dirent.h>
# include <sys/file.h>
#endif
@@ -5146,7 +5146,7 @@ void forward_slash(char *fname)
/// Path to Nvim's own temp dir. Ends in a slash.
static char *vim_tempdir = NULL;
-#if defined(HAVE_FLOCK) && defined(HAVE_DIRFD)
+#ifdef HAVE_DIRFD_AND_FLOCK
DIR *vim_tempdir_dp = NULL; ///< File descriptor of temp dir
#endif
@@ -5316,7 +5316,7 @@ int delete_recursive(const char *name)
return result;
}
-#if defined(HAVE_FLOCK) && defined(HAVE_DIRFD)
+#ifdef HAVE_DIRFD_AND_FLOCK
/// Open temporary directory and take file lock to prevent
/// to be auto-cleaned.
static void vim_opentempdir(void)
@@ -5353,7 +5353,7 @@ void vim_deltempdir(void)
return;
}
-#if defined(HAVE_FLOCK) && defined(HAVE_DIRFD)
+#ifdef HAVE_DIRFD_AND_FLOCK
vim_closetempdir();
#endif
// remove the trailing path separator
@@ -5391,7 +5391,7 @@ static bool vim_settempdir(char *tempdir)
vim_FullName(tempdir, buf, MAXPATHL, false);
add_pathsep(buf);
vim_tempdir = xstrdup(buf);
-#if defined(HAVE_FLOCK) && defined(HAVE_DIRFD)
+#ifdef HAVE_DIRFD_AND_FLOCK
vim_opentempdir();
#endif
xfree(buf);
diff --git a/src/nvim/generators/gen_ex_cmds.lua b/src/nvim/generators/gen_ex_cmds.lua
index 0c1051b04e..935d7b333e 100644
--- a/src/nvim/generators/gen_ex_cmds.lua
+++ b/src/nvim/generators/gen_ex_cmds.lua
@@ -66,7 +66,6 @@ defsfile:write(string.format([[
#include "nvim/ex_session.h"
#include "nvim/help.h"
#include "nvim/indent.h"
-#include "nvim/locale.h"
#include "nvim/lua/executor.h"
#include "nvim/mapping.h"
#include "nvim/mark.h"
@@ -75,6 +74,7 @@ defsfile:write(string.format([[
#include "nvim/message.h"
#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/os/lang.h"
#include "nvim/profile.h"
#include "nvim/quickfix.h"
#include "nvim/runtime.h"
diff --git a/src/nvim/locale.c b/src/nvim/locale.c
deleted file mode 100644
index c3cfd3bedb..0000000000
--- a/src/nvim/locale.c
+++ /dev/null
@@ -1,377 +0,0 @@
-// 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
-
-// locale.c: functions for language/locale configuration
-
-#include <stdbool.h>
-#include <stdio.h>
-
-#include "auto/config.h"
-#ifdef HAVE_LOCALE_H
-# include <locale.h>
-#endif
-
-#include "nvim/ascii.h"
-#include "nvim/buffer.h"
-#include "nvim/charset.h"
-#include "nvim/eval.h"
-#include "nvim/ex_cmds_defs.h"
-#include "nvim/garray.h"
-#include "nvim/gettext.h"
-#include "nvim/locale.h"
-#include "nvim/macros.h"
-#include "nvim/memory.h"
-#include "nvim/message.h"
-#include "nvim/option.h"
-#include "nvim/os/os.h"
-#include "nvim/os/shell.h"
-#include "nvim/path.h"
-#include "nvim/profile.h"
-#include "nvim/types.h"
-#include "nvim/vim.h"
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "locale.c.generated.h"
-#endif
-
-#if defined(HAVE_LOCALE_H)
-# define HAVE_GET_LOCALE_VAL
-
-static char *get_locale_val(int what)
-{
- // Obtain the locale value from the libraries.
- char *loc = setlocale(what, NULL);
-
- return loc;
-}
-#endif
-
-/// @return true when "lang" starts with a valid language name.
-/// Rejects NULL, empty string, "C", "C.UTF-8" and others.
-static bool is_valid_mess_lang(const char *lang)
-{
- return lang != NULL && ASCII_ISALPHA(lang[0]) && ASCII_ISALPHA(lang[1]);
-}
-
-/// Obtain the current messages language. Used to set the default for
-/// 'helplang'. May return NULL or an empty string.
-char *get_mess_lang(void)
-{
- char *p;
-
-#ifdef HAVE_GET_LOCALE_VAL
-# if defined(LC_MESSAGES)
- p = get_locale_val(LC_MESSAGES);
-# else
- // This is necessary for Win32, where LC_MESSAGES is not defined and $LANG
- // may be set to the LCID number. LC_COLLATE is the best guess, LC_TIME
- // and LC_MONETARY may be set differently for a Japanese working in the
- // US.
- p = get_locale_val(LC_COLLATE);
-# endif
-#else
- p = os_getenv("LC_ALL");
- if (!is_valid_mess_lang(p)) {
- p = os_getenv("LC_MESSAGES");
- if (!is_valid_mess_lang(p)) {
- p = os_getenv("LANG");
- }
- }
-#endif
- return is_valid_mess_lang(p) ? p : NULL;
-}
-
-// Complicated #if; matches with where get_mess_env() is used below.
-#ifdef HAVE_WORKING_LIBINTL
-/// Get the language used for messages from the environment.
-static char *get_mess_env(void)
-{
- char *p;
-
- p = (char *)os_getenv("LC_ALL");
- if (p == NULL) {
- p = (char *)os_getenv("LC_MESSAGES");
- if (p == NULL) {
- p = (char *)os_getenv("LANG");
- if (p != NULL && ascii_isdigit(*p)) {
- p = NULL; // ignore something like "1043"
- }
-# ifdef HAVE_GET_LOCALE_VAL
- if (p == NULL) {
- p = get_locale_val(LC_CTYPE);
- }
-# endif
- }
- }
- return p;
-}
-#endif
-
-/// Set the "v:lang" variable according to the current locale setting.
-/// Also do "v:lc_time"and "v:ctype".
-void set_lang_var(void)
-{
- const char *loc;
-
-#ifdef HAVE_GET_LOCALE_VAL
- loc = get_locale_val(LC_CTYPE);
-#else
- // setlocale() not supported: use the default value
- loc = "C";
-#endif
- set_vim_var_string(VV_CTYPE, loc, -1);
-
- // When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall
- // back to LC_CTYPE if it's empty.
-#ifdef HAVE_WORKING_LIBINTL
- loc = get_mess_env();
-#elif defined(LC_MESSAGES)
- loc = get_locale_val(LC_MESSAGES);
-#else
- // In Windows LC_MESSAGES is not defined fallback to LC_CTYPE
- loc = get_locale_val(LC_CTYPE);
-#endif
- set_vim_var_string(VV_LANG, loc, -1);
-
-#ifdef HAVE_GET_LOCALE_VAL
- loc = get_locale_val(LC_TIME);
-#endif
- set_vim_var_string(VV_LC_TIME, loc, -1);
-
-#ifdef HAVE_GET_LOCALE_VAL
- loc = get_locale_val(LC_COLLATE);
-#else
- // setlocale() not supported: use the default value
- loc = "C";
-#endif
- set_vim_var_string(VV_COLLATE, loc, -1);
-}
-
-#if defined(HAVE_LOCALE_H)
-/// Setup to use the current locale (for ctype() and many other things).
-void init_locale(void)
-{
- setlocale(LC_ALL, "");
-
-# ifdef LC_NUMERIC
- // Make sure strtod() uses a decimal point, not a comma.
- setlocale(LC_NUMERIC, "C");
-# endif
-
- char localepath[MAXPATHL] = { 0 };
- snprintf(localepath, sizeof(localepath), "%s", get_vim_var_str(VV_PROGPATH));
- char *tail = path_tail_with_sep(localepath);
- *tail = NUL;
- tail = path_tail(localepath);
- xstrlcpy(tail, "share/locale",
- sizeof(localepath) - (size_t)(tail - localepath));
- bindtextdomain(PROJECT_NAME, localepath);
- textdomain(PROJECT_NAME);
- TIME_MSG("locale set");
-}
-#endif
-
-#ifdef HAVE_WORKING_LIBINTL
-
-/// ":language": Set the language (locale).
-///
-/// @param eap
-void ex_language(exarg_T *eap)
-{
- char *loc;
- char *p;
- char *name;
- int what = LC_ALL;
- char *whatstr = "";
-# ifdef LC_MESSAGES
-# define VIM_LC_MESSAGES LC_MESSAGES
-# else
-# define VIM_LC_MESSAGES 6789
-# endif
-
- name = eap->arg;
-
- // Check for "messages {name}", "ctype {name}" or "time {name}" argument.
- // Allow abbreviation, but require at least 3 characters to avoid
- // confusion with a two letter language name "me" or "ct".
- p = skiptowhite(eap->arg);
- if ((*p == NUL || ascii_iswhite(*p)) && p - eap->arg >= 3) {
- if (STRNICMP(eap->arg, "messages", p - eap->arg) == 0) {
- what = VIM_LC_MESSAGES;
- name = skipwhite(p);
- whatstr = "messages ";
- } else if (STRNICMP(eap->arg, "ctype", p - eap->arg) == 0) {
- what = LC_CTYPE;
- name = skipwhite(p);
- whatstr = "ctype ";
- } else if (STRNICMP(eap->arg, "time", p - eap->arg) == 0) {
- what = LC_TIME;
- name = skipwhite(p);
- whatstr = "time ";
- } else if (STRNICMP(eap->arg, "collate", p - eap->arg) == 0) {
- what = LC_COLLATE;
- name = skipwhite(p);
- whatstr = "collate ";
- }
- }
-
- if (*name == NUL) {
- if (what == VIM_LC_MESSAGES) {
- p = get_mess_env();
- } else {
- p = setlocale(what, NULL);
- }
- if (p == NULL || *p == NUL) {
- p = "Unknown";
- }
- smsg(_("Current %slanguage: \"%s\""), whatstr, p);
- } else {
-# ifndef LC_MESSAGES
- if (what == VIM_LC_MESSAGES) {
- loc = "";
- } else {
-# endif
- loc = setlocale(what, name);
-# ifdef LC_NUMERIC
- // Make sure strtod() uses a decimal point, not a comma.
- setlocale(LC_NUMERIC, "C");
-# endif
-# ifndef LC_MESSAGES
- }
-# endif
- if (loc == NULL) {
- semsg(_("E197: Cannot set language to \"%s\""), name);
- } else {
-# ifdef HAVE_NL_MSG_CAT_CNTR
- // Need to do this for GNU gettext, otherwise cached translations
- // will be used again.
- extern int _nl_msg_cat_cntr;
-
- _nl_msg_cat_cntr++;
-# endif
- // Reset $LC_ALL, otherwise it would overrule everything.
- os_setenv("LC_ALL", "", 1);
-
- if (what != LC_TIME && what != LC_COLLATE) {
- // Tell gettext() what to translate to. It apparently doesn't
- // use the currently effective locale.
- if (what == LC_ALL) {
- os_setenv("LANG", name, 1);
-
- // Clear $LANGUAGE because GNU gettext uses it.
- os_setenv("LANGUAGE", "", 1);
- }
- if (what != LC_CTYPE) {
- os_setenv("LC_MESSAGES", name, 1);
- set_helplang_default(name);
- }
- }
-
- // Set v:lang, v:lc_time, v:collate and v:ctype to the final result.
- set_lang_var();
- maketitle();
- }
- }
-}
-
-static char **locales = NULL; // Array of all available locales
-
-# ifndef MSWIN
-static bool did_init_locales = false;
-
-/// @return an array of strings for all available locales + NULL for the
-/// last element or,
-/// NULL in case of error.
-static char **find_locales(void)
-{
- garray_T locales_ga;
- char *loc;
- char *saveptr = NULL;
-
- // Find all available locales by running command "locale -a". If this
- // doesn't work we won't have completion.
- char *locale_a = get_cmd_output("locale -a", NULL, kShellOptSilent, NULL);
- if (locale_a == NULL) {
- return NULL;
- }
- ga_init(&locales_ga, sizeof(char *), 20);
-
- // Transform locale_a string where each locale is separated by "\n"
- // into an array of locale strings.
- loc = os_strtok(locale_a, "\n", &saveptr);
-
- while (loc != NULL) {
- loc = xstrdup(loc);
- GA_APPEND(char *, &locales_ga, loc);
- loc = os_strtok(NULL, "\n", &saveptr);
- }
- xfree(locale_a);
- // Guarantee that .ga_data is NULL terminated
- ga_grow(&locales_ga, 1);
- ((char **)locales_ga.ga_data)[locales_ga.ga_len] = NULL;
- return locales_ga.ga_data;
-}
-# endif
-
-/// Lazy initialization of all available locales.
-static void init_locales(void)
-{
-# ifndef MSWIN
- if (did_init_locales) {
- return;
- }
-
- did_init_locales = true;
- locales = find_locales();
-# endif
-}
-
-# if defined(EXITFREE)
-void free_locales(void)
-{
- if (locales == NULL) {
- return;
- }
-
- for (int i = 0; locales[i] != NULL; i++) {
- xfree(locales[i]);
- }
- XFREE_CLEAR(locales);
-}
-# endif
-
-/// Function given to ExpandGeneric() to obtain the possible arguments of the
-/// ":language" command.
-char *get_lang_arg(expand_T *xp, int idx)
-{
- if (idx == 0) {
- return "messages";
- }
- if (idx == 1) {
- return "ctype";
- }
- if (idx == 2) {
- return "time";
- }
- if (idx == 3) {
- return "collate";
- }
-
- init_locales();
- if (locales == NULL) {
- return NULL;
- }
- return locales[idx - 4];
-}
-
-/// Function given to ExpandGeneric() to obtain the available locales.
-char *get_locales(expand_T *xp, int idx)
-{
- init_locales();
- if (locales == NULL) {
- return NULL;
- }
- return locales[idx];
-}
-
-#endif
diff --git a/src/nvim/locale.h b/src/nvim/locale.h
deleted file mode 100644
index 39735d371f..0000000000
--- a/src/nvim/locale.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef NVIM_LOCALE_H
-#define NVIM_LOCALE_H
-
-#include "nvim/ex_cmds_defs.h"
-#include "nvim/types.h"
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "locale.h.generated.h"
-#endif
-#endif // NVIM_LOCALE_H
diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c
index d72e7a1825..2db12b8ded 100644
--- a/src/nvim/lua/treesitter.c
+++ b/src/nvim/lua/treesitter.c
@@ -152,9 +152,7 @@ void tslua_init(lua_State *L)
build_meta(L, TS_META_QUERYCURSOR, querycursor_meta);
build_meta(L, TS_META_TREECURSOR, treecursor_meta);
-#ifdef NVIM_TS_HAS_SET_ALLOCATOR
ts_set_allocator(xmalloc, xcalloc, xrealloc, xfree);
-#endif
}
int tslua_has_language(lua_State *L)
@@ -1321,11 +1319,7 @@ static int node_rawquery(lua_State *L)
} else {
cursor = ts_query_cursor_new();
}
- // TODO(clason): API introduced after tree-sitter release 0.19.5
- // remove guard when minimum ts version is bumped to 0.19.6+
-#ifdef NVIM_TS_HAS_SET_MATCH_LIMIT
ts_query_cursor_set_match_limit(cursor, 64);
-#endif
ts_query_cursor_exec(cursor, query, node);
bool captures = lua_toboolean(L, 3);
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 975772169b..71c5c2af46 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -41,7 +41,6 @@
#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"
@@ -60,6 +59,7 @@
#include "nvim/optionstr.h"
#include "nvim/os/fileio.h"
#include "nvim/os/input.h"
+#include "nvim/os/lang.h"
#include "nvim/os/os.h"
#include "nvim/os/stdpaths_defs.h"
#include "nvim/os/time.h"
@@ -192,12 +192,10 @@ void early_init(mparm_T *paramp)
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();
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index e27bb003e7..d8be4f4997 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -29,6 +29,7 @@
#include <ctype.h>
#include <errno.h>
#include <iconv.h>
+#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -67,10 +68,6 @@
#include "nvim/types.h"
#include "nvim/vim.h"
-#ifdef HAVE_LOCALE_H
-# include <locale.h>
-#endif
-
typedef struct {
int rangeStart;
int rangeEnd;
@@ -2193,10 +2190,7 @@ char *enc_locale(void)
if (!(s = nl_langinfo(CODESET)) || *s == NUL)
#endif
{
-#if defined(HAVE_LOCALE_H)
- if (!(s = setlocale(LC_CTYPE, NULL)) || *s == NUL)
-#endif
- {
+ if (!(s = setlocale(LC_CTYPE, NULL)) || *s == NUL) {
if ((s = os_getenv("LC_ALL"))) {
if ((s = os_getenv("LC_CTYPE"))) {
s = os_getenv("LANG");
diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c
index 5f0f03dd69..d1fd28f882 100644
--- a/src/nvim/msgpack_rpc/helpers.c
+++ b/src/nvim/msgpack_rpc/helpers.c
@@ -84,12 +84,8 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
*cur.aobj = INTEGER_OBJ((Integer)cur.mobj->via.u64);
}
break;
-#ifdef NVIM_MSGPACK_HAS_FLOAT32
case MSGPACK_OBJECT_FLOAT32:
case MSGPACK_OBJECT_FLOAT64:
-#else
- case MSGPACK_OBJECT_FLOAT:
-#endif
{
STATIC_ASSERT(sizeof(Float) == sizeof(cur.mobj->via.f64),
"Msgpack floating-point size does not match API integer");
@@ -156,12 +152,8 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
case MSGPACK_OBJECT_BOOLEAN:
case MSGPACK_OBJECT_POSITIVE_INTEGER:
case MSGPACK_OBJECT_NEGATIVE_INTEGER:
-#ifdef NVIM_MSGPACK_HAS_FLOAT32
case MSGPACK_OBJECT_FLOAT32:
case MSGPACK_OBJECT_FLOAT64:
-#else
- case MSGPACK_OBJECT_FLOAT:
-#endif
case MSGPACK_OBJECT_EXT:
case MSGPACK_OBJECT_MAP:
case MSGPACK_OBJECT_ARRAY:
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 0303f0bccd..6ddc3b5cfb 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -62,7 +62,6 @@
#include "nvim/indent_c.h"
#include "nvim/insexpand.h"
#include "nvim/keycodes.h"
-#include "nvim/locale.h"
#include "nvim/log.h"
#include "nvim/lua/executor.h"
#include "nvim/macros.h"
diff --git a/src/nvim/os/lang.c b/src/nvim/os/lang.c
index 57c82bba86..8ca2aa3a4b 100644
--- a/src/nvim/os/lang.c
+++ b/src/nvim/os/lang.c
@@ -7,16 +7,347 @@
# include <CoreServices/CoreServices.h>
# undef Boolean
# undef FileInfo
+#endif
-# include "auto/config.h"
-# ifdef HAVE_LOCALE_H
-# include <locale.h>
-# endif
-# include "nvim/os/os.h"
+#include <locale.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include "auto/config.h"
+#include "nvim/ascii.h"
+#include "nvim/buffer.h"
+#include "nvim/charset.h"
+#include "nvim/eval.h"
+#include "nvim/ex_cmds_defs.h"
+#include "nvim/garray.h"
+#include "nvim/gettext.h"
+#include "nvim/macros.h"
+#include "nvim/memory.h"
+#include "nvim/message.h"
+#include "nvim/option.h"
+#include "nvim/os/lang.h"
+#include "nvim/os/os.h"
+#include "nvim/os/shell.h"
+#include "nvim/path.h"
+#include "nvim/profile.h"
+#include "nvim/types.h"
+#include "nvim/vim.h"
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "os/lang.c.generated.h"
#endif
-#include "nvim/os/lang.h"
+static char *get_locale_val(int what)
+{
+ // Obtain the locale value from the libraries.
+ char *loc = setlocale(what, NULL);
+
+ return loc;
+}
+
+/// @return true when "lang" starts with a valid language name.
+/// Rejects NULL, empty string, "C", "C.UTF-8" and others.
+static bool is_valid_mess_lang(const char *lang)
+{
+ return lang != NULL && ASCII_ISALPHA(lang[0]) && ASCII_ISALPHA(lang[1]);
+}
+
+/// Obtain the current messages language. Used to set the default for
+/// 'helplang'. May return NULL or an empty string.
+char *get_mess_lang(void)
+{
+ char *p;
+
+#if defined(LC_MESSAGES)
+ p = get_locale_val(LC_MESSAGES);
+#else
+ // This is necessary for Win32, where LC_MESSAGES is not defined and $LANG
+ // may be set to the LCID number. LC_COLLATE is the best guess, LC_TIME
+ // and LC_MONETARY may be set differently for a Japanese working in the
+ // US.
+ p = get_locale_val(LC_COLLATE);
+#endif
+ return is_valid_mess_lang(p) ? p : NULL;
+}
+
+// Complicated #if; matches with where get_mess_env() is used below.
+#ifdef HAVE_WORKING_LIBINTL
+/// Get the language used for messages from the environment.
+static char *get_mess_env(void)
+{
+ char *p;
+
+ p = (char *)os_getenv("LC_ALL");
+ if (p == NULL) {
+ p = (char *)os_getenv("LC_MESSAGES");
+ if (p == NULL) {
+ p = (char *)os_getenv("LANG");
+ if (p != NULL && ascii_isdigit(*p)) {
+ p = NULL; // ignore something like "1043"
+ }
+ if (p == NULL) {
+ p = get_locale_val(LC_CTYPE);
+ }
+ }
+ }
+ return p;
+}
+#endif
+
+/// Set the "v:lang" variable according to the current locale setting.
+/// Also do "v:lc_time"and "v:ctype".
+void set_lang_var(void)
+{
+ const char *loc;
+
+ loc = get_locale_val(LC_CTYPE);
+ set_vim_var_string(VV_CTYPE, loc, -1);
+
+ // When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall
+ // back to LC_CTYPE if it's empty.
+#ifdef HAVE_WORKING_LIBINTL
+ loc = get_mess_env();
+#elif defined(LC_MESSAGES)
+ loc = get_locale_val(LC_MESSAGES);
+#else
+ // In Windows LC_MESSAGES is not defined fallback to LC_CTYPE
+ loc = get_locale_val(LC_CTYPE);
+#endif
+ set_vim_var_string(VV_LANG, loc, -1);
+
+ loc = get_locale_val(LC_TIME);
+ set_vim_var_string(VV_LC_TIME, loc, -1);
+
+ loc = get_locale_val(LC_COLLATE);
+ set_vim_var_string(VV_COLLATE, loc, -1);
+}
+
+/// Setup to use the current locale (for ctype() and many other things).
+void init_locale(void)
+{
+ setlocale(LC_ALL, "");
+
+#ifdef LC_NUMERIC
+ // Make sure strtod() uses a decimal point, not a comma.
+ setlocale(LC_NUMERIC, "C");
+#endif
+
+ char localepath[MAXPATHL] = { 0 };
+ snprintf(localepath, sizeof(localepath), "%s", get_vim_var_str(VV_PROGPATH));
+ char *tail = path_tail_with_sep(localepath);
+ *tail = NUL;
+ tail = path_tail(localepath);
+ xstrlcpy(tail, "share/locale",
+ sizeof(localepath) - (size_t)(tail - localepath));
+ bindtextdomain(PROJECT_NAME, localepath);
+ textdomain(PROJECT_NAME);
+ TIME_MSG("locale set");
+}
+
+#ifdef HAVE_WORKING_LIBINTL
+
+/// ":language": Set the language (locale).
+///
+/// @param eap
+void ex_language(exarg_T *eap)
+{
+ char *loc;
+ char *p;
+ char *name;
+ int what = LC_ALL;
+ char *whatstr = "";
+# ifdef LC_MESSAGES
+# define VIM_LC_MESSAGES LC_MESSAGES
+# else
+# define VIM_LC_MESSAGES 6789
+# endif
+
+ name = eap->arg;
+
+ // Check for "messages {name}", "ctype {name}" or "time {name}" argument.
+ // Allow abbreviation, but require at least 3 characters to avoid
+ // confusion with a two letter language name "me" or "ct".
+ p = skiptowhite(eap->arg);
+ if ((*p == NUL || ascii_iswhite(*p)) && p - eap->arg >= 3) {
+ if (STRNICMP(eap->arg, "messages", p - eap->arg) == 0) {
+ what = VIM_LC_MESSAGES;
+ name = skipwhite(p);
+ whatstr = "messages ";
+ } else if (STRNICMP(eap->arg, "ctype", p - eap->arg) == 0) {
+ what = LC_CTYPE;
+ name = skipwhite(p);
+ whatstr = "ctype ";
+ } else if (STRNICMP(eap->arg, "time", p - eap->arg) == 0) {
+ what = LC_TIME;
+ name = skipwhite(p);
+ whatstr = "time ";
+ } else if (STRNICMP(eap->arg, "collate", p - eap->arg) == 0) {
+ what = LC_COLLATE;
+ name = skipwhite(p);
+ whatstr = "collate ";
+ }
+ }
+
+ if (*name == NUL) {
+ if (what == VIM_LC_MESSAGES) {
+ p = get_mess_env();
+ } else {
+ p = setlocale(what, NULL);
+ }
+ if (p == NULL || *p == NUL) {
+ p = "Unknown";
+ }
+ smsg(_("Current %slanguage: \"%s\""), whatstr, p);
+ } else {
+# ifndef LC_MESSAGES
+ if (what == VIM_LC_MESSAGES) {
+ loc = "";
+ } else {
+# endif
+ loc = setlocale(what, name);
+# ifdef LC_NUMERIC
+ // Make sure strtod() uses a decimal point, not a comma.
+ setlocale(LC_NUMERIC, "C");
+# endif
+# ifndef LC_MESSAGES
+ }
+# endif
+ if (loc == NULL) {
+ semsg(_("E197: Cannot set language to \"%s\""), name);
+ } else {
+# ifdef HAVE_NL_MSG_CAT_CNTR
+ // Need to do this for GNU gettext, otherwise cached translations
+ // will be used again.
+ extern int _nl_msg_cat_cntr;
+
+ _nl_msg_cat_cntr++;
+# endif
+ // Reset $LC_ALL, otherwise it would overrule everything.
+ os_setenv("LC_ALL", "", 1);
+
+ if (what != LC_TIME && what != LC_COLLATE) {
+ // Tell gettext() what to translate to. It apparently doesn't
+ // use the currently effective locale.
+ if (what == LC_ALL) {
+ os_setenv("LANG", name, 1);
+
+ // Clear $LANGUAGE because GNU gettext uses it.
+ os_setenv("LANGUAGE", "", 1);
+ }
+ if (what != LC_CTYPE) {
+ os_setenv("LC_MESSAGES", name, 1);
+ set_helplang_default(name);
+ }
+ }
+
+ // Set v:lang, v:lc_time, v:collate and v:ctype to the final result.
+ set_lang_var();
+ maketitle();
+ }
+ }
+}
+
+static char **locales = NULL; // Array of all available locales
+
+# ifndef MSWIN
+static bool did_init_locales = false;
+
+/// @return an array of strings for all available locales + NULL for the
+/// last element or,
+/// NULL in case of error.
+static char **find_locales(void)
+{
+ garray_T locales_ga;
+ char *loc;
+ char *saveptr = NULL;
+
+ // Find all available locales by running command "locale -a". If this
+ // doesn't work we won't have completion.
+ char *locale_a = get_cmd_output("locale -a", NULL, kShellOptSilent, NULL);
+ if (locale_a == NULL) {
+ return NULL;
+ }
+ ga_init(&locales_ga, sizeof(char *), 20);
+
+ // Transform locale_a string where each locale is separated by "\n"
+ // into an array of locale strings.
+ loc = os_strtok(locale_a, "\n", &saveptr);
+
+ while (loc != NULL) {
+ loc = xstrdup(loc);
+ GA_APPEND(char *, &locales_ga, loc);
+ loc = os_strtok(NULL, "\n", &saveptr);
+ }
+ xfree(locale_a);
+ // Guarantee that .ga_data is NULL terminated
+ ga_grow(&locales_ga, 1);
+ ((char **)locales_ga.ga_data)[locales_ga.ga_len] = NULL;
+ return locales_ga.ga_data;
+}
+# endif
+
+/// Lazy initialization of all available locales.
+static void init_locales(void)
+{
+# ifndef MSWIN
+ if (did_init_locales) {
+ return;
+ }
+
+ did_init_locales = true;
+ locales = find_locales();
+# endif
+}
+
+# if defined(EXITFREE)
+void free_locales(void)
+{
+ if (locales == NULL) {
+ return;
+ }
+
+ for (int i = 0; locales[i] != NULL; i++) {
+ xfree(locales[i]);
+ }
+ XFREE_CLEAR(locales);
+}
+# endif
+
+/// Function given to ExpandGeneric() to obtain the possible arguments of the
+/// ":language" command.
+char *get_lang_arg(expand_T *xp, int idx)
+{
+ if (idx == 0) {
+ return "messages";
+ }
+ if (idx == 1) {
+ return "ctype";
+ }
+ if (idx == 2) {
+ return "time";
+ }
+ if (idx == 3) {
+ return "collate";
+ }
+
+ init_locales();
+ if (locales == NULL) {
+ return NULL;
+ }
+ return locales[idx - 4];
+}
+
+/// Function given to ExpandGeneric() to obtain the available locales.
+char *get_locales(expand_T *xp, int idx)
+{
+ init_locales();
+ if (locales == NULL) {
+ return NULL;
+ }
+ return locales[idx];
+}
+
+#endif
void lang_init(void)
{
diff --git a/src/nvim/os/lang.h b/src/nvim/os/lang.h
index f60e064f57..bb1ebfb721 100644
--- a/src/nvim/os/lang.h
+++ b/src/nvim/os/lang.h
@@ -1,6 +1,9 @@
#ifndef NVIM_OS_LANG_H
#define NVIM_OS_LANG_H
+#include "nvim/ex_cmds_defs.h"
+#include "nvim/types.h"
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/lang.h.generated.h"
#endif
diff --git a/src/nvim/os/os_defs.h b/src/nvim/os/os_defs.h
index f86c0d3483..9e201f1dfa 100644
--- a/src/nvim/os/os_defs.h
+++ b/src/nvim/os/os_defs.h
@@ -36,10 +36,9 @@
// Command-processing buffer. Use large buffers for all platforms.
#define CMDBUFFSIZE 1024
-// Note: Some systems need both string.h and strings.h (Savage). However,
-// some systems can't handle both, only use string.h in that case.
+// Note: Some systems need both string.h and strings.h (Savage).
#include <string.h>
-#if defined(HAVE_STRINGS_H) && !defined(NO_STRINGS_WITH_STRING_H)
+#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index f1e2c5440f..f7d1154169 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -399,8 +399,8 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
fclose(fd);
return FAIL;
}
-#if SIZEOF_LONG_LONG > SIZEOF_SIZE_T
- assert(templen <= (long long)SIZE_MAX); // NOLINT(runtime/int)
+#if 8 > SIZEOF_SIZE_T
+ assert(templen <= SIZE_MAX); // NOLINT(runtime/int)
#endif
len = (size_t)templen;
fseek(fd, 0L, SEEK_SET);
diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c
index ef2986246b..411ba91fa7 100644
--- a/src/nvim/os/users.c
+++ b/src/nvim/os/users.c
@@ -15,7 +15,7 @@
#include "nvim/os/os.h"
#include "nvim/types.h"
#include "nvim/vim.h"
-#ifdef HAVE_PWD_H
+#ifdef HAVE_PWD_FUNCS
# include <pwd.h>
#endif
#ifdef MSWIN
@@ -50,7 +50,7 @@ int os_get_usernames(garray_T *users)
}
ga_init(users, sizeof(char *), 20);
-#if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H)
+#ifdef HAVE_PWD_FUNCS
{
struct passwd *pw;
@@ -81,7 +81,7 @@ int os_get_usernames(garray_T *users)
}
}
#endif
-#if defined(HAVE_GETPWNAM)
+#ifdef HAVE_PWD_FUNCS
{
const char *user_env = os_getenv("USER");
@@ -141,7 +141,7 @@ int os_get_username(char *s, size_t len)
/// @return OK if a username was found, else FAIL.
int os_get_uname(uv_uid_t uid, char *s, size_t len)
{
-#if defined(HAVE_PWD_H) && defined(HAVE_GETPWUID)
+#ifdef HAVE_PWD_FUNCS
struct passwd *pw;
if ((pw = getpwuid(uid)) != NULL // NOLINT(runtime/threadsafe_fn)
@@ -159,7 +159,7 @@ int os_get_uname(uv_uid_t uid, char *s, size_t len)
/// Caller must free() the returned string.
char *os_get_userdir(const char *name)
{
-#if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
+#ifdef HAVE_PWD_FUNCS
if (name == NULL || *name == NUL) {
return NULL;
}
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 48dc860ebd..df7c87ad60 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -60,27 +60,14 @@
#define LINUXSET0C "\x1b[?0c"
#define LINUXSET1C "\x1b[?1c"
-#ifdef NVIM_UNIBI_HAS_VAR_FROM
-# define UNIBI_SET_NUM_VAR(var, num) \
+#define UNIBI_SET_NUM_VAR(var, num) \
do { \
(var) = unibi_var_from_num((num)); \
} while (0)
-# define UNIBI_SET_STR_VAR(var, str) \
+#define UNIBI_SET_STR_VAR(var, str) \
do { \
(var) = unibi_var_from_str((str)); \
} while (0)
-#else
-# define UNIBI_SET_NUM_VAR(var, num) \
- do { \
- (var).p = NULL; \
- (var).i = (num); \
- } while (0)
-# define UNIBI_SET_STR_VAR(var, str) \
- do { \
- (var).i = INT_MIN; \
- (var).p = str; \
- } while (0)
-#endif
typedef struct {
int top, bot, left, right;