Commit d8dcd6ad authored by Bob Halley's avatar Bob Halley

basic NLS support

parent e44cd25d
......@@ -44,3 +44,6 @@
/* define if LinuxThreads is in use */
#undef HAVE_LINUXTHREADS
/* define if catgets() is available */
#undef HAVE_CATGETS
......@@ -30,9 +30,6 @@
/* define if your struct sockaddr has a sa_len member */
#undef HAVE_SA_LEN
/* define on DEC OSF to enable 4.4BSD style sa_len support */
#undef _SOCKADDR_LEN
/* define if your system needs pthread_init() before using pthreads */
#undef NEED_PTHREAD_INIT
......@@ -45,6 +42,9 @@
/* define if LinuxThreads is in use */
#undef HAVE_LINUXTHREADS
/* define if catgets() is available */
#undef HAVE_CATGETS
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
......
This diff is collapsed.
......@@ -13,7 +13,7 @@ dnl PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
dnl ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
dnl SOFTWARE.
AC_REVISION($Revision: 1.28 $)
AC_REVISION($Revision: 1.29 $)
AC_PREREQ(2.12)
......@@ -142,7 +142,7 @@ AC_CHECK_LIB(pthread, pthread_create,,
dnl For FreeBSD which has no libpthread but instead libc_r
if test "$ac_cv_lib_pthread" != "yes"; then
AC_CHECK_LIB(c_r,pthread_create)
AC_CHECK_LIB(c_r, pthread_create)
fi
......@@ -164,6 +164,11 @@ case "$host" in
;;
esac
dnl
dnl NLS
dnl
AC_CHECK_FUNC(catgets, AC_DEFINE(HAVE_CATGETS),)
dnl
dnl BSDI 3.1 needs pthread_init() to be called before certain pthreads
dnl calls. LinuxThreads requires some changes to the way we deal with
......@@ -282,6 +287,7 @@ AC_OUTPUT(
lib/isc/unix/Makefile
lib/isc/unix/include/Makefile
lib/isc/unix/include/isc/Makefile
lib/isc/nls/Makefile
lib/isc/pthreads/Makefile
lib/isc/pthreads/include/Makefile
lib/isc/pthreads/include/isc/Makefile
......
......@@ -77,14 +77,16 @@ static char *text[DNS_R_NRESULTS] = {
"unexpected error", /* 49 */
};
static isc_once_t once = ISC_ONCE_INIT;
static isc_once_t once = ISC_ONCE_INIT;
static isc_msgcat_t * dns_msgcat = NULL;
static void
initialize_action(void) {
isc_result_t result;
isc_msgcat_open("libdns.cat", &dns_msgcat);
result = isc_result_register(ISC_RESULTCLASS_DNS, DNS_R_NRESULTS,
text);
text, dns_msgcat, 2);
if (result != ISC_R_SUCCESS)
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_result_register() failed: %u", result);
......
......@@ -30,9 +30,9 @@ OBJS = @ISC_EXTRA_OBJS@ \
result.o rwlock.o symtab.o str.o event.o task.o timer.o \
version.o \
unix/app.o unix/time.o unix/stdtime.o unix/socket.o \
pthreads/condition.o unix/interfaceiter.o
unix/interfaceiter.o nls/msgcat.o pthreads/condition.o
SUBDIRS = include unix pthreads
SUBDIRS = include unix nls pthreads
TARGETS = timestamp
@BIND9_MAKE_RULES@
......
......@@ -24,8 +24,9 @@ top_srcdir = @top_srcdir@
#
HEADERS = assertions.h base64.h boolean.h buffer.h error.h event.h \
eventclass.h heap.h int.h interfaceiter.h lang.h lex.h \
list.h mem.h rbtgen.h region.h result.h resultclass.h \
rwlock.h socket.h str.h symtab.h task.h timer.h types.h
list.h mem.h msgcat.h rbtgen.h region.h result.h \
resultclass.h rwlock.h socket.h str.h symtab.h task.h \
timer.h types.h
SUBDIRS =
TARGETS =
......
/*
* Copyright (C) 1999 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#ifndef ISC_MSGCAT_H
#define ISC_MSGCAT_H 1
/*****
***** Module Info
*****/
/*
* ISC Message Catalog
*
* Message catalogs aid internationalization of applications by allowing
* messages to be retrieved from locale-specific files instead of
* hardwiring them into the application. This allows translations of
* messages appropriate to the locale to be supplied without recompiling
* the application.
*
* Notes:
* It's very important that message catalogs work, even if only the
* default_text can be used.
*
* MP:
* The caller must ensure appropriate synchronization of
* isc_msgcat_open() and isc_msgcat_close(). isc_msgcat_get()
* ensures appropriate synchronization.
*
* Reliability:
* No anticipated impact.
*
* Resources:
* <TBS>
*
* Security:
* No anticipated impact.
*
* Standards:
* None.
*/
/*****
***** Imports
*****/
#include <isc/lang.h>
#include <isc/types.h>
#include <isc/result.h>
ISC_LANG_BEGINDECLS
/*****
***** Methods
*****/
void
isc_msgcat_open(char *name, isc_msgcat_t **msgcatp);
/*
* Open a message catalog.
*
* Notes:
*
* If memory cannot be allocated or other failures occur, *msgcatp
* will be set to NULL. If a NULL msgcat is given to isc_msgcat_get(),
* the default_text will be returned, ensuring that some message text
* will be available, no matter what's going wrong.
*
* Requires:
*
* 'name' is a valid string.
*
* msgcatp != NULL && *msgcatp == NULL
*/
void
isc_msgcat_close(isc_msgcat_t **msgcatp);
/*
* Close a message catalog.
*
* Notes:
*
* Any string pointers returned by prior calls to isc_msgcat_get() are
* invalid after isc_msgcat_close() has been called and must not be
* used.
*
* Requires:
*
* *msgcatp is a valid message catalog or is NULL.
*
* Ensures:
*
* All resources associated with the message catalog are released.
*
* *msgcatp == NULL
*/
char *
isc_msgcat_get(isc_msgcat_t *msgcat, int set, int message, char *default_text);
/*
* Get message 'message' from message set 'set' in 'msgcat'. If it
* is not available, use 'default_text'.
*
* Requires:
*
* 'msgcat' is a valid message catalog or is NULL.
*
* set > 0
*
* message > 0
*
* 'default_text' is a valid string.
*/
ISC_LANG_ENDDECLS
#endif /* ISC_MSGCAT_H */
......@@ -21,11 +21,10 @@
#include <isc/boolean.h>
#include <isc/lang.h>
#include <isc/list.h>
#include <isc/types.h>
ISC_LANG_BEGINDECLS
typedef unsigned int isc_result_t;
#define ISC_R_SUCCESS 0
#define ISC_R_NOMEMORY 1
#define ISC_R_TIMEDOUT 2
......@@ -67,7 +66,9 @@ typedef unsigned int isc_result_t;
char * isc_result_totext(isc_result_t);
isc_result_t isc_result_register(unsigned int base,
unsigned int nresults,
char **text);
char **text,
isc_msgcat_t *msgcat,
int set);
ISC_LANG_ENDDECLS
......
# Copyright (C) 1999 Internet Software Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
# SOFTWARE.
srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
CINCLUDES = -I${srcdir}/include \
-I${srcdir}/../include
CDEFINES =
CWARNINGS =
OBJS = msgcat.o
SUBDIRS =
TARGETS = ${OBJS}
@BIND9_MAKE_RULES@
/*
* Copyright (C) 1999 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Principal Author: Bob Halley
*/
#include <config.h>
#include <stdlib.h>
#include <stddef.h>
#include <isc/assertions.h>
#include <isc/msgcat.h>
#ifdef HAVE_CATGETS
#include <nl_types.h>
#endif
/*
* Implementation Notes:
*
* We use malloc() and free() instead of isc_mem_get() and isc_mem_put()
* because we don't want to require a memory context to be specified
* in order to use a message catalog.
*/
struct isc_msgcat {
unsigned int magic;
#ifdef HAVE_CATGETS
nl_catd catalog;
#endif
};
#define MSGCAT_MAGIC 0x4D436174 /* MCat */
#define VALID_MSGCAT(m) ((m) != NULL && \
(m)->magic == MSGCAT_MAGIC)
void
isc_msgcat_open(char *name, isc_msgcat_t **msgcatp) {
isc_msgcat_t *msgcat;
/*
* Open a message catalog.
*/
REQUIRE(name != NULL);
REQUIRE(msgcatp != NULL && *msgcatp == NULL);
msgcat = malloc(sizeof *msgcat);
if (msgcat == NULL) {
*msgcatp = NULL;
return;
}
#ifdef HAVE_CATGETS
/*
* We don't check if catopen() fails because we don't care.
* If it does fail, then when we call catgets(), it will use
* the default string.
*/
msgcat->catalog = catopen(name, 0);
#endif
msgcat->magic = MSGCAT_MAGIC;
*msgcatp = msgcat;
}
void
isc_msgcat_close(isc_msgcat_t **msgcatp) {
isc_msgcat_t *msgcat;
/*
* Close a message catalog.
*/
REQUIRE(msgcatp != NULL);
msgcat = *msgcatp;
REQUIRE(VALID_MSGCAT(msgcat) || msgcat == NULL);
if (msgcat != NULL) {
#ifdef HAVE_CATGETS
if (msgcat->catalog != (nl_catd)(-1))
catclose(msgcat->catalog);
#endif
msgcat->magic = 0;
free(msgcat);
}
*msgcatp = NULL;
}
char *
isc_msgcat_get(isc_msgcat_t *msgcat, int set, int message,
char *default_text)
{
/*
* Get message 'message' from message set 'set' in 'msgcat'. If it
* is not available, use 'default'.
*/
REQUIRE(VALID_MSGCAT(msgcat) || msgcat == NULL);
REQUIRE(set > 0);
REQUIRE(message > 0);
REQUIRE(default_text != NULL);
#ifdef HAVE_CATGETS
if (msgcat == NULL)
return (default_text);
return (catgets(msgcat->catalog, set, message, default_text));
#else
return (default_text);
#endif
}
......@@ -26,6 +26,7 @@
#include <isc/error.h>
#include <isc/mutex.h>
#include <isc/once.h>
#include <isc/msgcat.h>
#include "util.h"
......@@ -33,6 +34,8 @@ typedef struct resulttable {
unsigned int base;
unsigned int last;
char ** text;
isc_msgcat_t * msgcat;
int set;
ISC_LINK(struct resulttable) link;
} resulttable;
......@@ -75,11 +78,14 @@ static char *text[ISC_R_NRESULTS] = {
};
static isc_once_t once = ISC_ONCE_INIT;
static isc_msgcat_t * isc_msgcat = NULL;
static ISC_LIST(resulttable) tables;
static isc_mutex_t lock;
static isc_result_t
register_table(unsigned int base, unsigned int nresults, char **text) {
register_table(unsigned int base, unsigned int nresults, char **text,
isc_msgcat_t *msgcat, int set)
{
resulttable *table;
REQUIRE(base % ISC_RESULTCLASS_SIZE == 0);
......@@ -96,6 +102,8 @@ register_table(unsigned int base, unsigned int nresults, char **text) {
table->base = base;
table->last = base + nresults;
table->text = text;
table->msgcat = msgcat;
table->set = set;
ISC_LINK_INIT(table, link);
LOCK(&lock);
......@@ -114,7 +122,9 @@ initialize_action(void) {
RUNTIME_CHECK(isc_mutex_init(&lock) == ISC_R_SUCCESS);
ISC_LIST_INIT(tables);
result = register_table(ISC_RESULTCLASS_ISC, ISC_R_NRESULTS, text);
isc_msgcat_open("libisc.cat", &isc_msgcat);
result = register_table(ISC_RESULTCLASS_ISC, ISC_R_NRESULTS, text,
isc_msgcat, 2);
if (result != ISC_R_SUCCESS)
UNEXPECTED_ERROR(__FILE__, __LINE__,
"register_table() failed: %u", result);
......@@ -128,7 +138,8 @@ initialize(void) {
char *
isc_result_totext(isc_result_t result) {
resulttable *table;
char *text;
char *text, *default_text;
int index;
initialize();
......@@ -139,7 +150,15 @@ isc_result_totext(isc_result_t result) {
table != NULL;
table = ISC_LIST_NEXT(table, link)) {
if (result >= table->base && result <= table->last) {
text = table->text[result - table->base];
index = (int)(result - table->base);
default_text = table->text[index];
/*
* Note: we use 'index + 1' as the message number
* instead of index because isc_msgcat_get() requires
* the message number to be > 0.
*/
text = isc_msgcat_get(table->msgcat, table->set,
index + 1, default_text);
break;
}
}
......@@ -150,8 +169,10 @@ isc_result_totext(isc_result_t result) {
}
isc_result_t
isc_result_register(unsigned int base, unsigned int nresults, char **text) {
isc_result_register(unsigned int base, unsigned int nresults, char **text,
isc_msgcat_t *msgcat, int set)
{
initialize();
return (register_table(base, nresults, text));
return (register_table(base, nresults, text, msgcat, set));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment