~ubuntu-branches/ubuntu/saucy/lordsawar/saucy

« back to all changes in this revision

Viewing changes to intl/bindtextdom.c

  • Committer: Bazaar Package Importer
  • Author(s): Barry deFreese, Barry deFreese
  • Date: 2008-12-20 13:52:12 UTC
  • mfrom: (1.1.6 upstream) (5.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20081220135212-noeb2w3y98ebo7o9
Tags: 0.1.4-1
[ Barry deFreese ]
* New upstream release.
* Move 0.0.8-2.1 changelog entry to correct point in changelog.
* Make lordsawar-data suggest lordsawar.
* Update my e-mail address.
* Add build-depends on intltool, uuid-dev, and libboost-dev.
* Don't install locales since there are no translations currently.
* Add simple man page for new lordsawar-pbm binary.
* Drop gcc4.3 patches as they have been fixed upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Implementation of the bindtextdomain(3) function
2
 
   Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc.
3
 
 
4
 
   This program is free software; you can redistribute it and/or modify it
5
 
   under the terms of the GNU Library General Public License as published
6
 
   by 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 GNU
12
 
   Library General Public License for more details.
13
 
 
14
 
   You should have received a copy of the GNU Library General Public
15
 
   License along with this program; if not, write to the Free Software
16
 
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17
 
   USA.  */
18
 
 
19
 
#ifdef HAVE_CONFIG_H
20
 
# include <config.h>
21
 
#endif
22
 
 
23
 
#include <stddef.h>
24
 
#include <stdlib.h>
25
 
#include <string.h>
26
 
 
27
 
#ifdef _LIBC
28
 
# include <libintl.h>
29
 
#else
30
 
# include "libgnuintl.h"
31
 
#endif
32
 
#include "gettextP.h"
33
 
 
34
 
#ifdef _LIBC
35
 
/* We have to handle multi-threaded applications.  */
36
 
# include <bits/libc-lock.h>
37
 
#else
38
 
/* Provide dummy implementation if this is outside glibc.  */
39
 
# define __libc_rwlock_define(CLASS, NAME)
40
 
# define __libc_rwlock_wrlock(NAME)
41
 
# define __libc_rwlock_unlock(NAME)
42
 
#endif
43
 
 
44
 
/* The internal variables in the standalone libintl.a must have different
45
 
   names than the internal variables in GNU libc, otherwise programs
46
 
   using libintl.a cannot be linked statically.  */
47
 
#if !defined _LIBC
48
 
# define _nl_default_dirname libintl_nl_default_dirname
49
 
# define _nl_domain_bindings libintl_nl_domain_bindings
50
 
#endif
51
 
 
52
 
/* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>.  */
53
 
#ifndef offsetof
54
 
# define offsetof(type,ident) ((size_t)&(((type*)0)->ident))
55
 
#endif
56
 
 
57
 
/* @@ end of prolog @@ */
58
 
 
59
 
/* Contains the default location of the message catalogs.  */
60
 
extern const char _nl_default_dirname[];
61
 
#ifdef _LIBC
62
 
extern const char _nl_default_dirname_internal[] attribute_hidden;
63
 
#else
64
 
# define INTUSE(name) name
65
 
#endif
66
 
 
67
 
/* List with bindings of specific domains.  */
68
 
extern struct binding *_nl_domain_bindings;
69
 
 
70
 
/* Lock variable to protect the global data in the gettext implementation.  */
71
 
__libc_rwlock_define (extern, _nl_state_lock attribute_hidden)
72
 
 
73
 
 
74
 
/* Names for the libintl functions are a problem.  They must not clash
75
 
   with existing names and they should follow ANSI C.  But this source
76
 
   code is also used in GNU C Library where the names have a __
77
 
   prefix.  So we have to make a difference here.  */
78
 
#ifdef _LIBC
79
 
# define BINDTEXTDOMAIN __bindtextdomain
80
 
# define BIND_TEXTDOMAIN_CODESET __bind_textdomain_codeset
81
 
# ifndef strdup
82
 
#  define strdup(str) __strdup (str)
83
 
# endif
84
 
#else
85
 
# define BINDTEXTDOMAIN libintl_bindtextdomain
86
 
# define BIND_TEXTDOMAIN_CODESET libintl_bind_textdomain_codeset
87
 
#endif
88
 
 
89
 
/* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP
90
 
   to be used for the DOMAINNAME message catalog.
91
 
   If *DIRNAMEP or *CODESETP is NULL, the corresponding attribute is not
92
 
   modified, only the current value is returned.
93
 
   If DIRNAMEP or CODESETP is NULL, the corresponding attribute is neither
94
 
   modified nor returned.  */
95
 
static void
96
 
set_binding_values (const char *domainname,
97
 
                    const char **dirnamep, const char **codesetp)
98
 
{
99
 
  struct binding *binding;
100
 
  int modified;
101
 
 
102
 
  /* Some sanity checks.  */
103
 
  if (domainname == NULL || domainname[0] == '\0')
104
 
    {
105
 
      if (dirnamep)
106
 
        *dirnamep = NULL;
107
 
      if (codesetp)
108
 
        *codesetp = NULL;
109
 
      return;
110
 
    }
111
 
 
112
 
  __libc_rwlock_wrlock (_nl_state_lock);
113
 
 
114
 
  modified = 0;
115
 
 
116
 
  for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
117
 
    {
118
 
      int compare = strcmp (domainname, binding->domainname);
119
 
      if (compare == 0)
120
 
        /* We found it!  */
121
 
        break;
122
 
      if (compare < 0)
123
 
        {
124
 
          /* It is not in the list.  */
125
 
          binding = NULL;
126
 
          break;
127
 
        }
128
 
    }
129
 
 
130
 
  if (binding != NULL)
131
 
    {
132
 
      if (dirnamep)
133
 
        {
134
 
          const char *dirname = *dirnamep;
135
 
 
136
 
          if (dirname == NULL)
137
 
            /* The current binding has be to returned.  */
138
 
            *dirnamep = binding->dirname;
139
 
          else
140
 
            {
141
 
              /* The domain is already bound.  If the new value and the old
142
 
                 one are equal we simply do nothing.  Otherwise replace the
143
 
                 old binding.  */
144
 
              char *result = binding->dirname;
145
 
              if (strcmp (dirname, result) != 0)
146
 
                {
147
 
                  if (strcmp (dirname, INTUSE(_nl_default_dirname)) == 0)
148
 
                    result = (char *) INTUSE(_nl_default_dirname);
149
 
                  else
150
 
                    {
151
 
#if defined _LIBC || defined HAVE_STRDUP
152
 
                      result = strdup (dirname);
153
 
#else
154
 
                      size_t len = strlen (dirname) + 1;
155
 
                      result = (char *) malloc (len);
156
 
                      if (__builtin_expect (result != NULL, 1))
157
 
                        memcpy (result, dirname, len);
158
 
#endif
159
 
                    }
160
 
 
161
 
                  if (__builtin_expect (result != NULL, 1))
162
 
                    {
163
 
                      if (binding->dirname != INTUSE(_nl_default_dirname))
164
 
                        free (binding->dirname);
165
 
 
166
 
                      binding->dirname = result;
167
 
                      modified = 1;
168
 
                    }
169
 
                }
170
 
              *dirnamep = result;
171
 
            }
172
 
        }
173
 
 
174
 
      if (codesetp)
175
 
        {
176
 
          const char *codeset = *codesetp;
177
 
 
178
 
          if (codeset == NULL)
179
 
            /* The current binding has be to returned.  */
180
 
            *codesetp = binding->codeset;
181
 
          else
182
 
            {
183
 
              /* The domain is already bound.  If the new value and the old
184
 
                 one are equal we simply do nothing.  Otherwise replace the
185
 
                 old binding.  */
186
 
              char *result = binding->codeset;
187
 
              if (result == NULL || strcmp (codeset, result) != 0)
188
 
                {
189
 
#if defined _LIBC || defined HAVE_STRDUP
190
 
                  result = strdup (codeset);
191
 
#else
192
 
                  size_t len = strlen (codeset) + 1;
193
 
                  result = (char *) malloc (len);
194
 
                  if (__builtin_expect (result != NULL, 1))
195
 
                    memcpy (result, codeset, len);
196
 
#endif
197
 
 
198
 
                  if (__builtin_expect (result != NULL, 1))
199
 
                    {
200
 
                      if (binding->codeset != NULL)
201
 
                        free (binding->codeset);
202
 
 
203
 
                      binding->codeset = result;
204
 
                      binding->codeset_cntr++;
205
 
                      modified = 1;
206
 
                    }
207
 
                }
208
 
              *codesetp = result;
209
 
            }
210
 
        }
211
 
    }
212
 
  else if ((dirnamep == NULL || *dirnamep == NULL)
213
 
           && (codesetp == NULL || *codesetp == NULL))
214
 
    {
215
 
      /* Simply return the default values.  */
216
 
      if (dirnamep)
217
 
        *dirnamep = INTUSE(_nl_default_dirname);
218
 
      if (codesetp)
219
 
        *codesetp = NULL;
220
 
    }
221
 
  else
222
 
    {
223
 
      /* We have to create a new binding.  */
224
 
      size_t len = strlen (domainname) + 1;
225
 
      struct binding *new_binding =
226
 
        (struct binding *) malloc (offsetof (struct binding, domainname) + len);
227
 
 
228
 
      if (__builtin_expect (new_binding == NULL, 0))
229
 
        goto failed;
230
 
 
231
 
      memcpy (new_binding->domainname, domainname, len);
232
 
 
233
 
      if (dirnamep)
234
 
        {
235
 
          const char *dirname = *dirnamep;
236
 
 
237
 
          if (dirname == NULL)
238
 
            /* The default value.  */
239
 
            dirname = INTUSE(_nl_default_dirname);
240
 
          else
241
 
            {
242
 
              if (strcmp (dirname, INTUSE(_nl_default_dirname)) == 0)
243
 
                dirname = INTUSE(_nl_default_dirname);
244
 
              else
245
 
                {
246
 
                  char *result;
247
 
#if defined _LIBC || defined HAVE_STRDUP
248
 
                  result = strdup (dirname);
249
 
                  if (__builtin_expect (result == NULL, 0))
250
 
                    goto failed_dirname;
251
 
#else
252
 
                  size_t len = strlen (dirname) + 1;
253
 
                  result = (char *) malloc (len);
254
 
                  if (__builtin_expect (result == NULL, 0))
255
 
                    goto failed_dirname;
256
 
                  memcpy (result, dirname, len);
257
 
#endif
258
 
                  dirname = result;
259
 
                }
260
 
            }
261
 
          *dirnamep = dirname;
262
 
          new_binding->dirname = (char *) dirname;
263
 
        }
264
 
      else
265
 
        /* The default value.  */
266
 
        new_binding->dirname = (char *) INTUSE(_nl_default_dirname);
267
 
 
268
 
      new_binding->codeset_cntr = 0;
269
 
 
270
 
      if (codesetp)
271
 
        {
272
 
          const char *codeset = *codesetp;
273
 
 
274
 
          if (codeset != NULL)
275
 
            {
276
 
              char *result;
277
 
 
278
 
#if defined _LIBC || defined HAVE_STRDUP
279
 
              result = strdup (codeset);
280
 
              if (__builtin_expect (result == NULL, 0))
281
 
                goto failed_codeset;
282
 
#else
283
 
              size_t len = strlen (codeset) + 1;
284
 
              result = (char *) malloc (len);
285
 
              if (__builtin_expect (result == NULL, 0))
286
 
                goto failed_codeset;
287
 
              memcpy (result, codeset, len);
288
 
#endif
289
 
              codeset = result;
290
 
              new_binding->codeset_cntr++;
291
 
            }
292
 
          *codesetp = codeset;
293
 
          new_binding->codeset = (char *) codeset;
294
 
        }
295
 
      else
296
 
        new_binding->codeset = NULL;
297
 
 
298
 
      /* Now enqueue it.  */
299
 
      if (_nl_domain_bindings == NULL
300
 
          || strcmp (domainname, _nl_domain_bindings->domainname) < 0)
301
 
        {
302
 
          new_binding->next = _nl_domain_bindings;
303
 
          _nl_domain_bindings = new_binding;
304
 
        }
305
 
      else
306
 
        {
307
 
          binding = _nl_domain_bindings;
308
 
          while (binding->next != NULL
309
 
                 && strcmp (domainname, binding->next->domainname) > 0)
310
 
            binding = binding->next;
311
 
 
312
 
          new_binding->next = binding->next;
313
 
          binding->next = new_binding;
314
 
        }
315
 
 
316
 
      modified = 1;
317
 
 
318
 
      /* Here we deal with memory allocation failures.  */
319
 
      if (0)
320
 
        {
321
 
        failed_codeset:
322
 
          if (new_binding->dirname != INTUSE(_nl_default_dirname))
323
 
            free (new_binding->dirname);
324
 
        failed_dirname:
325
 
          free (new_binding);
326
 
        failed:
327
 
          if (dirnamep)
328
 
            *dirnamep = NULL;
329
 
          if (codesetp)
330
 
            *codesetp = NULL;
331
 
        }
332
 
    }
333
 
 
334
 
  /* If we modified any binding, we flush the caches.  */
335
 
  if (modified)
336
 
    ++_nl_msg_cat_cntr;
337
 
 
338
 
  __libc_rwlock_unlock (_nl_state_lock);
339
 
}
340
 
 
341
 
/* Specify that the DOMAINNAME message catalog will be found
342
 
   in DIRNAME rather than in the system locale data base.  */
343
 
char *
344
 
BINDTEXTDOMAIN (const char *domainname, const char *dirname)
345
 
{
346
 
  set_binding_values (domainname, &dirname, NULL);
347
 
  return (char *) dirname;
348
 
}
349
 
 
350
 
/* Specify the character encoding in which the messages from the
351
 
   DOMAINNAME message catalog will be returned.  */
352
 
char *
353
 
BIND_TEXTDOMAIN_CODESET (const char *domainname, const char *codeset)
354
 
{
355
 
  set_binding_values (domainname, NULL, &codeset);
356
 
  return (char *) codeset;
357
 
}
358
 
 
359
 
#ifdef _LIBC
360
 
/* Aliases for function names in GNU C Library.  */
361
 
weak_alias (__bindtextdomain, bindtextdomain);
362
 
weak_alias (__bind_textdomain_codeset, bind_textdomain_codeset);
363
 
#endif