source: branches/libc-0.6/src/binutils/intl/loadmsgcat.c

Last change on this file was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

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