/* 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
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');
}
+/* 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)
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,
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)
}
+/* 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. */
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);
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");
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");
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. */
{
/* 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;
}
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");