OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [intl/] [bindtextdom.c] - Blame information for rev 253

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 22 khays
/* Implementation of the bindtextdomain(3) function
2
   Copyright (C) 1995-1998, 2000, 2001, 2002 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
#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
/* Prototypes for local functions.  */
90
static void set_binding_values PARAMS ((const char *domainname,
91
                                        const char **dirnamep,
92
                                        const char **codesetp));
93
 
94
/* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP
95
   to be used for the DOMAINNAME message catalog.
96
   If *DIRNAMEP or *CODESETP is NULL, the corresponding attribute is not
97
   modified, only the current value is returned.
98
   If DIRNAMEP or CODESETP is NULL, the corresponding attribute is neither
99
   modified nor returned.  */
100
static void
101
set_binding_values (domainname, dirnamep, codesetp)
102
     const char *domainname;
103
     const char **dirnamep;
104
     const char **codesetp;
105
{
106
  struct binding *binding;
107
  int modified;
108
 
109
  /* Some sanity checks.  */
110
  if (domainname == NULL || domainname[0] == '\0')
111
    {
112
      if (dirnamep)
113
        *dirnamep = NULL;
114
      if (codesetp)
115
        *codesetp = NULL;
116
      return;
117
    }
118
 
119
  __libc_rwlock_wrlock (_nl_state_lock);
120
 
121
  modified = 0;
122
 
123
  for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
124
    {
125
      int compare = strcmp (domainname, binding->domainname);
126
      if (compare == 0)
127
        /* We found it!  */
128
        break;
129
      if (compare < 0)
130
        {
131
          /* It is not in the list.  */
132
          binding = NULL;
133
          break;
134
        }
135
    }
136
 
137
  if (binding != NULL)
138
    {
139
      if (dirnamep)
140
        {
141
          const char *dirname = *dirnamep;
142
 
143
          if (dirname == NULL)
144
            /* The current binding has be to returned.  */
145
            *dirnamep = binding->dirname;
146
          else
147
            {
148
              /* The domain is already bound.  If the new value and the old
149
                 one are equal we simply do nothing.  Otherwise replace the
150
                 old binding.  */
151
              char *result = binding->dirname;
152
              if (strcmp (dirname, result) != 0)
153
                {
154
                  if (strcmp (dirname, INTUSE(_nl_default_dirname)) == 0)
155
                    result = (char *) INTUSE(_nl_default_dirname);
156
                  else
157
                    {
158
#if defined _LIBC || defined HAVE_STRDUP
159
                      result = strdup (dirname);
160
#else
161
                      size_t len = strlen (dirname) + 1;
162
                      result = (char *) malloc (len);
163
                      if (__builtin_expect (result != NULL, 1))
164
                        memcpy (result, dirname, len);
165
#endif
166
                    }
167
 
168
                  if (__builtin_expect (result != NULL, 1))
169
                    {
170
                      if (binding->dirname != INTUSE(_nl_default_dirname))
171
                        free (binding->dirname);
172
 
173
                      binding->dirname = result;
174
                      modified = 1;
175
                    }
176
                }
177
              *dirnamep = result;
178
            }
179
        }
180
 
181
      if (codesetp)
182
        {
183
          const char *codeset = *codesetp;
184
 
185
          if (codeset == NULL)
186
            /* The current binding has be to returned.  */
187
            *codesetp = binding->codeset;
188
          else
189
            {
190
              /* The domain is already bound.  If the new value and the old
191
                 one are equal we simply do nothing.  Otherwise replace the
192
                 old binding.  */
193
              char *result = binding->codeset;
194
              if (result == NULL || strcmp (codeset, result) != 0)
195
                {
196
#if defined _LIBC || defined HAVE_STRDUP
197
                  result = strdup (codeset);
198
#else
199
                  size_t len = strlen (codeset) + 1;
200
                  result = (char *) malloc (len);
201
                  if (__builtin_expect (result != NULL, 1))
202
                    memcpy (result, codeset, len);
203
#endif
204
 
205
                  if (__builtin_expect (result != NULL, 1))
206
                    {
207
                      if (binding->codeset != NULL)
208
                        free (binding->codeset);
209
 
210
                      binding->codeset = result;
211
                      binding->codeset_cntr++;
212
                      modified = 1;
213
                    }
214
                }
215
              *codesetp = result;
216
            }
217
        }
218
    }
219
  else if ((dirnamep == NULL || *dirnamep == NULL)
220
           && (codesetp == NULL || *codesetp == NULL))
221
    {
222
      /* Simply return the default values.  */
223
      if (dirnamep)
224
        *dirnamep = INTUSE(_nl_default_dirname);
225
      if (codesetp)
226
        *codesetp = NULL;
227
    }
228
  else
229
    {
230
      /* We have to create a new binding.  */
231
      size_t len = strlen (domainname) + 1;
232
      struct binding *new_binding =
233
        (struct binding *) malloc (offsetof (struct binding, domainname) + len);
234
 
235
      if (__builtin_expect (new_binding == NULL, 0))
236
        goto failed;
237
 
238
      memcpy (new_binding->domainname, domainname, len);
239
 
240
      if (dirnamep)
241
        {
242
          const char *dirname = *dirnamep;
243
 
244
          if (dirname == NULL)
245
            /* The default value.  */
246
            dirname = INTUSE(_nl_default_dirname);
247
          else
248
            {
249
              if (strcmp (dirname, INTUSE(_nl_default_dirname)) == 0)
250
                dirname = INTUSE(_nl_default_dirname);
251
              else
252
                {
253
                  char *result;
254
#if defined _LIBC || defined HAVE_STRDUP
255
                  result = strdup (dirname);
256
                  if (__builtin_expect (result == NULL, 0))
257
                    goto failed_dirname;
258
#else
259
                  size_t len = strlen (dirname) + 1;
260
                  result = (char *) malloc (len);
261
                  if (__builtin_expect (result == NULL, 0))
262
                    goto failed_dirname;
263
                  memcpy (result, dirname, len);
264
#endif
265
                  dirname = result;
266
                }
267
            }
268
          *dirnamep = dirname;
269
          new_binding->dirname = (char *) dirname;
270
        }
271
      else
272
        /* The default value.  */
273
        new_binding->dirname = (char *) INTUSE(_nl_default_dirname);
274
 
275
      new_binding->codeset_cntr = 0;
276
 
277
      if (codesetp)
278
        {
279
          const char *codeset = *codesetp;
280
 
281
          if (codeset != NULL)
282
            {
283
              char *result;
284
 
285
#if defined _LIBC || defined HAVE_STRDUP
286
              result = strdup (codeset);
287
              if (__builtin_expect (result == NULL, 0))
288
                goto failed_codeset;
289
#else
290
              size_t len = strlen (codeset) + 1;
291
              result = (char *) malloc (len);
292
              if (__builtin_expect (result == NULL, 0))
293
                goto failed_codeset;
294
              memcpy (result, codeset, len);
295
#endif
296
              codeset = result;
297
              new_binding->codeset_cntr++;
298
            }
299
          *codesetp = codeset;
300
          new_binding->codeset = (char *) codeset;
301
        }
302
      else
303
        new_binding->codeset = NULL;
304
 
305
      /* Now enqueue it.  */
306
      if (_nl_domain_bindings == NULL
307
          || strcmp (domainname, _nl_domain_bindings->domainname) < 0)
308
        {
309
          new_binding->next = _nl_domain_bindings;
310
          _nl_domain_bindings = new_binding;
311
        }
312
      else
313
        {
314
          binding = _nl_domain_bindings;
315
          while (binding->next != NULL
316
                 && strcmp (domainname, binding->next->domainname) > 0)
317
            binding = binding->next;
318
 
319
          new_binding->next = binding->next;
320
          binding->next = new_binding;
321
        }
322
 
323
      modified = 1;
324
 
325
      /* Here we deal with memory allocation failures.  */
326
      if (0)
327
        {
328
        failed_codeset:
329
          if (new_binding->dirname != INTUSE(_nl_default_dirname))
330
            free (new_binding->dirname);
331
        failed_dirname:
332
          free (new_binding);
333
        failed:
334
          if (dirnamep)
335
            *dirnamep = NULL;
336
          if (codesetp)
337
            *codesetp = NULL;
338
        }
339
    }
340
 
341
  /* If we modified any binding, we flush the caches.  */
342
  if (modified)
343
    ++_nl_msg_cat_cntr;
344
 
345
  __libc_rwlock_unlock (_nl_state_lock);
346
}
347
 
348
/* Specify that the DOMAINNAME message catalog will be found
349
   in DIRNAME rather than in the system locale data base.  */
350
char *
351
BINDTEXTDOMAIN (domainname, dirname)
352
     const char *domainname;
353
     const char *dirname;
354
{
355
  set_binding_values (domainname, &dirname, NULL);
356
  return (char *) dirname;
357
}
358
 
359
/* Specify the character encoding in which the messages from the
360
   DOMAINNAME message catalog will be returned.  */
361
char *
362
BIND_TEXTDOMAIN_CODESET (domainname, codeset)
363
     const char *domainname;
364
     const char *codeset;
365
{
366
  set_binding_values (domainname, NULL, &codeset);
367
  return (char *) codeset;
368
}
369
 
370
#ifdef _LIBC
371
/* Aliases for function names in GNU C Library.  */
372
weak_alias (__bindtextdomain, bindtextdomain);
373
weak_alias (__bind_textdomain_codeset, bind_textdomain_codeset);
374
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.