summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2015-10-05 16:33:31 +0900
committerDaiki Ueno <ueno@gnu.org>2015-10-06 10:03:34 +0900
commitd5a1f03517517ac2474ee50ea0b4f5d270457478 (patch)
tree635dcef4e3e78bc6c40cc59741de64e59ba5b21b
parent423d5cca70c2640eaf45dabdc36ed755701043a8 (diff)
downloadexternal_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/ChangeLog17
-rw-r--r--gettext-tools/src/msgfmt.c167
-rw-r--r--gettext-tools/src/msgfmt.h26
-rw-r--r--gettext-tools/src/write-desktop.c47
-rw-r--r--gettext-tools/src/write-desktop.h5
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);