+2008-10-03 Bruno Haible <bruno@clisp.org>
+
+ * gettext-po.c (po_message_check_format): Update for signature changes
+ of check_message and check_msgid_msgstr_format.
+
2008-07-19 Bruno Haible <bruno@clisp.org>
* Makefile.am (EXTRA_DIST): Add gnulib-m4/gnulib-cache.m4.
handler->xerror2;
if (!mp->obsolete)
- check_message (mp, &mp->pos, 0, 1, NULL, 0, 0, 0, 0, 0);
+ check_message (mp, &mp->pos, 0, 1, NULL, 0, 0, 0, 0);
/* Restore error handler. */
po_xerror = textmode_xerror;
check_msgid_msgstr_format (mp->msgid, mp->msgid_plural,
mp->msgstr, mp->msgstr_len,
- mp->is_format, NULL, 0, po_error_logger);
+ mp->is_format, NULL, po_error_logger);
/* Restore error handler. */
po_error = error;
+2008-10-03 Bruno Haible <bruno@clisp.org>
+
+ * plural-distrib.h: New file.
+ * format.h: Include plural-distrib.h.
+ (check_msgid_msgstr_format_i, check_msgid_msgstr_format): Replace
+ plural_distribution, plural_distribution_length arguments with a single
+ distribution argument.
+ * format.c (check_msgid_msgstr_format_i, check_msgid_msgstr_format):
+ Likewise.
+ * msgl-check.h: Include plural-distrib.h.
+ (check_plural_eval, check_message): Replace plural_distribution,
+ plural_distribution_length arguments with a single distribution
+ argument.
+ * msgl-check.c (check_plural_eval): Likewise. Free array in case of
+ error.
+ (check_plural): Replace plural_distribution, plural_distribution_length
+ arguments with a single distribution argument. Don't store a
+ distribution result when there are errors.
+ (check_pair, check_message): Replace plural_distribution,
+ plural_distribution_length arguments with a single distribution
+ argument.
+ (check_message_list): Update.
+ * msgmerge.c (message_merge: Replace plural_distribution,
+ plural_distribution_length arguments with a single distribution
+ argument.
+ (match_domain): Update.
+ * Makefile.am (noinst_HEADERS): Add plural-distrib.h.
+ * FILES: Mention plural-distrib.h.
+
2008-09-28 Bruno Haible <bruno@clisp.org>
* write-catalog.c (msgdomain_list_print): Open the output stream in
plural-eval.h
plural-eval.c
Evaluating plural expressions.
+plural-distrib.h
+ Value distribution of plural expressions.
msgl-check.h
msgl-check.c
Checking of messages.
dir-list.h file-list.h po-gram-gen.h po-gram-gen2.h \
msgl-charset.h msgl-equal.h msgl-iconv.h msgl-ascii.h msgl-cat.h msgl-header.h \
msgl-english.h msgl-check.h msgl-fsearch.h msgfmt.h msgunfmt.h \
-plural-count.h plural-eval.h \
+plural-count.h plural-eval.h plural-distrib.h \
read-mo.h write-mo.h \
read-java.h write-java.h \
read-csharp.h write-csharp.h \
/* Format strings.
- Copyright (C) 2001-2007 Free Software Foundation, Inc.
+ Copyright (C) 2001-2008 Free Software Foundation, Inc.
Written by Bruno Haible <haible@clisp.cons.org>, 2001.
This program is free software: you can redistribute it and/or modify
};
/* Check whether both formats strings contain compatible format
- specifications for format type i (0 <= i < NFORMATS).
- PLURAL_DISTRIBUTION is either NULL or an array of nplurals elements,
- PLURAL_DISTRIBUTION[j] being true if the value j appears to be assumed
- infinitely often by the plural formula.
- PLURAL_DISTRIBUTION_LENGTH is the length of the PLURAL_DISTRIBUTION array.
- Return the number of errors that were seen. */
+ specifications for format type i (0 <= i < NFORMATS). */
int
check_msgid_msgstr_format_i (const char *msgid, const char *msgid_plural,
const char *msgstr, size_t msgstr_len,
size_t i,
- const unsigned char *plural_distribution,
- unsigned long plural_distribution_length,
+ const struct plural_distribution *distribution,
formatstring_error_logger_t error_logger)
{
int seen_errors = 0;
bool strict_checking =
(msgid_plural == NULL
|| !has_plural_translations
- || (plural_distribution != NULL
- && j < plural_distribution_length
- && plural_distribution[j]));
+ || (distribution != NULL
+ && distribution->often != NULL
+ && j < distribution->often_length
+ && distribution->often[j]));
if (parser->check (msgid_descr, msgstr_descr,
strict_checking,
/* Check whether both formats strings contain compatible format
specifications.
- PLURAL_DISTRIBUTION is either NULL or an array of nplurals elements,
- PLURAL_DISTRIBUTION[j] being true if the value j appears to be assumed
- infinitely often by the plural formula.
- PLURAL_DISTRIBUTION_LENGTH is the length of the PLURAL_DISTRIBUTION array.
Return the number of errors that were seen. */
int
check_msgid_msgstr_format (const char *msgid, const char *msgid_plural,
const char *msgstr, size_t msgstr_len,
const enum is_format is_format[NFORMATS],
- const unsigned char *plural_distribution,
- unsigned long plural_distribution_length,
+ const struct plural_distribution *distribution,
formatstring_error_logger_t error_logger)
{
int seen_errors = 0;
if (possible_format_p (is_format[i]))
seen_errors += check_msgid_msgstr_format_i (msgid, msgid_plural,
msgstr, msgstr_len, i,
- plural_distribution,
- plural_distribution_length,
+ distribution,
error_logger);
return seen_errors;
/* Format strings.
- Copyright (C) 2001-2007 Free Software Foundation, Inc.
+ Copyright (C) 2001-2008 Free Software Foundation, Inc.
Written by Bruno Haible <haible@clisp.cons.org>, 2001.
This program is free software: you can redistribute it and/or modify
#include "pos.h" /* Get lex_pos_ty. */
#include "message.h" /* Get NFORMATS. */
+#include "plural-distrib.h" /* Get struct plural_distribution. */
#include "error.h" /* Get fallback definition of __attribute__. */
/* Check whether both formats strings contain compatible format
specifications for format type i (0 <= i < NFORMATS).
- PLURAL_DISTRIBUTION is either NULL or an array of nplurals elements,
- PLURAL_DISTRIBUTION[j] being true if the value j appears to be assumed
- infinitely often by the plural formula.
Return the number of errors that were seen. */
extern int
check_msgid_msgstr_format_i (const char *msgid, const char *msgid_plural,
const char *msgstr, size_t msgstr_len,
size_t i,
- const unsigned char *plural_distribution,
- unsigned long plural_distribution_length,
+ const struct plural_distribution *distribution,
formatstring_error_logger_t error_logger);
/* Check whether both formats strings contain compatible format
specifications.
- PLURAL_DISTRIBUTION is either NULL or an array of nplurals elements,
- PLURAL_DISTRIBUTION[j] being true if the value j appears to be assumed
- infinitely often by the plural formula.
- PLURAL_DISTRIBUTION_LENGTH is the length of the PLURAL_DISTRIBUTION array.
Return the number of errors that were seen. */
extern int
check_msgid_msgstr_format (const char *msgid, const char *msgid_plural,
const char *msgstr, size_t msgstr_len,
const enum is_format is_format[NFORMATS],
- const unsigned char *plural_distribution,
- unsigned long plural_distribution_length,
+ const struct plural_distribution *distribution,
formatstring_error_logger_t error_logger);
/* Checking of messages in PO files.
- Copyright (C) 1995-1998, 2000-2007 Free Software Foundation, Inc.
+ Copyright (C) 1995-1998, 2000-2008 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
/* Check the values returned by plural_eval.
Signals the errors through po_xerror.
Return the number of errors that were seen.
- If no errors, returns in *PLURAL_DISTRIBUTION either NULL or an array
- of length NPLURALS_VALUE describing which plural formula values appear
- infinitely often and in *PLURAL_DISTRIBUTION_LENGTH the length of this
- array. */
+ If no errors, returns in *DISTRIBUTION information about the plural_eval
+ values distribution. */
int
check_plural_eval (const struct expression *plural_expr,
unsigned long nplurals_value,
const message_ty *header,
- unsigned char **plural_distribution,
- unsigned long *plural_distribution_length)
+ struct plural_distribution *distribution)
{
/* Do as if the plural formula assumes a value N infinitely often if it
assumes it at least 5 times. */
#define OFTEN 5
- unsigned char * volatile distribution;
+ unsigned char * volatile array;
/* Allocate a distribution array. */
if (nplurals_value <= 100)
- distribution = XCALLOC (nplurals_value, unsigned char);
+ array = XCALLOC (nplurals_value, unsigned char);
else
/* nplurals_value is nonsense. Don't risk an out-of-memory. */
- distribution = NULL;
+ array = NULL;
if (sigsetjmp (sigfpe_exit, 1) == 0)
{
po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false,
_("plural expression can produce negative values"));
+ free (array);
return 1;
}
else if (val >= nplurals_value)
nplurals_value, val);
po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false, msg);
free (msg);
+ free (array);
return 1;
}
- if (distribution != NULL && distribution[val] < OFTEN)
- distribution[val]++;
+ if (array != NULL && array[val] < OFTEN)
+ array[val]++;
}
/* End of protection against arithmetic exceptions. */
uninstall_sigfpe_handler ();
- /* Normalize the distribution[val] statistics. */
- if (distribution != NULL)
+ /* Normalize the array[val] statistics. */
+ if (array != NULL)
{
unsigned long val;
for (val = 0; val < nplurals_value; val++)
- distribution[val] = (distribution[val] == OFTEN ? 1 : 0);
- *plural_distribution_length = nplurals_value;
+ array[val] = (array[val] == OFTEN ? 1 : 0);
}
- else
- *plural_distribution_length = 0;
- *plural_distribution = distribution;
+
+ distribution->expr = plural_expr;
+ distribution->often = array;
+ distribution->often_length = (array != NULL ? nplurals_value : 0);
return 0;
}
po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false, msg);
- if (distribution != NULL)
- free (distribution);
+ free (array);
return 1;
}
/* Perform plural expression checking.
Return the number of errors that were seen.
- If no errors, returns in *PLURAL_DISTRIBUTION either NULL or an array
- describing which plural formula values appear infinitely often and in
- *PLURAL_DISTRIBUTION_LENGTH the length of this array. */
+ If no errors, returns in *DISTRIBUTION information about the plural_eval
+ values distribution. */
static int
-check_plural (message_list_ty *mlp,
- unsigned char **plural_distribution,
- unsigned long *plural_distribution_length)
+check_plural (message_list_ty *mlp, struct plural_distribution *distributionp)
{
int seen_errors = 0;
const message_ty *has_plural;
const message_ty *min_pos;
unsigned long max_nplurals;
const message_ty *max_pos;
+ struct plural_distribution distribution;
size_t j;
message_ty *header;
- unsigned char *distribution = NULL;
- unsigned long distribution_length = 0;
/* Determine whether mlp has plural entries. */
has_plural = NULL;
min_pos = NULL;
max_nplurals = 0;
max_pos = NULL;
+ distribution.expr = NULL;
+ distribution.often = NULL;
+ distribution.often_length = 0;
for (j = 0; j < mlp->nitems; j++)
{
message_ty *mp = mlp->item[j];
if (!seen_errors)
seen_errors =
check_plural_eval (plural_expr, nplurals_value, header,
- &distribution, &distribution_length);
+ &distribution);
/* Check the number of plurals of the translations. */
if (!seen_errors)
}
no_plural:
/* By default, the Germanic formula (n != 1) is used. */
- distribution = XCALLOC (2, unsigned char);
- distribution[1] = 1;
- distribution_length = 2;
+ distribution.expr = &germanic_plural;
+ {
+ unsigned char *array = XCALLOC (2, unsigned char);
+ array[1] = 1;
+ distribution.often = array;
+ }
+ distribution.often_length = 2;
}
/* distribution is not needed if we report errors.
Also, if there was an error due to max_nplurals > nplurals_value,
we must not use distribution because we would be doing out-of-bounds
array accesses. */
- if (seen_errors > 0 && distribution != NULL)
- {
- free (distribution);
- distribution = NULL;
- distribution_length = 0;
- }
- *plural_distribution = distribution;
- *plural_distribution_length = distribution_length;
+ if (seen_errors > 0)
+ free ((unsigned char *) distribution.often);
+ else
+ *distributionp = distribution;
return seen_errors;
}
const enum is_format is_format[NFORMATS],
int check_newlines,
int check_format_strings,
- const unsigned char *plural_distribution,
- unsigned long plural_distribution_length,
+ const struct plural_distribution *distribution,
int check_compatibility,
int check_accelerators, char accelerator_char)
{
curr_msgid_pos = *msgid_pos;
seen_errors +=
check_msgid_msgstr_format (msgid, msgid_plural, msgstr, msgstr_len,
- is_format, plural_distribution,
- plural_distribution_length,
+ is_format, distribution,
formatstring_error_logger);
}
/* Perform all checks on a non-obsolete message.
- PLURAL_DISTRIBUTION is either NULL or an array of nplurals elements,
- PLURAL_DISTRIBUTION[j] being true if the value j appears to be assumed
- infinitely often by the plural formula.
- PLURAL_DISTRIBUTION_LENGTH is the length of the PLURAL_DISTRIBUTION array.
Return the number of errors that were seen. */
int
check_message (const message_ty *mp,
const lex_pos_ty *msgid_pos,
int check_newlines,
int check_format_strings,
- const unsigned char *plural_distribution,
- unsigned long plural_distribution_length,
+ const struct plural_distribution *distribution,
int check_header,
int check_compatibility,
int check_accelerators, char accelerator_char)
mp->is_format,
check_newlines,
check_format_strings,
- plural_distribution, plural_distribution_length,
+ distribution,
check_compatibility,
check_accelerators, accelerator_char);
}
int check_accelerators, char accelerator_char)
{
int seen_errors = 0;
- unsigned char *plural_distribution = NULL;
- unsigned long plural_distribution_length = 0;
+ struct plural_distribution distribution;
size_t j;
+ distribution.expr = NULL;
+ distribution.often = NULL;
+ distribution.often_length = 0;
+
if (check_header)
- seen_errors +=
- check_plural (mlp, &plural_distribution, &plural_distribution_length);
+ seen_errors += check_plural (mlp, &distribution);
for (j = 0; j < mlp->nitems; j++)
{
seen_errors += check_message (mp, &mp->pos,
check_newlines,
check_format_strings,
- plural_distribution,
- plural_distribution_length,
+ &distribution,
check_header, check_compatibility,
check_accelerators, accelerator_char);
}
/* Checking of messages in PO files.
- Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2008 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2005.
This program is free software: you can redistribute it and/or modify
#include "message.h"
#include "pos.h"
#include "plural-eval.h"
+#include "plural-distrib.h"
#ifdef __cplusplus
/* Check the values returned by plural_eval.
Signals the errors through po_xerror.
Return the number of errors that were seen.
- If no errors, returns in *PLURAL_DISTRIBUTION either NULL or an array
- of length NPLURALS_VALUE describing which plural formula values appear
- infinitely often and in *PLURAL_DISTRIBUTION_LENGTH the length of this
- array. */
+ If no errors, returns in *DISTRIBUTION information about the plural_eval
+ values distribution. */
extern int check_plural_eval (const struct expression *plural_expr,
unsigned long nplurals_value,
const message_ty *header,
- unsigned char **plural_distribution,
- unsigned long *plural_distribution_length);
+ struct plural_distribution *distribution);
-/* Perform all checks on a non-obsolete message.
- PLURAL_DISTRIBUTION is either NULL or an array of nplurals elements,
- PLURAL_DISTRIBUTION[j] being true if the value j appears to be assumed
- infinitely often by the plural formula.
- PLURAL_DISTRIBUTION_LENGTH is the length of the PLURAL_DISTRIBUTION array.
- Return the number of errors that were seen. */
+/* Perform all checks on a non-obsolete message. */
extern int check_message (const message_ty *mp,
const lex_pos_ty *msgid_pos,
int check_newlines,
int check_format_strings,
- const unsigned char *plural_distribution,
- unsigned long plural_distribution_length,
+ const struct plural_distribution *distribution,
int check_header,
int check_compatibility,
int check_accelerators, char accelerator_char);
static message_ty *
message_merge (message_ty *def, message_ty *ref, bool force_fuzzy,
- const unsigned char *plural_distribution,
- unsigned long plural_distribution_length)
+ const struct plural_distribution *distribution)
{
const char *msgstr;
size_t msgstr_len;
&& !possible_format_p (def->is_format[i])
&& check_msgid_msgstr_format_i (ref->msgid, ref->msgid_plural,
msgstr, msgstr_len, i,
- plural_distribution,
- plural_distribution_length,
- silent_error_logger) > 0)
+ distribution, silent_error_logger)
+ > 0)
result->is_fuzzy = true;
}
unsigned long int nplurals;
const struct expression *plural_expr;
char *untranslated_plural_msgstr;
- unsigned char *plural_distribution;
- unsigned long plural_distribution_length;
+ struct plural_distribution distribution;
struct search_result { message_ty *found; bool fuzzy; } *search_results;
size_t j;
po_xerror = silent_xerror;
if (check_plural_eval (plural_expr, nplurals, header_entry,
- &plural_distribution,
- &plural_distribution_length) > 0)
+ &distribution) > 0)
{
- plural_distribution = NULL;
- plural_distribution_length = 0;
+ distribution.expr = NULL;
+ distribution.often = NULL;
+ distribution.often_length = 0;
+ distribution.histogram = NULL;
}
po_xerror = old_po_xerror;
the definition, take the msgstr from the definition. Add
this merged entry to the output message list. */
message_ty *mp =
- message_merge (defmsg, refmsg, false,
- plural_distribution, plural_distribution_length);
+ message_merge (defmsg, refmsg, false, &distribution);
message_list_append (resultmlp, mp);
#: comments from the reference, take the # comments from
the definition, take the msgstr from the definition. Add
this merged entry to the output message list. */
- mp = message_merge (defmsg, refmsg, true,
- plural_distribution,
- plural_distribution_length);
+ mp = message_merge (defmsg, refmsg, true, &distribution);
message_list_append (resultmlp, mp);
--- /dev/null
+/* Value distribution of plural form expressions.
+ Copyright (C) 2001-2008 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2001-2005.
+
+ 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
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _PLURAL_DISTRIB_H
+#define _PLURAL_DISTRIB_H
+
+
+/* Definition of 'struct expression'. */
+#include "plural-exp.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* The value distribution of a plural formula. */
+struct plural_distribution
+{
+ /* The plural formula as a parsed expression. */
+ const struct expression *expr;
+
+ /* OFTEN is either NULL or an array of nplurals elements,
+ OFTEN[j] being true if the value j appears to be assumed infinitely often
+ by the plural formula. */
+ const unsigned char *often;
+
+ /* The length of the OFTEN array. */
+ unsigned long often_length;
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _PLURAL_DISTRIB_H */