1 /* 2 * Copyright 2010 Nexenta Systems, Inc. All rights reserved. 3 * Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Copyright (c) 2011 The FreeBSD Foundation 7 * All rights reserved. 8 * Portions of this software were developed by David Chisnall 9 * under sponsorship from the FreeBSD Foundation. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include "lint.h" 34 #include <stddef.h> 35 #include <stdlib.h> 36 #include "ldpart.h" 37 #include "lmessages.h" 38 39 #define LCMESSAGES_SIZE_FULL (sizeof (struct lc_messages_T) / sizeof (char *)) 40 #define LCMESSAGES_SIZE_MIN \ 41 (offsetof(struct lc_messages_T, yesstr) / sizeof (char *)) 42 43 struct xlocale_messages __xlocale_global_messages; 44 45 static char empty[] = ""; 46 47 static const struct lc_messages_T _C_messages_locale = { 48 "^[yY]", /* yesexpr */ 49 "^[nN]", /* noexpr */ 50 "yes", /* yesstr */ 51 "no" /* nostr */ 52 }; 53 54 static void 55 destruct_messages(void *v) 56 { 57 struct xlocale_messages *l = v; 58 59 if (l->buffer != NULL) 60 free(l->buffer); 61 62 free(l); 63 } 64 65 static int 66 messages_load_locale(struct xlocale_messages *loc, int *using_locale, 67 const char *name) 68 { 69 int ret; 70 struct lc_messages_T *l = &loc->locale; 71 72 ret = __part_load_locale(name, using_locale, 73 &loc->buffer, "LC_MESSAGES", 74 LCMESSAGES_SIZE_FULL, LCMESSAGES_SIZE_MIN, 75 (const char **)l); 76 if (ret == _LDP_LOADED) { 77 if (l->yesstr == NULL) 78 l->yesstr = empty; 79 if (l->nostr == NULL) 80 l->nostr = empty; 81 } 82 83 return (ret); 84 } 85 86 int 87 __messages_load_locale(const char *name) 88 { 89 return (messages_load_locale(&__xlocale_global_messages, 90 &__xlocale_global_locale.using_messages_locale, name)); 91 } 92 93 void * 94 __messages_load(const char *name, locale_t l) 95 { 96 struct xlocale_messages *new; 97 98 new = calloc(sizeof(struct xlocale_messages), 1); 99 /* XXX */ 100 new->header.header.destructor = destruct_messages; 101 if (messages_load_locale(new, &l->using_messages_locale, name) == 102 _LDP_ERROR) { 103 xlocale_release(new); 104 return (NULL); 105 } 106 107 return (new); 108 } 109 110 struct lc_messages_T * 111 __get_current_messages_locale(locale_t loc) 112 { 113 return (loc->using_messages_locale 114 ? &((struct xlocale_messages *)loc->components[XLC_MESSAGES])->locale 115 : (struct lc_messages_T *)&_C_messages_locale); 116 }