source: trunk/third/gnome-core/intl/loadmsgcat.c @ 15328

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