diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/nvim/CMakeLists.txt | 25 | ||||
| -rw-r--r-- | src/nvim/charset.c | 2 | ||||
| -rw-r--r-- | src/nvim/cmdexpand.c | 2 | ||||
| -rw-r--r-- | src/nvim/eval.c | 2 | ||||
| -rw-r--r-- | src/nvim/eval/decode.c | 4 | ||||
| -rw-r--r-- | src/nvim/fileio.c | 10 | ||||
| -rw-r--r-- | src/nvim/generators/gen_ex_cmds.lua | 2 | ||||
| -rw-r--r-- | src/nvim/locale.c | 377 | ||||
| -rw-r--r-- | src/nvim/locale.h | 10 | ||||
| -rw-r--r-- | src/nvim/lua/treesitter.c | 6 | ||||
| -rw-r--r-- | src/nvim/main.c | 4 | ||||
| -rw-r--r-- | src/nvim/mbyte.c | 10 | ||||
| -rw-r--r-- | src/nvim/msgpack_rpc/helpers.c | 8 | ||||
| -rw-r--r-- | src/nvim/option.c | 1 | ||||
| -rw-r--r-- | src/nvim/os/lang.c | 343 | ||||
| -rw-r--r-- | src/nvim/os/lang.h | 3 | ||||
| -rw-r--r-- | src/nvim/os/os_defs.h | 5 | ||||
| -rw-r--r-- | src/nvim/os/shell.c | 4 | ||||
| -rw-r--r-- | src/nvim/os/users.c | 10 | ||||
| -rw-r--r-- | src/nvim/tui/tui.c | 17 | 
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; | 
