From: Bruno Haible Date: Tue, 30 Sep 2025 13:35:06 +0000 (+0200) Subject: libgettextpo: Add API for the workflow flags and the sticky flags. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1dba8793ec5714d6c8f10723a2172c99934219ea;p=thirdparty%2Fgettext.git libgettextpo: Add API for the workflow flags and the sticky flags. Reported by Alexander Potashev at . * gettext-tools/src/message.h (format_flag, not_format_p): New declarations. * gettext-tools/src/message.c (format_flag): New variable. (not_format_p): New function. * gettext-tools/src/write-po.c (make_format_description_string): Add comments. (significant_format_p): Likewise. * gettext-tools/libgettextpo/gettext-po.in.h (po_flag_iterator_t): New type. (po_message_has_workflow_flag, po_message_set_workflow_flag, po_message_workflow_flags_iterator): New declarations. (po_message_has_sticky_flag, po_message_set_sticky_flag, po_message_sticky_flags_iterator): New declarations. (po_flag_iterator_free, po_flag_next): New declarations. * gettext-tools/libgettextpo/gettext-po.c (struct po_flag_iterator): New type. (po_message_has_workflow_flag, po_message_set_workflow_flag, po_message_workflow_flags_iterator): New functions. (po_message_get_format): Simplify by using not_format_p. (po_message_has_sticky_flag, po_message_set_sticky_flag, po_message_sticky_flags_iterator): New functions. (po_flag_iterator_free, po_flag_next): New functions. * gettext-tools/tests/gettextpo-1-prg.c (main): Add more test cases. * gettext-tools/doc/gettext.texi (po_message_t API): Document the new functions. (po_flag_iterator_t API): New subsection. * NEWS: Mention the new functions. --- diff --git a/NEWS b/NEWS index c28890deb..235284577 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,16 @@ Version 0.27 - September 2025 # libgettextpo library: * The function 'po_message_get_format' now supports distinguishing whether a negative format string mark, such as 'no-c-format', is set or not. + * The new functions + po_message_has_workflow_flag + po_message_set_workflow_flag + po_message_workflow_flags_iterator, po_flag_next, po_flag_iterator_free + can be used to manipulate or inspect the workflow flags of a message. + * The new functions + po_message_has_sticky_flag + po_message_set_sticky_flag + po_message_sticky_flags_iterator, po_flag_next, po_flag_iterator_free + can be used to manipulate or inspect the sticky flags of a messsage. Version 0.26 - July 2025 diff --git a/gettext-tools/doc/gettext.texi b/gettext-tools/doc/gettext.texi index b8e8ff12a..9571c6070 100644 --- a/gettext-tools/doc/gettext.texi +++ b/gettext-tools/doc/gettext.texi @@ -6206,6 +6206,7 @@ without caring about the other threads. * PO Header Entry API:: Meta information of the file * po_filepos_t API:: References to the sources * Format Type API:: Supported format types +* po_flag_iterator_t API:: Flag iteration * Checking API:: Enforcing constraints @end menu @@ -6552,6 +6553,34 @@ The @code{po_message_set_fuzzy} function changes the fuzzy mark of @var{message}. @end deftypefun +@deftypefun {int} po_message_has_workflow_flag (po_message_t@tie{}@var{message}, const@tie{}char@tie{}*@var{workflow_flag}) +The @code{po_message_has_workflow_flag} function returns true +when @var{message} is marked with a given workflow flag. + +When the argument @var{workflow_flag} is @code{"fuzzy"}, +this function corresponds to the @code{po_message_is_fuzzy} function. +@end deftypefun + +@deftypefun {void} po_message_set_workflow_flag (po_message_t@tie{}@var{message}, const@tie{}char@tie{}*@var{workflow_flag}, int@tie{}@var{value}) +The @code{po_message_set_workflow_flag} function changes +a given workflow flag on @var{message}: +If the @var{value} argument is non-zero, it sets it. +If the @var{value} argument is zero, it unsets it. + +When the argument @var{workflow_flag} is @code{"fuzzy"}, +this function corresponds to the @code{po_message_set_fuzzy} function. +@end deftypefun + +@deftypefun {po_flag_iterator_t} po_message_workflow_flags_iterator (po_message_t@tie{}@var{message}) +The @code{po_message_workflow_flags_iterator} function returns an iterator +across the workflow flags of @var{message}. +This includes the @code{"fuzzy"} flag. +This iterator returns the workflow flags set on @var{message}, +one by one, through the function @code{po_flag_next}. +When done, you should free the iterator, +through the function @code{po_flag_iterator_free}. +@end deftypefun + @deftypefun {int} po_message_is_format (po_message_t@tie{}@var{message}, const@tie{}char@tie{}*@var{format_type}) The @code{po_message_is_format} function returns true when the message is marked as being a format string of @var{format_type}. @@ -6578,6 +6607,43 @@ or @var{value} = -1 to remove the format string mark and its opposite. @end deftypefun +@deftypefun {int} po_message_has_sticky_flag (po_message_t@tie{}@var{message}, const@tie{}char@tie{}*@var{sticky_flag}) +The @code{po_message_has_sticky_flag} function returns true +when @var{message} is marked with a given sticky flag. + +This function is a generalization of the +@code{po_message_is_format} and @code{po_message_get_format} format functions. +@end deftypefun + +@deftypefun {void} po_message_set_sticky_flag (po_message_t@tie{}@var{message}, const@tie{}char@tie{}*@var{sticky_flag}, int@tie{}@var{value}) +The @code{po_message_set_sticky_flag} function changes +a given sticky flag on @var{message}: +If the @var{value} argument is non-zero, it sets it. +If the @var{value} argument is zero, it unsets it. + +This function is a generalization of the @code{po_message_set_format} function. + +Note that a message cannot have the sticky flags +@code{@var{language}-format} and @code{no-@var{language}-format} +at the same time. +Therefore, setting the @code{@var{language}-format} flag for some @var{language} +has the side effect of unsetting the @code{no-@var{language}-format} flag, +and vice versa. +@end deftypefun + +@deftypefun {po_flag_iterator_t} po_message_sticky_flags_iterator (po_message_t@tie{}@var{message}) +The @code{po_message_sticky_flags_iterator} function returns an iterator +across the sticky flags of @var{message}. +This includes the various +@code{@var{language}-format} and @code{no-@var{language}-format} flags, +as well as the @code{no-wrap} flag. +It does @emph{not} include the @code{"range"}, because that is not a flag. +This iterator returns the sticky flags set on @var{message}, +one by one, through the function @code{po_flag_next}. +When done, you should free the iterator, +through the function @code{po_flag_iterator_free}. +@end deftypefun + @deftypefun {int} po_message_is_range (po_message_t@tie{}@var{message}, int@tie{}*@var{minp}, int@tie{}*@var{maxp}) The @code{po_message_is_range} function returns true when the message has a numeric range set, and stores the minimum and maximum value in the @@ -6658,6 +6724,23 @@ it returns ``C#'' when @var{format_type} is ``csharp_format''. Return @code{NULL} if @var{format_type} is not a supported format type. @end deftypefun +@node po_flag_iterator_t API +@subsection po_flag_iterator_t API + +The following functions apply to a @code{po_flag_iterator_t} object, +as returned by the functions @code{po_message_workflow_flags_iterator} +and @code{po_message_sticky_flags_iterator}. + +@deftypefun {void} po_flag_iterator_free (po_flag_iterator_t@tie{}@var{iterator}) +The @code{po_flag_iterator_free} function frees the given @var{iterator}. +@end deftypefun + +@deftypefun {const char *} po_flag_next (po_flag_iterator_t@tie{}@var{iterator}) +The @code{po_flag_next} function returns +the next flag of the given kind on the given message. +At the end of the list of flags, it returns @code{NULL}. +@end deftypefun + @node Checking API @subsection Checking API diff --git a/gettext-tools/libgettextpo/gettext-po.c b/gettext-tools/libgettextpo/gettext-po.c index c364ae003..5fbb00c7c 100644 --- a/gettext-tools/libgettextpo/gettext-po.c +++ b/gettext-tools/libgettextpo/gettext-po.c @@ -59,6 +59,13 @@ struct po_message_iterator /* A po_filepos_t is actually a 'lex_pos_ty *'. */ +struct po_flag_iterator +{ + po_message_t message; + int kind; /* 0: workflow flags, 1: sticky flags */ + size_t index; +}; + /* Version number: (major<<16) + (minor<<8) + subminor */ int libgettextpo_version = LIBGETTEXTPO_VERSION; @@ -935,6 +942,44 @@ po_message_set_fuzzy (po_message_t message, int fuzzy) } +/* Return true if the message has a given workflow flag. + This function is a generalization of po_message_is_fuzzy. */ + +int +po_message_has_workflow_flag (po_message_t message, const char *workflow_flag) +{ + if (strcmp (workflow_flag, "fuzzy") == 0) + return po_message_is_fuzzy (message); + return 0; +} + + +/* Set or unset a given workflow flag on a message. + This function is a generalization of po_message_set_fuzzy. */ + +void +po_message_set_workflow_flag (po_message_t message, const char *workflow_flag, int value) +{ + if (strcmp (workflow_flag, "fuzzy") == 0) + po_message_set_fuzzy (message, value); +} + + +/* Create an iterator for traversing the list of workflow flags of a message. + This includes the "fuzzy" flag. */ + +po_flag_iterator_t +po_message_workflow_flags_iterator (po_message_t message) +{ + po_flag_iterator_t iterator = XMALLOC (struct po_flag_iterator); + iterator->message = message; + iterator->kind = 0; + iterator->index = 0; + + return iterator; +} + + /* Return true if the message is marked as being a format string of the given type (e.g. "c-format"). */ @@ -976,10 +1021,9 @@ po_message_get_format (po_message_t message, const char *format_type) enum is_format is_format = mp->is_format[i]; /* See significant_format_p and make_format_description_string in write-po.c. */ - if (is_format != undecided && is_format != impossible) - return (possible_format_p (is_format) ? 1 : 0); - else - return -1; + return (possible_format_p (is_format) ? 1 : + not_format_p (is_format) ? 0 : + -1); } return -1; } @@ -1003,6 +1047,109 @@ po_message_set_format (po_message_t message, const char *format_type, int value) } +/* Return true if the message has a given sticky flag. + This function is a generalization of po_message_is_format and + po_message_get_format. */ + +int +po_message_has_sticky_flag (po_message_t message, const char *sticky_flag) +{ + message_ty *mp = (message_ty *) message; + size_t len = strlen (sticky_flag); + + if (len >= 7 && memcmp (sticky_flag + len - 7, "-format", 7) == 0) + { + if (len >= 3 + 7 && memcmp (sticky_flag, "no-", 3) == 0) + { + size_t i; + for (i = 0; i < NFORMATS; i++) + if (strlen (format_language[i]) == len - 3 - 7 + && memcmp (format_language[i], sticky_flag + 3, len - 3 - 7) == 0) + /* The given sticky_flag corresponds to the opposite of + (enum format_type) i. */ + return not_format_p (mp->is_format[i]); + } + else + { + size_t i; + for (i = 0; i < NFORMATS; i++) + if (strlen (format_language[i]) == len - 7 + && memcmp (format_language[i], sticky_flag, len - 7) == 0) + /* The given sticky_flag corresponds to (enum format_type) i. */ + return possible_format_p (mp->is_format[i]); + } + } + else if (strcmp (sticky_flag, "no-wrap") == 0) + return mp->do_wrap == no; + return 0; +} + + +/* Set or unset a given sticky flag on a message. + This function is a generalization of po_message_set_format. */ + +void +po_message_set_sticky_flag (po_message_t message, const char *sticky_flag, int value) +{ + message_ty *mp = (message_ty *) message; + size_t len = strlen (sticky_flag); + + if (len >= 7 && memcmp (sticky_flag + len - 7, "-format", 7) == 0) + { + if (len >= 3 + 7 && memcmp (sticky_flag, "no-", 3) == 0) + { + size_t i; + for (i = 0; i < NFORMATS; i++) + if (strlen (format_language[i]) == len - 3 - 7 + && memcmp (format_language[i], sticky_flag + 3, len - 3 - 7) == 0) + /* The given sticky_flag corresponds to the opposite of + (enum format_type) i. */ + { + if (value) + mp->is_format[i] = no; + else + if (!possible_format_p (mp->is_format[i])) + mp->is_format[i] = undecided; + } + } + else + { + size_t i; + for (i = 0; i < NFORMATS; i++) + if (strlen (format_language[i]) == len - 7 + && memcmp (format_language[i], sticky_flag, len - 7) == 0) + /* The given sticky_flag corresponds to (enum format_type) i. */ + { + if (value) + mp->is_format[i] = yes; + else + if (!not_format_p (mp->is_format[i])) + mp->is_format[i] = undecided; + } + } + } + else if (strcmp (sticky_flag, "no-wrap") == 0) + mp->do_wrap = (value ? no : yes); +} + + +/* Create an iterator for traversing the list of sticky flags of a message. + This includes the "*-format" and "no-*-format" flags, as well as the + "no-wrap" flag. + It does *not* include the "range", because that is not a flag. */ + +po_flag_iterator_t +po_message_sticky_flags_iterator (po_message_t message) +{ + po_flag_iterator_t iterator = XMALLOC (struct po_flag_iterator); + iterator->message = message; + iterator->kind = 1; + iterator->index = 0; + + return iterator; +} + + /* If a numeric range of a message is set, return true and store the minimum and maximum value in *MINP and *MAXP. */ @@ -1115,6 +1262,73 @@ po_format_pretty_name (const char *format_type) } +/* Free an iterator. */ + +void +po_flag_iterator_free (po_flag_iterator_t iterator) +{ + free (iterator); +} + + +/* Return the next flag, and advance the iterator. + Return NULL at the end of the list of flags. */ +const char * +po_flag_next (po_flag_iterator_t iterator) +{ + message_ty *mp = (message_ty *) iterator->message; + + if (mp != NULL) + switch (iterator->kind) + { + case 0: + /* Return the next workflow flag. */ + if (iterator->index == 0) + { + iterator->index++; + if (mp->is_fuzzy) + return "fuzzy"; + } + /* Here iterator->index == 1. */ + return NULL; + + case 1: + /* Return the next sticky flag. */ + while (iterator->index < 2 * NFORMATS + 1) + { + size_t i = iterator->index; + iterator->index++; + if (i < 2 * NFORMATS) + { + if ((i % 2) == 0) + { + i = i / 2; + if (possible_format_p (mp->is_format[i])) + return format_flag[i] + 3; /* without "no-" prefix */ + } + else + { + i = i / 2; + if (not_format_p (mp->is_format[i])) + return format_flag[i] + 0; /* with "no-" prefix */ + } + } + else if (i == 2 * NFORMATS) + { + if (mp->do_wrap == no) + return "no-wrap"; + } + } + /* Here iterator->index == 2 * NFORMATS + 1. */ + return NULL; + + default: + abort (); + } + return NULL; +} + + /* Test whether an entire file PO file is valid, like msgfmt does it. If it is invalid, pass the reasons to the handler. */ diff --git a/gettext-tools/libgettextpo/gettext-po.in.h b/gettext-tools/libgettextpo/gettext-po.in.h index 8b2887f39..a1f727871 100644 --- a/gettext-tools/libgettextpo/gettext-po.in.h +++ b/gettext-tools/libgettextpo/gettext-po.in.h @@ -46,6 +46,10 @@ typedef struct po_message *po_message_t; /* A po_filepos_t represents a string's position within a source file. */ typedef struct po_filepos *po_filepos_t; +/* A po_flag_iterator_t represents an iterator through the workflow flags or + the sticky flags of a message. */ +typedef struct po_flag_iterator *po_flag_iterator_t; + /* A po_error_handler handles error situations. No longer used. */ struct po_error_handler { @@ -192,6 +196,7 @@ extern void po_message_insert (po_message_iterator_t iterator, po_message_t mess To finish initializing the message, you must set the msgid and msgstr. */ extern po_message_t po_message_create (void); + /* Return the context of a message, or NULL for a message not restricted to a context. */ extern const char * po_message_msgctxt (po_message_t message); @@ -200,6 +205,7 @@ extern const char * po_message_msgctxt (po_message_t message); context. */ extern void po_message_set_msgctxt (po_message_t message, const char *msgctxt); + /* Return the msgid (untranslated English string) of a message. */ extern const char * po_message_msgid (po_message_t message); @@ -214,6 +220,7 @@ extern const char * po_message_msgid_plural (po_message_t message); NULL means a message without plural. */ extern void po_message_set_msgid_plural (po_message_t message, const char *msgid_plural); + /* Return the msgstr (translation) of a message. Return the empty string for an untranslated message. */ extern const char * po_message_msgstr (po_message_t message); @@ -230,6 +237,7 @@ extern const char * po_message_msgstr_plural (po_message_t message, int index); Use a NULL value at the end to reduce the number of plural forms. */ extern void po_message_set_msgstr_plural (po_message_t message, int index, const char *msgstr); + /* Return the comments for a message. */ extern const char * po_message_comments (po_message_t message); @@ -237,6 +245,7 @@ extern const char * po_message_comments (po_message_t message); comments should be a multiline string, ending in a newline, or empty. */ extern void po_message_set_comments (po_message_t message, const char *comments); + /* Return the extracted comments for a message. */ extern const char * po_message_extracted_comments (po_message_t message); @@ -244,6 +253,7 @@ extern const char * po_message_extracted_comments (po_message_t message); comments should be a multiline string, ending in a newline, or empty. */ extern void po_message_set_extracted_comments (po_message_t message, const char *comments); + /* Return the i-th file position for a message, or NULL if i is out of range. */ extern po_filepos_t po_message_filepos (po_message_t message, int i); @@ -260,6 +270,7 @@ extern void po_message_remove_filepos (po_message_t message, int i); line number is available. */ extern void po_message_add_filepos (po_message_t message, const char *file, size_t start_line); + /* Return the previous context of a message, or NULL for none. */ extern const char * po_message_prev_msgctxt (po_message_t message); @@ -282,18 +293,33 @@ extern const char * po_message_prev_msgid_plural (po_message_t message); message. NULL is allowed. */ extern void po_message_set_prev_msgid_plural (po_message_t message, const char *prev_msgid_plural); + /* Return true if the message is marked obsolete. */ extern int po_message_is_obsolete (po_message_t message); /* Change the obsolete mark of a message. */ extern void po_message_set_obsolete (po_message_t message, int obsolete); + /* Return true if the message is marked fuzzy. */ extern int po_message_is_fuzzy (po_message_t message); /* Change the fuzzy mark of a message. */ extern void po_message_set_fuzzy (po_message_t message, int fuzzy); +/* Return true if the message has a given workflow flag. + This function is a generalization of po_message_is_fuzzy. */ +extern int po_message_has_workflow_flag (po_message_t message, const char *workflow_flag); + +/* Set or unset a given workflow flag on a message. + This function is a generalization of po_message_set_fuzzy. */ +extern void po_message_set_workflow_flag (po_message_t message, const char *workflow_flag, int value); + +/* Create an iterator for traversing the list of workflow flags of a message. + This includes the "fuzzy" flag. */ +extern po_flag_iterator_t po_message_workflow_flags_iterator (po_message_t message); + + /* Return true if the message is marked as being a format string of the given type (e.g. "c-format"). */ extern int po_message_is_format (po_message_t message, const char *format_type); @@ -311,6 +337,22 @@ extern int po_message_get_format (po_message_t message, const char *format_type) or value = -1 to remove the format string mark and its opposite. */ extern void po_message_set_format (po_message_t message, const char *format_type, int value); +/* Return true if the message has a given sticky flag. + This function is a generalization of po_message_is_format and + po_message_get_format. */ +extern int po_message_has_sticky_flag (po_message_t message, const char *sticky_flag); + +/* Set or unset a given sticky flag on a message. + This function is a generalization of po_message_set_format. */ +extern void po_message_set_sticky_flag (po_message_t message, const char *sticky_flag, int value); + +/* Create an iterator for traversing the list of sticky flags of a message. + This includes the "*-format" and "no-*-format" flags, as well as the + "no-wrap" flag. + It does *not* include the "range", because that is not a flag. */ +extern po_flag_iterator_t po_message_sticky_flags_iterator (po_message_t message); + + /* If a numeric range of a message is set, return true and store the minimum and maximum value in *MINP and *MAXP. */ extern int po_message_is_range (po_message_t message, int *minp, int *maxp); @@ -342,6 +384,16 @@ extern const char * const * po_format_list (void); extern const char * po_format_pretty_name (const char *format_type); +/* ========================= po_flag_iterator_t API ========================= */ + +/* Free an iterator. */ +extern void po_flag_iterator_free (po_flag_iterator_t iterator); + +/* Return the next flag, and advance the iterator. + Return NULL at the end of the list of flags. */ +extern const char * po_flag_next (po_flag_iterator_t iterator); + + /* ============================= Checking API ============================== */ /* Test whether an entire file PO file is valid, like msgfmt does it. diff --git a/gettext-tools/src/message.c b/gettext-tools/src/message.c index bc2885e5e..4e893664b 100644 --- a/gettext-tools/src/message.c +++ b/gettext-tools/src/message.c @@ -112,6 +112,47 @@ const char *const format_language_pretty[NFORMATS] = /* format_ycp */ "YCP" }; +const char *const format_flag[NFORMATS] = +{ + /* format_c */ "no-" "c" "-format", + /* format_objc */ "no-" "objc" "-format", + /* format_cplusplus_brace */ "no-" "c++" "-format", + /* format_python */ "no-" "python" "-format", + /* format_python_brace */ "no-" "python-brace" "-format", + /* format_java */ "no-" "java" "-format", + /* format_java_printf */ "no-" "java-printf" "-format", + /* format_csharp */ "no-" "csharp" "-format", + /* format_javascript */ "no-" "javascript" "-format", + /* format_scheme */ "no-" "scheme" "-format", + /* format_lisp */ "no-" "lisp" "-format", + /* format_elisp */ "no-" "elisp" "-format", + /* format_librep */ "no-" "librep" "-format", + /* format_rust */ "no-" "rust" "-format", + /* format_go */ "no-" "go" "-format", + /* format_ruby */ "no-" "ruby" "-format", + /* format_sh */ "no-" "sh" "-format", + /* format_sh_printf */ "no-" "sh-printf" "-format", + /* format_awk */ "no-" "awk" "-format", + /* format_lua */ "no-" "lua" "-format", + /* format_pascal */ "no-" "object-pascal" "-format", + /* format_modula2 */ "no-" "modula2" "-format", + /* format_d */ "no-" "d" "-format", + /* format_ocaml */ "no-" "ocaml" "-format", + /* format_smalltalk */ "no-" "smalltalk" "-format", + /* format_qt */ "no-" "qt" "-format", + /* format_qt_plursl */ "no-" "qt-plural" "-format", + /* format_kde */ "no-" "kde" "-format", + /* format_kde_kuit */ "no-" "kde-kuit" "-format", + /* format_boost */ "no-" "boost" "-format", + /* format_tcl */ "no-" "tcl" "-format", + /* format_perl */ "no-" "perl" "-format", + /* format_perl_brace */ "no-" "perl-brace" "-format", + /* format_php */ "no-" "php" "-format", + /* format_gcc_internal */ "no-" "gcc-internal" "-format", + /* format_gfc_internal */ "no-" "gfc-internal" "-format", + /* format_ycp */ "no-" "ycp" "-format" +}; + bool possible_format_p (enum is_format is_format) @@ -122,6 +163,13 @@ possible_format_p (enum is_format is_format) } +bool +not_format_p (enum is_format is_format) +{ + return is_format == no; +} + + const char *const syntax_check_name[NSYNTAXCHECKS] = { /* sc_ellipsis_unicode */ "ellipsis-unicode", diff --git a/gettext-tools/src/message.h b/gettext-tools/src/message.h index 147bbd864..b37e4890c 100644 --- a/gettext-tools/src/message.h +++ b/gettext-tools/src/message.h @@ -84,6 +84,7 @@ enum format_type #define NFORMATS 37 /* Number of format_type enum values. */ extern LIBGETTEXTSRC_DLL_VARIABLE const char *const format_language[NFORMATS]; extern LIBGETTEXTSRC_DLL_VARIABLE const char *const format_language_pretty[NFORMATS]; +extern LIBGETTEXTSRC_DLL_VARIABLE const char *const format_flag[NFORMATS]; /* Is current msgid a format string? */ enum is_format @@ -99,6 +100,9 @@ enum is_format extern bool possible_format_p (enum is_format); +extern bool + not_format_p (enum is_format); + /* Range of an unsigned integer argument. */ struct argument_range diff --git a/gettext-tools/src/write-po.c b/gettext-tools/src/write-po.c index b2b2a6d30..02d6d3b82 100644 --- a/gettext-tools/src/write-po.c +++ b/gettext-tools/src/write-po.c @@ -68,6 +68,7 @@ make_format_description_string (enum is_format is_format, const char *lang, switch (is_format) { + /* Cf. possible_format_p. */ case possible: if (debug) { @@ -79,6 +80,7 @@ make_format_description_string (enum is_format is_format, const char *lang, case yes: result = xasprintf ("%s-format", lang); break; + /* Cf. not_format_p. */ case no: result = xasprintf ("no-%s-format", lang); break; @@ -92,7 +94,9 @@ make_format_description_string (enum is_format is_format, const char *lang, } -/* Return true if IS_FORMAT is worth mentioning in a #, flags list. */ +/* Return true if IS_FORMAT is worth mentioning in a #, flags list. + This is the same as + possible_format_p (is_format) || not_format_p (is_format). */ bool significant_format_p (enum is_format is_format) diff --git a/gettext-tools/tests/gettextpo-1-prg.c b/gettext-tools/tests/gettextpo-1-prg.c index eb6523662..55a0fd9a1 100644 --- a/gettext-tools/tests/gettextpo-1-prg.c +++ b/gettext-tools/tests/gettextpo-1-prg.c @@ -257,6 +257,21 @@ main (int argc, char *argv[]) ASSERT (po_message_get_format (msg, "c-format") == -1); ASSERT (po_message_get_format (msg, "java-format") == -1); ASSERT (!po_message_is_range (msg, &min, &max)); + ASSERT (!po_message_has_workflow_flag (msg, "fuzzy")); + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (msg); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + ASSERT (!po_message_has_sticky_flag (msg, "c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } } { po_message_t msg = po_next_message (iter); @@ -288,6 +303,23 @@ main (int argc, char *argv[]) ASSERT (po_message_get_format (msg, "c-format") == 1); ASSERT (po_message_get_format (msg, "java-format") == -1); ASSERT (!po_message_is_range (msg, &min, &max)); + ASSERT (po_message_has_workflow_flag (msg, "fuzzy")); + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "fuzzy") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + ASSERT (po_message_has_sticky_flag (msg, "c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "c-format") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } } { po_message_t msg = po_next_message (iter); @@ -331,6 +363,22 @@ main (int argc, char *argv[]) ASSERT (po_message_get_format (msg, "c-format") == 1); ASSERT (po_message_get_format (msg, "java-format") == -1); ASSERT (!po_message_is_range (msg, &min, &max)); + ASSERT (!po_message_has_workflow_flag (msg, "fuzzy")); + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (msg); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + ASSERT (po_message_has_sticky_flag (msg, "c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "c-format") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } } { po_message_t msg = po_next_message (iter); @@ -355,6 +403,21 @@ main (int argc, char *argv[]) ASSERT (po_message_get_format (msg, "c-format") == -1); ASSERT (po_message_get_format (msg, "java-format") == -1); ASSERT (!po_message_is_range (msg, &min, &max)); + ASSERT (!po_message_has_workflow_flag (msg, "fuzzy")); + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (msg); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + ASSERT (!po_message_has_sticky_flag (msg, "c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } } { po_message_t msg = po_next_message (iter); @@ -386,6 +449,22 @@ main (int argc, char *argv[]) ASSERT (po_message_get_format (msg, "c-format") == -1); ASSERT (po_message_get_format (msg, "java-format") == 1); ASSERT (!po_message_is_range (msg, &min, &max)); + ASSERT (!po_message_has_workflow_flag (msg, "fuzzy")); + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (msg); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + ASSERT (!po_message_has_sticky_flag (msg, "c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "java-format") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } } { po_message_t msg = po_next_message (iter); @@ -409,6 +488,21 @@ main (int argc, char *argv[]) ASSERT (po_message_get_format (msg, "c-format") == -1); ASSERT (po_message_get_format (msg, "java-format") == -1); ASSERT (!po_message_is_range (msg, &min, &max)); + ASSERT (!po_message_has_workflow_flag (msg, "fuzzy")); + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (msg); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + ASSERT (!po_message_has_sticky_flag (msg, "c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } } { po_message_t msg = po_next_message (iter); @@ -908,12 +1002,96 @@ main (int argc, char *argv[]) { po_message_t msg = po_message_create (); ASSERT (!po_message_is_fuzzy (msg)); + ASSERT (!po_message_has_workflow_flag (msg, "fuzzy")); + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (msg); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } po_message_set_fuzzy (msg, 1); ASSERT (po_message_is_fuzzy (msg)); + ASSERT (po_message_has_workflow_flag (msg, "fuzzy")); + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "fuzzy") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } po_message_set_fuzzy (msg, 1); ASSERT (po_message_is_fuzzy (msg)); + ASSERT (po_message_has_workflow_flag (msg, "fuzzy")); + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "fuzzy") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } po_message_set_fuzzy (msg, 0); ASSERT (!po_message_is_fuzzy (msg)); + ASSERT (!po_message_has_workflow_flag (msg, "fuzzy")); + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (msg); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + } + + /* Test po_message_set_workflow_flag. */ + { + po_message_t msg = po_message_create (); + ASSERT (!po_message_is_fuzzy (msg)); + ASSERT (!po_message_has_workflow_flag (msg, "fuzzy")); + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (msg); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + + po_message_set_workflow_flag (msg, "fuzzy", 1); + ASSERT (po_message_is_fuzzy (msg)); + ASSERT (po_message_has_workflow_flag (msg, "fuzzy")); + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "fuzzy") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + + po_message_set_workflow_flag (msg, "fuzzy", 1); + ASSERT (po_message_is_fuzzy (msg)); + ASSERT (po_message_has_workflow_flag (msg, "fuzzy")); + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "fuzzy") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + + po_message_set_workflow_flag (msg, "review", 1); + ASSERT (po_message_is_fuzzy (msg)); + ASSERT (po_message_has_workflow_flag (msg, "fuzzy")); + /* This will change in 2027. */ + ASSERT (!po_message_has_workflow_flag (msg, "review")); + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "fuzzy") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + + po_message_set_workflow_flag (msg, "fuzzy", 0); + ASSERT (!po_message_is_fuzzy (msg)); + ASSERT (!po_message_has_workflow_flag (msg, "fuzzy")); + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (msg); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + } + { + po_flag_iterator_t fiter = po_message_workflow_flags_iterator (NULL); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); } /* Test po_message_set_format. */ @@ -925,6 +1103,17 @@ main (int argc, char *argv[]) ASSERT (po_message_get_format (msg, "c-format") == -1); ASSERT (po_message_get_format (msg, "java-format") == -1); ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (!po_message_has_sticky_flag (msg, "c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } po_message_set_format (msg, "c-format", 1); ASSERT (po_message_is_format (msg, "c-format")); @@ -933,6 +1122,18 @@ main (int argc, char *argv[]) ASSERT (po_message_get_format (msg, "c-format") == 1); ASSERT (po_message_get_format (msg, "java-format") == -1); ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (po_message_has_sticky_flag (msg, "c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "c-format") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } po_message_set_format (msg, "c-format", 1); ASSERT (po_message_is_format (msg, "c-format")); @@ -941,6 +1142,18 @@ main (int argc, char *argv[]) ASSERT (po_message_get_format (msg, "c-format") == 1); ASSERT (po_message_get_format (msg, "java-format") == -1); ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (po_message_has_sticky_flag (msg, "c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "c-format") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } po_message_set_format (msg, "java-format", 1); ASSERT (po_message_is_format (msg, "c-format")); @@ -949,6 +1162,19 @@ main (int argc, char *argv[]) ASSERT (po_message_get_format (msg, "c-format") == 1); ASSERT (po_message_get_format (msg, "java-format") == 1); ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (po_message_has_sticky_flag (msg, "c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "c-format") == 0); + ASSERT (strcmp (po_flag_next (fiter), "java-format") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } po_message_set_format (msg, "c-format", 0); ASSERT (!po_message_is_format (msg, "c-format")); @@ -957,6 +1183,19 @@ main (int argc, char *argv[]) ASSERT (po_message_get_format (msg, "c-format") == 0); ASSERT (po_message_get_format (msg, "java-format") == 1); ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (!po_message_has_sticky_flag (msg, "c-format")); + ASSERT (po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "no-c-format") == 0); + ASSERT (strcmp (po_flag_next (fiter), "java-format") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } po_message_set_format (msg, "xyzzy-format", 1); ASSERT (!po_message_is_format (msg, "c-format")); @@ -965,6 +1204,20 @@ main (int argc, char *argv[]) ASSERT (po_message_get_format (msg, "c-format") == 0); ASSERT (po_message_get_format (msg, "java-format") == 1); ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (!po_message_has_sticky_flag (msg, "c-format")); + ASSERT (po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + /* This will change in 2027. */ + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "no-c-format") == 0); + ASSERT (strcmp (po_flag_next (fiter), "java-format") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } po_message_set_format (msg, "java-format", -1); ASSERT (!po_message_is_format (msg, "c-format")); @@ -973,6 +1226,228 @@ main (int argc, char *argv[]) ASSERT (po_message_get_format (msg, "c-format") == 0); ASSERT (po_message_get_format (msg, "java-format") == -1); ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (!po_message_has_sticky_flag (msg, "c-format")); + ASSERT (po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "no-c-format") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + } + + /* Test po_message_set_sticky_flag. */ + { + po_message_t msg = po_message_create (); + ASSERT (!po_message_is_format (msg, "c-format")); + ASSERT (!po_message_is_format (msg, "java-format")); + ASSERT (!po_message_is_format (msg, "xyzzy-format")); + ASSERT (po_message_get_format (msg, "c-format") == -1); + ASSERT (po_message_get_format (msg, "java-format") == -1); + ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (!po_message_has_sticky_flag (msg, "c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-wrap")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + + po_message_set_sticky_flag (msg, "c-format", 1); + ASSERT (po_message_is_format (msg, "c-format")); + ASSERT (!po_message_is_format (msg, "java-format")); + ASSERT (!po_message_is_format (msg, "xyzzy-format")); + ASSERT (po_message_get_format (msg, "c-format") == 1); + ASSERT (po_message_get_format (msg, "java-format") == -1); + ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (po_message_has_sticky_flag (msg, "c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-wrap")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "c-format") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + + po_message_set_sticky_flag (msg, "c-format", 1); + ASSERT (po_message_is_format (msg, "c-format")); + ASSERT (!po_message_is_format (msg, "java-format")); + ASSERT (!po_message_is_format (msg, "xyzzy-format")); + ASSERT (po_message_get_format (msg, "c-format") == 1); + ASSERT (po_message_get_format (msg, "java-format") == -1); + ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (po_message_has_sticky_flag (msg, "c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-wrap")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "c-format") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + + po_message_set_sticky_flag (msg, "java-format", 1); + ASSERT (po_message_is_format (msg, "c-format")); + ASSERT (po_message_is_format (msg, "java-format")); + ASSERT (!po_message_is_format (msg, "xyzzy-format")); + ASSERT (po_message_get_format (msg, "c-format") == 1); + ASSERT (po_message_get_format (msg, "java-format") == 1); + ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (po_message_has_sticky_flag (msg, "c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-wrap")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "c-format") == 0); + ASSERT (strcmp (po_flag_next (fiter), "java-format") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + + po_message_set_sticky_flag (msg, "no-c-format", 1); + ASSERT (!po_message_is_format (msg, "c-format")); + ASSERT (po_message_is_format (msg, "java-format")); + ASSERT (!po_message_is_format (msg, "xyzzy-format")); + ASSERT (po_message_get_format (msg, "c-format") == 0); + ASSERT (po_message_get_format (msg, "java-format") == 1); + ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (!po_message_has_sticky_flag (msg, "c-format")); + ASSERT (po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-wrap")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "no-c-format") == 0); + ASSERT (strcmp (po_flag_next (fiter), "java-format") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + + po_message_set_sticky_flag (msg, "no-wrap", 1); + ASSERT (!po_message_is_format (msg, "c-format")); + ASSERT (po_message_is_format (msg, "java-format")); + ASSERT (!po_message_is_format (msg, "xyzzy-format")); + ASSERT (po_message_get_format (msg, "c-format") == 0); + ASSERT (po_message_get_format (msg, "java-format") == 1); + ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (!po_message_has_sticky_flag (msg, "c-format")); + ASSERT (po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + ASSERT (po_message_has_sticky_flag (msg, "no-wrap")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "no-c-format") == 0); + ASSERT (strcmp (po_flag_next (fiter), "java-format") == 0); + ASSERT (strcmp (po_flag_next (fiter), "no-wrap") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + + po_message_set_sticky_flag (msg, "python-format", 0); + ASSERT (!po_message_is_format (msg, "c-format")); + ASSERT (po_message_is_format (msg, "java-format")); + ASSERT (!po_message_is_format (msg, "python-format")); + ASSERT (!po_message_is_format (msg, "xyzzy-format")); + ASSERT (po_message_get_format (msg, "c-format") == 0); + ASSERT (po_message_get_format (msg, "java-format") == 1); + ASSERT (po_message_get_format (msg, "python-format") == -1); + ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (!po_message_has_sticky_flag (msg, "c-format")); + ASSERT (po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "python-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-python-format")); + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + ASSERT (po_message_has_sticky_flag (msg, "no-wrap")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "no-c-format") == 0); + ASSERT (strcmp (po_flag_next (fiter), "java-format") == 0); + ASSERT (strcmp (po_flag_next (fiter), "no-wrap") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + + po_message_set_sticky_flag (msg, "xyzzy-format", 1); + ASSERT (!po_message_is_format (msg, "c-format")); + ASSERT (po_message_is_format (msg, "java-format")); + ASSERT (!po_message_is_format (msg, "xyzzy-format")); + ASSERT (po_message_get_format (msg, "c-format") == 0); + ASSERT (po_message_get_format (msg, "java-format") == 1); + ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (!po_message_has_sticky_flag (msg, "c-format")); + ASSERT (po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + /* This will change in 2027. */ + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + ASSERT (po_message_has_sticky_flag (msg, "no-wrap")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "no-c-format") == 0); + ASSERT (strcmp (po_flag_next (fiter), "java-format") == 0); + ASSERT (strcmp (po_flag_next (fiter), "no-wrap") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + + po_message_set_sticky_flag (msg, "java-format", 0); + ASSERT (!po_message_is_format (msg, "c-format")); + ASSERT (!po_message_is_format (msg, "java-format")); + ASSERT (!po_message_is_format (msg, "xyzzy-format")); + ASSERT (po_message_get_format (msg, "c-format") == 0); + ASSERT (po_message_get_format (msg, "java-format") == -1); + ASSERT (po_message_get_format (msg, "xyzzy-format") == -1); + ASSERT (!po_message_has_sticky_flag (msg, "c-format")); + ASSERT (po_message_has_sticky_flag (msg, "no-c-format")); + ASSERT (!po_message_has_sticky_flag (msg, "java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-java-format")); + ASSERT (!po_message_has_sticky_flag (msg, "xyzzy-format")); + ASSERT (!po_message_has_sticky_flag (msg, "no-xyzzy-format")); + ASSERT (po_message_has_sticky_flag (msg, "no-wrap")); + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (msg); + ASSERT (strcmp (po_flag_next (fiter), "no-c-format") == 0); + ASSERT (strcmp (po_flag_next (fiter), "no-wrap") == 0); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); + } + } + { + po_flag_iterator_t fiter = po_message_sticky_flags_iterator (NULL); + ASSERT (po_flag_next (fiter) == NULL); + po_flag_iterator_free (fiter); } /* Test po_message_set_range. */