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