source: trunk/third/librep/intl/cat-compat.c @ 15283

Revision 15283, 6.5 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15282, which included commits to RCS files with non-trunk default branches.
Line 
1/* Compatibility code for gettext-using-catgets interface.
2   Copyright (C) 1995, 1997 Free Software Foundation, Inc.
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2, or (at your option)
7   any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software Foundation,
16   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18#ifdef HAVE_CONFIG_H
19# include <config.h>
20#endif
21
22#include <stdio.h>
23
24#ifdef STDC_HEADERS
25# include <stdlib.h>
26# include <string.h>
27#else
28char *getenv ();
29# ifdef HAVE_MALLOC_H
30#  include <malloc.h>
31# endif
32#endif
33
34#ifdef HAVE_NL_TYPES_H
35# include <nl_types.h>
36#endif
37
38#include "libgettext.h"
39
40/* @@ end of prolog @@ */
41
42/* XPG3 defines the result of `setlocale (category, NULL)' as:
43   ``Directs `setlocale()' to query `category' and return the current
44     setting of `local'.''
45   However it does not specify the exact format.  And even worse: POSIX
46   defines this not at all.  So we can use this feature only on selected
47   system (e.g. those using GNU C Library).  */
48#ifdef _LIBC
49# define HAVE_LOCALE_NULL
50#endif
51
52/* The catalog descriptor.  */
53static nl_catd catalog = (nl_catd) -1;
54
55/* Name of the default catalog.  */
56static const char default_catalog_name[] = "messages";
57
58/* Name of currently used catalog.  */
59static const char *catalog_name = default_catalog_name;
60
61/* Get ID for given string.  If not found return -1.  */
62static int msg_to_cat_id PARAMS ((const char *msg));
63
64/* Substitution for systems lacking this function in their C library.  */
65#if !_LIBC && !HAVE_STPCPY
66static char *stpcpy PARAMS ((char *dest, const char *src));
67#endif
68
69
70/* Set currently used domain/catalog.  */
71char *
72textdomain (domainname)
73     const char *domainname;
74{
75  nl_catd new_catalog;
76  char *new_name;
77  size_t new_name_len;
78  char *lang;
79
80#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES \
81    && defined HAVE_LOCALE_NULL
82  lang = setlocale (LC_MESSAGES, NULL);
83#else
84  lang = getenv ("LC_ALL");
85  if (lang == NULL || lang[0] == '\0')
86    {
87      lang = getenv ("LC_MESSAGES");
88      if (lang == NULL || lang[0] == '\0')
89        lang = getenv ("LANG");
90    }
91#endif
92  if (lang == NULL || lang[0] == '\0')
93    lang = "C";
94
95  /* See whether name of currently used domain is asked.  */
96  if (domainname == NULL)
97    return (char *) catalog_name;
98
99  if (domainname[0] == '\0')
100    domainname = default_catalog_name;
101
102  /* Compute length of added path element.  */
103  new_name_len = sizeof (LOCALEDIR) - 1 + 1 + strlen (lang)
104                 + sizeof ("/LC_MESSAGES/") - 1 + sizeof (PACKAGE) - 1
105                 + sizeof (".cat");
106
107  new_name = (char *) malloc (new_name_len);
108  if (new_name == NULL)
109    return NULL;
110
111  strcpy (new_name, PACKAGE);
112  new_catalog = catopen (new_name, 0);
113
114  if (new_catalog == (nl_catd) -1)
115    {
116      /* NLSPATH search didn't work, try absolute path */
117      sprintf (new_name, "%s/%s/LC_MESSAGES/%s.cat", LOCALEDIR, lang,
118               PACKAGE);
119      new_catalog = catopen (new_name, 0);
120
121      if (new_catalog == (nl_catd) -1)
122        {
123          free (new_name);
124          return (char *) catalog_name;
125        }
126    }
127
128  /* Close old catalog.  */
129  if (catalog != (nl_catd) -1)
130    catclose (catalog);
131  if (catalog_name != default_catalog_name)
132    free ((char *) catalog_name);
133
134  catalog = new_catalog;
135  catalog_name = new_name;
136
137  return (char *) catalog_name;
138}
139
140char *
141bindtextdomain (domainname, dirname)
142     const char *domainname;
143     const char *dirname;
144{
145#if HAVE_SETENV || HAVE_PUTENV
146  char *old_val, *new_val, *cp;
147  size_t new_val_len;
148
149  /* This does not make much sense here but to be compatible do it.  */
150  if (domainname == NULL)
151    return NULL;
152
153  /* Compute length of added path element.  If we use setenv we don't need
154     the first byts for NLSPATH=, but why complicate the code for this
155     peanuts.  */
156  new_val_len = sizeof ("NLSPATH=") - 1 + strlen (dirname)
157                + sizeof ("/%L/LC_MESSAGES/%N.cat");
158
159  old_val = getenv ("NLSPATH");
160  if (old_val == NULL || old_val[0] == '\0')
161    {
162      old_val = NULL;
163      new_val_len += 1 + sizeof (LOCALEDIR) - 1
164                     + sizeof ("/%L/LC_MESSAGES/%N.cat");
165    }
166  else
167    new_val_len += strlen (old_val);
168
169  new_val = (char *) malloc (new_val_len);
170  if (new_val == NULL)
171    return NULL;
172
173# if HAVE_SETENV
174  cp = new_val;
175# else
176  cp = stpcpy (new_val, "NLSPATH=");
177# endif
178
179  cp = stpcpy (cp, dirname);
180  cp = stpcpy (cp, "/%L/LC_MESSAGES/%N.cat:");
181
182  if (old_val == NULL)
183    {
184# if __STDC__
185      stpcpy (cp, LOCALEDIR "/%L/LC_MESSAGES/%N.cat");
186# else
187
188      cp = stpcpy (cp, LOCALEDIR);
189      stpcpy (cp, "/%L/LC_MESSAGES/%N.cat");
190# endif
191    }
192  else
193    stpcpy (cp, old_val);
194
195# if HAVE_SETENV
196  setenv ("NLSPATH", new_val, 1);
197  free (new_val);
198# else
199  putenv (new_val);
200  /* Do *not* free the environment entry we just entered.  It is used
201     from now on.   */
202# endif
203
204#endif
205
206  return (char *) domainname;
207}
208
209#undef gettext
210char *
211gettext (msg)
212     const char *msg;
213{
214  int msgid;
215
216  if (msg == NULL || catalog == (nl_catd) -1)
217    return (char *) msg;
218
219  /* Get the message from the catalog.  We always use set number 1.
220     The message ID is computed by the function `msg_to_cat_id'
221     which works on the table generated by `po-to-tbl'.  */
222  msgid = msg_to_cat_id (msg);
223  if (msgid == -1)
224    return (char *) msg;
225
226  return catgets (catalog, 1, msgid, (char *) msg);
227}
228
229/* Look through the table `_msg_tbl' which has `_msg_tbl_length' entries
230   for the one equal to msg.  If it is found return the ID.  In case when
231   the string is not found return -1.  */
232static int
233msg_to_cat_id (msg)
234     const char *msg;
235{
236  int cnt;
237
238  for (cnt = 0; cnt < _msg_tbl_length; ++cnt)
239    if (strcmp (msg, _msg_tbl[cnt]._msg) == 0)
240      return _msg_tbl[cnt]._msg_number;
241
242  return -1;
243}
244
245
246/* @@ begin of epilog @@ */
247
248/* We don't want libintl.a to depend on any other library.  So we
249   avoid the non-standard function stpcpy.  In GNU C Library this
250   function is available, though.  Also allow the symbol HAVE_STPCPY
251   to be defined.  */
252#if !_LIBC && !HAVE_STPCPY
253static char *
254stpcpy (dest, src)
255     char *dest;
256     const char *src;
257{
258  while ((*dest++ = *src++) != '\0')
259    /* Do nothing. */ ;
260  return dest - 1;
261}
262#endif
Note: See TracBrowser for help on using the repository browser.