In the %ls and %U directives handling of the u*_vasnprintf functions, the width handling is tricky. Let me add some more unit tests for this code.
2024-06-19 Bruno Haible <br...@clisp.org> u*-vasnprintf tests: Add more tests of %U, %lU, %llU directives. * tests/unistdio/test-u8-printf1.h (test_xfunction): Add more tests of %U, %lU, %llU directives with width and non-ASCII argument. * tests/unistdio/test-u16-printf1.h (test_xfunction): Likewise. * tests/unistdio/test-u32-printf1.h (test_xfunction): Likewise. * tests/unistdio/test-ulc-vasnprintf2.c (test_function): Likewise. * tests/unistdio/test-ulc-vasnprintf3.c (test_function): Likewise. diff --git a/tests/unistdio/test-u16-printf1.h b/tests/unistdio/test-u16-printf1.h index e501c9e462..d2a71153c6 100644 --- a/tests/unistdio/test-u16-printf1.h +++ b/tests/unistdio/test-u16-printf1.h @@ -120,6 +120,32 @@ test_xfunction (uint16_t * (*my_xasprintf) (const char *, ...)) free (result); } } + { /* Width with a non-ASCII argument. */ + static const uint8_t unicode_string[] = /* hétérogénéité */ + "h\303\251t\303\251rog\303\251n\303\251it\303\251"; + uint16_t *result = + my_xasprintf ("%20U %d", unicode_string, 33, 44, 55); + static const uint16_t expected[] = + { ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'h', 0x00e9, 't', + 0x00e9, 'r', 'o', 'g', 0x00e9, 'n', 0x00e9, 'i', 't', 0x00e9, + ' ', '3', '3', 0 + }; + ASSERT (result != NULL); + ASSERT (u16_strcmp (result, expected) == 0); + free (result); + } + { /* Width with a non-BMP argument. */ + static const uint8_t unicode_string[] = "\360\237\220\203"; /* 🐃 */ + uint16_t *result = + my_xasprintf ("%10U %d", unicode_string, 33, 44, 55); + static const uint16_t expected[] = + { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 0xd83d, + 0xdc03, ' ', '3', '3', 0 + }; + ASSERT (result != NULL); + ASSERT (u16_strcmp (result, expected) == 0); + free (result); + } { static const uint16_t unicode_string[] = { 'H', 'e', 'l', 'l', 'o', 0 }; @@ -178,6 +204,34 @@ test_xfunction (uint16_t * (*my_xasprintf) (const char *, ...)) free (result); } } + { /* Width with a non-ASCII argument. */ + static const uint16_t unicode_string[] = /* hétérogénéité */ + { 'h', 0x00e9, 't', 0x00e9, 'r', 'o', 'g', 0x00e9, 'n', 0x00e9, + 'i', 't', 0x00e9, 0 + }; + uint16_t *result = + my_xasprintf ("%20lU %d", unicode_string, 33, 44, 55); + static const uint16_t expected[] = + { ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'h', 0x00e9, 't', + 0x00e9, 'r', 'o', 'g', 0x00e9, 'n', 0x00e9, 'i', 't', 0x00e9, + ' ', '3', '3', 0 + }; + ASSERT (result != NULL); + ASSERT (u16_strcmp (result, expected) == 0); + free (result); + } + { /* Width with a non-BMP argument. */ + static const uint16_t unicode_string[] = { 0xd83d, 0xdc03, 0 }; /* 🐃 */ + uint16_t *result = + my_xasprintf ("%10lU %d", unicode_string, 33, 44, 55); + static const uint16_t expected[] = + { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 0xd83d, + 0xdc03, ' ', '3', '3', 0 + }; + ASSERT (result != NULL); + ASSERT (u16_strcmp (result, expected) == 0); + free (result); + } { static const uint32_t unicode_string[] = { 'H', 'e', 'l', 'l', 'o', 0 }; @@ -236,6 +290,34 @@ test_xfunction (uint16_t * (*my_xasprintf) (const char *, ...)) free (result); } } + { /* Width with a non-ASCII argument. */ + static const uint32_t unicode_string[] = /* hétérogénéité */ + { 'h', 0x00e9, 't', 0x00e9, 'r', 'o', 'g', 0x00e9, 'n', 0x00e9, + 'i', 't', 0x00e9, 0 + }; + uint16_t *result = + my_xasprintf ("%20llU %d", unicode_string, 33, 44, 55); + static const uint16_t expected[] = + { ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'h', 0x00e9, 't', + 0x00e9, 'r', 'o', 'g', 0x00e9, 'n', 0x00e9, 'i', 't', 0x00e9, + ' ', '3', '3', 0 + }; + ASSERT (result != NULL); + ASSERT (u16_strcmp (result, expected) == 0); + free (result); + } + { /* Width with a non-BMP argument. */ + static const uint32_t unicode_string[] = { 0x1f403, 0 }; /* 🐃 */ + uint16_t *result = + my_xasprintf ("%10llU %d", unicode_string, 33, 44, 55); + static const uint16_t expected[] = + { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 0xd83d, + 0xdc03, ' ', '3', '3', 0 + }; + ASSERT (result != NULL); + ASSERT (u16_strcmp (result, expected) == 0); + free (result); + } /* Test the support of the 's' conversion specifier for strings. */ diff --git a/tests/unistdio/test-u32-printf1.h b/tests/unistdio/test-u32-printf1.h index ae0edc6a63..d7ba2e0998 100644 --- a/tests/unistdio/test-u32-printf1.h +++ b/tests/unistdio/test-u32-printf1.h @@ -120,6 +120,32 @@ test_xfunction (uint32_t * (*my_xasprintf) (const char *, ...)) free (result); } } + { /* Width with a non-ASCII argument. */ + static const uint8_t unicode_string[] = /* hétérogénéité */ + "h\303\251t\303\251rog\303\251n\303\251it\303\251"; + uint32_t *result = + my_xasprintf ("%20U %d", unicode_string, 33, 44, 55); + static const uint32_t expected[] = + { ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'h', 0x00e9, 't', + 0x00e9, 'r', 'o', 'g', 0x00e9, 'n', 0x00e9, 'i', 't', 0x00e9, + ' ', '3', '3', 0 + }; + ASSERT (result != NULL); + ASSERT (u32_strcmp (result, expected) == 0); + free (result); + } + { /* Width with a non-BMP argument. */ + static const uint8_t unicode_string[] = "\360\237\220\203"; /* 🐃 */ + uint32_t *result = + my_xasprintf ("%10U %d", unicode_string, 33, 44, 55); + static const uint32_t expected[] = + { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 0x1f403, + ' ', '3', '3', 0 + }; + ASSERT (result != NULL); + ASSERT (u32_strcmp (result, expected) == 0); + free (result); + } { static const uint16_t unicode_string[] = { 'H', 'e', 'l', 'l', 'o', 0 }; @@ -178,6 +204,34 @@ test_xfunction (uint32_t * (*my_xasprintf) (const char *, ...)) free (result); } } + { /* Width with a non-ASCII argument. */ + static const uint16_t unicode_string[] = /* hétérogénéité */ + { 'h', 0x00e9, 't', 0x00e9, 'r', 'o', 'g', 0x00e9, 'n', 0x00e9, + 'i', 't', 0x00e9, 0 + }; + uint32_t *result = + my_xasprintf ("%20lU %d", unicode_string, 33, 44, 55); + static const uint32_t expected[] = + { ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'h', 0x00e9, 't', + 0x00e9, 'r', 'o', 'g', 0x00e9, 'n', 0x00e9, 'i', 't', 0x00e9, + ' ', '3', '3', 0 + }; + ASSERT (result != NULL); + ASSERT (u32_strcmp (result, expected) == 0); + free (result); + } + { /* Width with a non-BMP argument. */ + static const uint16_t unicode_string[] = { 0xd83d, 0xdc03, 0 }; /* 🐃 */ + uint32_t *result = + my_xasprintf ("%10lU %d", unicode_string, 33, 44, 55); + static const uint32_t expected[] = + { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 0x1f403, + ' ', '3', '3', 0 + }; + ASSERT (result != NULL); + ASSERT (u32_strcmp (result, expected) == 0); + free (result); + } { static const uint32_t unicode_string[] = { 'H', 'e', 'l', 'l', 'o', 0 }; @@ -236,6 +290,34 @@ test_xfunction (uint32_t * (*my_xasprintf) (const char *, ...)) free (result); } } + { /* Width with a non-ASCII argument. */ + static const uint32_t unicode_string[] = /* hétérogénéité */ + { 'h', 0x00e9, 't', 0x00e9, 'r', 'o', 'g', 0x00e9, 'n', 0x00e9, + 'i', 't', 0x00e9, 0 + }; + uint32_t *result = + my_xasprintf ("%20llU %d", unicode_string, 33, 44, 55); + static const uint32_t expected[] = + { ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'h', 0x00e9, 't', + 0x00e9, 'r', 'o', 'g', 0x00e9, 'n', 0x00e9, 'i', 't', 0x00e9, + ' ', '3', '3', 0 + }; + ASSERT (result != NULL); + ASSERT (u32_strcmp (result, expected) == 0); + free (result); + } + { /* Width with a non-BMP argument. */ + static const uint32_t unicode_string[] = { 0x1f403, 0 }; /* 🐃 */ + uint32_t *result = + my_xasprintf ("%10llU %d", unicode_string, 33, 44, 55); + static const uint32_t expected[] = + { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 0x1f403, + ' ', '3', '3', 0 + }; + ASSERT (result != NULL); + ASSERT (u32_strcmp (result, expected) == 0); + free (result); + } /* Test the support of the 's' conversion specifier for strings. */ diff --git a/tests/unistdio/test-u8-printf1.h b/tests/unistdio/test-u8-printf1.h index 3e8999b638..3963adb6b7 100644 --- a/tests/unistdio/test-u8-printf1.h +++ b/tests/unistdio/test-u8-printf1.h @@ -110,6 +110,26 @@ test_xfunction (uint8_t * (*my_xasprintf) (const char *, ...)) free (result); } } + { /* Width with a non-ASCII argument. */ + static const uint8_t unicode_string[] = /* hétérogénéité */ + "h\303\251t\303\251rog\303\251n\303\251it\303\251"; + uint8_t *result = + my_xasprintf ("%20U %d", unicode_string, 33, 44, 55); + static const uint8_t expected[] = + " h\303\251t\303\251rog\303\251n\303\251it\303\251 33"; + ASSERT (result != NULL); + ASSERT (u8_strcmp (result, expected) == 0); + free (result); + } + { /* Width with a non-BMP argument. */ + static const uint8_t unicode_string[] = "\360\237\220\203"; /* 🐃 */ + uint8_t *result = + my_xasprintf ("%10U %d", unicode_string, 33, 44, 55); + static const uint8_t expected[] = " \360\237\220\203 33"; + ASSERT (result != NULL); + ASSERT (u8_strcmp (result, expected) == 0); + free (result); + } { static const uint16_t unicode_string[] = { 'H', 'e', 'l', 'l', 'o', 0 }; @@ -162,6 +182,28 @@ test_xfunction (uint8_t * (*my_xasprintf) (const char *, ...)) free (result); } } + { /* Width with a non-ASCII argument. */ + static const uint16_t unicode_string[] = /* hétérogénéité */ + { 'h', 0x00e9, 't', 0x00e9, 'r', 'o', 'g', 0x00e9, 'n', 0x00e9, + 'i', 't', 0x00e9, 0 + }; + uint8_t *result = + my_xasprintf ("%20lU %d", unicode_string, 33, 44, 55); + static const uint8_t expected[] = + " h\303\251t\303\251rog\303\251n\303\251it\303\251 33"; + ASSERT (result != NULL); + ASSERT (u8_strcmp (result, expected) == 0); + free (result); + } + { /* Width with a non-BMP argument. */ + static const uint16_t unicode_string[] = { 0xd83d, 0xdc03, 0 }; /* 🐃 */ + uint8_t *result = + my_xasprintf ("%10lU %d", unicode_string, 33, 44, 55); + static const uint8_t expected[] = " \360\237\220\203 33"; + ASSERT (result != NULL); + ASSERT (u8_strcmp (result, expected) == 0); + free (result); + } { static const uint32_t unicode_string[] = { 'H', 'e', 'l', 'l', 'o', 0 }; @@ -214,6 +256,28 @@ test_xfunction (uint8_t * (*my_xasprintf) (const char *, ...)) free (result); } } + { /* Width with a non-ASCII argument. */ + static const uint32_t unicode_string[] = /* hétérogénéité */ + { 'h', 0x00e9, 't', 0x00e9, 'r', 'o', 'g', 0x00e9, 'n', 0x00e9, + 'i', 't', 0x00e9, 0 + }; + uint8_t *result = + my_xasprintf ("%20llU %d", unicode_string, 33, 44, 55); + static const uint8_t expected[] = + " h\303\251t\303\251rog\303\251n\303\251it\303\251 33"; + ASSERT (result != NULL); + ASSERT (u8_strcmp (result, expected) == 0); + free (result); + } + { /* Width with a non-BMP argument. */ + static const uint32_t unicode_string[] = { 0x1f403, 0 }; /* 🐃 */ + uint8_t *result = + my_xasprintf ("%10llU %d", unicode_string, 33, 44, 55); + static const uint8_t expected[] = " \360\237\220\203 33"; + ASSERT (result != NULL); + ASSERT (u8_strcmp (result, expected) == 0); + free (result); + } /* Test the support of the 's' conversion specifier for strings. */ diff --git a/tests/unistdio/test-ulc-vasnprintf2.c b/tests/unistdio/test-ulc-vasnprintf2.c index d91fa86e5a..ba14e612bc 100644 --- a/tests/unistdio/test-ulc-vasnprintf2.c +++ b/tests/unistdio/test-ulc-vasnprintf2.c @@ -76,6 +76,16 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...)) free (result); } } + { /* Width with a non-BMP argument. */ + static const uint8_t unicode_string[] = "\360\237\220\203"; /* 🐃 */ + size_t length; + char *result = + my_asnprintf (NULL, &length, "%10U %d", unicode_string, 33, 44, 55); + ASSERT (result != NULL); + ASSERT (strcmp (result, " ? 33") == 0); + ASSERT (length == strlen (result)); + free (result); + } { static const uint16_t unicode_string[] = /* Rafał Maszkowski */ @@ -124,6 +134,16 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...)) free (result); } } + { /* Width with a non-BMP argument. */ + static const uint16_t unicode_string[] = { 0xd83d, 0xdc03, 0 }; /* 🐃 */ + size_t length; + char *result = + my_asnprintf (NULL, &length, "%10lU %d", unicode_string, 33, 44, 55); + ASSERT (result != NULL); + ASSERT (strcmp (result, " ? 33") == 0); + ASSERT (length == strlen (result)); + free (result); + } { static const uint32_t unicode_string[] = /* Rafał Maszkowski */ @@ -172,6 +192,16 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...)) free (result); } } + { /* Width with a non-BMP argument. */ + static const uint32_t unicode_string[] = { 0x1f403, 0 }; /* 🐃 */ + size_t length; + char *result = + my_asnprintf (NULL, &length, "%10llU %d", unicode_string, 33, 44, 55); + ASSERT (result != NULL); + ASSERT (strcmp (result, " ? 33") == 0); + ASSERT (length == strlen (result)); + free (result); + } /* Test the support of the 's' conversion specifier for strings. */ diff --git a/tests/unistdio/test-ulc-vasnprintf3.c b/tests/unistdio/test-ulc-vasnprintf3.c index 7fc6171952..f73b4539cd 100644 --- a/tests/unistdio/test-ulc-vasnprintf3.c +++ b/tests/unistdio/test-ulc-vasnprintf3.c @@ -72,6 +72,16 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...)) free (result); } } + { /* Width with a non-BMP argument. */ + static const uint8_t unicode_string[] = "\360\237\220\203"; /* 🐃 */ + size_t length; + char *result = + my_asnprintf (NULL, &length, "%10U %d", unicode_string, 33, 44, 55); + ASSERT (result != NULL); + ASSERT (strcmp (result, " \360\237\220\203 33") == 0); + ASSERT (length == strlen (result)); + free (result); + } { static const uint16_t unicode_string[] = /* Rafał Maszkowski */ @@ -116,6 +126,16 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...)) free (result); } } + { /* Width with a non-BMP argument. */ + static const uint16_t unicode_string[] = { 0xd83d, 0xdc03, 0 }; /* 🐃 */ + size_t length; + char *result = + my_asnprintf (NULL, &length, "%10lU %d", unicode_string, 33, 44, 55); + ASSERT (result != NULL); + ASSERT (strcmp (result, " \360\237\220\203 33") == 0); + ASSERT (length == strlen (result)); + free (result); + } { static const uint32_t unicode_string[] = /* Rafał Maszkowski */ @@ -160,6 +180,16 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...)) free (result); } } + { /* Width with a non-BMP argument. */ + static const uint32_t unicode_string[] = { 0x1f403, 0 }; /* 🐃 */ + size_t length; + char *result = + my_asnprintf (NULL, &length, "%10llU %d", unicode_string, 33, 44, 55); + ASSERT (result != NULL); + ASSERT (strcmp (result, " \360\237\220\203 33") == 0); + ASSERT (length == strlen (result)); + free (result); + } /* Test the support of the 's' conversion specifier for strings. */