bug-gettext
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]