+2005-12-25 Bruno Haible <bruno@clisp.org>
+
+ Tell Python developers to use named arguments in format strings.
+ * format.h (get_python_format_unnamed_arg_count): New declaration.
+ * format-python.c (get_python_format_unnamed_arg_count): New function.
+ * xgettext.c (warn_format_string): New function.
+ (remember_a_message, remember_a_message_plural): Call it.
+ Suggested by Martin von Löwis.
+
2005-12-07 Bruno Haible <bruno@clisp.org>
* msgl-iconv.c (iconv_message_list): Fix syntax error.
};
+unsigned int
+get_python_format_unnamed_arg_count (const char *string)
+{
+ /* Parse the format string. */
+ char *invalid_reason = NULL;
+ struct spec *descr =
+ (struct spec *) format_parse (string, false, &invalid_reason);
+
+ if (descr != NULL)
+ {
+ unsigned int result = descr->unnamed_arg_count;
+
+ format_free (descr);
+ return result;
+ }
+ else
+ {
+ free (invalid_reason);
+ return 0;
+ }
+}
+
+
#ifdef TEST
/* Test program: Print the argument list specification returned by
get_sysdep_c_format_directives (const char *string, bool translated,
struct interval **intervalsp, size_t *lengthp);
+/* Returns the number of unnamed arguments consumed by a Python format
+ string. */
+extern unsigned int get_python_format_unnamed_arg_count (const char *string);
+
/* Check whether both formats strings contain compatible format
specifications.
PLURAL_DISTRIBUTION is either NULL or an array of nplurals elements,
}
+static void
+warn_format_string (enum is_format is_format[NFORMATS], const char *string,
+ lex_pos_ty *pos, const char *pretty_msgstr)
+{
+ if (possible_format_p (is_format[format_python])
+ && get_python_format_unnamed_arg_count (string) > 1)
+ {
+ char buffer[21];
+
+ error_with_progname = false;
+ if (pos->line_number == (size_t)(-1))
+ buffer[0] = '\0';
+ else
+ sprintf (buffer, ":%ld", (long) pos->line_number);
+ multiline_warning (xasprintf (_("%s%s: warning: "),
+ pos->file_name, buffer),
+ xasprintf (_("\
+'%s' format string with unnamed arguments cannot be properly localized:\n\
+The translator cannot reorder the arguments.\n\
+Please consider using a format string with named arguments,\n\
+and a mapping instead of a tuple for the arguments.\n"),
+ pretty_msgstr));
+ error_with_progname = true;
+ }
+}
+
+
message_ty *
remember_a_message (message_list_ty *mlp, char *msgctxt, char *msgid,
flag_context_ty context, lex_pos_ty *pos,
mp->do_wrap = do_wrap == no ? no : yes; /* By default we wrap. */
+ /* Warn about the use of non-reorderable format strings when the programming
+ language also provides reorderable format strings. */
+ warn_format_string (is_format, mp->msgid, pos, "msgid");
+
/* Remember where we saw this msgid. */
if (line_comment)
message_comment_filepos (mp, pos->file_name, pos->line_number);
free (invalid_reason);
}
}
+
+ /* Warn about the use of non-reorderable format strings when the programming
+ language also provides reorderable format strings. */
+ warn_format_string (mp->is_format, mp->msgid_plural, pos, "msgid_plural");
}
else
free (msgid_plural);