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