]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
macro: Introduce UTF8() macro to define UTF-8 string literal
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 16 Mar 2025 00:31:43 +0000 (09:31 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 16 Mar 2025 01:15:24 +0000 (10:15 +0900)
C23 changed char8_t from char to unsigned char, hence assigning a u8 literal
to const char* emits pointer sign warning, e.g.
========
../src/shared/qrcode-util.c: In function ‘print_border’:
../src/shared/qrcode-util.c:16:34: warning: pointer targets in passing argument 1 of ‘fputs’ differ in signedness [-Wpointer-sign]
   16 | #define UNICODE_FULL_BLOCK       u8"█"
      |                                  ^~~~~
      |                                  |
      |                                  const unsigned char *
../src/shared/qrcode-util.c:65:39: note: in expansion of macro ‘UNICODE_FULL_BLOCK’
   65 |                                 fputs(UNICODE_FULL_BLOCK, output);
      |                                       ^~~~~~~~~~~~~~~~~~
========

This introduces UTF8() macro, which define u8 literal and casts to consth char*,
then rewrites all u8 literal definitions with the macro.
With this change, we can build systemd with C23.

src/basic/glyph-util.c
src/fundamental/macro-fundamental.h
src/hostname/hostnamectl.c
src/shared/qrcode-util.c
src/test/test-memstream-util.c

index 2380f60606c881071e3a5c4c83c9ba8827c9bc4e..330872bad37f0d4e861b438c5e52fe2dec3ae57f 100644 (file)
@@ -92,73 +92,73 @@ const char* glyph_full(Glyph code, bool force_utf) {
                         [GLYPH_SPACE]                   = " ",
 
                         /* The following are multiple glyphs in both ASCII and in UNICODE */
-                        [GLYPH_TREE_VERTICAL]           = u8"│ ",
-                        [GLYPH_TREE_BRANCH]             = u8"├─",
-                        [GLYPH_TREE_RIGHT]              = u8"└─",
-                        [GLYPH_TREE_SPACE]              = u8"  ",
-                        [GLYPH_TREE_TOP]                = u8"┌─",
+                        [GLYPH_TREE_VERTICAL]           = UTF8("│ "),
+                        [GLYPH_TREE_BRANCH]             = UTF8("├─"),
+                        [GLYPH_TREE_RIGHT]              = UTF8("└─"),
+                        [GLYPH_TREE_SPACE]              = UTF8("  "),
+                        [GLYPH_TREE_TOP]                = UTF8("┌─"),
 
                         /* Single glyphs in both cases */
-                        [GLYPH_VERTICAL_DOTTED]         = u8"┆",
-                        [GLYPH_HORIZONTAL_DOTTED]       = u8"┄",
-                        [GLYPH_HORIZONTAL_FAT]          = u8"━",
-                        [GLYPH_TRIANGULAR_BULLET]       = u8"‣",
-                        [GLYPH_BLACK_CIRCLE]            = u8"●",
-                        [GLYPH_WHITE_CIRCLE]            = u8"○",
-                        [GLYPH_MULTIPLICATION_SIGN]     = u8"×",
-                        [GLYPH_CIRCLE_ARROW]            = u8"↻",
-                        [GLYPH_BULLET]                  = u8"•",
-                        [GLYPH_MU]                      = u8"μ",       /* actually called: GREEK SMALL LETTER MU */
-                        [GLYPH_CHECK_MARK]              = u8"✓",
-                        [GLYPH_CROSS_MARK]              = u8"✗",        /* actually called: BALLOT X */
-                        [GLYPH_LIGHT_SHADE]             = u8"░",
-                        [GLYPH_DARK_SHADE]              = u8"▒",
-                        [GLYPH_FULL_BLOCK]              = u8"█",
-                        [GLYPH_SIGMA]                   = u8"Σ",
-                        [GLYPH_ARROW_UP]                = u8"↑",       /* actually called: UPWARDS ARROW */
-                        [GLYPH_ARROW_DOWN]              = u8"↓",       /* actually called: DOWNWARDS ARROW */
+                        [GLYPH_VERTICAL_DOTTED]         = UTF8("┆"),
+                        [GLYPH_HORIZONTAL_DOTTED]       = UTF8("┄"),
+                        [GLYPH_HORIZONTAL_FAT]          = UTF8("━"),
+                        [GLYPH_TRIANGULAR_BULLET]       = UTF8("‣"),
+                        [GLYPH_BLACK_CIRCLE]            = UTF8("●"),
+                        [GLYPH_WHITE_CIRCLE]            = UTF8("○"),
+                        [GLYPH_MULTIPLICATION_SIGN]     = UTF8("×"),
+                        [GLYPH_CIRCLE_ARROW]            = UTF8("↻"),
+                        [GLYPH_BULLET]                  = UTF8("•"),
+                        [GLYPH_MU]                      = UTF8("μ"),       /* actually called: GREEK SMALL LETTER MU */
+                        [GLYPH_CHECK_MARK]              = UTF8("✓"),
+                        [GLYPH_CROSS_MARK]              = UTF8("✗"),        /* actually called: BALLOT X */
+                        [GLYPH_LIGHT_SHADE]             = UTF8("░"),
+                        [GLYPH_DARK_SHADE]              = UTF8("▒"),
+                        [GLYPH_FULL_BLOCK]              = UTF8("█"),
+                        [GLYPH_SIGMA]                   = UTF8("Σ"),
+                        [GLYPH_ARROW_UP]                = UTF8("↑"),       /* actually called: UPWARDS ARROW */
+                        [GLYPH_ARROW_DOWN]              = UTF8("↓"),       /* actually called: DOWNWARDS ARROW */
 
                         /* Single glyph in Unicode, two in ASCII */
-                        [GLYPH_ARROW_LEFT]              = u8"←",       /* actually called: LEFTWARDS ARROW */
-                        [GLYPH_ARROW_RIGHT]             = u8"→",       /* actually called: RIGHTWARDS ARROW */
+                        [GLYPH_ARROW_LEFT]              = UTF8("←"),       /* actually called: LEFTWARDS ARROW */
+                        [GLYPH_ARROW_RIGHT]             = UTF8("→"),       /* actually called: RIGHTWARDS ARROW */
 
                         /* Single glyph in Unicode, three in ASCII */
-                        [GLYPH_ELLIPSIS]                = u8"…",       /* actually called: HORIZONTAL ELLIPSIS */
+                        [GLYPH_ELLIPSIS]                = UTF8("…"),       /* actually called: HORIZONTAL ELLIPSIS */
 
                         /* Three glyphs in Unicode, five in ASCII */
-                        [GLYPH_EXTERNAL_LINK]           = u8"[🡕]",      /* actually called: NORTH EAST SANS-SERIF ARROW, enclosed in [] */
+                        [GLYPH_EXTERNAL_LINK]           = UTF8("[🡕]"),      /* actually called: NORTH EAST SANS-SERIF ARROW, enclosed in [] */
 
                         /* These smileys are a single glyph in Unicode, and three in ASCII */
-                        [GLYPH_ECSTATIC_SMILEY]         = u8"😇",       /* actually called: SMILING FACE WITH HALO */
-                        [GLYPH_HAPPY_SMILEY]            = u8"😀",       /* actually called: GRINNING FACE */
-                        [GLYPH_SLIGHTLY_HAPPY_SMILEY]   = u8"🙂",       /* actually called: SLIGHTLY SMILING FACE */
-                        [GLYPH_NEUTRAL_SMILEY]          = u8"😐",       /* actually called: NEUTRAL FACE */
-                        [GLYPH_SLIGHTLY_UNHAPPY_SMILEY] = u8"🙁",       /* actually called: SLIGHTLY FROWNING FACE */
-                        [GLYPH_UNHAPPY_SMILEY]          = u8"😨",       /* actually called: FEARFUL FACE */
-                        [GLYPH_DEPRESSED_SMILEY]        = u8"🤢",       /* actually called: NAUSEATED FACE */
+                        [GLYPH_ECSTATIC_SMILEY]         = UTF8("😇"),       /* actually called: SMILING FACE WITH HALO */
+                        [GLYPH_HAPPY_SMILEY]            = UTF8("😀"),       /* actually called: GRINNING FACE */
+                        [GLYPH_SLIGHTLY_HAPPY_SMILEY]   = UTF8("🙂"),       /* actually called: SLIGHTLY SMILING FACE */
+                        [GLYPH_NEUTRAL_SMILEY]          = UTF8("😐"),       /* actually called: NEUTRAL FACE */
+                        [GLYPH_SLIGHTLY_UNHAPPY_SMILEY] = UTF8("🙁"),       /* actually called: SLIGHTLY FROWNING FACE */
+                        [GLYPH_UNHAPPY_SMILEY]          = UTF8("😨"),       /* actually called: FEARFUL FACE */
+                        [GLYPH_DEPRESSED_SMILEY]        = UTF8("🤢"),       /* actually called: NAUSEATED FACE */
 
                         /* This emoji is a single character cell glyph in Unicode, and three in ASCII */
-                        [GLYPH_LOCK_AND_KEY]            = u8"🔐",       /* actually called: CLOSED LOCK WITH KEY */
+                        [GLYPH_LOCK_AND_KEY]            = UTF8("🔐"),       /* actually called: CLOSED LOCK WITH KEY */
 
                         /* This emoji is a single character cell glyph in Unicode, and two in ASCII */
-                        [GLYPH_TOUCH]                   = u8"👆",       /* actually called: BACKHAND INDEX POINTING UP */
+                        [GLYPH_TOUCH]                   = UTF8("👆"),       /* actually called: BACKHAND INDEX POINTING UP */
 
                         /* These four emojis are single character cell glyphs in Unicode and also in ASCII. */
-                        [GLYPH_RECYCLING]               = u8"♻️",        /* actually called: UNIVERSAL RECYCLNG SYMBOL */
-                        [GLYPH_DOWNLOAD]                = u8"⤵️",        /* actually called: RIGHT ARROW CURVING DOWN */
-                        [GLYPH_SPARKLES]                = u8"✨",
-                        [GLYPH_LOW_BATTERY]             = u8"🪫",
-                        [GLYPH_WARNING_SIGN]            = u8"⚠️",
-                        [GLYPH_COMPUTER_DISK]           = u8"💽",
-                        [GLYPH_WORLD]                   = u8"🌍",
-
-                        [GLYPH_RED_CIRCLE]              = u8"🔴",
-                        [GLYPH_YELLOW_CIRCLE]           = u8"🟡",
-                        [GLYPH_BLUE_CIRCLE]             = u8"🔵",
-                        [GLYPH_GREEN_CIRCLE]            = u8"🟢",
-                        [GLYPH_SUPERHERO]               = u8"🦸",
-                        [GLYPH_IDCARD]                  = u8"🪪",
-                        [GLYPH_HOME]                    = u8"🏠",
+                        [GLYPH_RECYCLING]               = UTF8("♻️"),        /* actually called: UNIVERSAL RECYCLNG SYMBOL */
+                        [GLYPH_DOWNLOAD]                = UTF8("⤵️"),        /* actually called: RIGHT ARROW CURVING DOWN */
+                        [GLYPH_SPARKLES]                = UTF8("✨"),
+                        [GLYPH_LOW_BATTERY]             = UTF8("🪫"),
+                        [GLYPH_WARNING_SIGN]            = UTF8("⚠️"),
+                        [GLYPH_COMPUTER_DISK]           = UTF8("💽"),
+                        [GLYPH_WORLD]                   = UTF8("🌍"),
+
+                        [GLYPH_RED_CIRCLE]              = UTF8("🔴"),
+                        [GLYPH_YELLOW_CIRCLE]           = UTF8("🟡"),
+                        [GLYPH_BLUE_CIRCLE]             = UTF8("🔵"),
+                        [GLYPH_GREEN_CIRCLE]            = UTF8("🟢"),
+                        [GLYPH_SUPERHERO]               = UTF8("🦸"),
+                        [GLYPH_IDCARD]                  = UTF8("🪪"),
+                        [GLYPH_HOME]                    = UTF8("🏠"),
                 },
         };
 
