locale-util: add logic to output smiley emojis at various happiness levels
authorLennart Poettering <lennart@poettering.net>
Tue, 6 Nov 2018 16:59:58 +0000 (17:59 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 30 Nov 2018 15:19:29 +0000 (16:19 +0100)
docs/ENVIRONMENT.md
src/basic/locale-util.c
src/basic/locale-util.h
src/test/test-locale-util.c

index 3e61ea51e7068725beb0e621d0caa7ab87c74eea..e965cb885a312c114e776e11f511f38b947fb74b 100644 (file)
@@ -46,9 +46,14 @@ All tools:
   are understood, too (us, ms, s, min, h, d, w, month, y). If it is not set or set
   to 0, then the built-in default is used.
 
-* `$SYSTEMD_MEMPOOL=0` — if set the internal memory caching logic employed by
+* `$SYSTEMD_MEMPOOL=0` — if set, the internal memory caching logic employed by
   hash tables is turned off, and libc malloc() is used for all allocations.
 
+* `$SYSTEMD_EMOJI=0` — if set, tools such as "systemd-analyze security" will
+  not output graphical smiley emojis, but ASCII alternatives instead. Note that
+  this only controls use of Unicode emoji glyphs, and has no effect on other
+  Unicode glyphs.
+
 systemctl:
 
 * `$SYSTEMCTL_FORCE_BUS=1` — if set, do not connect to PID1's private D-Bus
index b2ef66392e118340db7c62c78d4f5c649c4302f2..2225208cd20633039afd2351361858564f2ada86 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "def.h"
 #include "dirent-util.h"
+#include "env-util.h"
 #include "fd-util.h"
 #include "hashmap.h"
 #include "locale-util.h"
@@ -347,6 +348,24 @@ bool keymap_is_valid(const char *name) {
         return true;
 }
 
+static bool emoji_enabled(void) {
+        static int cached_emoji_enabled = -1;
+
+        if (cached_emoji_enabled < 0) {
+                int val;
+
+                val = getenv_bool("SYSTEMD_EMOJI");
+                if (val < 0)
+                        cached_emoji_enabled =
+                                is_locale_utf8() &&
+                                !STRPTR_IN_SET(getenv("TERM"), "dumb", "linux");
+                else
+                        cached_emoji_enabled = val;
+        }
+
+        return cached_emoji_enabled;
+}
+
 const char *special_glyph(SpecialGlyph code) {
 
         /* A list of a number of interesting unicode glyphs we can use to decorate our output. It's probably wise to be
@@ -359,40 +378,56 @@ 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]       = "*",
-                        [BULLET]             = "*",
-                        [ARROW]              = "->",
-                        [MDASH]              = "-",
-                        [ELLIPSIS]           = "...",
-                        [MU]                 = "u",
-                        [CHECK_MARK]         = "+",
-                        [CROSS_MARK]         = "-",
+                        [TREE_VERTICAL]           = "| ",
+                        [TREE_BRANCH]             = "|-",
+                        [TREE_RIGHT]              = "`-",
+                        [TREE_SPACE]              = "  ",
+                        [TRIANGULAR_BULLET]       = ">",
+                        [BLACK_CIRCLE]            = "*",
+                        [BULLET]                  = "*",
+                        [ARROW]                   = "->",
+                        [MDASH]                   = "-",
+                        [ELLIPSIS]                = "...",
+                        [MU]                      = "u",
+                        [CHECK_MARK]              = "+",
+                        [CROSS_MARK]              = "-",
+                        [ECSTATIC_SMILEY]         = ":-]",
+                        [HAPPY_SMILEY]            = ":-}",
+                        [SLIGHTLY_HAPPY_SMILEY]   = ":-)",
+                        [NEUTRAL_SMILEY]          = ":-|",
+                        [SLIGHTLY_UNHAPPY_SMILEY] = ":-(",
+                        [UNHAPPY_SMILEY]          = ":-{️",
+                        [DEPRESSED_SMILEY]        = ":-[",
                 },
 
                 /* 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",             /* ● */
-                        [BULLET]             = "\342\200\242",             /* • */
-                        [ARROW]              = "\342\206\222",             /* → */
-                        [MDASH]              = "\342\200\223",             /* – */
-                        [ELLIPSIS]           = "\342\200\246",             /* … */
-                        [MU]                 = "\316\274",                 /* μ */
-                        [CHECK_MARK]         = "\342\234\223",             /* ✓ */
-                        [CROSS_MARK]         = "\342\234\227",             /* ✗ */
+                        [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",             /* ● */
+                        [BULLET]                  = "\342\200\242",             /* • */
+                        [ARROW]                   = "\342\206\222",             /* → */
+                        [MDASH]                   = "\342\200\223",             /* – */
+                        [ELLIPSIS]                = "\342\200\246",             /* … */
+                        [MU]                      = "\316\274",                 /* μ */
+                        [CHECK_MARK]              = "\342\234\223",             /* ✓ */
+                        [CROSS_MARK]              = "\342\234\227",             /* ✗ */
+                        [ECSTATIC_SMILEY]         = "\360\237\230\207",         /* 😇 */
+                        [HAPPY_SMILEY]            = "\360\237\230\200",         /* 😀 */
+                        [SLIGHTLY_HAPPY_SMILEY]   = "\360\237\231\202",         /* 🙂 */
+                        [NEUTRAL_SMILEY]          = "\360\237\230\220",         /* 😐 */
+                        [SLIGHTLY_UNHAPPY_SMILEY] = "\360\237\231\201",         /* 🙁 */
+                        [UNHAPPY_SMILEY]          = "\360\237\230\250",         /* 😨️️ */
+                        [DEPRESSED_SMILEY]        = "\360\237\244\242",         /* 🤢 */
                 },
         };
 
-        return draw_table[is_locale_utf8()][code];
+        assert(code < _SPECIAL_GLYPH_MAX);
+
+        return draw_table[code >= _SPECIAL_GLYPH_FIRST_SMILEY ? emoji_enabled() : is_locale_utf8()][code];
 }
 
 void locale_variables_free(char*l[_VARIABLE_LC_MAX]) {
index 2aa2bef8c5cbb72005f214340ad75e3ebed4f0e5..8f4ce5485d90b73845c5a3affce22f855bf1b899 100644 (file)
@@ -52,6 +52,14 @@ typedef enum {
         MU,
         CHECK_MARK,
         CROSS_MARK,
+        _SPECIAL_GLYPH_FIRST_SMILEY,
+        ECSTATIC_SMILEY = _SPECIAL_GLYPH_FIRST_SMILEY,
+        HAPPY_SMILEY,
+        SLIGHTLY_HAPPY_SMILEY,
+        NEUTRAL_SMILEY,
+        SLIGHTLY_UNHAPPY_SMILEY,
+        UNHAPPY_SMILEY,
+        DEPRESSED_SMILEY,
         _SPECIAL_GLYPH_MAX
 } SpecialGlyph;
 
index a1d4307eb51feff7d54d1fbce899de31ad1c5a17..48994547ac3be3ea9347d9ce3f227cfbb6a9cbc3 100644 (file)
@@ -65,7 +65,7 @@ static void test_keymaps(void) {
 
 #define dump_glyph(x) log_info(STRINGIFY(x) ": %s", special_glyph(x))
 static void dump_special_glyphs(void) {
-        assert_cc(CROSS_MARK + 1 == _SPECIAL_GLYPH_MAX);
+        assert_cc(DEPRESSED_SMILEY + 1 == _SPECIAL_GLYPH_MAX);
 
         log_info("/* %s */", __func__);
 
@@ -84,6 +84,13 @@ static void dump_special_glyphs(void) {
         dump_glyph(MU);
         dump_glyph(CHECK_MARK);
         dump_glyph(CROSS_MARK);
+        dump_glyph(ECSTATIC_SMILEY);
+        dump_glyph(HAPPY_SMILEY);
+        dump_glyph(SLIGHTLY_HAPPY_SMILEY);
+        dump_glyph(NEUTRAL_SMILEY);
+        dump_glyph(SLIGHTLY_UNHAPPY_SMILEY);
+        dump_glyph(UNHAPPY_SMILEY);
+        dump_glyph(DEPRESSED_SMILEY);
 }
 
 int main(int argc, char *argv[]) {