From: Bruno Haible Date: Sat, 4 Oct 2008 01:37:01 +0000 (+0000) Subject: New 'struct plural_distribution' type. X-Git-Tag: v0.18~306 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3352f01305a924550469f94ec45084157ab7c188;p=thirdparty%2Fgettext.git New 'struct plural_distribution' type. --- diff --git a/gettext-tools/libgettextpo/ChangeLog b/gettext-tools/libgettextpo/ChangeLog index 26040ec4a..6935323f0 100644 --- a/gettext-tools/libgettextpo/ChangeLog +++ b/gettext-tools/libgettextpo/ChangeLog @@ -1,3 +1,8 @@ +2008-10-03 Bruno Haible + + * gettext-po.c (po_message_check_format): Update for signature changes + of check_message and check_msgid_msgstr_format. + 2008-07-19 Bruno Haible * Makefile.am (EXTRA_DIST): Add gnulib-m4/gnulib-cache.m4. diff --git a/gettext-tools/libgettextpo/gettext-po.c b/gettext-tools/libgettextpo/gettext-po.c index d4610c2e3..68bd13cbe 100644 --- a/gettext-tools/libgettextpo/gettext-po.c +++ b/gettext-tools/libgettextpo/gettext-po.c @@ -1261,7 +1261,7 @@ po_message_check_format (po_message_t message, po_xerror_handler_t handler) 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; @@ -1305,7 +1305,7 @@ po_message_check_format (po_message_t message, po_error_handler_t handler) 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; diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog index 59403d3f1..9b66e31f9 100644 --- a/gettext-tools/src/ChangeLog +++ b/gettext-tools/src/ChangeLog @@ -1,3 +1,32 @@ +2008-10-03 Bruno Haible + + * 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 * write-catalog.c (msgdomain_list_print): Open the output stream in diff --git a/gettext-tools/src/FILES b/gettext-tools/src/FILES index 3ade81540..764488966 100644 --- a/gettext-tools/src/FILES +++ b/gettext-tools/src/FILES @@ -237,6 +237,8 @@ plural-exp.c 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. diff --git a/gettext-tools/src/Makefile.am b/gettext-tools/src/Makefile.am index dc00a7605..81a5cf036 100644 --- a/gettext-tools/src/Makefile.am +++ b/gettext-tools/src/Makefile.am @@ -41,7 +41,7 @@ color.h write-catalog.h write-po.h write-properties.h write-stringtable.h \ 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 \ diff --git a/gettext-tools/src/format.c b/gettext-tools/src/format.c index 994f7e9fd..cd56afee5 100644 --- a/gettext-tools/src/format.c +++ b/gettext-tools/src/format.c @@ -1,5 +1,5 @@ /* Format strings. - Copyright (C) 2001-2007 Free Software Foundation, Inc. + Copyright (C) 2001-2008 Free Software Foundation, Inc. Written by Bruno Haible , 2001. This program is free software: you can redistribute it and/or modify @@ -59,18 +59,12 @@ struct formatstring_parser *formatstring_parsers[NFORMATS] = }; /* 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; @@ -127,9 +121,10 @@ check_msgid_msgstr_format_i (const char *msgid, const char *msgid_plural, 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, @@ -159,17 +154,12 @@ check_msgid_msgstr_format_i (const char *msgid, const char *msgid_plural, /* 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; @@ -185,8 +175,7 @@ check_msgid_msgstr_format (const char *msgid, const char *msgid_plural, 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; diff --git a/gettext-tools/src/format.h b/gettext-tools/src/format.h index 3bb96646b..38bbadcfe 100644 --- a/gettext-tools/src/format.h +++ b/gettext-tools/src/format.h @@ -1,5 +1,5 @@ /* Format strings. - Copyright (C) 2001-2007 Free Software Foundation, Inc. + Copyright (C) 2001-2008 Free Software Foundation, Inc. Written by Bruno Haible , 2001. This program is free software: you can redistribute it and/or modify @@ -22,6 +22,7 @@ #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__. */ @@ -140,31 +141,22 @@ extern unsigned int get_python_format_unnamed_arg_count (const char *string); /* 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); diff --git a/gettext-tools/src/msgl-check.c b/gettext-tools/src/msgl-check.c index 0b49530bd..00c93c0f0 100644 --- a/gettext-tools/src/msgl-check.c +++ b/gettext-tools/src/msgl-check.c @@ -1,5 +1,5 @@ /* 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 , April 1995. This program is free software: you can redistribute it and/or modify @@ -50,28 +50,25 @@ /* 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) { @@ -91,6 +88,7 @@ check_plural_eval (const struct expression *plural_expr, 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) @@ -104,28 +102,29 @@ check_plural_eval (const struct expression *plural_expr, 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; } @@ -159,8 +158,7 @@ check_plural_eval (const struct expression *plural_expr, po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false, msg); - if (distribution != NULL) - free (distribution); + free (array); return 1; } @@ -238,13 +236,10 @@ plural_help (const char *nullentry) /* 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; @@ -252,10 +247,9 @@ check_plural (message_list_ty *mlp, 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; @@ -263,6 +257,9 @@ check_plural (message_list_ty *mlp, 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]; @@ -416,7 +413,7 @@ check_plural (message_list_ty *mlp, 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) @@ -471,23 +468,23 @@ check_plural (message_list_ty *mlp, } 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; } @@ -531,8 +528,7 @@ check_pair (const message_ty *mp, 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) { @@ -649,8 +645,7 @@ plural handling is a GNU gettext extension")); 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); } @@ -794,18 +789,13 @@ some header fields still have the initial default value\n")); /* 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) @@ -819,7 +809,7 @@ check_message (const message_ty *mp, mp->is_format, check_newlines, check_format_strings, - plural_distribution, plural_distribution_length, + distribution, check_compatibility, check_accelerators, accelerator_char); } @@ -836,13 +826,15 @@ check_message_list (message_list_ty *mlp, 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++) { @@ -852,8 +844,7 @@ check_message_list (message_list_ty *mlp, 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); } diff --git a/gettext-tools/src/msgl-check.h b/gettext-tools/src/msgl-check.h index 72123011f..a11e95947 100644 --- a/gettext-tools/src/msgl-check.h +++ b/gettext-tools/src/msgl-check.h @@ -1,5 +1,5 @@ /* 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 , 2005. This program is free software: you can redistribute it and/or modify @@ -21,6 +21,7 @@ #include "message.h" #include "pos.h" #include "plural-eval.h" +#include "plural-distrib.h" #ifdef __cplusplus @@ -31,28 +32,19 @@ extern "C" { /* 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); diff --git a/gettext-tools/src/msgmerge.c b/gettext-tools/src/msgmerge.c index 4c48be04d..b5817607b 100644 --- a/gettext-tools/src/msgmerge.c +++ b/gettext-tools/src/msgmerge.c @@ -879,8 +879,7 @@ silent_xerror (int severity, 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; @@ -1273,9 +1272,8 @@ message_merge (message_ty *def, message_ty *ref, bool force_fuzzy, && !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; } @@ -1343,8 +1341,7 @@ match_domain (const char *fn1, const char *fn2, 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; @@ -1364,11 +1361,12 @@ match_domain (const char *fn1, const char *fn2, 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; @@ -1443,8 +1441,7 @@ match_domain (const char *fn1, const char *fn2, 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); @@ -1477,9 +1474,7 @@ this message is used but not defined...")); #: 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); diff --git a/gettext-tools/src/plural-distrib.h b/gettext-tools/src/plural-distrib.h new file mode 100644 index 000000000..f25f91891 --- /dev/null +++ b/gettext-tools/src/plural-distrib.h @@ -0,0 +1,52 @@ +/* Value distribution of plural form expressions. + Copyright (C) 2001-2008 Free Software Foundation, Inc. + Written by Bruno Haible , 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 . */ + +#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 */