1 /* $OpenBSD: setlocale.c,v 1.2 2015/08/23 07:33:50 guenther Exp $ */ 2 /* 3 * Copyright (c) 2015 Sebastien Marie <semarie@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <err.h> 19 #include <locale.h> 20 #include <stdlib.h> 21 #include <stdio.h> 22 #include <string.h> 23 24 /* 25 * test helpers for __LINE__ 26 */ 27 #define test_setlocale(_e, _c, _l) _test_setlocale(_e, _c, _l, __LINE__) 28 #define test_MB_CUR_MAX(_e) _test_MB_CUR_MAX(_e, __LINE__) 29 #define test_isalpha(_e, _c) _test_isalpha(_e, _c, __LINE__) 30 31 32 static void 33 _test_setlocale(char *expected, int category, char *locale, int line) 34 { 35 char *result = setlocale(category, locale); 36 37 if ((expected == NULL) || (result == NULL)) { 38 if (expected == result) 39 return; 40 41 errx(1, "[%d] setlocale(%d, \"%s\")=\"%s\" [expected: \"%s\"]", 42 line, category, locale, result, expected); 43 } 44 45 if (strcmp(expected, result) != 0) 46 errx(1, "[%d] setlocale(%d, \"%s\")=\"%s\" [expected: \"%s\"]", 47 line, category, locale, result, expected); 48 } 49 50 static void 51 _test_MB_CUR_MAX(size_t expected, int line) 52 { 53 if (MB_CUR_MAX != expected) 54 errx(1, "[%d] MB_CUR_MAX=%ld [expected %ld]", 55 line, MB_CUR_MAX, expected); 56 } 57 58 static void 59 _test_isalpha(int expected, int c, int line) 60 { 61 int result = isalpha(c); 62 if (!!result != expected) 63 errx(1, "[%d] isalpha(%d)=%d [expected %d]", 64 line, c, result, expected); 65 } 66 67 int 68 main(int argc, char *argv[]) 69 { 70 /* check initial state (should be "C") */ 71 test_setlocale("C", LC_ALL, NULL); /* check */ 72 test_MB_CUR_MAX(1); 73 test_isalpha(0, 0xe9); /* iso-8859-1 eacute */ 74 75 /* load from env */ 76 /* NOTE: we don't support non-C locales for some categories */ 77 /*test_setlocale("fr_FR.UTF-8", LC_ALL, "");*/ /* set */ 78 test_setlocale("fr_FR.UTF-8", LC_CTYPE, ""); /* set */ 79 test_setlocale("fr_FR.UTF-8", LC_MESSAGES, ""); /* set */ 80 test_MB_CUR_MAX(4); 81 test_isalpha(0, 0xe9); /* iso-8859-1 eacute */ 82 83 test_setlocale("C", LC_MESSAGES, "C"); /* set */ 84 test_MB_CUR_MAX(4); 85 test_setlocale("C/fr_FR.UTF-8/C/C/C/C", LC_ALL, NULL); /* check */ 86 87 test_setlocale("C", LC_CTYPE, "C"); /* set */ 88 test_MB_CUR_MAX(1); 89 test_setlocale("C", LC_ALL, NULL); /* check */ 90 91 /* check for errors on checking */ 92 test_setlocale("C", LC_ALL, "C"); /* reset */ 93 test_setlocale(NULL, -1, NULL); 94 test_setlocale(NULL, _LC_LAST, NULL); 95 test_setlocale(NULL, _LC_LAST+0xff, NULL); 96 test_setlocale("C", LC_ALL, NULL); /* check */ 97 98 /* check for errors on setting */ 99 test_setlocale(NULL, -1, ""); 100 test_setlocale(NULL, _LC_LAST, ""); 101 test_setlocale(NULL, _LC_LAST+0xff, ""); 102 test_setlocale("C", LC_ALL, NULL); /* check */ 103 104 /* no codeset, fallback to ASCII */ 105 test_setlocale("C", LC_ALL, "C"); /* reset */ 106 test_setlocale("invalid", LC_CTYPE, "invalid"); /* set */ 107 test_setlocale("invalid", LC_CTYPE, NULL); 108 test_MB_CUR_MAX(1); 109 test_isalpha(0, 0xe9); /* iso-8859-1 eacute */ 110 111 /* with codeset */ 112 test_setlocale("C", LC_ALL, "C"); /* reset */ 113 test_setlocale("invalid.UTF-8", LC_CTYPE, "invalid.UTF-8"); /* set */ 114 test_setlocale("invalid.UTF-8", LC_CTYPE, NULL); 115 test_MB_CUR_MAX(4); 116 117 /* with invalid codeset (is an error) */ 118 test_setlocale("C", LC_ALL, "C"); /* reset */ 119 test_setlocale(NULL, LC_CTYPE, "fr_FR.invalid"); /* set */ 120 test_setlocale("C", LC_CTYPE, NULL); 121 test_MB_CUR_MAX(1); 122 123 return (EXIT_SUCCESS); 124 } 125