From: Bruno Haible Date: Sat, 1 Sep 2007 21:36:38 +0000 (+0000) Subject: Implement msgctxt for Java ResourceBundles. X-Git-Tag: v0.17~272 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e1f8e881e60ff08f0e21c760adfd4c08a579d38c;p=thirdparty%2Fgettext.git Implement msgctxt for Java ResourceBundles. --- diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog index 439de2c0b..2881871e0 100644 --- a/gettext-tools/src/ChangeLog +++ b/gettext-tools/src/ChangeLog @@ -1,3 +1,18 @@ +2007-09-01 Bruno Haible + + Implement msgctxt for Java ResourceBundles. + * x-java.c (init_keywords): Also register pgettext and npgettext. + (init_flag_table_java): Update accordingly. + * write-java.c (msgid_hashcode): New function. + (compute_hashsize, compute_table_items): Use it instead of string_hashcode. + (write_java_msgid): New function. + (write_java_code): Use it instead of write_java_string. + (msgdomain_write_java): Remove error message if mlp has entries with + context. + * gnu/gettext/DumpResource.java (dumpMessage): Emit an msgctxt line + if the message contain the context separator. + Suggested by Felix Berger. + 2007-09-01 Bruno Haible * po-lex.c: Include uniwidth.h. diff --git a/gettext-tools/src/gnu/gettext/DumpResource.java b/gettext-tools/src/gnu/gettext/DumpResource.java index fea0f8eb7..585b5e193 100644 --- a/gettext-tools/src/gnu/gettext/DumpResource.java +++ b/gettext-tools/src/gnu/gettext/DumpResource.java @@ -1,5 +1,5 @@ /* GNU gettext for Java - * Copyright (C) 2001-2003 Free Software Foundation, Inc. + * Copyright (C) 2001-2003, 2007 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -53,6 +53,12 @@ public class DumpResource { out.write('"'); } private void dumpMessage (String msgid, String msgid_plural, Object msgstr) throws IOException { + int separatorPos = msgid.indexOf('\u0004'); + if (separatorPos >= 0) { + String msgctxt = msgid.substring(0,separatorPos); + msgid = msgid.substring(separatorPos+1); + out.write("msgctxt "); dumpString(msgctxt); + } out.write("msgid "); dumpString(msgid); out.write('\n'); if (msgid_plural != null) { out.write("msgid_plural "); dumpString(msgid_plural); out.write('\n'); diff --git a/gettext-tools/src/write-java.c b/gettext-tools/src/write-java.c index 32070211e..75e508577 100644 --- a/gettext-tools/src/write-java.c +++ b/gettext-tools/src/write-java.c @@ -136,6 +136,34 @@ string_hashcode (const char *str) } +/* Return the Java hash code of a (msgctxt, msgid) pair mod 2^31. */ +static unsigned int +msgid_hashcode (const char *msgctxt, const char *msgid) +{ + if (msgctxt == NULL) + return string_hashcode (msgid); + else + { + size_t msgctxt_len = strlen (msgctxt); + size_t msgid_len = strlen (msgid); + size_t combined_len = msgctxt_len + 1 + msgid_len; + char *combined; + unsigned int result; + + combined = (char *) xmalloca (combined_len); + memcpy (combined, msgctxt, msgctxt_len); + combined[msgctxt_len] = MSGCTXT_SEPARATOR; + memcpy (combined + msgctxt_len + 1, msgid, msgid_len + 1); + + result = string_hashcode (combined); + + freea (combined); + + return result; + } +} + + /* Compute a good hash table size for the given set of msgids. */ static unsigned int compute_hashsize (message_list_ty *mlp, bool *collisionp) @@ -153,7 +181,7 @@ compute_hashsize (message_list_ty *mlp, bool *collisionp) size_t j; for (j = 0; j < n; j++) - hashcodes[j] = string_hashcode (mlp->item[j]->msgid); + hashcodes[j] = msgid_hashcode (mlp->item[j]->msgctxt, mlp->item[j]->msgid); /* Try all numbers between n and 3*n. The score depends on the size of the table -- the smaller the better -- and the number of collision lookups, @@ -295,7 +323,8 @@ compute_table_items (message_list_ty *mlp, unsigned int hashsize) for (j = 0; j < n; j++) { - unsigned int hashcode = string_hashcode (mlp->item[j]->msgid); + unsigned int hashcode = + msgid_hashcode (mlp->item[j]->msgctxt, mlp->item[j]->msgid); unsigned int idx = hashcode % hashsize; if (bitmap[idx] != 0) @@ -370,6 +399,35 @@ write_java_string (FILE *stream, const char *str) } +/* Write a (msgctxt, msgid pair) as a string in Java Unicode notation to the + given stream. */ +static void +write_java_msgid (FILE *stream, message_ty *mp) +{ + const char *msgctxt = mp->msgctxt; + const char *msgid = mp->msgid; + + if (msgctxt == NULL) + write_java_string (stream, msgid); + else + { + size_t msgctxt_len = strlen (msgctxt); + size_t msgid_len = strlen (msgid); + size_t combined_len = msgctxt_len + 1 + msgid_len; + char *combined; + + combined = (char *) xmalloca (combined_len); + memcpy (combined, msgctxt, msgctxt_len); + combined[msgctxt_len] = MSGCTXT_SEPARATOR; + memcpy (combined + msgctxt_len + 1, msgid, msgid_len + 1); + + write_java_string (stream, combined); + + freea (combined); + } +} + + /* Write Java code that returns the value for a message. If the message has plural forms, it is an expression of type String[], otherwise it is an expression of type String. */ @@ -714,7 +772,7 @@ write_java_code (FILE *stream, const char *class_name, message_list_ty *mlp, struct table_item *ti = &table_items[j]; fprintf (stream, " t[%d] = ", 2 * ti->index); - write_java_string (stream, ti->mp->msgid); + write_java_msgid (stream, ti->mp); fprintf (stream, ";\n"); fprintf (stream, " t[%d] = ", 2 * ti->index + 1); write_java_msgstr (stream, ti->mp); @@ -797,7 +855,7 @@ write_java_code (FILE *stream, const char *class_name, message_list_ty *mlp, for (j = 0; j < mlp->nitems; j++) { fprintf (stream, " t.put("); - write_java_string (stream, mlp->item[j]->msgid); + write_java_msgid (stream, mlp->item[j]); fprintf (stream, ","); write_java_msgstr (stream, mlp->item[j]); fprintf (stream, ");\n"); @@ -814,7 +872,7 @@ write_java_code (FILE *stream, const char *class_name, message_list_ty *mlp, if (mlp->item[j]->msgid_plural != NULL) { fprintf (stream, " p.put("); - write_java_string (stream, mlp->item[j]->msgid); + write_java_msgid (stream, mlp->item[j]); fprintf (stream, ","); write_java_string (stream, mlp->item[j]->msgid_plural); fprintf (stream, ");\n"); @@ -897,25 +955,6 @@ msgdomain_write_java (message_list_ty *mlp, const char *canon_encoding, if (mlp->nitems == 0) return 0; - /* Determine whether mlp has entries with context. */ - { - bool has_context; - size_t j; - - has_context = false; - for (j = 0; j < mlp->nitems; j++) - if (mlp->item[j]->msgctxt != NULL) - has_context = true; - if (has_context) - { - multiline_error (xstrdup (""), - xstrdup (_("\ -message catalog has context dependent translations\n\ -but the Java ResourceBundle format doesn't support contexts\n"))); - return 1; - } - } - retval = 1; /* Convert the messages to Unicode. */ diff --git a/gettext-tools/src/x-java.c b/gettext-tools/src/x-java.c index cec1f08b6..d6dd5effa 100644 --- a/gettext-tools/src/x-java.c +++ b/gettext-tools/src/x-java.c @@ -100,10 +100,14 @@ init_keywords () { /* When adding new keywords here, also update the documentation in xgettext.texi! */ - x_java_keyword ("GettextResource.gettext:2"); /* static method */ - x_java_keyword ("GettextResource.ngettext:2,3"); /* static method */ + x_java_keyword ("GettextResource.gettext:2"); /* static method */ + x_java_keyword ("GettextResource.ngettext:2,3"); /* static method */ + x_java_keyword ("GettextResource.pgettext:2c,3"); /* static method */ + x_java_keyword ("GettextResource.npgettext:2c,3,4"); /* static method */ x_java_keyword ("gettext"); x_java_keyword ("ngettext:1,2"); + x_java_keyword ("pgettext:1c,2"); + x_java_keyword ("npgettext:1c,2,3"); x_java_keyword ("getString"); /* ResourceBundle.getString */ default_keywords = false; } @@ -115,9 +119,15 @@ init_flag_table_java () xgettext_record_flag ("GettextResource.gettext:2:pass-java-format"); xgettext_record_flag ("GettextResource.ngettext:2:pass-java-format"); xgettext_record_flag ("GettextResource.ngettext:3:pass-java-format"); + xgettext_record_flag ("GettextResource.pgettext:3:pass-java-format"); + xgettext_record_flag ("GettextResource.npgettext:3:pass-java-format"); + xgettext_record_flag ("GettextResource.npgettext:4:pass-java-format"); xgettext_record_flag ("gettext:1:pass-java-format"); xgettext_record_flag ("ngettext:1:pass-java-format"); xgettext_record_flag ("ngettext:2:pass-java-format"); + xgettext_record_flag ("pgettext:2:pass-java-format"); + xgettext_record_flag ("npgettext:2:pass-java-format"); + xgettext_record_flag ("npgettext:3:pass-java-format"); xgettext_record_flag ("getString:1:pass-java-format"); xgettext_record_flag ("MessageFormat:1:java-format"); xgettext_record_flag ("MessageFormat.format:1:java-format");