1 /* $OpenBSD: newlocale.c,v 1.2 2019/03/29 12:34:44 schwarze Exp $ */ 2 /* 3 * Copyright (c) 2017 Ingo Schwarze <schwarze@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 <errno.h> 19 #include <locale.h> 20 #include <string.h> 21 22 #include "rune.h" 23 24 locale_t 25 newlocale(int mask, const char *locname, locale_t oldloc) 26 { 27 int ic, flag; 28 29 /* Invalid input. */ 30 if (locname == NULL || mask & ~LC_ALL_MASK) { 31 errno = EINVAL; 32 return _LOCALE_NONE; 33 } 34 35 /* Check the syntax for all selected categories. */ 36 for (ic = flag = 1; ic < _LC_LAST; ic++) { 37 flag <<= 1; 38 if (ic != LC_CTYPE && mask & flag && 39 _get_locname(ic, locname) == NULL) { 40 errno = ENOENT; 41 return _LOCALE_NONE; 42 } 43 } 44 45 /* Only character encoding has thread-specific effects. */ 46 if ((mask & LC_CTYPE_MASK) == 0) 47 return oldloc == _LOCALE_UTF8 ? _LOCALE_UTF8 : _LOCALE_C; 48 49 /* The following may initialize UTF-8 for later use. */ 50 if ((locname = _get_locname(LC_CTYPE, locname)) == NULL) { 51 errno = ENOENT; 52 return _LOCALE_NONE; 53 } 54 return strchr(locname, '.') == NULL ? _LOCALE_C : _LOCALE_UTF8; 55 } 56