]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Implement msgctxt for Java ResourceBundles.
authorBruno Haible <bruno@clisp.org>
Sat, 1 Sep 2007 21:36:38 +0000 (21:36 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:15:02 +0000 (12:15 +0200)
gettext-tools/src/ChangeLog
gettext-tools/src/gnu/gettext/DumpResource.java
gettext-tools/src/write-java.c
gettext-tools/src/x-java.c

index 439de2c0b470c26fd737fb7365914821cbe6b651..2881871e0cfd7c6c8949ead915ccebdbc6370f65 100644 (file)
@@ -1,3 +1,18 @@
+2007-09-01  Bruno Haible  <bruno@clisp.org>
+
+       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  <bruno@clisp.org>
 
        * po-lex.c: Include uniwidth.h.
index fea0f8eb714106e1004f1e96b66f518884689c81..585b5e19336d294330761b861556624bb8508089 100644 (file)
@@ -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');
index 32070211e056914f9ca448e16ddc201947fed15d..75e5085775c3e32c1628c36726186ef582f5836a 100644 (file)
@@ -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.  */
index cec1f08b62046ce77d8d8db12c5e025220d43342..d6dd5effa040d3df3ca510c7792a9edbe74d3164 100644 (file)
@@ -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");