From f1916032e472e4ae7a68c62db933c4f9ecac4c13 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 20 Jun 2022 14:25:06 +0100 Subject: [PATCH 1/3] =?UTF-8?q?tests:=20Add=20tests=20for=20modifiers=20fo?= =?UTF-8?q?r=20GDateTime=E2=80=99s=20`%l`=20placeholder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They were missing. Signed-off-by: Philip Withnall Helps: #2655 --- glib/tests/gdatetime.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c index 141263b66..dd83ce7ba 100644 --- a/glib/tests/gdatetime.c +++ b/glib/tests/gdatetime.c @@ -1812,6 +1812,15 @@ test_modifiers (void) TEST_PRINTF_TIME ( 1, 0, 0, "%-k", "1"); TEST_PRINTF_TIME ( 1, 0, 0, "%0k", "01"); + TEST_PRINTF_TIME ( 1, 0, 0, "%l", " 1"); + TEST_PRINTF_TIME ( 1, 0, 0, "%_l", " 1"); + TEST_PRINTF_TIME ( 1, 0, 0, "%-l", "1"); + TEST_PRINTF_TIME ( 1, 0, 0, "%0l", "01"); + TEST_PRINTF_TIME (23, 0, 0, "%l", "11"); + TEST_PRINTF_TIME (23, 0, 0, "%_l", "11"); + TEST_PRINTF_TIME (23, 0, 0, "%-l", "11"); + TEST_PRINTF_TIME (23, 0, 0, "%0l", "11"); + oldlocale = g_strdup (setlocale (LC_ALL, NULL)); setlocale (LC_ALL, "fa_IR.utf-8"); #ifdef HAVE_LANGINFO_OUTDIGIT From 7074122f308b7b3402fba250f2010778fdad6eff Mon Sep 17 00:00:00 2001 From: Maksym Hazevych Date: Sat, 28 May 2022 16:57:06 +0300 Subject: [PATCH 2/3] gdatetime: Pad numbers with numeric space Padding numbers with a typical space character doesn't align them well because it has a different size. Instead, we need to use the "U+2007" figure (numeric) space that has the same size as a numerical digit. This is only visible when using the `tnum` font feature that makes numbers monospace. Closes #2655 --- glib/gdatetime.c | 8 ++++---- glib/tests/gdatetime.c | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/glib/gdatetime.c b/glib/gdatetime.c index 7d3d27213..0d2f5334d 100644 --- a/glib/gdatetime.c +++ b/glib/gdatetime.c @@ -3189,11 +3189,11 @@ g_date_time_format_utf8 (GDateTime *datetime, g_date_time_get_day_of_year (datetime)); break; case 'k': - format_number (outstr, alt_digits, pad_set ? pad : " ", 2, + format_number (outstr, alt_digits, pad_set ? pad : "\u2007", 2, g_date_time_get_hour (datetime)); break; case 'l': - format_number (outstr, alt_digits, pad_set ? pad : " ", 2, + format_number (outstr, alt_digits, pad_set ? pad : "\u2007", 2, (g_date_time_get_hour (datetime) + 11) % 12 + 1); break; case 'm': @@ -3366,9 +3366,9 @@ g_date_time_format_utf8 (GDateTime *datetime, * - \%I: the hour as a decimal number using a 12-hour clock (range 01 to 12) * - \%j: the day of the year as a decimal number (range 001 to 366) * - \%k: the hour (24-hour clock) as a decimal number (range 0 to 23); - * single digits are preceded by a blank + * single digits are preceded by a figure space * - \%l: the hour (12-hour clock) as a decimal number (range 1 to 12); - * single digits are preceded by a blank + * single digits are preceded by a figure space * - \%m: the month as a decimal number (range 01 to 12) * - \%M: the minute as a decimal number (range 00 to 59) * - \%f: the microsecond as a decimal number (range 000000 to 999999) diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c index dd83ce7ba..3820d233e 100644 --- a/glib/tests/gdatetime.c +++ b/glib/tests/gdatetime.c @@ -1611,11 +1611,11 @@ GDateTime *__dt = g_date_time_new_local (2009, 10, 24, 0, 0, 0);\ TEST_PRINTF_TIME (12, 0, 0, "%I", "12"); TEST_PRINTF_TIME (15, 0, 0, "%I", "03"); TEST_PRINTF ("%j", "297"); - TEST_PRINTF ("%k", " 0"); + TEST_PRINTF ("%k", "\u20070"); TEST_PRINTF_TIME (13, 13, 13, "%k", "13"); TEST_PRINTF ("%l", "12"); TEST_PRINTF_TIME (12, 0, 0, "%I", "12"); - TEST_PRINTF_TIME (13, 13, 13, "%l", " 1"); + TEST_PRINTF_TIME (13, 13, 13, "%l", "\u20071"); TEST_PRINTF_TIME (10, 13, 13, "%l", "10"); TEST_PRINTF ("%m", "10"); TEST_PRINTF ("%M", "00"); @@ -1711,7 +1711,7 @@ test_non_utf8_printf (void) TEST_PRINTF_TIME (13, 13, 13, "%k", "13"); TEST_PRINTF ("%l", "12"); TEST_PRINTF_TIME (12, 0, 0, "%I", "12"); - TEST_PRINTF_TIME (13, 13, 13, "%l", " 1"); + TEST_PRINTF_TIME (13, 13, 13, "%l", "\u20071"); TEST_PRINTF_TIME (10, 13, 13, "%l", "10"); TEST_PRINTF ("%m", "10"); TEST_PRINTF ("%M", "00"); @@ -1807,12 +1807,12 @@ test_modifiers (void) TEST_PRINTF_TIME (23, 0, 0, "%-I", "11"); TEST_PRINTF_TIME (23, 0, 0, "%0I", "11"); - TEST_PRINTF_TIME ( 1, 0, 0, "%k", " 1"); + TEST_PRINTF_TIME ( 1, 0, 0, "%k", "\u20071"); TEST_PRINTF_TIME ( 1, 0, 0, "%_k", " 1"); TEST_PRINTF_TIME ( 1, 0, 0, "%-k", "1"); TEST_PRINTF_TIME ( 1, 0, 0, "%0k", "01"); - TEST_PRINTF_TIME ( 1, 0, 0, "%l", " 1"); + TEST_PRINTF_TIME ( 1, 0, 0, "%l", "\u20071"); TEST_PRINTF_TIME ( 1, 0, 0, "%_l", " 1"); TEST_PRINTF_TIME ( 1, 0, 0, "%-l", "1"); TEST_PRINTF_TIME ( 1, 0, 0, "%0l", "01"); From 7169f6e1e58a53e4b69e5d40f3fd192dd9cd8ed4 Mon Sep 17 00:00:00 2001 From: Maksym Hazevych Date: Sun, 29 May 2022 01:56:40 +0300 Subject: [PATCH 3/3] gdatetime: Use figure space for `%e` Helps: #2655 --- glib/gdatetime.c | 5 +++-- glib/tests/gdatetime.c | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/glib/gdatetime.c b/glib/gdatetime.c index 0d2f5334d..c1af97e27 100644 --- a/glib/gdatetime.c +++ b/glib/gdatetime.c @@ -3141,7 +3141,7 @@ g_date_time_format_utf8 (GDateTime *datetime, g_date_time_get_day_of_month (datetime)); break; case 'e': - format_number (outstr, alt_digits, pad_set ? pad : " ", 2, + format_number (outstr, alt_digits, pad_set ? pad : "\u2007", 2, g_date_time_get_day_of_month (datetime)); break; case 'f': @@ -3355,7 +3355,8 @@ g_date_time_format_utf8 (GDateTime *datetime, * - \%c: the preferred date and time representation for the current locale * - \%C: the century number (year/100) as a 2-digit integer (00-99) * - \%d: the day of the month as a decimal number (range 01 to 31) - * - \%e: the day of the month as a decimal number (range 1 to 31) + * - \%e: the day of the month as a decimal number (range 1 to 31); + * single digits are preceded by a figure space * - \%F: equivalent to `%Y-%m-%d` (the ISO 8601 date format) * - \%g: the last two digits of the ISO 8601 week-based year as a * decimal number (00-99). This works well with \%V and \%u. diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c index 3820d233e..b20855f97 100644 --- a/glib/tests/gdatetime.c +++ b/glib/tests/gdatetime.c @@ -1602,7 +1602,8 @@ GDateTime *__dt = g_date_time_new_local (2009, 10, 24, 0, 0, 0);\ TEST_PRINTF ("%B", "October"); TEST_PRINTF ("%d", "24"); TEST_PRINTF_DATE (2009, 1, 1, "%d", "01"); - TEST_PRINTF ("%e", "24"); // fixme + TEST_PRINTF ("%e", "24"); + TEST_PRINTF_DATE (2009, 1, 1, "%e", "\u20071"); TEST_PRINTF_TIME (10, 10, 1.001, "%f", "001000"); TEST_PRINTF ("%h", "Oct"); TEST_PRINTF ("%H", "00"); @@ -1780,7 +1781,7 @@ test_modifiers (void) TEST_PRINTF_DATE (2009, 1, 21, "%-d", "21"); TEST_PRINTF_DATE (2009, 1, 21, "%0d", "21"); - TEST_PRINTF_DATE (2009, 1, 1, "%e", " 1"); + TEST_PRINTF_DATE (2009, 1, 1, "%e", "\u20071"); TEST_PRINTF_DATE (2009, 1, 1, "%_e", " 1"); TEST_PRINTF_DATE (2009, 1, 1, "%-e", "1"); TEST_PRINTF_DATE (2009, 1, 1, "%0e", "01"); @@ -2462,6 +2463,24 @@ test_format_time_mixed_utf8 (gconstpointer data) #endif } +#ifdef __linux__ +static gchar * +str_utf8_replace (const gchar *str, + gunichar from, + gunichar to) +{ + GString *str_out = g_string_new (""); + + for (; *str != '\0'; str = g_utf8_next_char (str)) + { + gunichar c = g_utf8_get_char (str); + g_string_append_unichar (str_out, (c == from) ? to : c); + } + + return g_string_free (g_steal_pointer (&str_out), FALSE); +} +#endif + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-y2k" static void @@ -2479,13 +2498,24 @@ test_strftime (void) GDateTime *date_time; gchar c_str[1000]; gchar *dt_str; + gchar *dt_str_replaced = NULL, *c_str_replaced = NULL; date_time = g_date_time_new_from_unix_local (t); dt_str = g_date_time_format (date_time, TEST_FORMAT); strftime (c_str, sizeof c_str, TEST_FORMAT, localtime (&t)); - g_assert_cmpstr (c_str, ==, dt_str); + + /* Ensure the comparison is done insensitively to spaces. + * g_date_time_format() sometimes uses figure spaces (U+2007) whereas + * strftime() currently doesn’t, and that’s fine. */ + dt_str_replaced = str_utf8_replace (dt_str, 0x2007, 0x20); + c_str_replaced = str_utf8_replace (c_str, 0x2007, 0x20); + + g_assert_cmpstr (c_str_replaced, ==, dt_str_replaced); + g_date_time_unref (date_time); g_free (dt_str); + g_free (dt_str_replaced); + g_free (c_str_replaced); } #endif }