Subject: Re: lib/18151: Multibyte locale support for statically linked programs
To: None <itojun@iijlab.net>
From: Anders Hjalmarsson <hjalmar@hjalmar.to>
List: netbsd-bugs
Date: 09/03/2002 20:52:53
>
> without locale modules compiled in there's no use in having
> locale-related logic.
>
> itojun
Here is a revised version of the patches. I hope this addresses your
concerns. If STATIC_LOCALES is empty the old stubs are used, so everything
is like before, the new code is only used if STATIC_LOCALES is non-empty.
-hjalmar
Index: share/mk/bsd.README
===================================================================
RCS file: /cvsroot/sharesrc/share/mk/bsd.README,v
retrieving revision 1.101
diff -u -r1.101 bsd.README
--- bsd.README 2002/08/19 14:51:58 1.101
+++ bsd.README 2002/09/03 18:45:36
@@ -364,6 +364,12 @@
point and possibly soft-float library support. Defaults
to "no".
+STATIC_LOCALES The list of locale modules to be compiled-in in the static
+ libc.a (and libc_p.a). Currently supported locales are:
+ BIG5 EUC EUCTW ISO2022 MSKanji UTF8
+ Defaults to "", which means that no multibyte locales
+ are supported by statically linked programs.
+
bsd.own.mk is generally useful when building your own Makefiles so that
they use the same default owners etc. as the rest of the tree.
Index: share/mk/bsd.own.mk
===================================================================
RCS file: /cvsroot/sharesrc/share/mk/bsd.own.mk,v
retrieving revision 1.305
diff -u -r1.305 bsd.own.mk
--- bsd.own.mk 2002/08/03 22:10:07 1.305
+++ bsd.own.mk 2002/09/03 18:45:37
@@ -479,4 +479,9 @@
USE_XF86_4?= yes
.endif
+# The list of locale modules to be compiled-in in the static
+# libc.a (and libc_p.a).
+#STATIC_LOCALES?=BIG5 EUC EUCTW ISO2022 MSKanji UTF8
+STATIC_LOCALES?=
+
.endif # _BSD_OWN_MK_
Index: lib/libc/Makefile
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/Makefile,v
retrieving revision 1.107
diff -u -r1.107 Makefile
--- Makefile 2002/08/19 14:55:14 1.107
+++ Makefile 2002/09/03 18:45:50
@@ -38,7 +38,7 @@
.if ${MACHINE_ARCH} == "i386"
# Set lint to exit on warnings
-LINTFLAGS+= -w
+# XXX citrus modules not clean LINTFLAGS+= -w
.endif
# ignore 'empty translation unit' warnings.
LINTFLAGS+= -X 272
@@ -150,8 +150,9 @@
FILESDIR= /var/db
-# workaround for I18N stuffs: build singlebyte setlocale() for libc.a,
-# multibyte for libc.so. the quirk should be removed when we support
+# workaround for I18N stuffs: build singlebyte, and a compiled-in set of
+# multibyte locales for libc.a, dynamically loadable multibyte locales
+# for libc.so. the quirk should be removed when we support
# dlopen() from within statically linked binaries.
CSHLIBFLAGS+= -D_I18N_DYNAMIC
Index: lib/libc/citrus/Makefile.inc
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/citrus/Makefile.inc,v
retrieving revision 1.2
diff -u -r1.2 Makefile.inc
--- Makefile.inc 2002/08/19 13:35:06 1.2
+++ Makefile.inc 2002/09/03 18:45:53
@@ -11,6 +11,23 @@
SRCS+= citrus_ctype.c citrus_module.c citrus_none.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}/citrus/modules
+CPPFLAGS+=-I${.CURDIR}/citrus
+CPPFLAGS+=-D_I18N_STATIC
+.for var in ${STATIC_LOCALES}
+SRCS+= citrus_${var:tl}.c
+CPPFLAGS+=-D_I18N_STATIC_${var}
+.endfor
+.endif # STATIC_LOCALES
+
# to be dynamically loaded - see lib/i18n_module
#SRCS+= citrus_big5.c citrus_euc.c citrus_euctw.c citrus_iso2022.c \
# citrus_mskanji.c citrus_utf8.c
Index: lib/libc/citrus/citrus_ctype.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/citrus/citrus_ctype.c,v
retrieving revision 1.2
diff -u -r1.2 citrus_ctype.c
--- citrus_ctype.c 2002/03/18 09:02:50 1.2
+++ citrus_ctype.c 2002/09/03 18:45:53
@@ -55,7 +55,7 @@
NULL /* ce_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);
@@ -176,7 +176,7 @@
}
#else
-/* !_I18N_DYNAMIC */
+/* !(_I18N_DYNAMIC || _I18N_STATIC) */
int
/*ARGSUSED*/
Index: lib/libc/citrus/citrus_module.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/citrus/citrus_module.c,v
retrieving revision 1.2
diff -u -r1.2 citrus_module.c
--- citrus_module.c 2002/04/20 05:55:47 1.2
+++ citrus_module.c 2002/09/03 18:45:53
@@ -345,22 +345,118 @@
if (handle)
dlclose((void *)handle);
}
-#else
-/* !_I18N_DYNAMIC */
+#elif defined(_I18N_STATIC)
+
+/*
+ * Compiled-in multibyte locale support for statically linked programs.
+ */
+
+#include "citrus_ctype.h"
+#include "modules/citrus_big5.h"
+#include "modules/citrus_euc.h"
+#include "modules/citrus_euctw.h"
+#include "modules/citrus_iso2022.h"
+#include "modules/citrus_mskanji.h"
+#include "modules/citrus_utf8.h"
+
+#define _CITRUS_GETOPS_FUNC(_m_, _if_) _citrus_##_m_##_##_if_##_getops
+
+#define _CITRUS_LOCALE_TABLE_ENTRY(_n_) \
+{ #_n_, _CITRUS_GETOPS_FUNC(_n_, ctype) }
+/*
+ * Table of compiled-in locales.
+ */
+static const struct _citrus_locale_table_rec {
+ const char *name;
+ _CITRUS_CTYPE_GETOPS_FUNC_BASE((*ctype_fun));
+} _citrus_static_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
+ { 0, 0 }
+};
+
void *
-/*ARGSUSED*/
_citrus_find_getops(_citrus_module_t handle, const char *modname,
const char *ifname)
{
- return (NULL);
+ const struct _citrus_locale_table_rec *p;
+
+ _DIAGASSERT(handle != NULL);
+ _DIAGASSERT(modname != NULL);
+ _DIAGASSERT(ifname != NULL);
+
+ /* LINTED handle is always from _citrus_load_module */
+ p = (const struct _citrus_locale_table_rec *)handle;
+
+ /* Sanity check, should perhaps be a _DIAGASSERT */
+ if (strcmp(p->name, modname))
+ return (NULL);
+
+ /* Currently only ctype is implemented. */
+ if (!strcmp(ifname, "ctype"))
+ return (void *)p->ctype_fun;
+ else
+ return (NULL);
+}
+
+int
+_citrus_load_module(_citrus_module_t *rhandle, char const *encname)
+{
+ const struct _citrus_locale_table_rec *p;
+
+ _DIAGASSERT(rhandle != NULL);
+
+ for (p = _citrus_static_locale_table; p->name; p++) {
+ if (!strcmp(p->name, encname)) {
+ /* LINTED will be used only by _citrus_find_getops */
+ *rhandle = (_citrus_module_t)p;
+ return (0);
+ }
+ }
+
+ /* Not found */
+ return (EINVAL);
}
+void
+/*ARGSUSED*/
+_citrus_unload_module(_citrus_module_t handle)
+{
+}
+
+#else
+/* No static multibyte locales */
+
int
/*ARGSUSED*/
-_citrus_load_module(_citrus_module_t *rhandle, char const *modname)
+_citrus_load_module(_citrus_module_t *rhandle, char const *encname)
{
return (EINVAL);
+}
+
+void *
+/*ARGSUSED*/
+_citrus_find_getops(_citrus_module_t handle, const char *modname,
+ const char *ifname)
+{
+ return (NULL);
}
void