Back to Evolution Project page
00001 /* Compatibility code for gettext-using-catgets interface. 00002 Copyright (C) 1995, 1997 Free Software Foundation, Inc. 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU General Public License as published by 00006 the Free Software Foundation; either version 2, or (at your option) 00007 any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU General Public License for more details. 00013 00014 You should have received a copy of the GNU General Public License 00015 along with this program; if not, write to the Free Software Foundation, 00016 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 00017 00018 #ifdef HAVE_CONFIG_H 00019 # include <config.h> 00020 #endif 00021 00022 #include <stdio.h> 00023 00024 #ifdef STDC_HEADERS 00025 # include <stdlib.h> 00026 # include <string.h> 00027 #else 00028 char *getenv (); 00029 # ifdef HAVE_MALLOC_H 00030 # include <malloc.h> 00031 # endif 00032 #endif 00033 00034 #ifdef HAVE_NL_TYPES_H 00035 # include <nl_types.h> 00036 #endif 00037 00038 #include "libgettext.h" 00039 00040 /* @@ end of prolog @@ */ 00041 00042 /* XPG3 defines the result of `setlocale (category, NULL)' as: 00043 ``Directs `setlocale()' to query `category' and return the current 00044 setting of `local'.'' 00045 However it does not specify the exact format. And even worse: POSIX 00046 defines this not at all. So we can use this feature only on selected 00047 system (e.g. those using GNU C Library). */ 00048 #ifdef _LIBC 00049 # define HAVE_LOCALE_NULL 00050 #endif 00051 00052 /* The catalog descriptor. */ 00053 static nl_catd catalog = (nl_catd) -1; 00054 00055 /* Name of the default catalog. */ 00056 static const char default_catalog_name[] = "messages"; 00057 00058 /* Name of currently used catalog. */ 00059 static const char *catalog_name = default_catalog_name; 00060 00061 /* Get ID for given string. If not found return -1. */ 00062 static int msg_to_cat_id PARAMS ((const char *msg)); 00063 00064 /* Substitution for systems lacking this function in their C library. */ 00065 #if !_LIBC && !HAVE_STPCPY 00066 static char *stpcpy PARAMS ((char *dest, const char *src)); 00067 #endif 00068 00069 00070 /* Set currently used domain/catalog. */ 00071 char * 00072 textdomain (domainname) 00073 const char *domainname; 00074 { 00075 nl_catd new_catalog; 00076 char *new_name; 00077 size_t new_name_len; 00078 char *lang; 00079 00080 #if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES \ 00081 && defined HAVE_LOCALE_NULL 00082 lang = setlocale (LC_MESSAGES, NULL); 00083 #else 00084 lang = getenv ("LC_ALL"); 00085 if (lang == NULL || lang[0] == '\0') 00086 { 00087 lang = getenv ("LC_MESSAGES"); 00088 if (lang == NULL || lang[0] == '\0') 00089 lang = getenv ("LANG"); 00090 } 00091 #endif 00092 if (lang == NULL || lang[0] == '\0') 00093 lang = "C"; 00094 00095 /* See whether name of currently used domain is asked. */ 00096 if (domainname == NULL) 00097 return (char *) catalog_name; 00098 00099 if (domainname[0] == '\0') 00100 domainname = default_catalog_name; 00101 00102 /* Compute length of added path element. */ 00103 new_name_len = sizeof (LOCALEDIR) - 1 + 1 + strlen (lang) 00104 + sizeof ("/LC_MESSAGES/") - 1 + sizeof (PACKAGE) - 1 00105 + sizeof (".cat"); 00106 00107 new_name = (char *) malloc (new_name_len); 00108 if (new_name == NULL) 00109 return NULL; 00110 00111 strcpy (new_name, PACKAGE); 00112 new_catalog = catopen (new_name, 0); 00113 00114 if (new_catalog == (nl_catd) -1) 00115 { 00116 /* NLSPATH search didn't work, try absolute path */ 00117 sprintf (new_name, "%s/%s/LC_MESSAGES/%s.cat", LOCALEDIR, lang, 00118 PACKAGE); 00119 new_catalog = catopen (new_name, 0); 00120 00121 if (new_catalog == (nl_catd) -1) 00122 { 00123 free (new_name); 00124 return (char *) catalog_name; 00125 } 00126 } 00127 00128 /* Close old catalog. */ 00129 if (catalog != (nl_catd) -1) 00130 catclose (catalog); 00131 if (catalog_name != default_catalog_name) 00132 free ((char *) catalog_name); 00133 00134 catalog = new_catalog; 00135 catalog_name = new_name; 00136 00137 return (char *) catalog_name; 00138 } 00139 00140 char * 00141 bindtextdomain (domainname, dirname) 00142 const char *domainname; 00143 const char *dirname; 00144 { 00145 #if HAVE_SETENV || HAVE_PUTENV 00146 char *old_val, *new_val, *cp; 00147 size_t new_val_len; 00148 00149 /* This does not make much sense here but to be compatible do it. */ 00150 if (domainname == NULL) 00151 return NULL; 00152 00153 /* Compute length of added path element. If we use setenv we don't need 00154 the first byts for NLSPATH=, but why complicate the code for this 00155 peanuts. */ 00156 new_val_len = sizeof ("NLSPATH=") - 1 + strlen (dirname) 00157 + sizeof ("/%L/LC_MESSAGES/%N.cat"); 00158 00159 old_val = getenv ("NLSPATH"); 00160 if (old_val == NULL || old_val[0] == '\0') 00161 { 00162 old_val = NULL; 00163 new_val_len += 1 + sizeof (LOCALEDIR) - 1 00164 + sizeof ("/%L/LC_MESSAGES/%N.cat"); 00165 } 00166 else 00167 new_val_len += strlen (old_val); 00168 00169 new_val = (char *) malloc (new_val_len); 00170 if (new_val == NULL) 00171 return NULL; 00172 00173 # if HAVE_SETENV 00174 cp = new_val; 00175 # else 00176 cp = stpcpy (new_val, "NLSPATH="); 00177 # endif 00178 00179 cp = stpcpy (cp, dirname); 00180 cp = stpcpy (cp, "/%L/LC_MESSAGES/%N.cat:"); 00181 00182 if (old_val == NULL) 00183 { 00184 # if __STDC__ 00185 stpcpy (cp, LOCALEDIR "/%L/LC_MESSAGES/%N.cat"); 00186 # else 00187 00188 cp = stpcpy (cp, LOCALEDIR); 00189 stpcpy (cp, "/%L/LC_MESSAGES/%N.cat"); 00190 # endif 00191 } 00192 else 00193 stpcpy (cp, old_val); 00194 00195 # if HAVE_SETENV 00196 setenv ("NLSPATH", new_val, 1); 00197 free (new_val); 00198 # else 00199 putenv (new_val); 00200 /* Do *not* free the environment entry we just entered. It is used 00201 from now on. */ 00202 # endif 00203 00204 #endif 00205 00206 return (char *) domainname; 00207 } 00208 00209 #undef gettext 00210 char * 00211 gettext (msg) 00212 const char *msg; 00213 { 00214 int msgid; 00215 00216 if (msg == NULL || catalog == (nl_catd) -1) 00217 return (char *) msg; 00218 00219 /* Get the message from the catalog. We always use set number 1. 00220 The message ID is computed by the function `msg_to_cat_id' 00221 which works on the table generated by `po-to-tbl'. */ 00222 msgid = msg_to_cat_id (msg); 00223 if (msgid == -1) 00224 return (char *) msg; 00225 00226 return catgets (catalog, 1, msgid, (char *) msg); 00227 } 00228 00229 /* Look through the table `_msg_tbl' which has `_msg_tbl_length' entries 00230 for the one equal to msg. If it is found return the ID. In case when 00231 the string is not found return -1. */ 00232 static int 00233 msg_to_cat_id (msg) 00234 const char *msg; 00235 { 00236 int cnt; 00237 00238 for (cnt = 0; cnt < _msg_tbl_length; ++cnt) 00239 if (strcmp (msg, _msg_tbl[cnt]._msg) == 0) 00240 return _msg_tbl[cnt]._msg_number; 00241 00242 return -1; 00243 } 00244 00245 00246 /* @@ begin of epilog @@ */ 00247 00248 /* We don't want libintl.a to depend on any other library. So we 00249 avoid the non-standard function stpcpy. In GNU C Library this 00250 function is available, though. Also allow the symbol HAVE_STPCPY 00251 to be defined. */ 00252 #if !_LIBC && !HAVE_STPCPY 00253 static char * 00254 stpcpy (dest, src) 00255 char *dest; 00256 const char *src; 00257 { 00258 while ((*dest++ = *src++) != '\0') 00259 /* Do nothing. */ ; 00260 return dest - 1; 00261 } 00262 #endif