Back to Evolution Project page
00001 /* Implementation of the bindtextdomain(3) function 00002 Copyright (C) 1995, 1996, 1997, 1998 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 #if defined STDC_HEADERS || defined _LIBC 00023 # include <stdlib.h> 00024 #else 00025 # ifdef HAVE_MALLOC_H 00026 # include <malloc.h> 00027 # else 00028 void free (); 00029 # endif 00030 #endif 00031 00032 #if defined HAVE_STRING_H || defined _LIBC 00033 # include <string.h> 00034 #else 00035 # include <strings.h> 00036 # ifndef memcpy 00037 # define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) 00038 # endif 00039 #endif 00040 00041 #ifdef _LIBC 00042 # include <libintl.h> 00043 #else 00044 # include "libgettext.h" 00045 #endif 00046 #include "gettext.h" 00047 #include "gettextP.h" 00048 00049 /* @@ end of prolog @@ */ 00050 00051 /* Contains the default location of the message catalogs. */ 00052 extern const char _nl_default_dirname[]; 00053 00054 /* List with bindings of specific domains. */ 00055 extern struct binding *_nl_domain_bindings; 00056 00057 00058 /* Names for the libintl functions are a problem. They must not clash 00059 with existing names and they should follow ANSI C. But this source 00060 code is also used in GNU C Library where the names have a __ 00061 prefix. So we have to make a difference here. */ 00062 #ifdef _LIBC 00063 # define BINDTEXTDOMAIN __bindtextdomain 00064 # ifndef strdup 00065 # define strdup(str) __strdup (str) 00066 # endif 00067 #else 00068 # define BINDTEXTDOMAIN bindtextdomain__ 00069 #endif 00070 00071 /* Specify that the DOMAINNAME message catalog will be found 00072 in DIRNAME rather than in the system locale data base. */ 00073 char * 00074 BINDTEXTDOMAIN (domainname, dirname) 00075 const char *domainname; 00076 const char *dirname; 00077 { 00078 struct binding *binding; 00079 00080 /* Some sanity checks. */ 00081 if (domainname == NULL || domainname[0] == '\0') 00082 return NULL; 00083 00084 for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) 00085 { 00086 int compare = strcmp (domainname, binding->domainname); 00087 if (compare == 0) 00088 /* We found it! */ 00089 break; 00090 if (compare < 0) 00091 { 00092 /* It is not in the list. */ 00093 binding = NULL; 00094 break; 00095 } 00096 } 00097 00098 if (dirname == NULL) 00099 /* The current binding has be to returned. */ 00100 return binding == NULL ? (char *) _nl_default_dirname : binding->dirname; 00101 00102 if (binding != NULL) 00103 { 00104 /* The domain is already bound. If the new value and the old 00105 one are equal we simply do nothing. Otherwise replace the 00106 old binding. */ 00107 if (strcmp (dirname, binding->dirname) != 0) 00108 { 00109 char *new_dirname; 00110 00111 if (strcmp (dirname, _nl_default_dirname) == 0) 00112 new_dirname = (char *) _nl_default_dirname; 00113 else 00114 { 00115 #if defined _LIBC || defined HAVE_STRDUP 00116 new_dirname = strdup (dirname); 00117 if (new_dirname == NULL) 00118 return NULL; 00119 #else 00120 size_t len = strlen (dirname) + 1; 00121 new_dirname = (char *) malloc (len); 00122 if (new_dirname == NULL) 00123 return NULL; 00124 00125 memcpy (new_dirname, dirname, len); 00126 #endif 00127 } 00128 00129 if (binding->dirname != _nl_default_dirname) 00130 free (binding->dirname); 00131 00132 binding->dirname = new_dirname; 00133 } 00134 } 00135 else 00136 { 00137 /* We have to create a new binding. */ 00138 #if !defined _LIBC && !defined HAVE_STRDUP 00139 size_t len; 00140 #endif 00141 struct binding *new_binding = 00142 (struct binding *) malloc (sizeof (*new_binding)); 00143 00144 if (new_binding == NULL) 00145 return NULL; 00146 00147 #if defined _LIBC || defined HAVE_STRDUP 00148 new_binding->domainname = strdup (domainname); 00149 if (new_binding->domainname == NULL) 00150 return NULL; 00151 #else 00152 len = strlen (domainname) + 1; 00153 new_binding->domainname = (char *) malloc (len); 00154 if (new_binding->domainname == NULL) 00155 return NULL; 00156 memcpy (new_binding->domainname, domainname, len); 00157 #endif 00158 00159 if (strcmp (dirname, _nl_default_dirname) == 0) 00160 new_binding->dirname = (char *) _nl_default_dirname; 00161 else 00162 { 00163 #if defined _LIBC || defined HAVE_STRDUP 00164 new_binding->dirname = strdup (dirname); 00165 if (new_binding->dirname == NULL) 00166 return NULL; 00167 #else 00168 len = strlen (dirname) + 1; 00169 new_binding->dirname = (char *) malloc (len); 00170 if (new_binding->dirname == NULL) 00171 return NULL; 00172 memcpy (new_binding->dirname, dirname, len); 00173 #endif 00174 } 00175 00176 /* Now enqueue it. */ 00177 if (_nl_domain_bindings == NULL 00178 || strcmp (domainname, _nl_domain_bindings->domainname) < 0) 00179 { 00180 new_binding->next = _nl_domain_bindings; 00181 _nl_domain_bindings = new_binding; 00182 } 00183 else 00184 { 00185 binding = _nl_domain_bindings; 00186 while (binding->next != NULL 00187 && strcmp (domainname, binding->next->domainname) > 0) 00188 binding = binding->next; 00189 00190 new_binding->next = binding->next; 00191 binding->next = new_binding; 00192 } 00193 00194 binding = new_binding; 00195 } 00196 00197 return binding->dirname; 00198 } 00199 00200 #ifdef _LIBC 00201 /* Alias for function name in GNU C Library. */ 00202 weak_alias (__bindtextdomain, bindtextdomain); 00203 #endif