From 5be9f868f6cf09f45b25f2021480281931d20faf Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Mon, 4 Jul 2005 08:02:43 +0000 Subject: [PATCH] Allow inclusion of Citrus modules in statically linked binaries. To achieve this, ensure that _citrus_module_$MOD is referenced from the binary and link with -L/usr/lib/i18n -l$MOD for all modules you are interested in. --- lib/libc/citrus/citrus_ctype_local.h | 7 +++-- lib/libc/citrus/citrus_iconv_local.h | 7 +++-- lib/libc/citrus/citrus_mapper_local.h | 7 +++-- lib/libc/citrus/citrus_module.c | 43 ++++++++++++++++++++++++--- lib/libc/citrus/citrus_module.h | 27 ++++++++++++++++- lib/libc/citrus/citrus_none.c | 30 ++++++++++++++++++- lib/libc/citrus/citrus_stdenc_local.h | 7 +++-- 7 files changed, 114 insertions(+), 14 deletions(-) diff --git a/lib/libc/citrus/citrus_ctype_local.h b/lib/libc/citrus/citrus_ctype_local.h index da5c332cc0..332174b1cd 100644 --- a/lib/libc/citrus/citrus_ctype_local.h +++ b/lib/libc/citrus/citrus_ctype_local.h @@ -1,5 +1,5 @@ /* $NetBSD: src/lib/libc/citrus/citrus_ctype_local.h,v 1.2 2003/03/05 20:18:15 tshiozak Exp $ */ -/* $DragonFly: src/lib/libc/citrus/citrus_ctype_local.h,v 1.1 2005/03/11 23:33:53 joerg Exp $ */ +/* $DragonFly: src/lib/libc/citrus/citrus_ctype_local.h,v 1.2 2005/07/04 08:02:43 joerg Exp $ */ /*- @@ -32,6 +32,8 @@ #ifndef _CITRUS_CTYPE_LOCAL_H_ #define _CITRUS_CTYPE_LOCAL_H_ +#include "citrus_module.h" + #define _CITRUS_CTYPE_GETOPS_FUNC_BASE(_n_) \ int _n_(_citrus_ctype_ops_rec_t *, size_t, uint32_t) #define _CITRUS_CTYPE_GETOPS_FUNC(_n_) \ @@ -89,7 +91,8 @@ static int _citrus_##_e_##_ctype_wctomb(void * __restrict, \ static int _citrus_##_e_##_ctype_btowc(_citrus_ctype_rec_t * __restrict, \ int, wint_t * __restrict); \ static int _citrus_##_e_##_ctype_wctob(_citrus_ctype_rec_t * __restrict, \ - wint_t, int * __restrict) + wint_t, int * __restrict); \ +CITRUS_MODULE(_e_, ctype, _citrus_##_e_##_ctype_getops) #define _CITRUS_CTYPE_DEF_OPS(_e_) \ _citrus_ctype_ops_rec_t _citrus_##_e_##_ctype_ops = { \ diff --git a/lib/libc/citrus/citrus_iconv_local.h b/lib/libc/citrus/citrus_iconv_local.h index 9c834c9457..39dedbb333 100644 --- a/lib/libc/citrus/citrus_iconv_local.h +++ b/lib/libc/citrus/citrus_iconv_local.h @@ -1,5 +1,5 @@ /* $NetBSD: src/lib/libc/citrus/citrus_iconv_local.h,v 1.2 2003/07/01 09:42:16 tshiozak Exp $ */ -/* $DragonFly: src/lib/libc/citrus/citrus_iconv_local.h,v 1.1 2005/03/11 23:33:53 joerg Exp $ */ +/* $DragonFly: src/lib/libc/citrus/citrus_iconv_local.h,v 1.2 2005/07/04 08:02:43 joerg Exp $ */ /*- * Copyright (c)2003 Citrus Project, @@ -30,6 +30,8 @@ #ifndef _CITRUS_ICONV_LOCAL_H_ #define _CITRUS_ICONV_LOCAL_H_ +#include "citrus_module.h" + #define _CITRUS_ICONV_GETOPS_FUNC_BASE(_n_) \ int _n_(struct _citrus_iconv_ops *, size_t, uint32_t) #define _CITRUS_ICONV_GETOPS_FUNC(_n_) \ @@ -51,7 +53,8 @@ static int _citrus_##_m_##_iconv_convert \ static int _citrus_##_m_##_iconv_init_context \ (struct _citrus_iconv *); \ static void _citrus_##_m_##_iconv_uninit_context \ - (struct _citrus_iconv *) + (struct _citrus_iconv *); \ +CITRUS_MODULE(_m_, iconv, _citrus_##_m_##_iconv_getops) #define _CITRUS_ICONV_DEF_OPS(_m_) \ diff --git a/lib/libc/citrus/citrus_mapper_local.h b/lib/libc/citrus/citrus_mapper_local.h index ddef553e45..208007cbf9 100644 --- a/lib/libc/citrus/citrus_mapper_local.h +++ b/lib/libc/citrus/citrus_mapper_local.h @@ -1,5 +1,5 @@ /* $NetBSD: src/lib/libc/citrus/citrus_mapper_local.h,v 1.1 2003/06/25 09:51:36 tshiozak Exp $ */ -/* $DragonFly: src/lib/libc/citrus/citrus_mapper_local.h,v 1.1 2005/03/11 23:33:53 joerg Exp $ */ +/* $DragonFly: src/lib/libc/citrus/citrus_mapper_local.h,v 1.2 2005/07/04 08:02:43 joerg Exp $ */ /*- * Copyright (c)2003 Citrus Project, @@ -30,6 +30,8 @@ #ifndef _CITRUS_MAPPER_LOCAL_H_ #define _CITRUS_MAPPER_LOCAL_H_ +#include "citrus_module.h" + #define _CITRUS_MAPPER_GETOPS_FUNC_BASE(_n_) \ int _n_(struct _citrus_mapper_ops *, size_t, u_int32_t) #define _CITRUS_MAPPER_GETOPS_FUNC(_n_) \ @@ -47,7 +49,8 @@ static int _citrus_##_m_##_mapper_convert \ _citrus_index_t * __restrict, _citrus_index_t, \ void * __restrict); \ static void _citrus_##_m_##_mapper_init_state \ - (struct _citrus_mapper * __restrict, void * __restrict); + (struct _citrus_mapper * __restrict, void * __restrict); \ +CITRUS_MODULE(_m_, mapper, _citrus_##_m_##_mapper_getops) #define _CITRUS_MAPPER_DEF_OPS(_m_) \ struct _citrus_mapper_ops _citrus_##_m_##_mapper_ops = { \ diff --git a/lib/libc/citrus/citrus_module.c b/lib/libc/citrus/citrus_module.c index 7c11eebb7f..9b478291da 100644 --- a/lib/libc/citrus/citrus_module.c +++ b/lib/libc/citrus/citrus_module.c @@ -1,5 +1,5 @@ /* $NetBSD: src/lib/libc/citrus/citrus_module.c,v 1.4 2004/12/21 09:00:01 yamt Exp $ */ -/* $DragonFly: src/lib/libc/citrus/citrus_module.c,v 1.2 2005/03/16 06:13:24 joerg Exp $ */ +/* $DragonFly: src/lib/libc/citrus/citrus_module.c,v 1.3 2005/07/04 08:02:43 joerg Exp $ */ /*- * Copyright (c)1999, 2000, 2001, 2002 Citrus Project, @@ -111,7 +111,7 @@ #include #include -#ifdef _I18N_DYNAMIC +#ifdef __PIC__ static int _getdewey(int [], char *); static int _cmpndewey(int [], int, int [], int); @@ -335,11 +335,35 @@ _citrus_unload_module(_citrus_module_t handle) #else /* !_I18N_DYNAMIC */ +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, const char *modname, +_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); } @@ -347,12 +371,23 @@ 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) +_citrus_unload_module(_citrus_module_t handle __unused) { } #endif diff --git a/lib/libc/citrus/citrus_module.h b/lib/libc/citrus/citrus_module.h index 84b8493fdc..62771ce560 100644 --- a/lib/libc/citrus/citrus_module.h +++ b/lib/libc/citrus/citrus_module.h @@ -1,5 +1,5 @@ /* $NetBSD: src/lib/libc/citrus/citrus_module.h,v 1.1 2002/03/17 22:14:20 tshiozak Exp $ */ -/* $DragonFly: src/lib/libc/citrus/citrus_module.h,v 1.1 2005/03/11 23:33:53 joerg Exp $ */ +/* $DragonFly: src/lib/libc/citrus/citrus_module.h,v 1.2 2005/07/04 08:02:43 joerg Exp $ */ /*- * Copyright (c)2002 Citrus Project, @@ -31,6 +31,31 @@ #ifndef _CITRUS_MODULE_H_ #define _CITRUS_MODULE_H_ +#include + +struct citrus_metadata { + const char *module_name; + const char *interface_name; + void *module_ops; +}; + +#ifdef __PIC__ +#define CITRUS_MODULE(name, interface, ops) +#else + +#define CITRUS_MODULE(name, interface, ops) \ +static const char __citrus_module_ ## name ## _ ## interface ## _str[] = \ + #name; \ +static struct citrus_metadata \ + __citrus_module_ ## name ## _ ## interface = { \ + __citrus_module_ ## name ## _ ##interface ## _str, \ + #interface, ops \ +}; \ +__weak_reference(__citrus_module_ ## name ## _ ## interface ## _str, \ + _citrus_module_ ## name); \ +DATA_SET(citrus_set, __citrus_module_ ## name ## _ ## interface); +#endif + typedef struct _citrus_module_rec *_citrus_module_t; __BEGIN_DECLS diff --git a/lib/libc/citrus/citrus_none.c b/lib/libc/citrus/citrus_none.c index 63ec213f32..3298ffdde4 100644 --- a/lib/libc/citrus/citrus_none.c +++ b/lib/libc/citrus/citrus_none.c @@ -1,5 +1,5 @@ /* $NetBSD: src/lib/libc/citrus/citrus_none.c,v 1.12 2004/01/18 03:57:30 yamt Exp $ */ -/* $DragonFly: src/lib/libc/citrus/citrus_none.c,v 1.3 2005/04/26 14:03:57 joerg Exp $ */ +/* $DragonFly: src/lib/libc/citrus/citrus_none.c,v 1.4 2005/07/04 08:02:43 joerg Exp $ */ /*- * Copyright (c)2002 Citrus Project, @@ -45,6 +45,10 @@ #include "citrus_stdenc.h" /* ---------------------------------------------------------------------- */ +static int +_citrus_NONE_ctype_getops(_citrus_ctype_ops_rec_t *, size_t, uint32_t); +static int +_citrus_NONE_stdenc_getops(struct _citrus_stdenc_ops *, size_t, uint32_t); _CITRUS_CTYPE_DECLS(NONE); _CITRUS_CTYPE_DEF_OPS(NONE); @@ -52,6 +56,30 @@ _CITRUS_CTYPE_DEF_OPS(NONE); /* ---------------------------------------------------------------------- */ +static int +_citrus_NONE_ctype_getops(_citrus_ctype_ops_rec_t *ops, size_t lenops, + uint32_t expected_version) +{ + if (expected_version<_CITRUS_CTYPE_ABI_VERSION || lenops