Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libintl add plural support.
details: https://anonhg.NetBSD.org/src/rev/94f864190f15
branches: trunk
changeset: 580889:94f864190f15
user: tshiozak <tshiozak%NetBSD.org@localhost>
date: Sat May 14 17:58:56 2005 +0000
description:
add plural support.
diffstat:
lib/libintl/Makefile | 6 +-
lib/libintl/gettext.c | 85 ++-
lib/libintl/libintl_local.h | 5 +-
lib/libintl/plural_parser.c | 1120 +++++++++++++++++++++++++++++++++++++++++++
lib/libintl/plural_parser.h | 43 +
5 files changed, 1237 insertions(+), 22 deletions(-)
diffs (truncated from 1436 to 300 lines):
diff -r e062a3794642 -r 94f864190f15 lib/libintl/Makefile
--- a/lib/libintl/Makefile Sat May 14 17:55:42 2005 +0000
+++ b/lib/libintl/Makefile Sat May 14 17:58:56 2005 +0000
@@ -1,15 +1,15 @@
-# $NetBSD: Makefile,v 1.5 2004/09/23 21:35:27 tshiozak Exp $
+# $NetBSD: Makefile,v 1.6 2005/05/14 17:58:56 tshiozak Exp $
.include <bsd.own.mk>
LIB= intl
SRCS= gettext.c textdomain.c gettext_iconv.c gettext_dummy.c strhash.c \
- sysdep.c
+ sysdep.c plural_parser.c
INCS= libintl.h
INCSDIR=/usr/include
#CFLAGS+=-g
-CPPFLAGS+=-I${.CURDIR}
+CPPFLAGS+=-I${.CURDIR} -I${.CURDIR}/../libc
MAN= gettext.3
MLINKS= gettext.3 dgettext.3 gettext.3 dcgettext.3 \
diff -r e062a3794642 -r 94f864190f15 lib/libintl/gettext.c
--- a/lib/libintl/gettext.c Sat May 14 17:55:42 2005 +0000
+++ b/lib/libintl/gettext.c Sat May 14 17:58:56 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gettext.c,v 1.21 2005/04/27 09:51:52 yamt Exp $ */
+/* $NetBSD: gettext.c,v 1.22 2005/05/14 17:58:56 tshiozak Exp $ */
/*-
* Copyright (c) 2000, 2001 Citrus Project,
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: gettext.c,v 1.21 2005/04/27 09:51:52 yamt Exp $");
+__RCSID("$NetBSD: gettext.c,v 1.22 2005/05/14 17:58:56 tshiozak Exp $");
#include <sys/param.h>
#include <sys/stat.h>
@@ -48,6 +48,7 @@
#include <libintl.h>
#include <locale.h>
#include "libintl_local.h"
+#include "plural_parser.h"
#include "pathnames.h"
static const char *lookup_category __P((int));
@@ -58,9 +59,12 @@
static int validate __P((void *, struct mohandle *));
static int mapit __P((const char *, struct domainbinding *));
static int unmapit __P((struct domainbinding *));
-static const char *lookup_hash __P((const char *, struct domainbinding *));
-static const char *lookup_bsearch __P((const char *, struct domainbinding *));
-static const char *lookup __P((const char *, struct domainbinding *));
+static const char *lookup_hash __P((const char *, struct domainbinding *,
+ size_t *));
+static const char *lookup_bsearch __P((const char *, struct domainbinding *,
+ size_t *));
+static const char *lookup __P((const char *, struct domainbinding *,
+ size_t *));
static const char *get_lang_env __P((const char *));
/*
@@ -503,7 +507,7 @@
const u_int32_t *htable;
struct moentry_h *p;
struct mo *mo;
- size_t l;
+ size_t l, headerlen;
int i;
char *v;
struct mohandle *mohandle = &db->mohandle;
@@ -635,7 +639,7 @@
}
}
/* grab MIME-header and charset field */
- mohandle->mo.mo_header = lookup("", db);
+ mohandle->mo.mo_header = lookup("", db, &headerlen);
if (mohandle->mo.mo_header)
v = strstr(mohandle->mo.mo_header, "charset=");
else
@@ -648,6 +652,10 @@
if (v)
*v = '\0';
}
+ if (_gettext_parse_plural(&mohandle->mo.mo_plural,
+ &mohandle->mo.mo_nplurals,
+ mohandle->mo.mo_header, headerlen))
+ mohandle->mo.mo_plural = NULL;
/*
* XXX check charset, reject it if we are unable to support the charset
@@ -714,15 +722,18 @@
free_sysdep_table(mohandle->mo.mo_sysdep_ttable,
mohandle->mo.mo_sysdep_nstring);
}
+ if (mohandle->mo.mo_plural)
+ _gettext_free_plural(mohandle->mo.mo_plural);
memset(&mohandle->mo, 0, sizeof(mohandle->mo));
return 0;
}
/* ARGSUSED */
static const char *
-lookup_hash(msgid, db)
+lookup_hash(msgid, db, rlen)
const char *msgid;
struct domainbinding *db;
+ size_t *rlen;
{
struct mohandle *mohandle = &db->mohandle;
u_int32_t idx, hashval, step, strno;
@@ -748,6 +759,9 @@
if (len <= mohandle->mo.mo_otable[strno].len &&
!strcmp(msgid, mohandle->mo.mo_otable[strno].off)) {
/* hit */
+ if (rlen)
+ *rlen =
+ mohandle->mo.mo_ttable[strno].len;
return mohandle->mo.mo_ttable[strno].off;
}
} else {
@@ -761,6 +775,8 @@
if (expand_sysdep(mohandle, sysdep_ttable))
/* memory exhausted */
return NULL;
+ if (rlen)
+ *rlen = sysdep_ttable->expanded_len;
return sysdep_ttable->expanded;
}
}
@@ -770,9 +786,10 @@
}
static const char *
-lookup_bsearch(msgid, db)
+lookup_bsearch(msgid, db, rlen)
const char *msgid;
struct domainbinding *db;
+ size_t *rlen;
{
int top, bottom, middle, omiddle;
int n;
@@ -793,8 +810,11 @@
break;
n = strcmp(msgid, mohandle->mo.mo_otable[middle].off);
- if (n == 0)
+ if (n == 0) {
+ if (rlen)
+ *rlen = mohandle->mo.mo_ttable[middle].len;
return (const char *)mohandle->mo.mo_ttable[middle].off;
+ }
else if (n < 0)
bottom = middle;
else
@@ -806,17 +826,18 @@
}
static const char *
-lookup(msgid, db)
+lookup(msgid, db, rlen)
const char *msgid;
struct domainbinding *db;
+ size_t *rlen;
{
const char *v;
- v = lookup_hash(msgid, db);
+ v = lookup_hash(msgid, db, rlen);
if (v)
return v;
- return lookup_bsearch(msgid, db);
+ return lookup_bsearch(msgid, db, rlen);
}
static const char *
@@ -842,6 +863,22 @@
return split_locale(lang);
}
+static const char *
+get_indexed_string(const char *str, size_t len, unsigned long idx)
+{
+ while (idx > 0) {
+ if (len <= 1)
+ return str;
+ if (*str == '\0')
+ idx--;
+ if (len > 0) {
+ str++;
+ len--;
+ }
+ }
+ return str;
+}
+
char *
dcngettext(domainname, msgid1, msgid2, n, category)
const char *domainname;
@@ -859,10 +896,8 @@
static char *ocname = NULL;
static char *odomainname = NULL;
struct domainbinding *db;
-
- msgid = (n == 1) ? msgid1 : msgid2;
- if (msgid == NULL)
- return NULL;
+ unsigned long plural_index;
+ size_t len;
if (!domainname)
domainname = __current_domainname;
@@ -925,8 +960,22 @@
strlcpy(olpath, lpath, sizeof(olpath));
found:
- v = lookup(msgid, db);
+ if (db->mohandle.mo.mo_plural) {
+ plural_index =
+ _gettext_calculate_plural(db->mohandle.mo.mo_plural, n);
+ if (plural_index >= db->mohandle.mo.mo_nplurals)
+ plural_index = 0;
+ msgid = msgid1;
+ } else
+ msgid = (n == 1) ? msgid1 : msgid2;
+
+ if (msgid == NULL)
+ return NULL;
+
+ v = lookup(msgid, db, &len);
if (v) {
+ if (db->mohandle.mo.mo_plural)
+ v = get_indexed_string(v, len, plural_index);
/*
* convert the translated message's encoding.
*
diff -r e062a3794642 -r 94f864190f15 lib/libintl/libintl_local.h
--- a/lib/libintl/libintl_local.h Sat May 14 17:55:42 2005 +0000
+++ b/lib/libintl/libintl_local.h Sat May 14 17:58:56 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: libintl_local.h,v 1.9 2004/09/23 21:35:27 tshiozak Exp $ */
+/* $NetBSD: libintl_local.h,v 1.10 2005/05/14 17:58:56 tshiozak Exp $ */
/*-
* Copyright (c) 2000, 2001 Citrus Project,
@@ -97,6 +97,7 @@
struct mosysdepsegentry_h segs[1]; /* text segments */
};
+struct gettext_plural;
struct mo_h {
u_int32_t mo_magic; /* determines endian */
u_int32_t mo_revision; /* file format revision: 0 */
@@ -104,6 +105,8 @@
struct moentry_h *mo_otable; /* O: original text table offset */
struct moentry_h *mo_ttable; /* T: translated text table offset */
const char *mo_header;
+ struct gettext_plural *mo_plural;
+ unsigned long mo_nplurals;
char *mo_charset;
u_int32_t mo_hsize; /* S: size of hashing table */
u_int32_t *mo_htable; /* H: hashing table */
diff -r e062a3794642 -r 94f864190f15 lib/libintl/plural_parser.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/libintl/plural_parser.c Sat May 14 17:58:56 2005 +0000
@@ -0,0 +1,1120 @@
+/* $NetBSD: plural_parser.c,v 1.1 2005/05/14 17:58:57 tshiozak Exp $ */
+
+/*-
+ * Copyright (c) 2005 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: plural_parser.c,v 1.1 2005/05/14 17:58:57 tshiozak Exp $");
Home |
Main Index |
Thread Index |
Old Index