172165Sphantom/*
287658Sphantom * Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org>
372165Sphantom * All rights reserved.
472165Sphantom *
5227753Stheraven * Copyright (c) 2011 The FreeBSD Foundation
6227753Stheraven * All rights reserved.
7227753Stheraven * Portions of this software were developed by David Chisnall
8227753Stheraven * under sponsorship from the FreeBSD Foundation.
9227753Stheraven *
1072165Sphantom * Redistribution and use in source and binary forms, with or without
1172165Sphantom * modification, are permitted provided that the following conditions
1272165Sphantom * are met:
1372165Sphantom * 1. Redistributions of source code must retain the above copyright
1472165Sphantom *    notice, this list of conditions and the following disclaimer.
1572165Sphantom * 2. Redistributions in binary form must reproduce the above copyright
1672165Sphantom *    notice, this list of conditions and the following disclaimer in the
1772165Sphantom *    documentation and/or other materials provided with the distribution.
1872165Sphantom *
1972165Sphantom * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2072165Sphantom * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2172165Sphantom * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2272165Sphantom * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2372165Sphantom * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2472165Sphantom * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2572165Sphantom * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2672165Sphantom * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2772165Sphantom * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2872165Sphantom * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2972165Sphantom * SUCH DAMAGE.
3072165Sphantom */
3172165Sphantom
3292986Sobrien#include <sys/cdefs.h>
3392986Sobrien__FBSDID("$FreeBSD$");
3492986Sobrien
3572390Srwatson#include <stddef.h>
3672390Srwatson
37116875Sphantom#include "ldpart.h"
3872165Sphantom#include "lmessages.h"
3972165Sphantom
4072360Sphantom#define LCMESSAGES_SIZE_FULL (sizeof(struct lc_messages_T) / sizeof(char *))
4172360Sphantom#define LCMESSAGES_SIZE_MIN \
4272360Sphantom		(offsetof(struct lc_messages_T, yesstr) / sizeof(char *))
4372165Sphantom
44227753Stheravenstruct xlocale_messages {
45227753Stheraven	struct xlocale_component header;
46227753Stheraven	char *buffer;
47227753Stheraven	struct lc_messages_T locale;
48227753Stheraven};
49227753Stheraven
50227753Stheravenstruct xlocale_messages __xlocale_global_messages;
51227753Stheraven
5272976Sphantomstatic char empty[] = "";
5372165Sphantom
5472165Sphantomstatic const struct lc_messages_T _C_messages_locale = {
5572165Sphantom	"^[yY]" ,	/* yesexpr */
5672165Sphantom	"^[nN]" ,	/* noexpr */
5772165Sphantom	"yes" , 	/* yesstr */
5872165Sphantom	"no"		/* nostr */
5972165Sphantom};
6072165Sphantom
61227753Stheravenstatic void destruct_messages(void *v)
62227753Stheraven{
63227753Stheraven	struct xlocale_messages *l = v;
64227753Stheraven	if (l->buffer)
65227753Stheraven		free(l->buffer);
66227753Stheraven	free(l);
67227753Stheraven}
6872165Sphantom
69227753Stheravenstatic int
70227753Stheravenmessages_load_locale(struct xlocale_messages *loc, int *using_locale, const char *name)
71101470Sache{
72101498Sache	int ret;
73227753Stheraven	struct lc_messages_T *l = &loc->locale;
7472443Sphantom
75227753Stheraven	ret = __part_load_locale(name, using_locale,
76227753Stheraven		  &loc->buffer, "LC_MESSAGES",
77101498Sache		  LCMESSAGES_SIZE_FULL, LCMESSAGES_SIZE_MIN,
78227753Stheraven		  (const char **)l);
79101498Sache	if (ret == _LDP_LOADED) {
80227753Stheraven		if (l->yesstr == NULL)
81227753Stheraven			l->yesstr = empty;
82227753Stheraven		if (l->nostr == NULL)
83227753Stheraven			l->nostr = empty;
84101498Sache	}
85101498Sache	return (ret);
8672165Sphantom}
87227753Stheravenint
88227753Stheraven__messages_load_locale(const char *name)
89227753Stheraven{
90227753Stheraven	return messages_load_locale(&__xlocale_global_messages,
91227753Stheraven			&__xlocale_global_locale.using_messages_locale, name);
92227753Stheraven}
93227753Stheravenvoid *
94227753Stheraven__messages_load(const char *name, locale_t l)
95227753Stheraven{
96227753Stheraven	struct xlocale_messages *new = calloc(sizeof(struct xlocale_messages), 1);
97227753Stheraven	new->header.header.destructor = destruct_messages;
98227753Stheraven	if (messages_load_locale(new, &l->using_messages_locale, name) == _LDP_ERROR) {
99227753Stheraven		xlocale_release(new);
100227753Stheraven		return NULL;
101227753Stheraven	}
102227753Stheraven	return new;
103227753Stheraven}
10472165Sphantom
10572165Sphantomstruct lc_messages_T *
106227753Stheraven__get_current_messages_locale(locale_t loc)
107101470Sache{
108227753Stheraven	return (loc->using_messages_locale
109227753Stheraven		? &((struct xlocale_messages *)loc->components[XLC_MESSAGES])->locale
11072165Sphantom		: (struct lc_messages_T *)&_C_messages_locale);
11172165Sphantom}
11272165Sphantom
11372165Sphantom#ifdef LOCALE_DEBUG
11472165Sphantomvoid
11572165Sphantommsgdebug() {
11672165Sphantomprintf(	"yesexpr = %s\n"
11772165Sphantom	"noexpr = %s\n"
11872165Sphantom	"yesstr = %s\n"
11972165Sphantom	"nostr = %s\n",
12072165Sphantom	_messages_locale.yesexpr,
12172165Sphantom	_messages_locale.noexpr,
12272165Sphantom	_messages_locale.yesstr,
12372165Sphantom	_messages_locale.nostr
12472165Sphantom);
12572165Sphantom}
12672165Sphantom#endif /* LOCALE_DEBUG */
127