Print this page
4964 nl_langinfo(CRNCYSTR) returns wrong alignment character
4999 libc test suite enhancements
4939 desire wcsnrtombs() function
Reviewed by: Jason King <jason.brian.king@gmail.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com>
Approved by: TBD


  12 /*
  13  * Copyright 2014 Garrett D'Amore <garrett@damore.org>
  14  */
  15 
  16 /*
  17  * This program tests that newlocale and uselocale work properly in
  18  * multi-threaded programs.  In order for it to work, it requires that
  19  * some additional locales be installed.
  20  */
  21 
  22 #include <stdio.h>
  23 #include <stdlib.h>
  24 #include <string.h>
  25 #include <locale.h>
  26 #include <libintl.h>
  27 #include <langinfo.h>
  28 #include <nl_types.h>
  29 #include <err.h>
  30 #include <unistd.h>
  31 #include <pthread.h>


  32 
  33 int debug = 0;
  34 
  35 /*
  36  * Note that on some platforms, different symbols are used.  For example,
  37  * MacOS Mavericks uses "Eu" for Euro symbol, instead of €.  If the locale
  38  * data changes, then this program will need to update to reflect that.
  39  */
  40 struct ldata {
  41         const char *locale;
  42         const char *day1;
  43         const char *cursym;
  44 } ldata[] = {
  45         { "C", "Sunday", "" },
  46         { "en_US.UTF-8", "Sunday", "$" },
  47         { "de_DE.UTF-8", "Sonntag", "€" },
  48         { "ru_RU.UTF-8", "воскресенье", "руб." },
  49         { "ja_JP.UTF-8", "日曜日", "¥" },
  50 };
  51 
  52 #define NUM_LDATA       5
  53 #define NUMTHR  20
  54 #define NUMITR  200
  55 
  56 static void
  57 test_start(const char *testName, const char *format, ...)
  58 {
  59         va_list args;
  60 
  61         (void) printf("TEST STARTING %s: ", testName);
  62 
  63         va_start(args, format);
  64         (void) vprintf(format, args);
  65         va_end(args);
  66         (void) fflush(stdout);
  67 }
  68 
  69 static void
  70 test_failed(const char *testName, const char *format, ...)
  71 {
  72         va_list args;
  73 
  74         (void) printf("TEST FAILED %s: ", testName);
  75 
  76         va_start(args, format);
  77         (void) vprintf(format, args);
  78         va_end(args);
  79 
  80         (void) exit(-1);
  81 }
  82 
  83 static void
  84 test_passed(const char *testName)
  85 {
  86         (void) printf("TEST PASS: %s\n", testName);
  87         (void) fflush(stdout);
  88 }
  89 
  90 void *
  91 testlocale_thr(void *ptr)
  92 {
  93         locale_t        cloc, loc;
  94         struct lconv    *lc;
  95         char            *day;
  96         char            *tname = ptr;
  97 
  98         for (int i = 0; i < NUMITR; i++) {
  99                 struct ldata *l = &ldata[i % NUM_LDATA];
 100                 cloc = uselocale(NULL);
 101 
 102                 loc = newlocale(LC_ALL_MASK, l->locale, NULL);
 103                 if (loc == NULL) {
 104                         test_failed("newlocale %s failed", l->locale);
 105                 }
 106                 day = nl_langinfo_l(DAY_1, loc);
 107                 if (strcmp(day, l->day1) != 0) {
 108                         test_failed(tname, "newlocale data mismatch (%s != %s)",
 109                             day, l->day1);
 110                 }
 111                 if (debug)
 112                         (void) printf("DAY1: %s\n", day);
 113 
 114                 day = nl_langinfo(DAY_1);
 115                 if (strcmp(day, "Sunday") != 0) {
 116                         test_failed(tname, "C locale day wrong %s != Sunday",
 117                             day);
 118                 }
 119                 lc = localeconv();
 120                 if (strcmp(lc->currency_symbol, "") != 0) {
 121                         test_failed(tname, "C cursym mismatch (%s != %s)",
 122                             lc->currency_symbol, "");
 123                 }
 124 
 125                 /* we sleep a random bit to mix it up */
 126                 (void) usleep(rand() % 10);
 127 
 128                 (void) uselocale(loc);
 129                 day = nl_langinfo(DAY_1);
 130                 if (strcmp(day, l->day1) != 0) {
 131                         test_failed(tname, "uselocale data mismatch (%s != %s)",
 132                             day, l->day1);
 133                 }
 134 
 135                 lc = localeconv();
 136                 if (strcmp(lc->currency_symbol, l->cursym) != 0) {
 137                         test_failed(tname, "uselocal cursym %s != %s",
 138                             lc->currency_symbol, l->cursym);
 139                 }
 140                 if (debug)
 141                         (void) printf("CSYM: %s\n", lc->currency_symbol);
 142 
 143                 /* we sleep a random bit to mix it up */
 144                 (void) usleep(rand() % 10);
 145 
 146                 if (uselocale(cloc) != loc) {
 147                         test_failed(tname, "revert old locale mismatch");
 148                 }
 149                 freelocale(loc);
 150                 if (uselocale(LC_GLOBAL_LOCALE) != cloc) {
 151                         test_failed(tname, "revert GLOBAL_LOCALE mismatch");
 152                 }
 153         }
 154         return (NULL);
 155 }
 156 
 157 
 158 void
 159 testlocale(void)
 160 {
 161         char            *tname = "newlocale/uselocale";
 162         pthread_t       tid[NUMTHR];
 163 
 164         test_start(tname, "running %d threads %d iterations\n", NUMTHR, NUMITR);






 165 
 166         for (int i = 0; i < NUMTHR; i++) {
 167                 (void) pthread_create(&tid[i], NULL, testlocale_thr, tname);


 168         }




 169 
 170         for (int i = 0; i < NUMTHR; i++) {
 171                 (void) pthread_join(tid[i], NULL);

 172         }
 173         test_passed(tname);




 174 }
 175 





































































 176 int
 177 main(int argc, char **argv)
 178 {
 179         int optc;
 180 
 181         while ((optc = getopt(argc, argv, "d")) != EOF) {
 182                 switch (optc) {
 183                 case 'd':
 184                         debug++;
 185                         break;







 186                 default:
 187                         (void) fprintf(stderr, "Usage: %s [-d]\n", argv[0]);
 188                         exit(1);
 189                 }
 190         }
 191 
 192         testlocale();



 193 
 194         exit(0);
 195 }


  12 /*
  13  * Copyright 2014 Garrett D'Amore <garrett@damore.org>
  14  */
  15 
  16 /*
  17  * This program tests that newlocale and uselocale work properly in
  18  * multi-threaded programs.  In order for it to work, it requires that
  19  * some additional locales be installed.
  20  */
  21 
  22 #include <stdio.h>
  23 #include <stdlib.h>
  24 #include <string.h>
  25 #include <locale.h>
  26 #include <libintl.h>
  27 #include <langinfo.h>
  28 #include <nl_types.h>
  29 #include <err.h>
  30 #include <unistd.h>
  31 #include <pthread.h>
  32 #include <note.h>
  33 #include "test_common.h"
  34 


  35 /*
  36  * Note that on some platforms, different symbols are used.  For example,
  37  * MacOS Mavericks uses "Eu" for Euro symbol, instead of €.  If the locale
  38  * data changes, then this program will need to update to reflect that.
  39  */
  40 struct ldata {
  41         const char *locale;
  42         const char *day1;
  43         const char *cursym;
  44 } ldata[] = {
  45         { "C", "Sunday", "" },
  46         { "en_US.UTF-8", "Sunday", "$" },
  47         { "de_DE.UTF-8", "Sonntag", "€" },
  48         { "ru_RU.UTF-8", "воскресенье", "руб." },
  49         { "ja_JP.UTF-8", "日曜日", "¥" },
  50 };
  51 
  52 #define NUM_LDATA       5
  53 #define NUMTHR  20
  54 #define NUMITR  200
  55 
  56 int extra_debug = 0;



  57 
  58 void
  59 testlocale_thr_one(test_t t, void *arg)








  60 {
  61         _NOTE(ARGUNUSED(arg));




















  62         locale_t        cloc, loc;
  63         struct lconv    *lc;
  64         char            *day;

  65 
  66         for (int i = 0; i < NUMITR; i++) {
  67                 struct ldata *l = &ldata[i % NUM_LDATA];
  68                 cloc = uselocale(NULL);
  69 
  70                 loc = newlocale(LC_ALL_MASK, l->locale, NULL);
  71                 if (loc == NULL) {
  72                         test_failed(t, "newlocale %s failed", l->locale);
  73                 }
  74                 day = nl_langinfo_l(DAY_1, loc);
  75                 if (strcmp(day, l->day1) != 0) {
  76                         test_failed(t, "newlocale data mismatch (%s != %s)",
  77                             day, l->day1);
  78                 }
  79                 if (extra_debug)
  80                         test_debugf(t, "DAY1: %s", day);
  81 
  82                 day = nl_langinfo(DAY_1);
  83                 if (strcmp(day, "Sunday") != 0) {
  84                         test_failed(t, "C locale day wrong %s != Sunday",
  85                             day);
  86                 }
  87                 lc = localeconv();
  88                 if (strcmp(lc->currency_symbol, "") != 0) {
  89                         test_failed(t, "C cursym mismatch (%s != %s)",
  90                             lc->currency_symbol, "");
  91                 }
  92 
  93                 /* we sleep a random bit to mix it up */
  94                 (void) usleep(rand() % 10);
  95 
  96                 (void) uselocale(loc);
  97                 day = nl_langinfo(DAY_1);
  98                 if (strcmp(day, l->day1) != 0) {
  99                         test_failed(t, "uselocale data mismatch (%s != %s)",
 100                             day, l->day1);
 101                 }
 102 
 103                 lc = localeconv();
 104                 if (strcmp(lc->currency_symbol, l->cursym) != 0) {
 105                         test_failed(t, "uselocal cursym %s != %s",
 106                             lc->currency_symbol, l->cursym);
 107                 }
 108                 if (extra_debug)
 109                         test_debugf(t, "CSYM: %s", lc->currency_symbol);
 110 
 111                 /* we sleep a random bit to mix it up */
 112                 (void) usleep(rand() % 10);
 113 
 114                 if (uselocale(cloc) != loc) {
 115                         test_failed(t, "revert old locale mismatch");
 116                 }
 117                 freelocale(loc);
 118                 if (uselocale(LC_GLOBAL_LOCALE) != cloc) {
 119                         test_failed(t, "revert GLOBAL_LOCALE mismatch");
 120                 }
 121         }
 122         test_passed(t);
 123 }
 124 
 125 
 126 void
 127 test_newlocale_threaded(void)
 128 {
 129         test_run(NUMTHR, testlocale_thr_one, NULL, "newlocale_threaded");
 130 }
 131 
 132 void
 133 test_newlocale_negative(void)
 134 {
 135         locale_t loc, bad;
 136         char *day;
 137         char *tname = "newlocale_negative";
 138         test_t t;
 139 
 140         t = test_start(tname);
 141         loc = newlocale(LC_ALL_MASK, "de_DE.UTF-8", NULL);
 142         if (loc == NULL) {
 143                 test_failed(t, "cannot set de_DE.UTF-8");
 144         }
 145         day = nl_langinfo_l(DAY_1, loc);
 146         if (strcmp(day, "Sonntag") != 0) {
 147                 test_failed(t, "incorrect Sonntag != %s", day);
 148         }
 149 
 150         bad = newlocale(LC_ALL_MASK, "cn_US.BIZRRE", loc);
 151         if (bad != NULL) {
 152                 test_failed(t, "passed setting bogus locale");
 153         }
 154         day = nl_langinfo_l(DAY_1, loc);
 155         if (strcmp(day, "Sonntag") != 0) {
 156                 test_failed(t, "incorrect Sonntag != %s", day);
 157         }
 158         test_passed(t);
 159 }
 160 
 161 void
 162 test_newlocale_categories(void)
 163 {
 164         locale_t loc;
 165         char *day, *cur, *yes;
 166         char *tname = "newlocale_categories";
 167         test_t t;
 168 
 169         t = test_start(tname);
 170 
 171         loc = NULL;
 172         loc = newlocale(LC_TIME_MASK, "de_DE.UTF-8", loc);
 173         loc = newlocale(LC_MESSAGES_MASK, "ru_RU.UTF-8", loc);
 174         loc = newlocale(LC_MONETARY_MASK, "en_US.UTF-8", loc);
 175 
 176         if (loc == NULL) {
 177                 test_failed(t, "failed to set locale");
 178         }
 179 
 180         day = nl_langinfo_l(DAY_1, loc);
 181         if ((day == NULL) || (strcmp(day, "Sonntag") != 0)) {
 182                 test_failed(t, "day1 mismatch %s != %s", day, "Sonntag");
 183         }
 184         yes = nl_langinfo_l(YESSTR, loc);
 185         if ((yes == NULL) || (strcmp(yes, "да") != 0)) {
 186                 test_failed(t, "currency mismatch");
 187         }
 188         cur = nl_langinfo_l(CRNCYSTR, loc);
 189         if ((cur == NULL) || (strcmp(cur, "-$") != 0)) {
 190                 test_failed(t, "currency mismatch [%s] != [%s]", cur, "-$");
 191         }
 192 
 193         test_passed(t);
 194 }
 195 
 196 void
 197 test_newlocale_composite(void)
 198 {
 199         locale_t loc;
 200         char *day, *cur, *yes;
 201         char *tname = "newlocale_composite";
 202         test_t t;
 203 
 204         t = test_start(tname);
 205 
 206         /* order: CTYPE/NUMERIC/TIME/COLLATE/MONETARY/MESSAGES */
 207         loc = newlocale(LC_ALL_MASK,
 208             "C/C/de_DE.UTF-8/C/en_US.UTF-8/ru_RU.UTF-8", NULL);
 209 
 210         if (loc == NULL) {
 211                 test_failed(t, "failed to set composite locale");
 212         }
 213 
 214         day = nl_langinfo_l(DAY_1, loc);
 215         if ((day == NULL) || (strcmp(day, "Sonntag") != 0)) {
 216                 test_failed(t, "day1 mismatch %s != %s", day, "Sonntag");
 217         }
 218         yes = nl_langinfo_l(YESSTR, loc);
 219         if ((yes == NULL) || (strcmp(yes, "да") != 0)) {
 220                 test_failed(t, "currency mismatch");
 221         }
 222         cur = nl_langinfo_l(CRNCYSTR, loc);
 223         if ((cur == NULL) || (strcmp(cur, "-$") != 0)) {
 224                 test_failed(t, "currency mismatch [%s] != [%s]", cur, "-$");
 225         }
 226 
 227         test_passed(t);
 228 }
 229 
 230 int
 231 main(int argc, char **argv)
 232 {
 233         int optc;
 234 
 235         while ((optc = getopt(argc, argv, "Ddf")) != EOF) {
 236                 switch (optc) {
 237                 case 'd':
 238                         test_set_debug();
 239                         break;
 240                 case 'f':
 241                         test_set_force();
 242                         break;
 243                 case 'D':
 244                         test_set_debug();
 245                         extra_debug++;
 246                         break;
 247                 default:
 248                         (void) fprintf(stderr, "Usage: %s [-df]\n", argv[0]);
 249                         exit(1);
 250                 }
 251         }
 252 
 253         test_newlocale_threaded();
 254         test_newlocale_negative();
 255         test_newlocale_categories();
 256         test_newlocale_composite();
 257 
 258         exit(0);
 259 }