diff options
author | Daiki Ueno <ueno@gnu.org> | 2015-10-05 16:33:31 +0900 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2015-10-06 10:03:34 +0900 |
commit | d5a1f03517517ac2474ee50ea0b4f5d270457478 (patch) | |
tree | 635dcef4e3e78bc6c40cc59741de64e59ba5b21b | |
parent | 423d5cca70c2640eaf45dabdc36ed755701043a8 (diff) | |
download | external_gettext-d5a1f03517517ac2474ee50ea0b4f5d270457478.zip external_gettext-d5a1f03517517ac2474ee50ea0b4f5d270457478.tar.gz external_gettext-d5a1f03517517ac2474ee50ea0b4f5d270457478.tar.bz2 |
msgfmt: Refactor --desktop handling
* gettext-tools/src/msgfmt.c (get_languages): Avoid redundant memory
allocation.
(msgfmt_operand_list_init): New function.
(msgfmt_operand_list_destroy): New function.
(msgfmt_operand_list_append): New function.
(msgfmt_operand_list_add_directory): New function.
(msgfmt_desktop_bulk): Rewrite using msgfmt_operand_list_ty.
* gettext-tools/src/msgfmt.h (msgfmt_operand_ty,
msgfmt_operand_list_ty): New type.
* gettext-tools/src/write-desktop.c (msgdomain_write_desktop_bulk):
Simplify using msgfmt_operand_list_ty.
(msgdomain_write_desktop): Simplify using msgfmt_operand_list_ty.
* gettext-tools/src/write-desktop.h (msgdomain_write_desktop_bulk):
Take OPERANDS as the first argument, instead of LANGUAGES and MESSAGES.
-rw-r--r-- | gettext-tools/src/ChangeLog | 17 | ||||
-rw-r--r-- | gettext-tools/src/msgfmt.c | 167 | ||||
-rw-r--r-- | gettext-tools/src/msgfmt.h | 26 | ||||
-rw-r--r-- | gettext-tools/src/write-desktop.c | 47 | ||||
-rw-r--r-- | gettext-tools/src/write-desktop.h | 5 |
5 files changed, 170 insertions, 92 deletions
diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog index a29357e..95b0b33 100644 --- a/gettext-tools/src/ChangeLog +++ b/gettext-tools/src/ChangeLog @@ -1,5 +1,22 @@ 2015-10-06 Daiki Ueno <ueno@gnu.org> + msgfmt: Refactor --desktop handling + * msgfmt.c (get_languages): Avoid redundant memory allocation. + (msgfmt_operand_list_init): New function. + (msgfmt_operand_list_destroy): New function. + (msgfmt_operand_list_append): New function. + (msgfmt_operand_list_add_directory): New function. + (msgfmt_desktop_bulk): Rewrite using msgfmt_operand_list_ty. + * msgfmt.h (msgfmt_operand_ty) + (msgfmt_operand_list_ty): New type. + * write-desktop.c (msgdomain_write_desktop_bulk): + Simplify using msgfmt_operand_list_ty. + (msgdomain_write_desktop): Simplify using msgfmt_operand_list_ty. + * write-desktop.h (msgdomain_write_desktop_bulk): Take OPERANDS as + the first argument, instead of LANGUAGES and MESSAGES. + +2015-10-06 Daiki Ueno <ueno@gnu.org> + * sentence.c (sentence_end): Assign initial values to local variables to suppress compiler warnings with -Wmaybe-uninitialized. This shouldn't address any real bug. diff --git a/gettext-tools/src/msgfmt.c b/gettext-tools/src/msgfmt.c index ef91f49..c139803 100644 --- a/gettext-tools/src/msgfmt.c +++ b/gettext-tools/src/msgfmt.c @@ -212,7 +212,6 @@ static struct msg_domain *new_domain (const char *name, const char *file_name); static bool is_nonobsolete (const message_ty *mp); static void read_catalog_file_msgfmt (char *filename, catalog_input_format_ty input_syntax); -static string_list_ty *get_languages (const char *directory); static int msgfmt_desktop_bulk (const char *directory, const char *template_file_name, hash_table *keywords, @@ -1298,35 +1297,30 @@ add_languages (string_list_ty *languages, string_list_ty *desired_languages, /* Compute the languages list by reading the "LINGUAS" envvar or the LINGUAS file under DIRECTORY. */ -static string_list_ty * -get_languages (const char *directory) +static void +get_languages (string_list_ty *languages, const char *directory) { char *envval; - string_list_ty *languages; - string_list_ty *desired_languages = NULL; - char *linguas_file_name; + string_list_ty real_desired_languages, *desired_languages = NULL; + char *linguas_file_name = NULL; struct stat statbuf; FILE *fp; size_t line_len = 0; char *line_buf = NULL; - languages = string_list_alloc (); envval = getenv ("LINGUAS"); if (envval) { - desired_languages = string_list_alloc (); - add_languages (desired_languages, NULL, envval, strlen (envval)); + string_list_init (&real_desired_languages); + add_languages (&real_desired_languages, NULL, envval, strlen (envval)); + desired_languages = &real_desired_languages; } linguas_file_name = xconcatenated_filename (directory, "LINGUAS", NULL); if (stat (linguas_file_name, &statbuf) < 0) { error (EXIT_SUCCESS, 0, _("%s does not exist"), linguas_file_name); - string_list_free (languages); - if (desired_languages != NULL) - string_list_free (desired_languages); - free (linguas_file_name); - return NULL; + goto out; } fp = fopen (linguas_file_name, "r"); @@ -1334,11 +1328,7 @@ get_languages (const char *directory) { error (EXIT_SUCCESS, 0, _("%s exists but cannot read"), linguas_file_name); - string_list_free (languages); - if (desired_languages != NULL) - string_list_free (desired_languages); - free (linguas_file_name); - return NULL; + goto out; } while (!feof (fp)) @@ -1368,32 +1358,68 @@ get_languages (const char *directory) free (line_buf); fclose (fp); + + out: if (desired_languages != NULL) - string_list_free (desired_languages); + string_list_destroy (desired_languages); free (linguas_file_name); +} - return languages; +static void +msgfmt_operand_list_init (msgfmt_operand_list_ty *operands) +{ + operands->items = NULL; + operands->nitems = 0; + operands->nitems_max = 0; +} + +static void +msgfmt_operand_list_destroy (msgfmt_operand_list_ty *operands) +{ + size_t i; + + for (i = 0; i < operands->nitems; i++) + { + free (operands->items[i].language); + message_list_free (operands->items[i].mlp, 0); + } + free (operands->items); +} + +static void +msgfmt_operand_list_append (msgfmt_operand_list_ty *operands, + const char *language, + message_list_ty *messages) +{ + msgfmt_operand_ty *operand; + + if (operands->nitems == operands->nitems_max) + { + operands->nitems_max = operands->nitems_max * 2 + 1; + operands->items = xrealloc (operands->items, + sizeof (msgfmt_operand_ty) + * operands->nitems_max); + } + + operand = &operands->items[operands->nitems++]; + operand->language = xstrdup (language); + operand->mlp = messages; } -/* Helper function to support 'bulk' operation mode of --desktop. - This reads all .po files in DIRECTORY and merges them into a - .desktop file FILE_NAME. Currently it does not support some - options available in 'iterative' mode, such as --statistics. */ static int -msgfmt_desktop_bulk (const char *directory, - const char *template_file_name, - hash_table *keywords, - const char *file_name) +msgfmt_operand_list_add_directory (msgfmt_operand_list_ty *operands, + const char *directory) { - string_list_ty *languages = NULL; - message_list_ty **messages = NULL; + string_list_ty languages; void *saved_dir_list; int retval = 0; size_t i; - languages = get_languages (directory); - if (!languages) - return EXIT_FAILURE; + string_list_init (&languages); + get_languages (&languages, directory); + + if (languages.nitems == 0) + return 0; /* Reset the directory search list so only .po files under DIRECTORY will be read. */ @@ -1401,34 +1427,35 @@ msgfmt_desktop_bulk (const char *directory, dir_list_append (directory); /* Read all .po files. */ - messages = XNMALLOC (languages->nitems, message_list_ty *); - for (i = 0; i < languages->nitems; i++) + for (i = 0; i < languages.nitems; i++) { - const char *language = languages->item[i]; + const char *language = languages.item[i]; + message_list_ty *mlp; char *input_file_name; int nerrors; - current_domain = new_domain (file_name, file_name); + current_domain = new_domain (MESSAGE_DOMAIN_DEFAULT, + add_mo_suffix (MESSAGE_DOMAIN_DEFAULT)); input_file_name = xconcatenated_filename ("", language, ".po"); read_catalog_file_msgfmt (input_file_name, &input_format_po); free (input_file_name); - /* The domain directive is not supported by --desktop mode. + /* The domain directive is not supported in the bulk execution mode. Thus, domain_list should always contain a single domain. */ assert (current_domain == domain_list && domain_list->next == NULL); - messages[i] = current_domain->mlp; + mlp = current_domain->mlp; free (current_domain); current_domain = domain_list = NULL; /* Remove obsolete messages. They were only needed for duplicate checking. */ - message_list_remove_if_not (messages[i], is_nonobsolete); + message_list_remove_if_not (mlp, is_nonobsolete); /* Perform all kinds of checks: plural expressions, format strings, ... */ nerrors = - check_message_list (messages[i], + check_message_list (mlp, /* Untranslated and fuzzy messages have already been dealt with during parsing, see below in msgfmt_frob_new_message. */ @@ -1437,38 +1464,58 @@ msgfmt_desktop_bulk (const char *directory, check_compatibility, check_accelerators, accelerator_char); - /* Exit with status 1 on any error. */ + retval += nerrors; if (nerrors > 0) { error (0, 0, ngettext ("found %d fatal error", "found %d fatal errors", nerrors), nerrors); - retval = EXIT_FAILURE; - goto out; + continue; } /* Convert the messages to Unicode. */ - iconv_message_list (messages[i], NULL, po_charset_utf8, NULL); + iconv_message_list (mlp, NULL, po_charset_utf8, NULL); + + msgfmt_operand_list_append (operands, language, mlp); } - /* Write the messages into .desktop file. */ - if (msgdomain_write_desktop_bulk (languages, - messages, - template_file_name, - keywords, - file_name)) + string_list_destroy (&languages); + dir_list_restore (saved_dir_list); + + return retval; +} + +/* Helper function to support 'bulk' operation mode of --desktop. + This reads all .po files in DIRECTORY and merges them into a + .desktop file FILE_NAME. Currently it does not support some + options available in 'iterative' mode, such as --statistics. */ +static int +msgfmt_desktop_bulk (const char *directory, + const char *template_file_name, + hash_table *keywords, + const char *file_name) +{ + msgfmt_operand_list_ty operands; + int retval; + + msgfmt_operand_list_init (&operands); + + /* Read all .po files. */ + retval = msgfmt_operand_list_add_directory (&operands, directory); + if (retval > 0) { - retval = EXIT_FAILURE; - goto out; + msgfmt_operand_list_destroy (&operands); + return retval; } - out: - dir_list_restore (saved_dir_list); - for (i = 0; i < languages->nitems; i++) - message_list_free (messages[i], 0); - free (messages); - string_list_free (languages); + /* Write the messages into .desktop file. */ + retval = msgdomain_write_desktop_bulk (&operands, + template_file_name, + keywords, + file_name); + + msgfmt_operand_list_destroy (&operands); return retval; } diff --git a/gettext-tools/src/msgfmt.h b/gettext-tools/src/msgfmt.h index 8f28b33..3651a30 100644 --- a/gettext-tools/src/msgfmt.h +++ b/gettext-tools/src/msgfmt.h @@ -19,10 +19,36 @@ #ifndef _MSGFMT_H #define _MSGFMT_H +#include "message.h" + +#ifdef __cplusplus +extern "C" { +#endif + /* Be more verbose. Use only 'fprintf' and 'multiline_warning' but not 'error' or 'multiline_error' to emit verbosity messages, because 'error' and 'multiline_error' during PO file parsing cause the program to exit with EXIT_FAILURE. See function lex_end(). */ extern int verbose; +/* Data types for bulk operation mode. */ +typedef struct msgfmt_operand_ty msgfmt_operand_ty; +struct msgfmt_operand_ty +{ + char *language; + message_list_ty *mlp; +}; + +typedef struct msgfmt_operand_list_ty msgfmt_operand_list_ty; +struct msgfmt_operand_list_ty +{ + msgfmt_operand_ty *items; + size_t nitems; + size_t nitems_max; +}; + +#ifdef __cplusplus +} +#endif + #endif /* _MSGFMT_H */ diff --git a/gettext-tools/src/write-desktop.c b/gettext-tools/src/write-desktop.c index b1de2fd..cb45f8a 100644 --- a/gettext-tools/src/write-desktop.c +++ b/gettext-tools/src/write-desktop.c @@ -43,8 +43,7 @@ typedef struct msgfmt_desktop_reader_ty msgfmt_desktop_reader_ty; struct msgfmt_desktop_reader_ty { DESKTOP_READER_TY - string_list_ty *languages; - message_list_ty **messages; + msgfmt_operand_list_ty *operands; hash_table *keywords; FILE *output_file; }; @@ -78,13 +77,12 @@ msgfmt_desktop_handle_pair (desktop_reader_ty *reader, char *unescaped = desktop_unescape_string (value, is_list); size_t i; - for (i = 0; i < msgfmt_reader->languages->nitems; i++) + for (i = 0; i < msgfmt_reader->operands->nitems; i++) { - const char *language = msgfmt_reader->languages->item[i]; - message_list_ty *mlp = msgfmt_reader->messages[i]; + msgfmt_operand_ty *operand = &msgfmt_reader->operands->items[i]; message_ty *mp; - mp = message_list_search (mlp, NULL, unescaped); + mp = message_list_search (operand->mlp, NULL, unescaped); if (mp && *mp->msgstr != '\0') { char *escaped; @@ -92,7 +90,7 @@ msgfmt_desktop_handle_pair (desktop_reader_ty *reader, escaped = desktop_escape_string (mp->msgstr, is_list); fprintf (msgfmt_reader->output_file, "%s[%s]=%s\n", - key, language, escaped); + key, operand->language, escaped); free (escaped); } } @@ -138,8 +136,7 @@ desktop_reader_class_ty msgfmt_methods = }; int -msgdomain_write_desktop_bulk (string_list_ty *languages, - message_list_ty **messages, +msgdomain_write_desktop_bulk (msgfmt_operand_list_ty *operands, const char *template_file_name, hash_table *keywords, const char *file_name) @@ -151,8 +148,7 @@ msgdomain_write_desktop_bulk (string_list_ty *languages, reader = desktop_reader_alloc (&msgfmt_methods); msgfmt_reader = (msgfmt_desktop_reader_ty *) reader; - msgfmt_reader->languages = languages; - msgfmt_reader->messages = messages; + msgfmt_reader->operands = operands; msgfmt_reader->keywords = keywords; if (strcmp (file_name, "-") == 0) @@ -200,27 +196,20 @@ msgdomain_write_desktop (message_list_ty *mlp, hash_table *keywords, const char *file_name) { - string_list_ty *languages; - message_list_ty **messages; - int retval; + msgfmt_operand_ty operand; + msgfmt_operand_list_ty operands; /* Convert the messages to Unicode. */ iconv_message_list (mlp, canon_encoding, po_charset_utf8, NULL); - languages = string_list_alloc (); - string_list_append (languages, locale_name); + /* Create a single-element operands and run the bulk operation on it. */ + operand.language = (char *) locale_name; + operand.mlp = mlp; + operands.nitems = 1; + operands.items = &operand; - messages = XNMALLOC (1, message_list_ty *); - messages[0] = mlp; - - retval = msgdomain_write_desktop_bulk (languages, - messages, - template_file_name, - keywords, - file_name); - - string_list_free (languages); - free (messages); - - return retval; + return msgdomain_write_desktop_bulk (&operands, + template_file_name, + keywords, + file_name); } diff --git a/gettext-tools/src/write-desktop.h b/gettext-tools/src/write-desktop.h index 43cb54c..d6408e2 100644 --- a/gettext-tools/src/write-desktop.h +++ b/gettext-tools/src/write-desktop.h @@ -19,7 +19,7 @@ #ifndef _WRITE_DESKTOP_H #define _WRITE_DESKTOP_H -#include "message.h" +#include "msgfmt.h" #ifdef __cplusplus extern "C" { @@ -38,8 +38,7 @@ extern int const char *file_name); extern int - msgdomain_write_desktop_bulk (string_list_ty *languages, - message_list_ty **messages, + msgdomain_write_desktop_bulk (msgfmt_operand_list_ty *operands, const char *template_file_name, hash_table *keywords, const char *file_name); |