11debfc3dSmrg /* Message translation utilities.
2*8feb0f0bSmrg Copyright (C) 2001-2020 Free Software Foundation, Inc.
31debfc3dSmrg
41debfc3dSmrg This file is part of GCC.
51debfc3dSmrg
61debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
71debfc3dSmrg the terms of the GNU General Public License as published by the Free
81debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
91debfc3dSmrg version.
101debfc3dSmrg
111debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
121debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
131debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
141debfc3dSmrg for more details.
151debfc3dSmrg
161debfc3dSmrg You should have received a copy of the GNU General Public License
171debfc3dSmrg along with GCC; see the file COPYING3. If not see
181debfc3dSmrg <http://www.gnu.org/licenses/>. */
191debfc3dSmrg
201debfc3dSmrg #include "config.h"
211debfc3dSmrg #include "system.h"
221debfc3dSmrg #include "coretypes.h"
231debfc3dSmrg #include "intl.h"
241debfc3dSmrg
251debfc3dSmrg #ifdef HAVE_LANGINFO_CODESET
261debfc3dSmrg #include <langinfo.h>
271debfc3dSmrg #endif
281debfc3dSmrg
291debfc3dSmrg /* Opening quotation mark for diagnostics. */
301debfc3dSmrg const char *open_quote = "'";
311debfc3dSmrg
321debfc3dSmrg /* Closing quotation mark for diagnostics. */
331debfc3dSmrg const char *close_quote = "'";
341debfc3dSmrg
351debfc3dSmrg /* The name of the locale encoding. */
361debfc3dSmrg const char *locale_encoding = NULL;
371debfc3dSmrg
381debfc3dSmrg /* Whether the locale is using UTF-8. */
391debfc3dSmrg bool locale_utf8 = false;
401debfc3dSmrg
411debfc3dSmrg #ifdef ENABLE_NLS
421debfc3dSmrg
431debfc3dSmrg /* Initialize the translation library for GCC. This performs the
441debfc3dSmrg appropriate sequence of calls - setlocale, bindtextdomain,
451debfc3dSmrg textdomain. LC_CTYPE determines the character set used by the
461debfc3dSmrg terminal, so it has be set to output messages correctly. */
471debfc3dSmrg
481debfc3dSmrg void
gcc_init_libintl(void)491debfc3dSmrg gcc_init_libintl (void)
501debfc3dSmrg {
511debfc3dSmrg #ifdef HAVE_LC_MESSAGES
521debfc3dSmrg setlocale (LC_CTYPE, "");
531debfc3dSmrg setlocale (LC_MESSAGES, "");
541debfc3dSmrg #else
551debfc3dSmrg setlocale (LC_ALL, "");
561debfc3dSmrg #endif
571debfc3dSmrg
581debfc3dSmrg (void) bindtextdomain ("gcc", LOCALEDIR);
591debfc3dSmrg (void) textdomain ("gcc");
601debfc3dSmrg
611debfc3dSmrg /* Opening quotation mark. */
621debfc3dSmrg open_quote = _("`");
631debfc3dSmrg
641debfc3dSmrg /* Closing quotation mark. */
651debfc3dSmrg close_quote = _("'");
661debfc3dSmrg
671debfc3dSmrg #if defined HAVE_LANGINFO_CODESET
681debfc3dSmrg locale_encoding = nl_langinfo (CODESET);
691debfc3dSmrg if (locale_encoding != NULL
701debfc3dSmrg && (!strcasecmp (locale_encoding, "utf-8")
711debfc3dSmrg || !strcasecmp (locale_encoding, "utf8")))
721debfc3dSmrg locale_utf8 = true;
731debfc3dSmrg #endif
741debfc3dSmrg
751debfc3dSmrg if (!strcmp (open_quote, "`") && !strcmp (close_quote, "'"))
761debfc3dSmrg {
771debfc3dSmrg /* Untranslated quotes that it may be possible to replace with
781debfc3dSmrg U+2018 and U+2019; but otherwise use "'" instead of "`" as
791debfc3dSmrg opening quote. */
801debfc3dSmrg open_quote = "'";
811debfc3dSmrg #if defined HAVE_LANGINFO_CODESET
821debfc3dSmrg if (locale_utf8)
831debfc3dSmrg {
841debfc3dSmrg open_quote = "\xe2\x80\x98";
851debfc3dSmrg close_quote = "\xe2\x80\x99";
861debfc3dSmrg }
871debfc3dSmrg #endif
881debfc3dSmrg }
891debfc3dSmrg }
901debfc3dSmrg
911debfc3dSmrg #if defined HAVE_WCHAR_H && defined HAVE_WORKING_MBSTOWCS && defined HAVE_WCSWIDTH
921debfc3dSmrg #include <wchar.h>
931debfc3dSmrg
941debfc3dSmrg /* Returns the width in columns of MSGSTR, which came from gettext.
951debfc3dSmrg This is for indenting subsequent output. */
961debfc3dSmrg
971debfc3dSmrg size_t
gcc_gettext_width(const char * msgstr)981debfc3dSmrg gcc_gettext_width (const char *msgstr)
991debfc3dSmrg {
1001debfc3dSmrg size_t nwcs = mbstowcs (0, msgstr, 0);
1011debfc3dSmrg wchar_t *wmsgstr = XALLOCAVEC (wchar_t, nwcs + 1);
1021debfc3dSmrg
1031debfc3dSmrg mbstowcs (wmsgstr, msgstr, nwcs + 1);
1041debfc3dSmrg return wcswidth (wmsgstr, nwcs);
1051debfc3dSmrg }
1061debfc3dSmrg
1071debfc3dSmrg #else /* no wcswidth */
1081debfc3dSmrg
1091debfc3dSmrg /* We don't have any way of knowing how wide the string is. Guess
1101debfc3dSmrg the length of the string. */
1111debfc3dSmrg
1121debfc3dSmrg size_t
gcc_gettext_width(const char * msgstr)1131debfc3dSmrg gcc_gettext_width (const char *msgstr)
1141debfc3dSmrg {
1151debfc3dSmrg return strlen (msgstr);
1161debfc3dSmrg }
1171debfc3dSmrg
1181debfc3dSmrg #endif
1191debfc3dSmrg
1201debfc3dSmrg #endif /* ENABLE_NLS */
1211debfc3dSmrg
1221debfc3dSmrg #ifndef ENABLE_NLS
1231debfc3dSmrg
1241debfc3dSmrg const char *
fake_ngettext(const char * singular,const char * plural,unsigned long n)1251debfc3dSmrg fake_ngettext (const char *singular, const char *plural, unsigned long n)
1261debfc3dSmrg {
1271debfc3dSmrg if (n == 1UL)
1281debfc3dSmrg return singular;
1291debfc3dSmrg
1301debfc3dSmrg return plural;
1311debfc3dSmrg }
1321debfc3dSmrg
1331debfc3dSmrg #endif
1341debfc3dSmrg
1351debfc3dSmrg /* Return the indent for successive lines, using the width of
1361debfc3dSmrg the STR. STR must have been translated already. The string
1371debfc3dSmrg must be freed by the caller. */
1381debfc3dSmrg
1391debfc3dSmrg char *
get_spaces(const char * str)1401debfc3dSmrg get_spaces (const char *str)
1411debfc3dSmrg {
1421debfc3dSmrg size_t len = gcc_gettext_width (str);
1431debfc3dSmrg char *spaces = XNEWVEC (char, len + 1);
1441debfc3dSmrg memset (spaces, ' ', len);
1451debfc3dSmrg spaces[len] = '\0';
1461debfc3dSmrg return spaces;
1471debfc3dSmrg }
1481debfc3dSmrg
1491debfc3dSmrg
1501debfc3dSmrg
151