1 /* Message translation utilities. 2 Copyright (C) 2001-2018 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free 8 Software Foundation; either version 3, or (at your option) any later 9 version. 10 11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GCC; see the file COPYING3. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20 #include "config.h" 21 #include "system.h" 22 #include "coretypes.h" 23 #include "intl.h" 24 25 #ifdef HAVE_LANGINFO_CODESET 26 #include <langinfo.h> 27 #endif 28 29 /* Opening quotation mark for diagnostics. */ 30 const char *open_quote = "'"; 31 32 /* Closing quotation mark for diagnostics. */ 33 const char *close_quote = "'"; 34 35 /* The name of the locale encoding. */ 36 const char *locale_encoding = NULL; 37 38 /* Whether the locale is using UTF-8. */ 39 bool locale_utf8 = false; 40 41 #ifdef ENABLE_NLS 42 43 /* Initialize the translation library for GCC. This performs the 44 appropriate sequence of calls - setlocale, bindtextdomain, 45 textdomain. LC_CTYPE determines the character set used by the 46 terminal, so it has be set to output messages correctly. */ 47 48 void 49 gcc_init_libintl (void) 50 { 51 #ifdef HAVE_LC_MESSAGES 52 setlocale (LC_CTYPE, ""); 53 setlocale (LC_MESSAGES, ""); 54 #else 55 setlocale (LC_ALL, ""); 56 #endif 57 58 (void) bindtextdomain ("gcc", LOCALEDIR); 59 (void) textdomain ("gcc"); 60 61 /* Opening quotation mark. */ 62 open_quote = _("`"); 63 64 /* Closing quotation mark. */ 65 close_quote = _("'"); 66 67 #if defined HAVE_LANGINFO_CODESET 68 locale_encoding = nl_langinfo (CODESET); 69 if (locale_encoding != NULL 70 && (!strcasecmp (locale_encoding, "utf-8") 71 || !strcasecmp (locale_encoding, "utf8"))) 72 locale_utf8 = true; 73 #endif 74 75 if (!strcmp (open_quote, "`") && !strcmp (close_quote, "'")) 76 { 77 /* Untranslated quotes that it may be possible to replace with 78 U+2018 and U+2019; but otherwise use "'" instead of "`" as 79 opening quote. */ 80 open_quote = "'"; 81 #if defined HAVE_LANGINFO_CODESET 82 if (locale_utf8) 83 { 84 open_quote = "\xe2\x80\x98"; 85 close_quote = "\xe2\x80\x99"; 86 } 87 #endif 88 } 89 } 90 91 #if defined HAVE_WCHAR_H && defined HAVE_WORKING_MBSTOWCS && defined HAVE_WCSWIDTH 92 #include <wchar.h> 93 94 /* Returns the width in columns of MSGSTR, which came from gettext. 95 This is for indenting subsequent output. */ 96 97 size_t 98 gcc_gettext_width (const char *msgstr) 99 { 100 size_t nwcs = mbstowcs (0, msgstr, 0); 101 wchar_t *wmsgstr = XALLOCAVEC (wchar_t, nwcs + 1); 102 103 mbstowcs (wmsgstr, msgstr, nwcs + 1); 104 return wcswidth (wmsgstr, nwcs); 105 } 106 107 #else /* no wcswidth */ 108 109 /* We don't have any way of knowing how wide the string is. Guess 110 the length of the string. */ 111 112 size_t 113 gcc_gettext_width (const char *msgstr) 114 { 115 return strlen (msgstr); 116 } 117 118 #endif 119 120 #endif /* ENABLE_NLS */ 121 122 #ifndef ENABLE_NLS 123 124 const char * 125 fake_ngettext (const char *singular, const char *plural, unsigned long n) 126 { 127 if (n == 1UL) 128 return singular; 129 130 return plural; 131 } 132 133 #endif 134 135 /* Return the indent for successive lines, using the width of 136 the STR. STR must have been translated already. The string 137 must be freed by the caller. */ 138 139 char * 140 get_spaces (const char *str) 141 { 142 size_t len = gcc_gettext_width (str); 143 char *spaces = XNEWVEC (char, len + 1); 144 memset (spaces, ' ', len); 145 spaces[len] = '\0'; 146 return spaces; 147 } 148 149 150 151