1*946379e7Schristos /* Message list charset and locale charset handling.
2*946379e7Schristos Copyright (C) 2001-2003, 2005-2006 Free Software Foundation, Inc.
3*946379e7Schristos Written by Bruno Haible <haible@clisp.cons.org>, 2001.
4*946379e7Schristos
5*946379e7Schristos This program is free software; you can redistribute it and/or modify
6*946379e7Schristos it under the terms of the GNU General Public License as published by
7*946379e7Schristos the Free Software Foundation; either version 2, or (at your option)
8*946379e7Schristos any later version.
9*946379e7Schristos
10*946379e7Schristos This program is distributed in the hope that it will be useful,
11*946379e7Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
12*946379e7Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13*946379e7Schristos GNU General Public License for more details.
14*946379e7Schristos
15*946379e7Schristos You should have received a copy of the GNU General Public License
16*946379e7Schristos along with this program; if not, write to the Free Software Foundation,
17*946379e7Schristos Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18*946379e7Schristos
19*946379e7Schristos
20*946379e7Schristos #ifdef HAVE_CONFIG_H
21*946379e7Schristos # include "config.h"
22*946379e7Schristos #endif
23*946379e7Schristos #include <alloca.h>
24*946379e7Schristos
25*946379e7Schristos /* Specification. */
26*946379e7Schristos #include "msgl-charset.h"
27*946379e7Schristos
28*946379e7Schristos #include <stddef.h>
29*946379e7Schristos #include <string.h>
30*946379e7Schristos
31*946379e7Schristos #include "po-charset.h"
32*946379e7Schristos #include "localcharset.h"
33*946379e7Schristos #include "error.h"
34*946379e7Schristos #include "progname.h"
35*946379e7Schristos #include "basename.h"
36*946379e7Schristos #include "xallocsa.h"
37*946379e7Schristos #include "xerror.h"
38*946379e7Schristos #include "xvasprintf.h"
39*946379e7Schristos #include "message.h"
40*946379e7Schristos #include "c-strstr.h"
41*946379e7Schristos #include "exit.h"
42*946379e7Schristos #include "gettext.h"
43*946379e7Schristos
44*946379e7Schristos #define _(str) gettext (str)
45*946379e7Schristos
46*946379e7Schristos void
compare_po_locale_charsets(const msgdomain_list_ty * mdlp)47*946379e7Schristos compare_po_locale_charsets (const msgdomain_list_ty *mdlp)
48*946379e7Schristos {
49*946379e7Schristos const char *locale_code;
50*946379e7Schristos const char *canon_locale_code;
51*946379e7Schristos bool warned;
52*946379e7Schristos size_t j, k;
53*946379e7Schristos
54*946379e7Schristos /* Check whether the locale encoding and the PO file's encoding are the
55*946379e7Schristos same. Otherwise emit a warning. */
56*946379e7Schristos locale_code = locale_charset ();
57*946379e7Schristos canon_locale_code = po_charset_canonicalize (locale_code);
58*946379e7Schristos warned = false;
59*946379e7Schristos for (k = 0; k < mdlp->nitems; k++)
60*946379e7Schristos {
61*946379e7Schristos const message_list_ty *mlp = mdlp->item[k]->messages;
62*946379e7Schristos
63*946379e7Schristos for (j = 0; j < mlp->nitems; j++)
64*946379e7Schristos if (mlp->item[j]->msgstr == NULL
65*946379e7Schristos && mlp->item[j]->msgid[0] == '\0' && !mlp->item[j]->obsolete)
66*946379e7Schristos {
67*946379e7Schristos const char *header = mlp->item[j]->msgstr;
68*946379e7Schristos
69*946379e7Schristos if (header != NULL)
70*946379e7Schristos {
71*946379e7Schristos const char *charsetstr = c_strstr (header, "charset=");
72*946379e7Schristos
73*946379e7Schristos if (charsetstr != NULL)
74*946379e7Schristos {
75*946379e7Schristos size_t len;
76*946379e7Schristos char *charset;
77*946379e7Schristos const char *canon_charset;
78*946379e7Schristos
79*946379e7Schristos charsetstr += strlen ("charset=");
80*946379e7Schristos len = strcspn (charsetstr, " \t\n");
81*946379e7Schristos charset = (char *) xallocsa (len + 1);
82*946379e7Schristos memcpy (charset, charsetstr, len);
83*946379e7Schristos charset[len] = '\0';
84*946379e7Schristos
85*946379e7Schristos canon_charset = po_charset_canonicalize (charset);
86*946379e7Schristos if (canon_charset == NULL)
87*946379e7Schristos error (EXIT_FAILURE, 0,
88*946379e7Schristos _("\
89*946379e7Schristos present charset \"%s\" is not a portable encoding name"),
90*946379e7Schristos charset);
91*946379e7Schristos freesa (charset);
92*946379e7Schristos if (canon_locale_code != canon_charset)
93*946379e7Schristos {
94*946379e7Schristos multiline_warning (xasprintf (_("warning: ")),
95*946379e7Schristos xasprintf (_("\
96*946379e7Schristos Locale charset \"%s\" is different from\n\
97*946379e7Schristos input file charset \"%s\".\n\
98*946379e7Schristos Output of '%s' might be incorrect.\n\
99*946379e7Schristos Possible workarounds are:\n\
100*946379e7Schristos "), locale_code, canon_charset, basename (program_name)));
101*946379e7Schristos multiline_warning (NULL,
102*946379e7Schristos xasprintf (_("\
103*946379e7Schristos - Set LC_ALL to a locale with encoding %s.\n\
104*946379e7Schristos "), canon_charset));
105*946379e7Schristos if (canon_locale_code != NULL)
106*946379e7Schristos multiline_warning (NULL,
107*946379e7Schristos xasprintf (_("\
108*946379e7Schristos - Convert the translation catalog to %s using 'msgconv',\n\
109*946379e7Schristos then apply '%s',\n\
110*946379e7Schristos then convert back to %s using 'msgconv'.\n\
111*946379e7Schristos "), canon_locale_code, basename (program_name), canon_charset));
112*946379e7Schristos if (strcmp (canon_charset, "UTF-8") != 0
113*946379e7Schristos && (canon_locale_code == NULL
114*946379e7Schristos || strcmp (canon_locale_code, "UTF-8") != 0))
115*946379e7Schristos multiline_warning (NULL,
116*946379e7Schristos xasprintf (_("\
117*946379e7Schristos - Set LC_ALL to a locale with encoding %s,\n\
118*946379e7Schristos convert the translation catalog to %s using 'msgconv',\n\
119*946379e7Schristos then apply '%s',\n\
120*946379e7Schristos then convert back to %s using 'msgconv'.\n\
121*946379e7Schristos "), "UTF-8", "UTF-8", basename (program_name), canon_charset));
122*946379e7Schristos warned = true;
123*946379e7Schristos }
124*946379e7Schristos }
125*946379e7Schristos }
126*946379e7Schristos }
127*946379e7Schristos }
128*946379e7Schristos if (canon_locale_code == NULL && !warned)
129*946379e7Schristos multiline_warning (xasprintf (_("warning: ")),
130*946379e7Schristos xasprintf (_("\
131*946379e7Schristos Locale charset \"%s\" is not a portable encoding name.\n\
132*946379e7Schristos Output of '%s' might be incorrect.\n\
133*946379e7Schristos A possible workaround is to set LC_ALL=C.\n\
134*946379e7Schristos "), locale_code, basename (program_name)));
135*946379e7Schristos }
136