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

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [newlib-1.18.0/] [newlib-1.18.0-or32-1.0rc2/] [newlib/] [libc/] [sys/] [linux/] [intl/] [bindtextdom.c] - Blame information for rev 520

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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