Subject: lib/18151: Multibyte locale support for statically linked programs
To: None <gnats-bugs@gnats.netbsd.org>
From: Anders Hjalmarsson <hjalmar@hjalmar.to>
List: netbsd-bugs
Date: 09/02/2002 20:51:36
>Number:         18151
>Category:       lib
>Synopsis:       Multibyte locale support for statically linked programs
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    lib-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Mon Sep 02 11:53:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Anders Hjalmarsson
>Release:        NetBSD 1.6F current 20020824
>Organization:
>Environment:
System: NetBSD bigbox.hjalmar.to 1.6F NetBSD 1.6F (BIGBOX-$Revision: 1.7 $) #204: Sun Sep 1 02:14:27 CEST 2002 hjalmar@bigbox.hjalmar.to:/usr/SRC/config/i386/compile/BIGBOX i386
Architecture: i386
Machine: i386
>Description:
	Multibyte locales do not work in statically linked programs.
	The following patches add support for compiled-in multibyte
	locale modules to the static libc, the shared libc continues
	to load all modules dynamically.
	The set of locale modules to compile-in is specified by the
	make variable STATIC_LOCALES when builing libc, the default
	(in bsd.own.mk) is none.
	The size increase is about 25k (i386) for a statically linked program
	if all currently supported multibyte locales are compiled-in.

	Known bug: The object files for the locale modules get added
	to the shared libc as well. This does not seem to cause any harm
	except a slight size increase, but it is ugly.

>How-To-Repeat:
	Not applicable.
>Fix:

Index: share/mk/bsd.README
===================================================================
RCS file: /cvsroot/sharesrc/share/mk/bsd.README,v
retrieving revision 1.101
diff -r1.101 bsd.README
366a367,372
> 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.
> 
Index: share/mk/bsd.own.mk
===================================================================
RCS file: /cvsroot/sharesrc/share/mk/bsd.own.mk,v
retrieving revision 1.305
diff -r1.305 bsd.own.mk
481a482,486
> # 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?=
> 
Index: lib/libc/Makefile
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/Makefile,v
retrieving revision 1.107
diff -r1.107 Makefile
41c41
< LINTFLAGS+=	-w
---
> # XXX citrus modules not clean LINTFLAGS+=	-w
153,154c153,155
< # 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
Index: lib/libc/citrus/Makefile.inc
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/citrus/Makefile.inc,v
retrieving revision 1.2
diff -r1.2 Makefile.inc
13a14,29
> # 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
> .for var in ${STATIC_LOCALES}
> SRCS+=	citrus_${var:tl}.c
> CPPFLAGS+=-D_I18N_STATIC_${var}
> .endfor
> .endif # STATIC_LOCALES
> 
Index: lib/libc/citrus/citrus_ctype.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/citrus/citrus_ctype.c,v
retrieving revision 1.2
diff -r1.2 citrus_ctype.c
58,59d57
< #ifdef _I18N_DYNAMIC
< 
177,200d174
< 
< #else
< /* !_I18N_DYNAMIC */
< 
< int
< /*ARGSUSED*/
< _citrus_ctype_open(_citrus_ctype_t *rcc,
< 		   char const *encname, void *variable, size_t lenvar,
< 		   size_t szpriv)
< {
< 	if (!strcmp(encname, _CITRUS_DEFAULT_CTYPE_NAME)) {
< 		*rcc = &_citrus_ctype_default;
< 		return (0);
< 	}
< 	return (EINVAL);
< }
< 
< void
< /*ARGSUSED*/
< _citrus_ctype_close(_citrus_ctype_t cc)
< {
< }
< 
< #endif
Index: lib/libc/citrus/citrus_module.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/citrus/citrus_module.c,v
retrieving revision 1.2
diff -r1.2 citrus_module.c
350a351,395
> /*
>  * 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 }
> };
> 
352d396
< /*ARGSUSED*/
356c400,417
< 	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 (0);
> 
> 	/* Currently only ctype is implemented. */
> 	if (!strcmp(ifname, "ctype"))
> 		return (void *)p->ctype_fun;
> 	else
> 		return (0);
360,361c421
< /*ARGSUSED*/
< _citrus_load_module(_citrus_module_t *rhandle, char const *modname)
---
> _citrus_load_module(_citrus_module_t *rhandle, char const *encname)
362a423,435
> 	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 */
>Release-Note:
>Audit-Trail:
>Unformatted: