Imported Upstream version 0.19.7
[platform/upstream/gettext.git] / gettext-tools / src / write-desktop.c
1 /* Writing Desktop Entry files.
2    Copyright (C) 1995-1998, 2000-2003, 2005-2006, 2008-2009, 2014-2015
3    Free Software Foundation, Inc.
4    This file was written by Daiki Ueno <ueno@gnu.org>.
5
6    This program is free software: you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 /* Specification.  */
24 #include "write-desktop.h"
25
26 #include <assert.h>
27 #include <errno.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include "error.h"
31 #include "msgl-iconv.h"
32 #include "po-charset.h"
33 #include "read-catalog.h"
34 #include "read-po.h"
35 #include "read-desktop.h"
36 #include "fwriteerror.h"
37 #include "xalloc.h"
38 #include "gettext.h"
39
40 #define _(str) gettext (str)
41
42 typedef struct msgfmt_desktop_reader_ty msgfmt_desktop_reader_ty;
43 struct msgfmt_desktop_reader_ty
44 {
45   DESKTOP_READER_TY
46   msgfmt_operand_list_ty *operands;
47   hash_table *keywords;
48   FILE *output_file;
49 };
50
51 static void
52 msgfmt_desktop_handle_group (struct desktop_reader_ty *reader,
53                              const char *group)
54 {
55   msgfmt_desktop_reader_ty *msgfmt_reader = (msgfmt_desktop_reader_ty *) reader;
56
57   fprintf (msgfmt_reader->output_file, "[%s]\n", group);
58 }
59
60 static void
61 msgfmt_desktop_handle_pair (desktop_reader_ty *reader,
62                             lex_pos_ty *key_pos,
63                             const char *key,
64                             const char *locale,
65                             const char *value)
66 {
67   msgfmt_desktop_reader_ty *msgfmt_reader = (msgfmt_desktop_reader_ty *) reader;
68   void *keyword_value;
69
70   if (!locale)
71     {
72       /* Write translated pair, if any.  */
73       if (hash_find_entry (msgfmt_reader->keywords, key, strlen (key),
74                            &keyword_value) == 0)
75         {
76           bool is_list = (bool) keyword_value;
77           char *unescaped = desktop_unescape_string (value, is_list);
78           size_t i;
79
80           for (i = 0; i < msgfmt_reader->operands->nitems; i++)
81             {
82               msgfmt_operand_ty *operand = &msgfmt_reader->operands->items[i];
83               message_ty *mp;
84
85               mp = message_list_search (operand->mlp, NULL, unescaped);
86               if (mp && *mp->msgstr != '\0')
87                 {
88                   char *escaped;
89
90                   escaped = desktop_escape_string (mp->msgstr, is_list);
91                   fprintf (msgfmt_reader->output_file,
92                            "%s[%s]=%s\n",
93                            key, operand->language, escaped);
94                   free (escaped);
95                 }
96             }
97           free (unescaped);
98         }
99
100       /* Write untranslated pair.  */
101       fprintf (msgfmt_reader->output_file, "%s=%s\n", key, value);
102     }
103   else
104     /* Preserve already translated pair.  */
105     fprintf (msgfmt_reader->output_file, "%s[%s]=%s\n", key, locale, value);
106 }
107
108 static void
109 msgfmt_desktop_handle_comment (struct desktop_reader_ty *reader, const char *s)
110 {
111   msgfmt_desktop_reader_ty *msgfmt_reader = (msgfmt_desktop_reader_ty *) reader;
112
113   fputc ('#', msgfmt_reader->output_file);
114   fputs (s, msgfmt_reader->output_file);
115   fputc ('\n', msgfmt_reader->output_file);
116 }
117
118 static void
119 msgfmt_desktop_handle_blank (struct desktop_reader_ty *reader, const char *s)
120 {
121   msgfmt_desktop_reader_ty *msgfmt_reader = (msgfmt_desktop_reader_ty *) reader;
122
123   fputs (s, msgfmt_reader->output_file);
124   fputc ('\n', msgfmt_reader->output_file);
125 }
126
127 desktop_reader_class_ty msgfmt_methods =
128   {
129     sizeof (msgfmt_desktop_reader_ty),
130     NULL,
131     NULL,
132     msgfmt_desktop_handle_group,
133     msgfmt_desktop_handle_pair,
134     msgfmt_desktop_handle_comment,
135     msgfmt_desktop_handle_blank
136   };
137
138 int
139 msgdomain_write_desktop_bulk (msgfmt_operand_list_ty *operands,
140                               const char *template_file_name,
141                               hash_table *keywords,
142                               const char *file_name)
143 {
144   desktop_reader_ty *reader;
145   msgfmt_desktop_reader_ty *msgfmt_reader;
146   FILE *template_file;
147
148   reader = desktop_reader_alloc (&msgfmt_methods);
149   msgfmt_reader = (msgfmt_desktop_reader_ty *) reader;
150
151   msgfmt_reader->operands = operands;
152   msgfmt_reader->keywords = keywords;
153
154   if (strcmp (file_name, "-") == 0)
155     msgfmt_reader->output_file = stdout;
156   else
157     {
158       msgfmt_reader->output_file = fopen (file_name, "w");
159       if (msgfmt_reader->output_file == NULL)
160         {
161           desktop_reader_free (reader);
162           error (0, errno, _("error while opening \"%s\" for writing"),
163                  file_name);
164           return 1;
165         }
166     }
167
168   template_file = fopen (template_file_name, "r");
169   if (template_file == NULL)
170     {
171       desktop_reader_free (reader);
172       error (0, errno, _("error while opening \"%s\" for reading"),
173              template_file_name);
174       return 1;
175     }
176
177   desktop_parse (reader, template_file, template_file_name, template_file_name);
178
179   /* Make sure nothing went wrong.  */
180   if (fwriteerror (msgfmt_reader->output_file))
181     {
182       error (0, errno, _("error while writing \"%s\" file"),
183              file_name);
184       return 1;
185     }
186
187   desktop_reader_free (reader);
188
189   return 0;
190 }
191
192 int
193 msgdomain_write_desktop (message_list_ty *mlp,
194                          const char *canon_encoding,
195                          const char *locale_name,
196                          const char *template_file_name,
197                          hash_table *keywords,
198                          const char *file_name)
199 {
200   msgfmt_operand_ty operand;
201   msgfmt_operand_list_ty operands;
202
203   /* Convert the messages to Unicode.  */
204   iconv_message_list (mlp, canon_encoding, po_charset_utf8, NULL);
205
206   /* Create a single-element operands and run the bulk operation on it.  */
207   operand.language = (char *) locale_name;
208   operand.mlp = mlp;
209   operands.nitems = 1;
210   operands.items = &operand;
211
212   return msgdomain_write_desktop_bulk (&operands,
213                                        template_file_name,
214                                        keywords,
215                                        file_name);
216 }