1d915a14eSPedro F. Giffuni /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3d915a14eSPedro F. Giffuni *
474f2b975SAlexey Zelkin * Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org>
590423eceSAlexey Zelkin * All rights reserved.
690423eceSAlexey Zelkin *
73c87aa1dSDavid Chisnall * Copyright (c) 2011 The FreeBSD Foundation
85b5fa75aSEd Maste *
93c87aa1dSDavid Chisnall * Portions of this software were developed by David Chisnall
103c87aa1dSDavid Chisnall * under sponsorship from the FreeBSD Foundation.
113c87aa1dSDavid Chisnall *
1290423eceSAlexey Zelkin * Redistribution and use in source and binary forms, with or without
1390423eceSAlexey Zelkin * modification, are permitted provided that the following conditions
1490423eceSAlexey Zelkin * are met:
1590423eceSAlexey Zelkin * 1. Redistributions of source code must retain the above copyright
1690423eceSAlexey Zelkin * notice, this list of conditions and the following disclaimer.
1790423eceSAlexey Zelkin * 2. Redistributions in binary form must reproduce the above copyright
1890423eceSAlexey Zelkin * notice, this list of conditions and the following disclaimer in the
1990423eceSAlexey Zelkin * documentation and/or other materials provided with the distribution.
2090423eceSAlexey Zelkin *
2190423eceSAlexey Zelkin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2290423eceSAlexey Zelkin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2390423eceSAlexey Zelkin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2490423eceSAlexey Zelkin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2590423eceSAlexey Zelkin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2690423eceSAlexey Zelkin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2790423eceSAlexey Zelkin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2890423eceSAlexey Zelkin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2990423eceSAlexey Zelkin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3090423eceSAlexey Zelkin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3190423eceSAlexey Zelkin * SUCH DAMAGE.
3290423eceSAlexey Zelkin */
3390423eceSAlexey Zelkin
344be19dddSRobert Watson #include <stddef.h>
354be19dddSRobert Watson
3690423eceSAlexey Zelkin #include "ldpart.h"
37683fe113SAlexey Zelkin #include "lmessages.h"
3890423eceSAlexey Zelkin
39fc19bba6SAlexey Zelkin #define LCMESSAGES_SIZE_FULL (sizeof(struct lc_messages_T) / sizeof(char *))
40fc19bba6SAlexey Zelkin #define LCMESSAGES_SIZE_MIN \
41fc19bba6SAlexey Zelkin (offsetof(struct lc_messages_T, yesstr) / sizeof(char *))
4290423eceSAlexey Zelkin
433c87aa1dSDavid Chisnall struct xlocale_messages {
443c87aa1dSDavid Chisnall struct xlocale_component header;
453c87aa1dSDavid Chisnall char *buffer;
463c87aa1dSDavid Chisnall struct lc_messages_T locale;
473c87aa1dSDavid Chisnall };
483c87aa1dSDavid Chisnall
493c87aa1dSDavid Chisnall struct xlocale_messages __xlocale_global_messages;
503c87aa1dSDavid Chisnall
5141b55591SAlexey Zelkin static char empty[] = "";
5290423eceSAlexey Zelkin
5390423eceSAlexey Zelkin static const struct lc_messages_T _C_messages_locale = {
5490423eceSAlexey Zelkin "^[yY]" , /* yesexpr */
5590423eceSAlexey Zelkin "^[nN]" , /* noexpr */
5690423eceSAlexey Zelkin "yes" , /* yesstr */
5790423eceSAlexey Zelkin "no" /* nostr */
5890423eceSAlexey Zelkin };
5990423eceSAlexey Zelkin
605b7e92d4SKonstantin Belousov static void
destruct_messages(void * v)615b7e92d4SKonstantin Belousov destruct_messages(void *v)
623c87aa1dSDavid Chisnall {
633c87aa1dSDavid Chisnall struct xlocale_messages *l = v;
643c87aa1dSDavid Chisnall if (l->buffer)
653c87aa1dSDavid Chisnall free(l->buffer);
663c87aa1dSDavid Chisnall free(l);
673c87aa1dSDavid Chisnall }
6890423eceSAlexey Zelkin
693c87aa1dSDavid Chisnall static int
messages_load_locale(struct xlocale_messages * loc,int * using_locale,const char * name)705b7e92d4SKonstantin Belousov messages_load_locale(struct xlocale_messages *loc, int *using_locale,
715b7e92d4SKonstantin Belousov const char *name)
72ecc4c620SAndrey A. Chernov {
7376692b80SAndrey A. Chernov int ret;
743c87aa1dSDavid Chisnall struct lc_messages_T *l = &loc->locale;
7539d2c772SAlexey Zelkin
763c87aa1dSDavid Chisnall ret = __part_load_locale(name, using_locale,
773c87aa1dSDavid Chisnall &loc->buffer, "LC_MESSAGES",
7839d2c772SAlexey Zelkin LCMESSAGES_SIZE_FULL, LCMESSAGES_SIZE_MIN,
793c87aa1dSDavid Chisnall (const char **)l);
8076692b80SAndrey A. Chernov if (ret == _LDP_LOADED) {
813c87aa1dSDavid Chisnall if (l->yesstr == NULL)
823c87aa1dSDavid Chisnall l->yesstr = empty;
833c87aa1dSDavid Chisnall if (l->nostr == NULL)
843c87aa1dSDavid Chisnall l->nostr = empty;
8576692b80SAndrey A. Chernov }
8676692b80SAndrey A. Chernov return (ret);
8790423eceSAlexey Zelkin }
885b7e92d4SKonstantin Belousov
893c87aa1dSDavid Chisnall int
__messages_load_locale(const char * name)903c87aa1dSDavid Chisnall __messages_load_locale(const char *name)
913c87aa1dSDavid Chisnall {
925b7e92d4SKonstantin Belousov return (messages_load_locale(&__xlocale_global_messages,
935b7e92d4SKonstantin Belousov &__xlocale_global_locale.using_messages_locale, name));
943c87aa1dSDavid Chisnall }
955b7e92d4SKonstantin Belousov
963c87aa1dSDavid Chisnall void *
__messages_load(const char * name,locale_t l)973c87aa1dSDavid Chisnall __messages_load(const char *name, locale_t l)
983c87aa1dSDavid Chisnall {
995b7e92d4SKonstantin Belousov struct xlocale_messages *new = calloc(sizeof(struct xlocale_messages),
1005b7e92d4SKonstantin Belousov 1);
101bc9ce839SKonstantin Belousov if (new == NULL)
102bc9ce839SKonstantin Belousov return (NULL);
1033c87aa1dSDavid Chisnall new->header.header.destructor = destruct_messages;
1045b7e92d4SKonstantin Belousov if (messages_load_locale(new, &l->using_messages_locale, name) ==
1055b7e92d4SKonstantin Belousov _LDP_ERROR) {
1063c87aa1dSDavid Chisnall xlocale_release(new);
1075b7e92d4SKonstantin Belousov return (NULL);
1083c87aa1dSDavid Chisnall }
1095b7e92d4SKonstantin Belousov return (new);
1103c87aa1dSDavid Chisnall }
11190423eceSAlexey Zelkin
11290423eceSAlexey Zelkin struct lc_messages_T *
__get_current_messages_locale(locale_t loc)1133c87aa1dSDavid Chisnall __get_current_messages_locale(locale_t loc)
114ecc4c620SAndrey A. Chernov {
1155b7e92d4SKonstantin Belousov return (loc->using_messages_locale ? &((struct xlocale_messages *)
1165b7e92d4SKonstantin Belousov loc->components[XLC_MESSAGES])->locale :
1175b7e92d4SKonstantin Belousov (struct lc_messages_T *)&_C_messages_locale);
11890423eceSAlexey Zelkin }
11990423eceSAlexey Zelkin
12090423eceSAlexey Zelkin #ifdef LOCALE_DEBUG
12190423eceSAlexey Zelkin void
msgdebug(void)1225b7e92d4SKonstantin Belousov msgdebug(void) {
12390423eceSAlexey Zelkin printf( "yesexpr = %s\n"
12490423eceSAlexey Zelkin "noexpr = %s\n"
12590423eceSAlexey Zelkin "yesstr = %s\n"
12690423eceSAlexey Zelkin "nostr = %s\n",
12790423eceSAlexey Zelkin _messages_locale.yesexpr,
12890423eceSAlexey Zelkin _messages_locale.noexpr,
12990423eceSAlexey Zelkin _messages_locale.yesstr,
13090423eceSAlexey Zelkin _messages_locale.nostr
13190423eceSAlexey Zelkin );
13290423eceSAlexey Zelkin }
13390423eceSAlexey Zelkin #endif /* LOCALE_DEBUG */
134