1/* $NetBSD: citrus_lc_numeric.c,v 1.3 2010/05/22 08:13:18 tnozaki Exp $ */ 2 3/*- 4 * Copyright (c)2008 Citrus Project, 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30#if defined(LIBC_SCCS) && !defined(lint) 31__RCSID("$NetBSD: citrus_lc_numeric.c,v 1.3 2010/05/22 08:13:18 tnozaki Exp $"); 32#endif /* LIBC_SCCS and not lint */ 33 34#include "namespace.h" 35#include "reentrant.h" 36#include <sys/types.h> 37#include <sys/localedef.h> 38#include <sys/queue.h> 39#include <assert.h> 40#include <errno.h> 41#include <langinfo.h> 42#include <limits.h> 43#define __SETLOCALE_SOURCE__ 44#include <locale.h> 45#include <stddef.h> 46#include <stdio.h> 47#include <stdlib.h> 48#include <string.h> 49 50#include "setlocale_local.h" 51 52#include "citrus_namespace.h" 53#include "citrus_types.h" 54#include "citrus_bcs.h" 55#include "citrus_region.h" 56#include "citrus_lookup.h" 57#include "citrus_aliasname_local.h" 58#include "citrus_module.h" 59#include "citrus_mmap.h" 60#include "citrus_hash.h" 61#include "citrus_db.h" 62#include "citrus_db_hash.h" 63#include "citrus_memstream.h" 64#include "runetype_local.h" 65 66#include "fix_grouping.h" 67#include "citrus_fix_grouping.h" 68 69/* 70 * macro required by all template headers 71 */ 72#define _PREFIX(name) __CONCAT(_citrus_LC_NUMERIC_, name) 73 74#include "nb_lc_numeric_misc.h" 75#include "citrus_lc_template_decl.h" 76 77static __inline void 78_citrus_LC_NUMERIC_uninit(_NumericLocale *data) 79{ 80 free(__UNCONST(data->decimal_point)); 81 free(__UNCONST(data->thousands_sep)); 82 free(__UNCONST(data->grouping)); 83} 84 85#include "citrus_lc_numeric.h" 86 87struct _citrus_LC_NUMERIC_key { 88 const char *name; 89 size_t offset; 90}; 91 92#define OFFSET(field) (offsetof(_NumericLocale, field)) 93static const struct _citrus_LC_NUMERIC_key keys[] = { 94 { _CITRUS_LC_NUMERIC_SYM_DECIMAL_POINT, OFFSET(decimal_point) }, 95 { _CITRUS_LC_NUMERIC_SYM_THOUSANDS_SEP, OFFSET(thousands_sep) }, 96 { _CITRUS_LC_NUMERIC_SYM_GROUPING, OFFSET(grouping ) }, 97 { NULL, 0 } 98}; 99 100static __inline int 101_citrus_LC_NUMERIC_init_normal(_NumericLocale * __restrict data, 102 struct _citrus_db * __restrict db) 103{ 104 const struct _citrus_LC_NUMERIC_key *key; 105 char **p; 106 const char *s; 107 108 _DIAGASSERT(data != NULL); 109 _DIAGASSERT(db != NULL); 110 111 memset(data, 0, sizeof(*data)); 112 for (key = &keys[0]; key->name != NULL; ++key) { 113 if (_db_lookupstr_by_s(db, key->name, &s, NULL)) 114 goto fatal; 115 p = (char **)(void *) 116 (((char *)(void *)data) + key->offset); 117 *p = strdup(s); 118 if (*p == NULL) 119 goto fatal; 120 } 121 _CITRUS_FIXUP_CHAR_MAX_MD(data->grouping); 122 123 return 0; 124 125fatal: 126 _citrus_LC_NUMERIC_uninit(data); 127 return EFTYPE; 128} 129 130static __inline int 131_citrus_LC_NUMERIC_init_fallback(_NumericLocale * __restrict data, 132 struct _memstream * __restrict ms) 133{ 134 const struct _citrus_LC_NUMERIC_key *key; 135 char **p; 136 const char *s; 137 size_t n; 138 139 _DIAGASSERT(data != NULL); 140 _DIAGASSERT(ms != NULL); 141 142 memset(data, 0, sizeof(*data)); 143 for (key = &keys[0]; key->name != NULL; ++key) { 144 if ((s = _memstream_getln(ms, &n)) == NULL) 145 goto fatal; 146 p = (char **)(void *) 147 (((char *)(void *)data) + key->offset); 148 *p = strndup(s, n - 1); 149 if (*p == NULL) 150 goto fatal; 151 } 152 data->grouping = 153 __fix_locale_grouping_str(data->grouping); 154 155 return 0; 156 157fatal: 158 _citrus_LC_NUMERIC_uninit(data); 159 return EFTYPE; 160} 161 162/* 163 * macro required by citrus_lc_template.h 164 */ 165#define _CATEGORY_DB "LC_NUMERIC" 166#define _CATEGORY_MAGIC _CITRUS_LC_NUMERIC_MAGIC_1 167 168#include "citrus_lc_template.h" 169_LOCALE_CATEGORY_ENTRY(_citrus_LC_NUMERIC_); 170