Add -lm dependency for gettextlib to fix LTO build
[platform/upstream/gettext.git] / gettext-tools / src / msgl-charset.c
1 /* Message list charset and locale charset handling.
2    Copyright (C) 2001-2003, 2005-2007, 2009, 2015 Free Software
3    Foundation, Inc.
4    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
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
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
23 #include <alloca.h>
24
25 /* Specification.  */
26 #include "msgl-charset.h"
27
28 #include <stddef.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "po-charset.h"
33 #include "localcharset.h"
34 #include "error.h"
35 #include "progname.h"
36 #include "basename.h"
37 #include "xmalloca.h"
38 #include "xerror.h"
39 #include "xvasprintf.h"
40 #include "message.h"
41 #include "c-strstr.h"
42 #include "gettext.h"
43
44 #define _(str) gettext (str)
45
46 void
47 compare_po_locale_charsets (const msgdomain_list_ty *mdlp)
48 {
49   const char *locale_code;
50   const char *canon_locale_code;
51   bool warned;
52   size_t j, k;
53
54   /* Check whether the locale encoding and the PO file's encoding are the
55      same.  Otherwise emit a warning.  */
56   locale_code = locale_charset ();
57   canon_locale_code = po_charset_canonicalize (locale_code);
58   warned = false;
59   for (k = 0; k < mdlp->nitems; k++)
60     {
61       const message_list_ty *mlp = mdlp->item[k]->messages;
62
63       for (j = 0; j < mlp->nitems; j++)
64         if (is_header (mlp->item[j]) && !mlp->item[j]->obsolete)
65           {
66             const char *header = mlp->item[j]->msgstr;
67
68             if (header != NULL)
69               {
70                 const char *charsetstr = c_strstr (header, "charset=");
71
72                 if (charsetstr != NULL)
73                   {
74                     size_t len;
75                     char *charset;
76                     const char *canon_charset;
77
78                     charsetstr += strlen ("charset=");
79                     len = strcspn (charsetstr, " \t\n");
80                     charset = (char *) xmalloca (len + 1);
81                     memcpy (charset, charsetstr, len);
82                     charset[len] = '\0';
83
84                     canon_charset = po_charset_canonicalize (charset);
85                     if (canon_charset == NULL)
86                       error (EXIT_FAILURE, 0,
87                              _("\
88 present charset \"%s\" is not a portable encoding name"),
89                              charset);
90                     freea (charset);
91                     if (canon_locale_code != canon_charset)
92                       {
93                         multiline_warning (xasprintf (_("warning: ")),
94                                            xasprintf (_("\
95 Locale charset \"%s\" is different from\n\
96 input file charset \"%s\".\n\
97 Output of '%s' might be incorrect.\n\
98 Possible workarounds are:\n\
99 "), locale_code, canon_charset, basename (program_name)));
100                         multiline_warning (NULL,
101                                            xasprintf (_("\
102 - Set LC_ALL to a locale with encoding %s.\n\
103 "), canon_charset));
104                         if (canon_locale_code != NULL)
105                           multiline_warning (NULL,
106                                              xasprintf (_("\
107 - Convert the translation catalog to %s using 'msgconv',\n\
108   then apply '%s',\n\
109   then convert back to %s using 'msgconv'.\n\
110 "), canon_locale_code, basename (program_name), canon_charset));
111                         if (strcmp (canon_charset, "UTF-8") != 0
112                             && (canon_locale_code == NULL
113                                 || strcmp (canon_locale_code, "UTF-8") != 0))
114                           multiline_warning (NULL,
115                                              xasprintf (_("\
116 - Set LC_ALL to a locale with encoding %s,\n\
117   convert the translation catalog to %s using 'msgconv',\n\
118   then apply '%s',\n\
119   then convert back to %s using 'msgconv'.\n\
120 "), "UTF-8", "UTF-8", basename (program_name), canon_charset));
121                         warned = true;
122                       }
123                   }
124               }
125           }
126       }
127   if (canon_locale_code == NULL && !warned)
128     multiline_warning (xasprintf (_("warning: ")),
129                        xasprintf (_("\
130 Locale charset \"%s\" is not a portable encoding name.\n\
131 Output of '%s' might be incorrect.\n\
132 A possible workaround is to set LC_ALL=C.\n\
133 "), locale_code, basename (program_name)));
134 }