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