Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libintl - add hash table support.
details: https://anonhg.NetBSD.org/src/rev/1cb865d29607
branches: trunk
changeset: 570095:1cb865d29607
user: tshiozak <tshiozak%NetBSD.org@localhost>
date: Thu Sep 23 16:44:26 2004 +0000
description:
- add hash table support.
- make use of __UNCONST() instead of LINTED.
diffstat:
lib/libintl/Makefile | 4 +-
lib/libintl/gettext.c | 110 ++++++++++++++++++++++++++++++++++++-------
lib/libintl/libintl_local.h | 24 ++++++++-
lib/libintl/strhash.c | 63 +++++++++++++++++++++++++
lib/libintl/textdomain.c | 6 +-
5 files changed, 182 insertions(+), 25 deletions(-)
diffs (truncated from 385 to 300 lines):
diff -r bbb54538567a -r 1cb865d29607 lib/libintl/Makefile
--- a/lib/libintl/Makefile Thu Sep 23 14:45:20 2004 +0000
+++ b/lib/libintl/Makefile Thu Sep 23 16:44:26 2004 +0000
@@ -1,9 +1,9 @@
-# $NetBSD: Makefile,v 1.3 2004/01/18 08:40:40 yamt Exp $
+# $NetBSD: Makefile,v 1.4 2004/09/23 16:44:26 tshiozak Exp $
.include <bsd.own.mk>
LIB= intl
-SRCS= gettext.c textdomain.c gettext_iconv.c gettext_dummy.c
+SRCS= gettext.c textdomain.c gettext_iconv.c gettext_dummy.c strhash.c
INCS= libintl.h
INCSDIR=/usr/include
diff -r bbb54538567a -r 1cb865d29607 lib/libintl/gettext.c
--- a/lib/libintl/gettext.c Thu Sep 23 14:45:20 2004 +0000
+++ b/lib/libintl/gettext.c Thu Sep 23 16:44:26 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gettext.c,v 1.18 2004/01/18 08:40:40 yamt Exp $ */
+/* $NetBSD: gettext.c,v 1.19 2004/09/23 16:44:26 tshiozak Exp $ */
/*-
* Copyright (c) 2000, 2001 Citrus Project,
@@ -29,13 +29,14 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: gettext.c,v 1.18 2004/01/18 08:40:40 yamt Exp $");
+__RCSID("$NetBSD: gettext.c,v 1.19 2004/09/23 16:44:26 tshiozak Exp $");
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/uio.h>
+#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
@@ -189,25 +190,25 @@
if (t) {
if (c) {
snprintf(tmp, sizeof(tmp), "%s_%s.%s@%s",
- l, t, c, m);
+ l, t, c, m);
strlcat(result, tmp, sizeof(result));
strlcat(result, ":", sizeof(result));
}
- snprintf(tmp, sizeof(tmp), "%s_%s@%s", l, t, m);
+ snprintf(tmp, sizeof(tmp), "%s_%s@%s", l, t, m);
strlcat(result, tmp, sizeof(result));
strlcat(result, ":", sizeof(result));
}
- snprintf(tmp, sizeof(tmp), "%s@%s", l, m);
+ snprintf(tmp, sizeof(tmp), "%s@%s", l, m);
strlcat(result, tmp, sizeof(result));
strlcat(result, ":", sizeof(result));
}
if (t) {
if (c) {
- snprintf(tmp, sizeof(tmp), "%s_%s.%s", l, t, c);
+ snprintf(tmp, sizeof(tmp), "%s_%s.%s", l, t, c);
strlcat(result, tmp, sizeof(result));
strlcat(result, ":", sizeof(result));
}
- snprintf(tmp, sizeof(tmp), "%s_%s", l, t);
+ snprintf(tmp, sizeof(tmp), "%s_%s", l, t);
strlcat(result, tmp, sizeof(result));
strlcat(result, ":", sizeof(result));
}
@@ -309,6 +310,7 @@
char *base;
u_int32_t magic, revision;
struct moentry *otable, *ttable;
+ const u_int32_t *htable;
struct moentry_h *p;
struct mo *mo;
size_t l;
@@ -338,8 +340,18 @@
close(fd);
goto fail;
}
- if (read(fd, &revision, sizeof(revision)) != sizeof(revision) ||
- flip(revision, magic) != MO_REVISION) {
+ if (read(fd, &revision, sizeof(revision)) != sizeof(revision)) {
+ close(fd);
+ goto fail;
+ }
+ switch (flip(revision, magic)) {
+ case MO_MAKE_REV(0, 0):
+#if 0
+ case MO_MAKE_REV(0, 1):
+ case MO_MAKE_REV(1, 1):
+#endif
+ break;
+ default:
close(fd);
goto fail;
}
@@ -359,9 +371,12 @@
mohandle->mo.mo_magic = mo->mo_magic;
mohandle->mo.mo_revision = flip(mo->mo_revision, magic);
mohandle->mo.mo_nstring = flip(mo->mo_nstring, magic);
+ mohandle->mo.mo_hsize = flip(mo->mo_hsize, magic);
/* validate otable/ttable */
+ /* LINTED: ignore the alignment problem. */
otable = (struct moentry *)(base + flip(mo->mo_otable, magic));
+ /* LINTED: ignore the alignment problem. */
ttable = (struct moentry *)(base + flip(mo->mo_ttable, magic));
if (!validate(otable, mohandle) ||
!validate(&otable[mohandle->mo.mo_nstring], mohandle)) {
@@ -408,7 +423,26 @@
goto fail;
}
}
-
+ /* allocate htable, and convert it to the host order. */
+ if (mohandle->mo.mo_hsize > 2) {
+ l = sizeof(u_int32_t) * mohandle->mo.mo_hsize;
+ mohandle->mo.mo_htable = (u_int32_t *)malloc(l);
+ if (!mohandle->mo.mo_htable) {
+ unmapit(db);
+ goto fail;
+ }
+ /* LINTED: ignore the alignment problem. */
+ htable = (const u_int32_t *)(base+flip(mo->mo_hoffset, magic));
+ for (i=0; i < mohandle->mo.mo_hsize; i++) {
+ mohandle->mo.mo_htable[i] = flip(htable[i], magic);
+ if (mohandle->mo.mo_htable[i] >=
+ mohandle->mo.mo_nstring+1) {
+ /* illegal string number. */
+ unmapit(db);
+ goto fail;
+ }
+ }
+ }
/* grab MIME-header and charset field */
mohandle->mo.mo_header = lookup("", db);
if (mohandle->mo.mo_header)
@@ -454,22 +488,63 @@
free(mohandle->mo.mo_ttable);
if (mohandle->mo.mo_charset)
free(mohandle->mo.mo_charset);
+ if (mohandle->mo.mo_htable)
+ free(mohandle->mo.mo_htable);
memset(&mohandle->mo, 0, sizeof(mohandle->mo));
return 0;
}
+/*
+ * calculate the step value if the hash value is conflicted.
+ */
+static __inline u_int32_t
+calc_collision_step(u_int32_t hashval, u_int32_t hashsize)
+{
+ _DIAGASSERT(hashsize>2);
+ return (hashval % (hashsize - 2)) + 1;
+}
+
+/*
+ * calculate the next index while conflicting.
+ */
+static __inline u_int32_t
+calc_next_index(u_int32_t curidx, u_int32_t hashsize, u_int32_t step)
+{
+ return curidx+step - (curidx >= hashsize-step ? hashsize : 0);
+}
+
/* ARGSUSED */
static const char *
lookup_hash(msgid, db)
const char *msgid;
struct domainbinding *db;
{
+ struct mohandle *mohandle = &db->mohandle;
+ u_int32_t idx, hashval, step, strno;
+ size_t len;
- /*
- * XXX should try a hashed lookup here, but to do so, we need to
- * look inside the GPL'ed *.c and re-implement...
- */
- return NULL;
+ if (mohandle->mo.mo_hsize <= 2 || mohandle->mo.mo_htable == NULL)
+ return NULL;
+
+ hashval = __intl_string_hash(msgid);
+ step = calc_collision_step(hashval, mohandle->mo.mo_hsize);
+ idx = hashval % mohandle->mo.mo_hsize;
+ len = strlen(msgid);
+ while (/*CONSTCOND*/1) {
+ strno = mohandle->mo.mo_htable[idx];
+ if (strno == 0) {
+ /* unexpected miss */
+ return NULL;
+ }
+ strno--;
+ if (len <= mohandle->mo.mo_otable[strno].len &&
+ !strcmp(msgid, mohandle->mo.mo_otable[strno].off)) {
+ /* hit */
+ return mohandle->mo.mo_ttable[strno].off;
+ }
+ idx = calc_next_index(idx, mohandle->mo.mo_hsize, step);
+ }
+ /*NOTREACHED*/
}
static const char *
@@ -576,7 +651,7 @@
lpath = get_lang_env(cname);
if (!lpath)
goto fail;
-
+
for (db = __bindings; db; db = db->next)
if (strcmp(db->domainname, domainname) == 0)
break;
@@ -650,6 +725,5 @@
}
fail:
- /* LINTED const cast */
- return (char *)msgid;
+ return (char *)__UNCONST(msgid);
}
diff -r bbb54538567a -r 1cb865d29607 lib/libintl/libintl_local.h
--- a/lib/libintl/libintl_local.h Thu Sep 23 14:45:20 2004 +0000
+++ b/lib/libintl/libintl_local.h Thu Sep 23 16:44:26 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: libintl_local.h,v 1.7 2004/01/18 08:40:40 yamt Exp $ */
+/* $NetBSD: libintl_local.h,v 1.8 2004/09/23 16:44:26 tshiozak Exp $ */
/*-
* Copyright (c) 2000, 2001 Citrus Project,
@@ -30,7 +30,9 @@
#define MO_MAGIC 0x950412de
#define MO_MAGIC_SWAPPED 0xde120495
-#define MO_REVISION 0
+#define MO_GET_REV_MAJOR(r) (((r) >> 16) & 0xFFFF)
+#define MO_GET_REV_MINOR(r) ((r) & 0xFFFF)
+#define MO_MAKE_REV(maj, min) (((maj) << 16) | (min))
#define GETTEXT_MMAP_MAX (1024 * 1024) /*XXX*/
@@ -45,6 +47,13 @@
u_int32_t mo_ttable; /* T: translated text table offset */
u_int32_t mo_hsize; /* S: size of hashing table */
u_int32_t mo_hoffset; /* H: offset of hashing table */
+ /* rev 0.1 / 1.1 */
+ /* system dependent string support */
+ u_int32_t mo_sysdep_nsegs; /* number of sysdep segments */
+ u_int32_t mo_sysdep_segoff; /* offset of sysdep segment table */
+ u_int32_t mo_sysdep_nstring; /* number of strings */
+ u_int32_t mo_sysdep_otable; /* offset of original text table */
+ u_int32_t mo_sysdep_ttable; /* offset of translated text table */
} __attribute__((__packed__));
struct moentry {
@@ -52,6 +61,12 @@
u_int32_t off; /* offset of \0-terminated string */
} __attribute__((__packed__));
+struct mosysdepstr
+{
+ u_int32_t off; /* offset of seed text */
+ struct moentry segs[1]; /* text segments */
+} __attribute__((__packed__));
+
/* libintl internal data format */
struct moentry_h {
size_t len; /* strlen(str), so region will be len + 1 */
@@ -66,6 +81,8 @@
struct moentry_h *mo_ttable; /* T: translated text table offset */
const char *mo_header;
char *mo_charset;
+ u_int32_t mo_hsize; /* S: size of hashing table */
+ u_int32_t *mo_htable; /* H: hashing table */
};
struct mohandle {
@@ -85,4 +102,7 @@
extern struct domainbinding *__bindings;
extern char __current_domainname[PATH_MAX];
+__BEGIN_DECLS
const char *__gettext_iconv __P((const char *, struct domainbinding *));
+u_int32_t __intl_string_hash __P((const char *));
+__END_DECLS
diff -r bbb54538567a -r 1cb865d29607 lib/libintl/strhash.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/libintl/strhash.c Thu Sep 23 16:44:26 2004 +0000
@@ -0,0 +1,63 @@
+/* $NetBSD: strhash.c,v 1.1 2004/09/23 16:44:26 tshiozak Exp $ */
+
+/*-
+ * Copyright (c)2003, 2004 Citrus Project,
+ * All rights reserved.
Home |
Main Index |
Thread Index |
Old Index