+2006-08-16 Bruno Haible <bruno@clisp.org>
+
+ * read-mo.c: Include stdbool.h, stdlib.h, format.h.
+ (read_mo_file): Mark messages with system-dependent segments as
+ "#, c-format" or "#, objc-format", as appropriate.
+ Reported by Egmont Koblinger <egmont@uhulinux.hu>.
+
2006-08-07 Bruno Haible <bruno@clisp.org>
* xgettext.c (remember_a_message): Use the position passed as argument
/* Reading binary .mo files.
- Copyright (C) 1995-1998, 2000-2005 Free Software Foundation, Inc.
+ Copyright (C) 1995-1998, 2000-2006 Free Software Foundation, Inc.
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, April 1995.
This program is free software; you can redistribute it and/or modify
#include "read-mo.h"
#include <errno.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stddef.h>
+#include <stdlib.h>
#include <string.h>
/* This include file describes the main part of binary .mo format. */
#include "binary-io.h"
#include "exit.h"
#include "message.h"
+#include "format.h"
#include "gettext.h"
#define _(str) gettext (str)
char *msgstr;
size_t msgstr_len;
nls_uint32 offset;
+ size_t f;
/* Read the msgctxt and msgid. */
offset = get_uint32 (&bf, header.orig_sysdep_tab_offset + i * 4);
: NULL),
msgstr, msgstr_len,
&pos);
+
+ /* Only messages with c-format or objc-format annotation are
+ recognized as having system-dependent strings by msgfmt.
+ Which one of the two, we don't know. We have to guess,
+ assuming that c-format is more probable than objc-format and
+ that the .mo was likely produced by "msgfmt -c". */
+ for (f = format_c; ; f = format_objc)
+ {
+ bool valid = true;
+ struct formatstring_parser *parser = formatstring_parsers[f];
+ const char *str_end;
+ const char *str;
+
+ str_end = msgid + msgid_len;
+ for (str = msgid; str < str_end; str += strlen (str) + 1)
+ {
+ char *invalid_reason = NULL;
+ void *descr = parser->parse (str, false, &invalid_reason);
+
+ if (descr != NULL)
+ parser->free (descr);
+ else
+ {
+ free (invalid_reason);
+ valid = false;
+ break;
+ }
+ }
+ if (valid)
+ {
+ str_end = msgstr + msgstr_len;
+ for (str = msgstr; str < str_end; str += strlen (str) + 1)
+ {
+ char *invalid_reason = NULL;
+ void *descr =
+ parser->parse (str, true, &invalid_reason);
+
+ if (descr != NULL)
+ parser->free (descr);
+ else
+ {
+ free (invalid_reason);
+ valid = false;
+ break;
+ }
+ }
+ }
+
+ if (valid)
+ {
+ /* Found the most likely among c-format, objc-format. */
+ mp->is_format[f] = yes;
+ break;
+ }
+
+ /* Try next f. */
+ if (f == format_objc)
+ break;
+ }
+
message_list_append (mlp, mp);
}
break;