libc: locale support for static binaries.
authorAlexander Polakov <polachok@gmail.com>
Tue, 1 Sep 2009 21:09:48 +0000 (01:09 +0400)
committerSimon Schubert <corecode@dragonflybsd.org>
Wed, 2 Sep 2009 01:56:43 +0000 (03:56 +0200)
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
lib/libc/citrus/citrus_ctype.c
lib/libc/citrus/citrus_module.c

index 9a02571..8138238 100644 (file)
@@ -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
index 5f60787..614d423 100644 (file)
@@ -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*/
index 5ae6994..b6b2d5d 100644 (file)
 #include <locale.h>
 #include <stddef.h>
 #include <paths.h>
+#include <wchar.h>
 #include "citrus_module.h"
 
 #include <sys/types.h>
@@ -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,7 +426,7 @@ _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);
@@ -390,4 +437,60 @@ void
 _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)
+{
+}
 #endif