From 523600ea6cc1edb7b4d116fdf70437a6b7f226d1 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 27 Aug 2022 11:26:47 +0800 Subject: vim-patch:8.2.1269: language and locale code spread out (#19964) Problem: Language and locale code spread out. Solution: Move relevant code to src/locale.c. (Yegappan Lakshmanan, closes vim/vim#6509) https://github.com/vim/vim/commit/054f14bbe58fece17f1a74ca63f0b37518f0b4de Also remove redundant includes. --- src/nvim/locale.c | 369 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 src/nvim/locale.c (limited to 'src/nvim/locale.c') diff --git a/src/nvim/locale.c b/src/nvim/locale.c new file mode 100644 index 0000000000..ba0566011c --- /dev/null +++ b/src/nvim/locale.c @@ -0,0 +1,369 @@ +// 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 "auto/config.h" + +#ifdef HAVE_LOCALE_H +# include +#endif + +#include "nvim/ascii.h" +#include "nvim/buffer.h" +#include "nvim/charset.h" +#include "nvim/eval.h" +#include "nvim/garray.h" +#include "nvim/locale.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" + +#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(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 = (char *)skiptowhite((char_u *)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 WIN32 +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 = (char *)get_cmd_output((char_u *)"locale -a", NULL, + kShellOptSilent, NULL); + if (locale_a == NULL) { + return NULL; + } + ga_init(&locales_ga, sizeof(char_u *), 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_u **)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 WIN32 + if (!did_init_locales) { + did_init_locales = true; + locales = find_locales(); + } +# endif +} + +# if defined(EXITFREE) +void free_locales(void) +{ + int i; + if (locales != NULL) { + for (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 -- cgit From 2828aae7b49921380f229ebf4d7432f39c6c2c2b Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Tue, 30 Aug 2022 14:52:09 +0200 Subject: refactor: replace char_u with char 4 (#19987) * refactor: replace char_u with char Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/locale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/locale.c') diff --git a/src/nvim/locale.c b/src/nvim/locale.c index ba0566011c..3e0774c096 100644 --- a/src/nvim/locale.c +++ b/src/nvim/locale.c @@ -188,7 +188,7 @@ void ex_language(exarg_T *eap) // 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 = (char *)skiptowhite((char_u *)eap->arg); + 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; -- cgit From 6d557e324fd4223fff3279a0112f40431c540163 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Sun, 18 Sep 2022 03:17:15 +0200 Subject: vim-patch:8.1.0941: macros for MS-Windows are inconsistent (#20215) Problem: Macros for MS-Windows are inconsistent, using "32", "3264 and others. Solution: Use MSWIN for all MS-Windows builds. Use FEAT_GUI_MSWIN for the GUI build. (Hirohito Higashi, closes vim/vim#3932) https://github.com/vim/vim/commit/4f97475d326c2773a78561fb874e4f23c25cbcd9 --- src/nvim/locale.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/locale.c') diff --git a/src/nvim/locale.c b/src/nvim/locale.c index 3e0774c096..c472d9ba66 100644 --- a/src/nvim/locale.c +++ b/src/nvim/locale.c @@ -270,7 +270,7 @@ void ex_language(exarg_T *eap) static char **locales = NULL; // Array of all available locales -# ifndef WIN32 +# ifndef MSWIN static bool did_init_locales = false; /// @return an array of strings for all available locales + NULL for the @@ -311,7 +311,7 @@ static char **find_locales(void) /// Lazy initialization of all available locales. static void init_locales(void) { -# ifndef WIN32 +# ifndef MSWIN if (!did_init_locales) { did_init_locales = true; locales = find_locales(); -- cgit From 784e498c4a9c1f03266ced5ec3f55c3a6c94b80d Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Fri, 21 Oct 2022 14:47:44 +0200 Subject: refactor: clang-tidy fixes to silence clangd warning (#20683) * refactor: readability-uppercase-literal-suffix * refactor: readability-named-parameter * refactor: bugprone-suspicious-string-compare * refactor: google-readability-casting * refactor: readability-redundant-control-flow * refactor: bugprone-too-small-loop-variable * refactor: readability-non-const-parameter * refactor: readability-avoid-const-params-in-decls * refactor: google-readability-todo * refactor: readability-inconsistent-declaration-parameter-name * refactor: bugprone-suspicious-missing-comma * refactor: remove noisy or slow warnings --- src/nvim/locale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/locale.c') diff --git a/src/nvim/locale.c b/src/nvim/locale.c index c472d9ba66..f2db9fcc59 100644 --- a/src/nvim/locale.c +++ b/src/nvim/locale.c @@ -42,7 +42,7 @@ static char *get_locale_val(int what) /// @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(char *lang) +static bool is_valid_mess_lang(const char *lang) { return lang != NULL && ASCII_ISALPHA(lang[0]) && ASCII_ISALPHA(lang[1]); } -- cgit From 66360675cf4d091b7460e4a8e1435c13216c1929 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sun, 11 Sep 2022 17:12:44 +0200 Subject: build: allow IWYU to fix includes for all .c files Allow Include What You Use to remove unnecessary includes and only include what is necessary. This helps with reducing compilation times and makes it easier to visualise which dependencies are actually required. Work on https://github.com/neovim/neovim/issues/549, but doesn't close it since this only works fully for .c files and not headers. --- src/nvim/locale.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/nvim/locale.c') diff --git a/src/nvim/locale.c b/src/nvim/locale.c index f2db9fcc59..c07420be1d 100644 --- a/src/nvim/locale.c +++ b/src/nvim/locale.c @@ -3,8 +3,10 @@ // locale.c: functions for language/locale configuration -#include "auto/config.h" +#include +#include +#include "auto/config.h" #ifdef HAVE_LOCALE_H # include #endif @@ -13,8 +15,11 @@ #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" @@ -23,6 +28,7 @@ #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" -- cgit From e89c39d6f016a4140293755250e968e839009617 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Sat, 14 Jan 2023 08:58:28 +0100 Subject: refactor: replace char_u with char 21 (#21779) refactor: replace char_u with char Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/locale.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/nvim/locale.c') diff --git a/src/nvim/locale.c b/src/nvim/locale.c index c07420be1d..12d6b47be8 100644 --- a/src/nvim/locale.c +++ b/src/nvim/locale.c @@ -290,8 +290,7 @@ static char **find_locales(void) // Find all available locales by running command "locale -a". If this // doesn't work we won't have completion. - char *locale_a = (char *)get_cmd_output((char_u *)"locale -a", NULL, - kShellOptSilent, NULL); + char *locale_a = get_cmd_output("locale -a", NULL, kShellOptSilent, NULL); if (locale_a == NULL) { return NULL; } -- cgit From 2065ce877ef81bcd66132bd26e75aa4d761dca12 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 14 Jan 2023 21:36:15 +0800 Subject: vim-patch:partial:9.0.1196: code is indented more than necessary (#21796) Problem: Code is indented more than necessary. Solution: Use an early return where it makes sense. (Yegappan Lakshmanan, closes vim/vim#11813) https://github.com/vim/vim/commit/e8575988969579f9e1439181ae338b2ff74054a8 Partial port as this depends on some previous eval and 'smoothscroll' patches. Co-authored-by: Yegappan Lakshmanan --- src/nvim/locale.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src/nvim/locale.c') diff --git a/src/nvim/locale.c b/src/nvim/locale.c index 12d6b47be8..6322271073 100644 --- a/src/nvim/locale.c +++ b/src/nvim/locale.c @@ -317,23 +317,26 @@ static char **find_locales(void) static void init_locales(void) { # ifndef MSWIN - if (!did_init_locales) { - did_init_locales = true; - locales = find_locales(); + if (did_init_locales) { + return; } + + did_init_locales = true; + locales = find_locales(); # endif } # if defined(EXITFREE) void free_locales(void) { - int i; - if (locales != NULL) { - for (i = 0; locales[i] != NULL; i++) { - xfree(locales[i]); - } - XFREE_CLEAR(locales); + if (locales == NULL) { + return; + } + + for (int i = 0; locales[i] != NULL; i++) { + xfree(locales[i]); } + XFREE_CLEAR(locales); } # endif -- cgit From 8a4285d5637c146a0ae606918a8e77063c6a5f0d Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Wed, 18 Jan 2023 14:17:11 +0100 Subject: refactor: replace char_u with char 24 (#21823) refactor: replace char_u with char Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/locale.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/locale.c') diff --git a/src/nvim/locale.c b/src/nvim/locale.c index 6322271073..c3cfd3bedb 100644 --- a/src/nvim/locale.c +++ b/src/nvim/locale.c @@ -294,7 +294,7 @@ static char **find_locales(void) if (locale_a == NULL) { return NULL; } - ga_init(&locales_ga, sizeof(char_u *), 20); + ga_init(&locales_ga, sizeof(char *), 20); // Transform locale_a string where each locale is separated by "\n" // into an array of locale strings. @@ -308,7 +308,7 @@ static char **find_locales(void) xfree(locale_a); // Guarantee that .ga_data is NULL terminated ga_grow(&locales_ga, 1); - ((char_u **)locales_ga.ga_data)[locales_ga.ga_len] = NULL; + ((char **)locales_ga.ga_data)[locales_ga.ga_len] = NULL; return locales_ga.ga_data; } # endif -- cgit