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