[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[bug-gettext] [PATCH 2/2] msgfmt: Add support for Desktop Entry files
From: |
Daiki Ueno |
Subject: |
[bug-gettext] [PATCH 2/2] msgfmt: Add support for Desktop Entry files |
Date: |
Fri, 14 Mar 2014 17:42:16 +0900 |
---
gettext-tools/src/Makefile.am | 3 +-
gettext-tools/src/msgfmt.c | 36 +++++++-
gettext-tools/src/write-desktop.c | 189 ++++++++++++++++++++++++++++++++++++++
gettext-tools/src/write-desktop.h | 36 ++++++++
4 files changed, 261 insertions(+), 3 deletions(-)
create mode 100644 gettext-tools/src/write-desktop.c
create mode 100644 gettext-tools/src/write-desktop.h
diff --git a/gettext-tools/src/Makefile.am b/gettext-tools/src/Makefile.am
index e69c00c..25947c3 100644
--- a/gettext-tools/src/Makefile.am
+++ b/gettext-tools/src/Makefile.am
@@ -48,6 +48,7 @@ read-csharp.h write-csharp.h \
read-resources.h write-resources.h \
read-tcl.h write-tcl.h \
write-qt.h \
+read-desktop.h write-desktop.h \
po-time.h plural-table.h lang-table.h format.h filters.h \
xgettext.h x-c.h x-po.h x-sh.h x-python.h x-lisp.h x-elisp.h x-librep.h \
x-scheme.h x-smalltalk.h x-java.h x-properties.h x-csharp.h x-awk.h x-ycp.h \
@@ -160,7 +161,7 @@ msgcmp_SOURCES += msgl-fsearch.c
msgfmt_SOURCES = msgfmt.c
msgfmt_SOURCES += \
write-mo.c write-java.c write-csharp.c write-resources.c write-tcl.c \
- write-qt.c ../../gettext-runtime/intl/hash-string.c
+ write-qt.c write-desktop.c ../../gettext-runtime/intl/hash-string.c
if !WOE32DLL
msgmerge_SOURCES = msgmerge.c
else
diff --git a/gettext-tools/src/msgfmt.c b/gettext-tools/src/msgfmt.c
index 4da999a..6db4703 100644
--- a/gettext-tools/src/msgfmt.c
+++ b/gettext-tools/src/msgfmt.c
@@ -45,6 +45,7 @@
#include "write-resources.h"
#include "write-tcl.h"
#include "write-qt.h"
+#include "write-desktop.h"
#include "propername.h"
#include "message.h"
#include "open-catalog.h"
@@ -94,6 +95,10 @@ static const char *tcl_base_directory;
/* Qt mode output file specification. */
static bool qt_mode;
+/* Desktop Entry mode output file specification. */
+static bool desktop_mode;
+static const char *desktop_template_name;
+
/* We may have more than one input file. Domains with same names in
different files have to merged. So we need a list of tables for
each output file. */
@@ -157,6 +162,7 @@ static const struct option long_options[] =
{ "check-header", no_argument, NULL, CHAR_MAX + 4 },
{ "csharp", no_argument, NULL, CHAR_MAX + 10 },
{ "csharp-resources", no_argument, NULL, CHAR_MAX + 11 },
+ { "desktop", required_argument, NULL, CHAR_MAX + 14 },
{ "directory", required_argument, NULL, 'D' },
{ "endianness", required_argument, NULL, CHAR_MAX + 13 },
{ "help", no_argument, NULL, 'h' },
@@ -353,6 +359,10 @@ main (int argc, char *argv[])
byteswap = endianness ^ ENDIANNESS;
}
break;
+ case CHAR_MAX + 14: /* --desktop=TEMPLATE */
+ desktop_mode = true;
+ desktop_template_name = optarg;
+ break;
default:
usage (EXIT_FAILURE);
break;
@@ -391,9 +401,11 @@ There is NO WARRANTY, to the extent permitted by law.\n\
| (csharp_mode ? 2 : 0)
| (csharp_resources_mode ? 4 : 0)
| (tcl_mode ? 8 : 0)
- | (qt_mode ? 16 : 0);
+ | (qt_mode ? 16 : 0)
+ | (desktop_mode ? 32 : 0);
static const char *mode_options[] =
- { "--java", "--csharp", "--csharp-resources", "--tcl", "--qt" };
+ { "--java", "--csharp", "--csharp-resources", "--tcl", "--qt",
+ "--desktop" };
/* More than one bit set? */
if (modes & (modes - 1))
{
@@ -471,6 +483,14 @@ There is NO WARRANTY, to the extent permitted by law.\n\
usage (EXIT_FAILURE);
}
}
+ else if (desktop_mode)
+ {
+ if (java_locale_name != NULL)
+ {
+ error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
+ "--desktop", "--locale");
+ }
+ }
else
{
if (java_resource_name != NULL)
@@ -493,6 +513,16 @@ There is NO WARRANTY, to the extent permitted by law.\n\
}
}
+ if (desktop_mode)
+ {
+ if (write_desktop (desktop_template_name,
+ output_file_name ? output_file_name : "-",
+ argc - optind, &argv[optind]))
+ exit_status = EXIT_FAILURE;
+
+ exit (exit_status);
+ }
+
/* The -o option determines the name of the domain and therefore
the output file. */
if (output_file_name != NULL)
@@ -688,6 +718,8 @@ Operation mode:\n"));
--tcl Tcl mode: generate a tcl/msgcat .msg file\n"));
printf (_("\
--qt Qt mode: generate a Qt .qm file\n"));
+ printf (_("\
+ --desktop=TEMPLATE Desktop Entry mode: generate a .desktop
file\n"));
printf ("\n");
printf (_("\
Output file location:\n"));
diff --git a/gettext-tools/src/write-desktop.c
b/gettext-tools/src/write-desktop.c
new file mode 100644
index 0000000..d0cd5d0
--- /dev/null
+++ b/gettext-tools/src/write-desktop.c
@@ -0,0 +1,189 @@
+/* Writing Desktop Entry files.
+ Copyright (C) 1995-1998, 2000-2003, 2005-2006, 2008-2009, 2014 Free
Software Foundation, Inc.
+ This file was written by Daiki Ueno <address@hidden>.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Specification. */
+#include "write-desktop.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "error.h"
+#include "message.h"
+#include "read-catalog.h"
+#include "read-po.h"
+#include "read-desktop.h"
+#include "gettext.h"
+
+#define _(str) gettext (str)
+
+typedef struct msgfmt_desktop_reader_ty msgfmt_desktop_reader_ty;
+struct msgfmt_desktop_reader_ty
+{
+ DESKTOP_READER_TY
+ hash_table messages;
+ FILE *output_file;
+};
+
+static void
+msgfmt_desktop_handle_localestring (desktop_reader_ty *reader,
+ lex_pos_ty *key_pos,
+ const char *key,
+ const char *locale,
+ const char *value)
+{
+ msgfmt_desktop_reader_ty *msgfmt_reader = (msgfmt_desktop_reader_ty *)
reader;
+ void *ptr, *valuep;
+ const void *keyp;
+ size_t keylen;
+ bool locale_found;
+
+ if (!locale)
+ fprintf (msgfmt_reader->output_file, "%s=%s\n", key, value);
+
+ locale_found = false;
+ ptr = NULL;
+ while (hash_iterate (&msgfmt_reader->messages, &ptr, &keyp, &keylen, &valuep)
+ == 0)
+ {
+ msgdomain_list_ty *mdlp = valuep;
+ size_t i;
+
+ for (i = 0; i < mdlp->nitems; i++)
+ {
+ msgdomain_ty *mdp = mdlp->item[i];
+ message_ty *mp;
+ size_t j;
+
+ mp = message_list_search (mdp->messages, NULL, value);
+ if (mp && *mp->msgstr != '\0')
+ {
+ fprintf (msgfmt_reader->output_file,
+ "%s[%s]=%s\n",
+ key, (const char *) keyp, mp->msgstr);
+
+ if (locale && strcmp (locale, (const char *) keyp) == 0)
+ locale_found = true;
+ }
+ }
+ }
+
+ if (locale && !locale_found)
+ fprintf (msgfmt_reader->output_file, "%s[%s]=%s\n", key, locale, value);
+}
+
+static void
+msgfmt_desktop_handle_comment (struct desktop_reader_ty *reader, const char *s)
+{
+ msgfmt_desktop_reader_ty *msgfmt_reader = (msgfmt_desktop_reader_ty *)
reader;
+
+ fputc ('#', msgfmt_reader->output_file);
+ fputs (s, msgfmt_reader->output_file);
+ fputc ('\n', msgfmt_reader->output_file);
+}
+
+static void
+msgfmt_desktop_handle_line (struct desktop_reader_ty *reader, const char *s)
+{
+ msgfmt_desktop_reader_ty *msgfmt_reader = (msgfmt_desktop_reader_ty *)
reader;
+
+ fputs (s, msgfmt_reader->output_file);
+ fputc ('\n', msgfmt_reader->output_file);
+}
+
+desktop_reader_class_ty msgfmt_methods =
+ {
+ sizeof (msgfmt_desktop_reader_ty),
+ NULL,
+ NULL,
+ msgfmt_desktop_handle_localestring,
+ msgfmt_desktop_handle_comment,
+ msgfmt_desktop_handle_line
+ };
+
+int
+write_desktop (const char *template_file_name,
+ const char *output_file_name,
+ int ncatalogs,
+ char **catalogs)
+{
+ desktop_reader_ty *reader;
+ msgfmt_desktop_reader_ty *msgfmt_reader;
+ FILE *template_file, *output_file;
+ int i;
+
+ reader = desktop_reader_alloc (&msgfmt_methods);
+ msgfmt_reader = (msgfmt_desktop_reader_ty *) reader;
+
+ hash_init (&msgfmt_reader->messages, 100);
+
+ if (strcmp (output_file_name, "-") == 0)
+ msgfmt_reader->output_file = stdout;
+ else
+ {
+ msgfmt_reader->output_file = fopen (output_file_name, "w");
+ if (msgfmt_reader->output_file == NULL)
+ {
+ desktop_reader_free (reader);
+ error (EXIT_SUCCESS,
+ errno, _("error while opening \"%s\" for writing"),
+ output_file_name);
+ return 1;
+ }
+ }
+
+ /* Process all given .po files. */
+ for (i = 0; i < ncatalogs; i++)
+ {
+ msgdomain_list_ty *mdlp;
+ char *po_file_base;
+ char *desktop_locale_name, *p;
+
+ po_file_base = basename (catalogs[i]);
+ p = strrchr (po_file_base, '.');
+ assert (p);
+
+ *p = '\0';
+ desktop_locale_name = po_file_base;
+
+ mdlp = read_catalog_file (catalogs[i], &input_format_po);
+
+ hash_insert_entry (&msgfmt_reader->messages,
+ desktop_locale_name, strlen (desktop_locale_name),
+ mdlp);
+ }
+
+ template_file = fopen (template_file_name, "r");
+ if (template_file == NULL)
+ {
+ desktop_reader_free (reader);
+ error (EXIT_SUCCESS,
+ errno, _("error while opening \"%s\" for reading"),
+ template_file_name);
+ return 1;
+ }
+
+ desktop_reader_add_default_keywords (reader);
+ desktop_parse (reader, template_file, template_file_name,
template_file_name);
+ desktop_reader_free (reader);
+
+ return 0;
+}
diff --git a/gettext-tools/src/write-desktop.h
b/gettext-tools/src/write-desktop.h
new file mode 100644
index 0000000..9b93a34
--- /dev/null
+++ b/gettext-tools/src/write-desktop.h
@@ -0,0 +1,36 @@
+/* Reading Desktop Entry files.
+ Copyright (C) 1995-1998, 2000-2003, 2005-2006, 2008-2009, 2014 Free
Software Foundation, Inc.
+ This file was written by Daiki Ueno <address@hidden>.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _WRITE_DESKTOP_H
+#define _WRITE_DESKTOP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int
+write_desktop (const char *template_file_name,
+ const char *output_file_name,
+ int ncatalogs,
+ char **catalogs);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _WRITE_DESKTOP_H */
--
1.8.4.2