1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2025 Oxide Computer Company 14 * Copyright 2025 Bill Sommerfeld 15 */ 16 17 /* 18 * Locale test for the XPG4 version of wcsftime(), which takes a char * 19 * format; later standards use a wchar_t * format. 20 */ 21 22 #define _XOPEN_SOURCE 23 #define _XOPEN_VERSION 4 24 25 #include <err.h> 26 #include <stdlib.h> 27 #include <wchar.h> 28 #include <locale.h> 29 #include <sys/sysmacros.h> 30 #include <sys/debug.h> 31 #include <stdbool.h> 32 #include <string.h> 33 34 #ifndef _XPG4 35 #error _XPG4 should be defined for this file 36 #endif 37 38 #ifdef _XPG5 39 #error _XPG5 should not be defined for this file 40 #endif 41 42 /* 43 * We're just testing that the desired locale reaches the underlying 44 * formatter so we only look at one attribute: the full month name. 45 */ 46 static const struct test_locale { 47 const char *name; 48 const char *monthname; 49 } locales[] = { 50 { "C.UTF-8", "December" }, 51 {"ja_JP.UTF-8", "12月", }, 52 {"de_DE.UTF-8", "Dezember"}, 53 {"en_US.UTF-8", "December" }, 54 }; 55 56 struct tm sample_tm = { .tm_mon = 11, .tm_wday = 1 }; 57 58 #define WCSSIZE 100 59 #define CSIZE 200 60 61 /* 62 * Test that the correct decimal point is recognized. 63 * Use old version of wcsftime which takes a char * parameter. 64 */ 65 static bool 66 test_locale(const char *name, const char *monthname) 67 { 68 bool result_ok = true; 69 wchar_t wcs[WCSSIZE]; 70 char cstring[CSIZE]; 71 72 size_t len; 73 74 if (setlocale(LC_ALL, name) == NULL) { 75 err(EXIT_FAILURE, "INTERNAL TEST FAILURE: failed to " 76 "set locale %s", name); 77 } 78 79 len = wcsftime(wcs, WCSSIZE, "%B", &sample_tm); 80 if (len == (size_t)-1) { 81 warn("TEST FAILED: wcsftime_l returned -1"); 82 result_ok = false; 83 } 84 85 if (wcstombs(cstring, wcs, CSIZE) == (size_t)-1) { 86 err(EXIT_FAILURE, "INTERNAL TEST FAILURE: failed to " 87 "convert wide char string back to multibyte string"); 88 } 89 90 if (strcmp(cstring, monthname)) { 91 warn("TEST FAILED: Wrong month name for locale %s month %d: " 92 "got %s expected %s", name, sample_tm.tm_mon+1, 93 cstring, monthname); 94 result_ok = false; 95 } 96 return (result_ok); 97 } 98 99 100 int 101 main(void) 102 { 103 int ret = EXIT_SUCCESS; 104 size_t i; 105 106 for (i = 0; i < ARRAY_SIZE(locales); i++) { 107 if (!test_locale(locales[i].name, locales[i].monthname)) 108 ret = EXIT_FAILURE; 109 } 110 111 if (ret == EXIT_SUCCESS) { 112 (void) printf("All tests completed successfully\n"); 113 } 114 115 return (ret); 116 } 117