From: Yu Watanabe Date: Sun, 16 Mar 2025 00:31:43 +0000 (+0900) Subject: macro: Introduce UTF8() macro to define UTF-8 string literal X-Git-Tag: v258-rc1~1064^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e193378d327e20dfa7778e613c8cd16817afbd2b;p=thirdparty%2Fsystemd.git macro: Introduce UTF8() macro to define UTF-8 string literal 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. --- diff --git a/src/basic/glyph-util.c b/src/basic/glyph-util.c index 2380f60606c..330872bad37 100644 --- a/src/basic/glyph-util.c +++ b/src/basic/glyph-util.c @@ -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("🏠"), }, }; diff --git a/src/fundamental/macro-fundamental.h b/src/fundamental/macro-fundamental.h index bc7bd2f4924..1d39d60ae85 100644 --- a/src/fundamental/macro-fundamental.h +++ b/src/fundamental/macro-fundamental.h @@ -125,6 +125,10 @@ #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 diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c index 144e3550a30..8374f452cf2 100644 --- a/src/hostname/hostnamectl.c +++ b/src/hostname/hostnamectl.c @@ -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; } diff --git a/src/shared/qrcode-util.c b/src/shared/qrcode-util.c index da88d80d03c..aac0b3886be 100644 --- a/src/shared/qrcode-util.c +++ b/src/shared/qrcode-util.c @@ -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; diff --git a/src/test/test-memstream-util.c b/src/test/test-memstream-util.c index b8cc8568f04..bce53e118b6 100644 --- a/src/test/test-memstream-util.c +++ b/src/test/test-memstream-util.c @@ -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);