~vcs-imports/gawk/master

« back to all changes in this revision

Viewing changes to intl/loadmsgcat.c

  • Committer: Arnold D. Robbins
  • Date: 2010-07-16 10:09:56 UTC
  • Revision ID: git-v1:bc70de7b3302d5a81515b901cae376b8b51d2004
Tags: gawk-3.1.0
Move to gawk-3.1.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Load needed message catalogs.
 
2
   Copyright (C) 1995, 1996, 1997, 1998 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 <fcntl.h>
 
23
#include <sys/types.h>
 
24
#include <sys/stat.h>
 
25
 
 
26
#if defined STDC_HEADERS || defined _LIBC
 
27
# include <stdlib.h>
 
28
#endif
 
29
 
 
30
#if defined HAVE_UNISTD_H || defined _LIBC
 
31
# include <unistd.h>
 
32
#endif
 
33
 
 
34
#define DISALLOW_MMAP 1 /* ADR */
 
35
#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
 
36
    || (defined _LIBC && defined _POSIX_MAPPED_FILES)
 
37
# include <sys/mman.h>
 
38
# undef HAVE_MMAP
 
39
# define HAVE_MMAP      1
 
40
#else
 
41
# undef HAVE_MMAP
 
42
#endif
 
43
 
 
44
#include "gettext.h"
 
45
#include "gettextP.h"
 
46
 
 
47
/* @@ end of prolog @@ */
 
48
 
 
49
#ifdef _LIBC
 
50
/* Rename the non ISO C functions.  This is required by the standard
 
51
   because some ISO C functions will require linking with this object
 
52
   file and the name space must not be polluted.  */
 
53
# define open   __open
 
54
# define close  __close
 
55
# define read   __read
 
56
# define mmap   __mmap
 
57
# define munmap __munmap
 
58
#endif
 
59
 
 
60
/* We need a sign, whether a new catalog was loaded, which can be associated
 
61
   with all translations.  This is important if the translations are
 
62
   cached by one of GCC's features.  */
 
63
int _nl_msg_cat_cntr = 0;
 
64
 
 
65
 
 
66
/* Load the message catalogs specified by FILENAME.  If it is no valid
 
67
   message catalog do nothing.  */
 
68
void
 
69
internal_function
 
70
_nl_load_domain (domain_file)
 
71
     struct loaded_l10nfile *domain_file;
 
72
{
 
73
  int fd;
 
74
  size_t size;
 
75
  struct stat st;
 
76
  struct mo_file_header *data = (struct mo_file_header *) -1;
 
77
  int use_mmap = 0;
 
78
  struct loaded_domain *domain;
 
79
 
 
80
  domain_file->decided = 1;
 
81
  domain_file->data = NULL;
 
82
 
 
83
  /* If the record does not represent a valid locale the FILENAME
 
84
     might be NULL.  This can happen when according to the given
 
85
     specification the locale file name is different for XPG and CEN
 
86
     syntax.  */
 
87
  if (domain_file->filename == NULL)
 
88
    return;
 
89
 
 
90
  /* Try to open the addressed file.  */
 
91
  fd = open (domain_file->filename, O_RDONLY);
 
92
  if (fd == -1)
 
93
    return;
 
94
 
 
95
  /* We must know about the size of the file.  */
 
96
  if (fstat (fd, &st) != 0
 
97
      || (size = (size_t) st.st_size) != st.st_size
 
98
      || size < sizeof (struct mo_file_header))
 
99
    {
 
100
      /* Something went wrong.  */
 
101
      close (fd);
 
102
      return;
 
103
    }
 
104
 
 
105
#ifdef HAVE_MMAP
 
106
  /* Now we are ready to load the file.  If mmap() is available we try
 
107
     this first.  If not available or it failed we try to load it.  */
 
108
  data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
 
109
                                         MAP_PRIVATE, fd, 0);
 
110
 
 
111
  if (data != (struct mo_file_header *) -1)
 
