xref: /netbsd-src/lib/libc/locale/generic_lc_all.c (revision ace5b9b5feb0e7608bd2da7a617428d2e1cf8aa3)
1*ace5b9b5Schristos /* $NetBSD: generic_lc_all.c,v 1.7 2024/01/20 14:52:48 christos Exp $ */
252ed7b03Stnozaki 
352ed7b03Stnozaki /*-
452ed7b03Stnozaki  * Copyright (c)2008 Citrus Project,
552ed7b03Stnozaki  * All rights reserved.
652ed7b03Stnozaki  *
752ed7b03Stnozaki  * Redistribution and use in source and binary forms, with or without
852ed7b03Stnozaki  * modification, are permitted provided that the following conditions
952ed7b03Stnozaki  * are met:
1052ed7b03Stnozaki  * 1. Redistributions of source code must retain the above copyright
1152ed7b03Stnozaki  *    notice, this list of conditions and the following disclaimer.
1252ed7b03Stnozaki  * 2. Redistributions in binary form must reproduce the above copyright
1352ed7b03Stnozaki  *    notice, this list of conditions and the following disclaimer in the
1452ed7b03Stnozaki  *    documentation and/or other materials provided with the distribution.
1552ed7b03Stnozaki  *
1652ed7b03Stnozaki  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1752ed7b03Stnozaki  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1852ed7b03Stnozaki  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1952ed7b03Stnozaki  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2052ed7b03Stnozaki  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2152ed7b03Stnozaki  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2252ed7b03Stnozaki  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2352ed7b03Stnozaki  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2452ed7b03Stnozaki  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2552ed7b03Stnozaki  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2652ed7b03Stnozaki  * SUCH DAMAGE.
2752ed7b03Stnozaki  */
2852ed7b03Stnozaki 
2952ed7b03Stnozaki #include <sys/cdefs.h>
3052ed7b03Stnozaki #if defined(LIBC_SCCS) && !defined(lint)
31*ace5b9b5Schristos __RCSID("$NetBSD: generic_lc_all.c,v 1.7 2024/01/20 14:52:48 christos Exp $");
3252ed7b03Stnozaki #endif /* LIBC_SCCS and not lint */
3352ed7b03Stnozaki 
34c5b83981Skamil #include "namespace.h"
3552ed7b03Stnozaki #include <sys/types.h>
3652ed7b03Stnozaki #include <assert.h>
3752ed7b03Stnozaki #include <langinfo.h>
3852ed7b03Stnozaki #define __SETLOCALE_SOURCE__
3952ed7b03Stnozaki #include <locale.h>
4052ed7b03Stnozaki #include <stdio.h>
4152ed7b03Stnozaki #include <stdlib.h>
4252ed7b03Stnozaki #include <string.h>
4352ed7b03Stnozaki 
4452ed7b03Stnozaki #include "setlocale_local.h"
4552ed7b03Stnozaki 
4652ed7b03Stnozaki /*
4752ed7b03Stnozaki  * macro required by all template headers
4852ed7b03Stnozaki  */
4952ed7b03Stnozaki #define _PREFIX(name)	__CONCAT(_generic_LC_ALL_, name)
5052ed7b03Stnozaki 
5152ed7b03Stnozaki #include "generic_lc_template_decl.h"
5252ed7b03Stnozaki 
5352ed7b03Stnozaki const char *
_generic_LC_ALL_setlocale(const char * __restrict name,struct _locale * __restrict locale)5452ed7b03Stnozaki _generic_LC_ALL_setlocale(const char * __restrict name,
5514b179f1Sjoerg     struct _locale * __restrict locale)
5652ed7b03Stnozaki {
572f142eb3Stnozaki 	_locale_set_t sl;
5852ed7b03Stnozaki 	char head[_LOCALENAME_LEN_MAX * (_LC_LAST - 1)], *tail;
5952ed7b03Stnozaki 	const char *tokens[_LC_LAST], *s, *t;
606c81c0d8Stnozaki 	int load_locale_success, i, j;
6152ed7b03Stnozaki 
622f142eb3Stnozaki 	sl = _find_category(1);
632f142eb3Stnozaki 	_DIAGASSERT(sl != NULL);
646c81c0d8Stnozaki 	load_locale_success = 0;
6552ed7b03Stnozaki 	if (name != NULL) {
6652ed7b03Stnozaki 		strlcpy(&head[0], name, sizeof(head));
6752ed7b03Stnozaki 		tokens[1] = &head[0];
68*ace5b9b5Schristos 		tail = __UNCONST(strchr(tokens[1], '/'));
6952ed7b03Stnozaki 		if (tail == NULL) {
7052ed7b03Stnozaki 			for (i = 2; i < _LC_LAST; ++i)
7152ed7b03Stnozaki 				tokens[i] = tokens[1];
7252ed7b03Stnozaki 		} else {
7352ed7b03Stnozaki 			*tail++ = '\0';
7452ed7b03Stnozaki 			for (i = 2; i < _LC_LAST - 1; ++i) {
7552ed7b03Stnozaki 				tokens[i] = (const char *)tail;
76*ace5b9b5Schristos 				tail = __UNCONST(strchr(tokens[i], '/'));
7752ed7b03Stnozaki 				if (tail == NULL)
7852ed7b03Stnozaki 					return NULL;
7952ed7b03Stnozaki 				*tail++ = '\0';
8052ed7b03Stnozaki 			}
8152ed7b03Stnozaki 			tokens[_LC_LAST - 1] = (const char *)tail;
82*ace5b9b5Schristos 			tail = __UNCONST(strchr(tokens[i], '/'));
836c81c0d8Stnozaki 			if (tail != NULL)
8452ed7b03Stnozaki 				return NULL;
8552ed7b03Stnozaki 		}
862f142eb3Stnozaki 		if ((*sl)(tokens[1], locale) != NULL)
876c81c0d8Stnozaki 			load_locale_success = 1;
8852ed7b03Stnozaki 	}
892f142eb3Stnozaki 	s = (*sl)(NULL, locale);
9052ed7b03Stnozaki 	_DIAGASSERT(s != NULL);
9152ed7b03Stnozaki 	strlcpy(&locale->query[0], s, sizeof(locale->query));
9252ed7b03Stnozaki 	for (i = 2, j = 0; i < _LC_LAST; ++i) {
932f142eb3Stnozaki 		sl = _find_category(i);
942f142eb3Stnozaki 		_DIAGASSERT(sl != NULL);
956c81c0d8Stnozaki 		if (name != NULL) {
962f142eb3Stnozaki 			if ((*sl)(tokens[i], locale) != NULL)
976c81c0d8Stnozaki 				load_locale_success = 1;
986c81c0d8Stnozaki 		}
992f142eb3Stnozaki 		t = (*sl)(NULL, locale);
10052ed7b03Stnozaki 		_DIAGASSERT(t != NULL);
10152ed7b03Stnozaki 		if (j == 0) {
10252ed7b03Stnozaki 			if (!strcmp(s, t))
10352ed7b03Stnozaki 				continue;
10452ed7b03Stnozaki 			for (j = 2; j < i; ++j) {
10552ed7b03Stnozaki 				strlcat(&locale->query[0], "/",
10652ed7b03Stnozaki 				    sizeof(locale->query));
10752ed7b03Stnozaki 				strlcat(&locale->query[0], s,
10852ed7b03Stnozaki 				    sizeof(locale->query));
10952ed7b03Stnozaki 			}
11052ed7b03Stnozaki 		}
11152ed7b03Stnozaki 		strlcat(&locale->query[0], "/", sizeof(locale->query));
11252ed7b03Stnozaki 		strlcat(&locale->query[0], t, sizeof(locale->query));
11352ed7b03Stnozaki 	}
1146c81c0d8Stnozaki 	if (name != NULL && !load_locale_success)
1156c81c0d8Stnozaki 		return NULL;
11652ed7b03Stnozaki 	return (const char *)&locale->query[0];
11752ed7b03Stnozaki }
118