summaryrefslogtreecommitdiff
path: root/src/basic/locale-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic/locale-util.c')
-rw-r--r--src/basic/locale-util.c110
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",