112
    {
 
113
      /* mmap() call was successful.  */
 
114
      close (fd);
 
115
      use_mmap = 1;
 
116
    }
 
117
#endif
 
118
 
 
119
  /* If the data is not yet available (i.e. mmap'ed) we try to load
 
120
     it manually.  */
 
121
  if (data == (struct mo_file_header *) -1)
 
122
    {
 
123
      size_t to_read;
 
124
      char *read_ptr;
 
125
 
 
126
      data = (struct mo_file_header *) malloc (size);
 
127
      if (data == NULL)
 
128
        return;
 
129
 
 
130
      to_read = size;
 
131
      read_ptr = (char *) data;
 
132
      do
 
133
        {
 
134
          long int nb = (long int) read (fd, read_ptr, to_read);
 
135
          if (nb == -1)
 
136
            {
 
137
              close (fd);
 
138
              return;
 
139
            }
 
140
 
 
141
          read_ptr += nb;
 
142
          to_read -= nb;
 
143
        }
 
144
      while (to_read > 0);
 
145
 
 
146
      close (fd);
 
147
    }
 
148
 
 
149
  /* Using the magic number we can test whether it really is a message
 
150
     catalog file.  */
 
151
  if (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED)
 
152
    {
 
153
      /* The magic number is wrong: not a message catalog file.  */
 
154
#ifdef HAVE_MMAP
 
155
      if (use_mmap)
 
156
        munmap ((caddr_t) data, size);
 
157
      else
 
158
#endif
 
159
        free (data);
 
160
      return;
 
161
    }
 
162
 
 
163
  domain_file->data
 
164
    = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
 
165
  if (domain_file->data == NULL)
 
166
    return;
 
167
 
 
168
  domain = (struct loaded_domain *) domain_file->data;
 
169
  domain->data = (char *) data;
 
170
  domain->use_mmap = use_mmap;
 
171
  domain->mmap_size = size;
 
172
  domain->must_swap = data->magic != _MAGIC;
 
173
 
 
174
  /* Fill in the information about the available tables.  */
 
175
  switch (W (domain->must_swap, data->revision))
 
176
    {
 
177
    case 0:
 
178
      domain->nstrings = W (domain->must_swap, data->nstrings);
 
179
      domain->orig_tab = (struct string_desc *)
 
180
        ((char *) data + W (domain->must_swap, data->orig_tab_offset));
 
181
      domain->trans_tab = (struct string_desc *)
 
182
        ((char *) data + W (domain->must_swap, data->trans_tab_offset));
 
183
      domain->hash_size = W (domain->must_swap, data->hash_tab_size);
 
184
      domain->hash_tab = (nls_uint32 *)
 
185
        ((char *) data + W (domain->must_swap, data->hash_tab_offset));
 
186
      break;
 
187
    default:
 
188
      /* This is an invalid revision.  */
 
189
#ifdef HAVE_MMAP
 
190
      if (use_mmap)
 
191
        munmap ((caddr_t) data, size);
 
192
      else
 
193
#endif
 
194
        free (data);
 
195
      free (domain);
 
196
      domain_file->data = NULL;
 
197
      return;
 
198
    }
 
199
 
 
200
  /* Show that one domain is changed.  This might make some cached
 
201
     translations invalid.  */
 
202
  ++_nl_msg_cat_cntr;
 
203
}
 
204
 
 
205
 
 
206
#ifdef _LIBC
 
207
void
 
208
internal_function
 
209
_nl_unload_domain (domain)
 
210
     struct loaded_domain *domain;
 
211
{
 
212
#ifdef _POSIX_MAPPED_FILES
 
213
  if (domain->use_mmap)
 
214
    munmap ((caddr_t) domain->data, domain->mmap_size);
 
215
  else
 
216
#endif  /* _POSIX_MAPPED_FILES */
 
217
    free ((void *) domain->data);
 
218
 
 
219
  free (domain);
 
220
}
 
221
#endif