Allow inclusion of Citrus modules in statically linked binaries.
authorJoerg Sonnenberger <joerg@dragonflybsd.org>
Mon, 4 Jul 2005 08:02:43 +0000 (08:02 +0000)
committerJoerg Sonnenberger <joerg@dragonflybsd.org>
Mon, 4 Jul 2005 08:02:43 +0000 (08:02 +0000)
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
lib/libc/citrus/citrus_iconv_local.h
lib/libc/citrus/citrus_mapper_local.h
lib/libc/citrus/citrus_module.c
lib/libc/citrus/citrus_module.h
lib/libc/citrus/citrus_none.c
lib/libc/citrus/citrus_stdenc_local.h

index da5c332..332174b 100644 (file)
@@ -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 = {                  \
index 9c834c9..39dedbb 100644 (file)
@@ -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_)                                     \
index ddef553..208007c 100644 (file)
@@ -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 = {               \
index 7c11eeb..9b47829 100644 (file)
@@ -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,
 #include <dirent.h>
 #include <dlfcn.h>
 
-#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
index 84b8493..62771ce 100644 (file)
@@ -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,
 #ifndef _CITRUS_MODULE_H_
 #define _CITRUS_MODULE_H_
 
+#include <sys/linker_set.h>
+
+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
index 63ec213..3298ffd 100644 (file)
@@ -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,
 #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<sizeof(*ops))
+               return (EINVAL);
+
+       memcpy(ops, &_citrus_NONE_ctype_ops, sizeof(_citrus_NONE_ctype_ops));
+
+       return (0);
+}
+
+static int
+_citrus_NONE_stdenc_getops(struct _citrus_stdenc_ops *ops, size_t lenops,
+                        uint32_t expected_version)
+{
+       if (expected_version<_CITRUS_STDENC_ABI_VERSION || lenops<sizeof(*ops))
+               return (EINVAL);
+
+       memcpy(ops, &_citrus_NONE_stdenc_ops, sizeof(_citrus_NONE_stdenc_ops));
+
+       return (0);
+}
+
 static int
 /*ARGSUSED*/
 _citrus_NONE_ctype_init(void ** __restrict cl, void * __restrict var __unused,
index 968a5ab..4e1c20f 100644 (file)
@@ -1,5 +1,5 @@
 /*     $NetBSD: src/lib/libc/citrus/citrus_stdenc_local.h,v 1.2 2003/06/26 12:09:57 tshiozak Exp $     */
-/*     $DragonFly: src/lib/libc/citrus/citrus_stdenc_local.h,v 1.1 2005/03/11 23:33:53 joerg Exp $ */
+/*     $DragonFly: src/lib/libc/citrus/citrus_stdenc_local.h,v 1.2 2005/07/04 08:02:43 joerg Exp $ */
 
 /*-
  * Copyright (c)2003 Citrus Project,
@@ -31,6 +31,8 @@
 #ifndef _CITRUS_STDENC_LOCAL_H_
 #define _CITRUS_STDENC_LOCAL_H_
 
+#include "citrus_module.h"
+
 #define _CITRUS_STDENC_GETOPS_FUNC_BASE(n)                     \
 int n(struct _citrus_stdenc_ops *, size_t, uint32_t)
 #define _CITRUS_STDENC_GETOPS_FUNC(_e_)                                        \
@@ -64,7 +66,8 @@ static int    _citrus_##_e_##_stdenc_wctomb                           \
         _citrus_wc_t, void * __restrict, size_t * __restrict);         \
 static int     _citrus_##_e_##_stdenc_put_state_reset                  \
        (struct _citrus_stdenc * __restrict, char * __restrict, size_t, \
-        void * __restrict, size_t * __restrict)
+        void * __restrict, size_t * __restrict);                       \
+CITRUS_MODULE(_e_, stdenc, _citrus_##_e_##_stdenc_getops)
 
 #define _CITRUS_STDENC_DEF_OPS(_e_)                                    \
 struct _citrus_stdenc_ops _citrus_##_e_##_stdenc_ops = {               \