From 517f2e5ff2e76fef4f53761f7308c2b915c514a9 Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Wed, 2 Sep 2009 01:09:48 +0400 Subject: [PATCH] libc: locale support for static binaries. Compile a fixed set of locales definable by STATIC_LOCALES into libc. Partially-Obtained-From: http://osdir.com/ml/os.netbsd.bugs/2002-09/msg00025.html Dragonfly-bug: http://bugs.dragonflybsd.org/issue1362 --- lib/libc/citrus/Makefile.inc | 19 +++++ lib/libc/citrus/citrus_ctype.c | 4 +- lib/libc/citrus/citrus_module.c | 121 +++++++++++++++++++++++++++++--- 3 files changed, 133 insertions(+), 11 deletions(-) diff --git a/lib/libc/citrus/Makefile.inc b/lib/libc/citrus/Makefile.inc index 9a02571419..8138238e6a 100644 --- a/lib/libc/citrus/Makefile.inc +++ b/lib/libc/citrus/Makefile.inc @@ -5,8 +5,27 @@ .include "../../i18n_module/Makefile.shlib" CFLAGS+= -DI18NMODULE_MAJOR=${MODULE_SHLIB_MAJOR} -D_I18N_DYNAMIC +STATIC_LOCALES?= SRCS+= citrus_bcs.c citrus_csmapper.c citrus_ctype.c citrus_ctype_fallback.c SRCS+= citrus_db.c citrus_db_hash.c citrus_esdb.c citrus_hash.c SRCS+= citrus_iconv.c citrus_lookup.c citrus_mapper.c citrus_memstream.c SRCS+= citrus_mmap.c citrus_module.c citrus_none.c citrus_stdenc.c +SRCS+= citrus_prop.c + +# Add the locale modules to compile-in in the static libc.a (and libc_p.a) +# If a new locale module is added, the includes and the table in +# citrus_module.c must be updated. +# A new module must have the file name citrus_xxx.c where xxx is the lower +# case name of the module. +# Currently the modules specified by STATIC_LOCALES are included in the +# shared libc (but never used). This is a bug. +.if ${STATIC_LOCALES} != "" +.PATH: ${.CURDIR}/../libc/citrus/modules +CFLAGS+=-I${.CURDIR}/citrus +CFLAGS+=-D_I18N_STATIC +.for var in ${STATIC_LOCALES} +SRCS+= citrus_${var:L}.c +CFLAGS+=-D_I18N_STATIC_${var} +.endfor +.endif # STATIC_LOCALES diff --git a/lib/libc/citrus/citrus_ctype.c b/lib/libc/citrus/citrus_ctype.c index 5f60787181..614d423f24 100644 --- a/lib/libc/citrus/citrus_ctype.c +++ b/lib/libc/citrus/citrus_ctype.c @@ -50,7 +50,7 @@ _citrus_ctype_rec_t _citrus_ctype_default = { NULL /* cc_module */ }; -#ifdef _I18N_DYNAMIC +#if defined(_I18N_DYNAMIC) || defined(_I18N_STATIC) static int _initctypemodule(_citrus_ctype_t, char const *, _citrus_module_t, void *, size_t, size_t); @@ -183,7 +183,7 @@ _citrus_ctype_close(_citrus_ctype_t cc) } #else -/* !_I18N_DYNAMIC */ +/* !(_I18N_DYNAMIC || _I18N_STATIC) */ int /*ARGSUSED*/ diff --git a/lib/libc/citrus/citrus_module.c b/lib/libc/citrus/citrus_module.c index 5ae6994a9a..b6b2d5da02 100644 --- a/lib/libc/citrus/citrus_module.c +++ b/lib/libc/citrus/citrus_module.c @@ -105,6 +105,7 @@ #include #include #include +#include #include "citrus_module.h" #include @@ -332,16 +333,64 @@ _citrus_unload_module(_citrus_module_t handle) if (handle) dlclose((void *)handle); } -#else -/* !_I18N_DYNAMIC */ +#elif defined(_I18N_STATIC) +/* + * Compiled-in multibyte locale support for statically linked programs. + */ -SET_DECLARE(citrus_set, struct citrus_metadata); +#include "citrus_ctype.h" +#ifdef _I18N_STATIC_BIG5 +#include "modules/citrus_big5.h" +#endif +#ifdef _I18N_STATIC_EUC +#include "modules/citrus_euc.h" +#endif +#ifdef _I18N_STATIC_EUCTW +#include "modules/citrus_euctw.h" +#endif +#ifdef _I18N_STATIC_ISO2022 +#include "modules/citrus_iso2022.h" +#endif +#ifdef _I18N_STATIC_MSKanji +#include "modules/citrus_mskanji.h" +#endif +#ifdef _I18N_STATIC_UTF8 +#include "modules/citrus_utf8.h" +#endif -struct citrus_metadata empty = { - NULL, NULL, NULL +#define _CITRUS_GETOPS_FUNC(_m_, _if_) _citrus_##_m_##_##_if_##_getops +/* only ctype is supported */ +#define _CITRUS_LOCALE_TABLE_ENTRY(_n_) \ +{ #_n_, "ctype", _CITRUS_GETOPS_FUNC(_n_, ctype) } + +/* + * Table of compiled-in locales. + */ +struct citrus_metadata locale_table[] = { +#ifdef _I18N_STATIC_BIG5 + _CITRUS_LOCALE_TABLE_ENTRY(BIG5), +#endif +#ifdef _I18N_STATIC_EUC + _CITRUS_LOCALE_TABLE_ENTRY(EUC), +#endif +#ifdef _I18N_STATIC_EUCTW + _CITRUS_LOCALE_TABLE_ENTRY(EUCTW), +#endif +#ifdef _I18N_STATIC_ISO2022 + _CITRUS_LOCALE_TABLE_ENTRY(ISO2022), +#endif +#ifdef _I18N_STATIC_MSKanji + _CITRUS_LOCALE_TABLE_ENTRY(MSKanji), +#endif +#ifdef _I18N_STATIC_UTF8 + _CITRUS_LOCALE_TABLE_ENTRY(UTF8), +#endif + { NULL, NULL, NULL }, }; -DATA_SET(citrus_set, empty); +SET_DECLARE(citrus_set, struct citrus_metadata); + +DATA_SET(citrus_set, locale_table); #define MAGIC_HANDLE (void *)(0xC178C178) @@ -352,8 +401,6 @@ _citrus_find_getops(_citrus_module_t handle __unused, const char *modname, { struct citrus_metadata **mdp, *mod; - _DIAGASSERT(handle == MAGIC_HANDLE); - SET_FOREACH(mdp, citrus_set) { mod = *mdp; if (mod == NULL || mod->module_name == NULL || mod->interface_name == NULL) @@ -379,12 +426,68 @@ _citrus_load_module(_citrus_module_t *rhandle, char const *modname) continue; if (strcmp(mod->module_name, modname) != 0) continue; - *rhandle = MAGIC_HANDLE; + *rhandle = (_citrus_module_t)mod; return(0); } return (EINVAL); } +void +/*ARGSUSED*/ +_citrus_unload_module(_citrus_module_t handle __unused) +{ +} +#else +SET_DECLARE(citrus_set, struct citrus_metadata); + +struct citrus_metadata empty = { + NULL, NULL, NULL +}; + +DATA_SET(citrus_set, empty); + +#define MAGIC_HANDLE (void *)(0xC178C178) + +void * +/*ARGSUSED*/ +_citrus_find_getops(_citrus_module_t handle __unused, const char *modname, + const char *ifname) +{ + struct citrus_metadata **mdp, *mod; + + _DIAGASSERT(handle == MAGIC_HANDLE); + + SET_FOREACH(mdp, citrus_set) { + mod = *mdp; + if (mod == NULL || mod->module_name == NULL || mod->interface_name == NULL) + continue; + if (strcmp(mod->module_name, modname) != 0) + continue; + if (strcmp(mod->interface_name, ifname) != 0) + continue; + return(mod->module_ops); + } + return (NULL); +} + +int +/*ARGSUSED*/ +_citrus_load_module(_citrus_module_t *rhandle, char const *modname) +{ + struct citrus_metadata **mdp, *mod; + + SET_FOREACH(mdp, citrus_set) { + mod = *mdp; + if (mod == NULL || mod->module_name == NULL) + continue; + if (strcmp(mod->module_name, modname) != 0) + continue; + *rhandle = MAGIC_HANDLE; + return(0); + } + return (EINVAL); +} + void /*ARGSUSED*/ _citrus_unload_module(_citrus_module_t handle __unused) -- 2.41.0