diff options
Diffstat (limited to 'src/basic/locale-util.c')
-rw-r--r-- | src/basic/locale-util.c | 110 |
1 files changed, 104 insertions, 6 deletions
diff --git a/src/basic/locale-util.c b/src/basic/locale-util.c index 61db9a8125..ada0a28cd8 100644 --- a/src/basic/locale-util.c +++ b/src/basic/locale-util.c @@ -1,5 +1,3 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - /*** This file is part of systemd. @@ -19,14 +17,29 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <langinfo.h> +#include <libintl.h> +#include <locale.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> #include <sys/mman.h> +#include <sys/stat.h> +#include "dirent-util.h" +#include "fd-util.h" +#include "hashmap.h" +#include "locale-util.h" +#include "path-util.h" #include "set.h" -#include "util.h" -#include "utf8.h" +#include "string-table.h" +#include "string-util.h" #include "strv.h" - -#include "locale-util.h" +#include "utf8.h" static int add_locales_from_archive(Set *locales) { /* Stolen from glibc... */ @@ -140,6 +153,8 @@ static int add_locales_from_libdir (Set *locales) { FOREACH_DIRENT(entry, dir, return -errno) { char *z; + dirent_ensure_type(dir, entry); + if (entry->d_type != DT_DIR) continue; @@ -204,6 +219,89 @@ bool locale_is_valid(const char *name) { return true; } +void init_gettext(void) { + setlocale(LC_ALL, ""); + textdomain(GETTEXT_PACKAGE); +} + +bool is_locale_utf8(void) { + const char *set; + static int cached_answer = -1; + + /* Note that we default to 'true' here, since today UTF8 is + * pretty much supported everywhere. */ + + if (cached_answer >= 0) + goto out; + + if (!setlocale(LC_ALL, "")) { + cached_answer = true; + goto out; + } + + set = nl_langinfo(CODESET); + if (!set) { + cached_answer = true; + goto out; + } + + if (streq(set, "UTF-8")) { + cached_answer = true; + goto out; + } + + /* For LC_CTYPE=="C" return true, because CTYPE is effectly + * unset and everything can do to UTF-8 nowadays. */ + set = setlocale(LC_CTYPE, NULL); + if (!set) { + cached_answer = true; + goto out; + } + + /* Check result, but ignore the result if C was set + * explicitly. */ + cached_answer = + STR_IN_SET(set, "C", "POSIX") && + !getenv("LC_ALL") && + !getenv("LC_CTYPE") && + !getenv("LANG"); + +out: + return (bool) cached_answer; +} + + +const char *special_glyph(SpecialGlyph code) { + + static const char* const draw_table[2][_SPECIAL_GLYPH_MAX] = { + /* ASCII fallback */ + [false] = { + [TREE_VERTICAL] = "| ", + [TREE_BRANCH] = "|-", + [TREE_RIGHT] = "`-", + [TREE_SPACE] = " ", + [TRIANGULAR_BULLET] = ">", + [BLACK_CIRCLE] = "*", + [ARROW] = "->", + [MDASH] = "-", + }, + + /* UTF-8 */ + [ true ] = { + [TREE_VERTICAL] = "\342\224\202 ", /* │ */ + [TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */ + [TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */ + [TREE_SPACE] = " ", /* */ + [TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */ + [BLACK_CIRCLE] = "\342\227\217", /* ● */ + [ARROW] = "\342\206\222", /* → */ + [MDASH] = "\342\200\223", /* – */ + }, + }; + + return draw_table[is_locale_utf8()][code]; +} + static const char * const locale_variable_table[_VARIABLE_LC_MAX] = { [VARIABLE_LANG] = "LANG", [VARIABLE_LANGUAGE] = "LANGUAGE", |