~ubuntu-branches/ubuntu/trusty/codeblocks/trusty-proposed

« back to all changes in this revision

Viewing changes to src/plugins/contrib/SpellChecker/hunspell/intl/bindtextdom.c

  • Committer: Package Import Robot
  • Author(s): Vincent Cheng
  • Date: 2013-05-06 00:20:02 UTC
  • mfrom: (6.1.2 experimental)
  • Revision ID: package-import@ubuntu.com-20130506002002-ngc7bwkewnak8fja
Tags: 12.11-3
* Upload to unstable.
* Update watch file, thanks to Bart Martens.

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