index bc7bd2f4924999118ec09e1206fe66757611c256..1d39d60ae857bb2ea69f1d412599aaf839a98ee7 100644 (file)
 #define XSTRINGIFY(x) #x
 #define STRINGIFY(x) XSTRINGIFY(x)
 
+/* C23 changed char8_t from char to unsigned char, hence we cannot pass u8 literals to e.g. fputs() without
+ * casting. Let's introduce our own way to declare UTF-8 literals, which casts u8 literals to const char*. */
+#define UTF8(s) ((const char*) (u8"" s))
+
 #ifndef __COVERITY__
 #  define VOID_0 ((void)0)
 #else
index 144e3550a307f3a151fcbacacb7dcf94929d4430..8374f452cf2a5a7065d10763898fb4e8b807131e 100644 (file)
@@ -70,21 +70,21 @@ typedef struct StatusInfo {
 
 static const char* chassis_string_to_glyph(const char *chassis) {
         if (streq_ptr(chassis, "laptop"))
-                return u8"💻"; /* Personal Computer */
+                return UTF8("💻"); /* Personal Computer */
         if (streq_ptr(chassis, "desktop"))
-                return u8"🖥️"; /* Desktop Computer */
+                return UTF8("🖥️"); /* Desktop Computer */
         if (streq_ptr(chassis, "server"))
-                return u8"🖳"; /* Old Personal Computer */
+                return UTF8("🖳"); /* Old Personal Computer */
         if (streq_ptr(chassis, "tablet"))
-                return u8"具"; /* Ideograph tool, implement; draw up, write, looks vaguely tabletty */
+                return UTF8("具"); /* Ideograph tool, implement; draw up, write, looks vaguely tabletty */
         if (streq_ptr(chassis, "watch"))
-                return u8"⌚"; /* Watch */
+                return UTF8("⌚"); /* Watch */
         if (streq_ptr(chassis, "handset"))
-                return u8"🕻"; /* Left Hand Telephone Receiver */
+                return UTF8("🕻"); /* Left Hand Telephone Receiver */
         if (streq_ptr(chassis, "vm"))
-                return u8"🖴"; /* Hard disk */
+                return UTF8("🖴"); /* Hard disk */
         if (streq_ptr(chassis, "container"))
-                return u8"☐"; /* Ballot Box  */
+                return UTF8("☐"); /* Ballot Box  */
         return NULL;
 }
 
index da88d80d03c355945bb18b80ce80d5f2f02b0ad9..aac0b3886befb936c5536c069712f549dece76c9 100644 (file)
@@ -13,9 +13,9 @@
 #include "terminal-util.h"
 
 #define ANSI_WHITE_ON_BLACK "\033[40;37;1m"
-#define UNICODE_FULL_BLOCK       u8"█"
-#define UNICODE_LOWER_HALF_BLOCK u8"▄"
-#define UNICODE_UPPER_HALF_BLOCK u8"▀"
+#define UNICODE_FULL_BLOCK       UTF8("█")
+#define UNICODE_LOWER_HALF_BLOCK UTF8("▄")
+#define UNICODE_UPPER_HALF_BLOCK UTF8("▀")
 
 static void *qrcode_dl = NULL;
 
index b8cc8568f04a6b2f5ebf1c590154e76dffa9f245..bce53e118b6fcde7cde998cef5f65be216d73ebc 100644 (file)
@@ -30,10 +30,10 @@ TEST(memstream) {
         assert_se(f = memstream_init(&m));
         fputs("hoge", f);
         fputs("おはよう!", f);
-        fputs(u8"😀😀😀", f);
-        assert_se(memstream_finalize(&m, &buf, &sz) >= 0);
-        ASSERT_STREQ(buf, u8"hogeおはよう!😀😀😀");
-        assert_se(sz == strlen(u8"hogeおはよう!😀😀😀"));
+        fputs(UTF8("😀😀😀"), f);
+        ASSERT_OK(memstream_finalize(&m, &buf, &sz));
+        ASSERT_STREQ(buf, UTF8("hogeおはよう!😀😀😀"));
+        ASSERT_EQ(sz, strlen(UTF8("hogeおはよう!😀😀😀")));
 
         buf = mfree(buf);