#include <ctype.h>#include <errno.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <stdlib.h>#include <string.h>#include "gmo.h"#include "gettextP.h"#include "hash-string.h"#include "plural-exp.h"Go to the source code of this file.
Defines | |
| #define | _GNU_SOURCE 1 |
| #define | PRId8 "d" |
| #define | PRIi8 "i" |
| #define | PRIo8 "o" |
| #define | PRIu8 "u" |
| #define | PRIx8 "x" |
| #define | PRIX8 "X" |
| #define | PRId16 "d" |
| #define | PRIi16 "i" |
| #define | PRIo16 "o" |
| #define | PRIu16 "u" |
| #define | PRIx16 "x" |
| #define | PRIX16 "X" |
| #define | PRId32 "d" |
| #define | PRIi32 "i" |
| #define | PRIo32 "o" |
| #define | PRIu32 "u" |
| #define | PRIx32 "x" |
| #define | PRIX32 "X" |
| #define | PRId64 (sizeof (long) == 8 ? "ld" : "lld") |
| #define | PRIi64 (sizeof (long) == 8 ? "li" : "lli") |
| #define | PRIo64 (sizeof (long) == 8 ? "lo" : "llo") |
| #define | PRIu64 (sizeof (long) == 8 ? "lu" : "llu") |
| #define | PRIx64 (sizeof (long) == 8 ? "lx" : "llx") |
| #define | PRIX64 (sizeof (long) == 8 ? "lX" : "llX") |
| #define | PRIdLEAST8 "d" |
| #define | PRIiLEAST8 "i" |
| #define | PRIoLEAST8 "o" |
| #define | PRIuLEAST8 "u" |
| #define | PRIxLEAST8 "x" |
| #define | PRIXLEAST8 "X" |
| #define | PRIdLEAST16 "d" |
| #define | PRIiLEAST16 "i" |
| #define | PRIoLEAST16 "o" |
| #define | PRIuLEAST16 "u" |
| #define | PRIxLEAST16 "x" |
| #define | PRIXLEAST16 "X" |
| #define | PRIdLEAST32 "d" |
| #define | PRIiLEAST32 "i" |
| #define | PRIoLEAST32 "o" |
| #define | PRIuLEAST32 "u" |
| #define | PRIxLEAST32 "x" |
| #define | PRIXLEAST32 "X" |
| #define | PRIdLEAST64 PRId64 |
| #define | PRIiLEAST64 PRIi64 |
| #define | PRIoLEAST64 PRIo64 |
| #define | PRIuLEAST64 PRIu64 |
| #define | PRIxLEAST64 PRIx64 |
| #define | PRIXLEAST64 PRIX64 |
| #define | PRIdFAST8 "d" |
| #define | PRIiFAST8 "i" |
| #define | PRIoFAST8 "o" |
| #define | PRIuFAST8 "u" |
| #define | PRIxFAST8 "x" |
| #define | PRIXFAST8 "X" |
| #define | PRIdFAST16 "d" |
| #define | PRIiFAST16 "i" |
| #define | PRIoFAST16 "o" |
| #define | PRIuFAST16 "u" |
| #define | PRIxFAST16 "x" |
| #define | PRIXFAST16 "X" |
| #define | PRIdFAST32 "d" |
| #define | PRIiFAST32 "i" |
| #define | PRIoFAST32 "o" |
| #define | PRIuFAST32 "u" |
| #define | PRIxFAST32 "x" |
| #define | PRIXFAST32 "X" |
| #define | PRIdFAST64 PRId64 |
| #define | PRIiFAST64 PRIi64 |
| #define | PRIoFAST64 PRIo64 |
| #define | PRIuFAST64 PRIu64 |
| #define | PRIxFAST64 PRIx64 |
| #define | PRIXFAST64 PRIX64 |
| #define | PRIdMAX (sizeof (uintmax_t) == sizeof (long) ? "ld" : "lld") |
| #define | PRIiMAX (sizeof (uintmax_t) == sizeof (long) ? "li" : "lli") |
| #define | PRIoMAX (sizeof (uintmax_t) == sizeof (long) ? "lo" : "llo") |
| #define | PRIuMAX (sizeof (uintmax_t) == sizeof (long) ? "lu" : "llu") |
| #define | PRIxMAX (sizeof (uintmax_t) == sizeof (long) ? "lx" : "llx") |
| #define | PRIXMAX (sizeof (uintmax_t) == sizeof (long) ? "lX" : "llX") |
| #define | PRIdPTR |
| #define | PRIiPTR |
| #define | PRIoPTR |
| #define | PRIuPTR |
| #define | PRIxPTR |
| #define | PRIXPTR |
| #define | alloca(n) malloc (n) |
| #define | freea(p) free (p) |
| #define | O_BINARY 0 |
Functions | |
| char * | alloca () |
| const char *get_sysdep_segment_value | PARAMS ((const char *name)) |
| const char * | get_sysdep_segment_value (char *name) const |
| const char *internal_function | _nl_init_domain_conv (struct loaded_l10nfile *domain_file, struct loaded_domain *domain, struct binding *domainbinding) |
| void internal_function | _nl_free_domain_conv (struct loaded_domain *domain) |
| void internal_function | _nl_load_domain (struct loaded_l10nfile *domain_file, struct binding *domainbinding) |
Variables | |
| int | _nl_msg_cat_cntr |
|
|
Definition at line 23 of file loadmsgcat.c. |
|
|
Definition at line 466 of file loadmsgcat.c. |
|
|
Definition at line 467 of file loadmsgcat.c. |
|
|
Definition at line 484 of file loadmsgcat.c. |
|
|
Definition at line 119 of file loadmsgcat.c. |
|
|
Definition at line 143 of file loadmsgcat.c. |
|
|
Definition at line 167 of file loadmsgcat.c. |
|
|
Definition at line 95 of file loadmsgcat.c. |
|
|
Definition at line 311 of file loadmsgcat.c. |
|
|
Definition at line 335 of file loadmsgcat.c. |
|
|
Definition at line 359 of file loadmsgcat.c. |
|
|
Definition at line 287 of file loadmsgcat.c. |
|
|
Definition at line 215 of file loadmsgcat.c. |
|
|
Definition at line 239 of file loadmsgcat.c. |
|
|
Definition at line 263 of file loadmsgcat.c. |
|
|
Definition at line 191 of file loadmsgcat.c. |
|
|
Definition at line 383 of file loadmsgcat.c. |
|
|
Value: (sizeof (void *) == sizeof (long) ? "ld" : \ sizeof (void *) == sizeof (int) ? "d" : \ "lld") Definition at line 407 of file loadmsgcat.c. |
|
|
Definition at line 123 of file loadmsgcat.c. |
|
|
Definition at line 147 of file loadmsgcat.c. |
|
|
Definition at line 171 of file loadmsgcat.c. |
|
|
Definition at line 99 of file loadmsgcat.c. |
|
|
Definition at line 315 of file loadmsgcat.c. |
|
|
Definition at line 339 of file loadmsgcat.c. |
|
|
Definition at line 363 of file loadmsgcat.c. |
|
|
Definition at line 291 of file loadmsgcat.c. |
|
|
Definition at line 219 of file loadmsgcat.c. |
|
|
Definition at line 243 of file loadmsgcat.c. |
|
|
Definition at line 267 of file loadmsgcat.c. |
|
|
Definition at line 195 of file loadmsgcat.c. |
|
|
Definition at line 387 of file loadmsgcat.c. |
|
|
Value: (sizeof (void *) == sizeof (long) ? "li" : \ sizeof (void *) == sizeof (int) ? "i" : \ "lli") Definition at line 414 of file loadmsgcat.c. |
|
|
Definition at line 127 of file loadmsgcat.c. |
|
|
Definition at line 151 of file loadmsgcat.c. |
|
|
Definition at line 175 of file loadmsgcat.c. |
|
|
Definition at line 103 of file loadmsgcat.c. |
|
|
Definition at line 319 of file loadmsgcat.c. |
|
|
Definition at line 343 of file loadmsgcat.c. |
|
|
Definition at line 367 of file loadmsgcat.c. |
|
|
Definition at line 295 of file loadmsgcat.c. |
|
|
Definition at line 223 of file loadmsgcat.c. |
|
|
Definition at line 247 of file loadmsgcat.c. |
|
|
Definition at line 271 of file loadmsgcat.c. |
|
|
Definition at line 199 of file loadmsgcat.c. |
|
|
Definition at line 391 of file loadmsgcat.c. |
|
|
Value: (sizeof (void *) == sizeof (long) ? "lo" : \ sizeof (void *) == sizeof (int) ? "o" : \ "llo") Definition at line 421 of file loadmsgcat.c. |
|
|
Definition at line 131 of file loadmsgcat.c. |
|
|
Definition at line 155 of file loadmsgcat.c. |
|
|
Definition at line 179 of file loadmsgcat.c. |
|
|
Definition at line 107 of file loadmsgcat.c. |
|
|
Definition at line 323 of file loadmsgcat.c. |
|
|
Definition at line 347 of file loadmsgcat.c. |
|
|
Definition at line 371 of file loadmsgcat.c. |
|
|
Definition at line 299 of file loadmsgcat.c. |
|
|
Definition at line 227 of file loadmsgcat.c. |
|
|
Definition at line 251 of file loadmsgcat.c. |
|
|
Definition at line 275 of file loadmsgcat.c. |
|
|
Definition at line 203 of file loadmsgcat.c. |
|
|
Definition at line 395 of file loadmsgcat.c. |
|
|
Value: (sizeof (void *) == sizeof (long) ? "lu" : \ sizeof (void *) == sizeof (int) ? "u" : \ "llu") Definition at line 428 of file loadmsgcat.c. |
|
|
Definition at line 139 of file loadmsgcat.c. |
|
|
Definition at line 135 of file loadmsgcat.c. |
|
|
Definition at line 163 of file loadmsgcat.c. |
|
|
Definition at line 159 of file loadmsgcat.c. |
|
|
Definition at line 187 of file loadmsgcat.c. |
|
|
Definition at line 183 of file loadmsgcat.c. |
|
|
Definition at line 115 of file loadmsgcat.c. |
|
|
Definition at line 111 of file loadmsgcat.c. |
|
|
Definition at line 331 of file loadmsgcat.c. |
|
|
Definition at line 327 of file loadmsgcat.c. |
|
|
Definition at line 355 of file loadmsgcat.c. |
|
|
Definition at line 351 of file loadmsgcat.c. |
|
|
Definition at line 379 of file loadmsgcat.c. |
|
|
Definition at line 375 of file loadmsgcat.c. |
|
|
Definition at line 307 of file loadmsgcat.c. |
|
|
Definition at line 303 of file loadmsgcat.c. |
|
|
Definition at line 235 of file loadmsgcat.c. |
|
|
Definition at line 231 of file loadmsgcat.c. |
|
|
Definition at line 259 of file loadmsgcat.c. |
|
|
Definition at line 255 of file loadmsgcat.c. |
|
|
Definition at line 283 of file loadmsgcat.c. |
|
|
Definition at line 279 of file loadmsgcat.c. |
|
|
Definition at line 211 of file loadmsgcat.c. |
|
|
Definition at line 207 of file loadmsgcat.c. |
|
|
Definition at line 403 of file loadmsgcat.c. |
|
|
Definition at line 399 of file loadmsgcat.c. |
|
|
Value: (sizeof (void *) == sizeof (long) ? "lX" : \ sizeof (void *) == sizeof (int) ? "X" : \ "llX") Definition at line 442 of file loadmsgcat.c. |
|
|
Value: (sizeof (void *) == sizeof (long) ? "lx" : \ sizeof (void *) == sizeof (int) ? "x" : \ "llx") Definition at line 435 of file loadmsgcat.c. |
|
|
Definition at line 878 of file loadmsgcat.c. 00880 {
00881 if (domain->conv_tab != NULL && domain->conv_tab != (char **) -1)
00882 free (domain->conv_tab);
00883
00884 #ifdef _LIBC
00885 if (domain->conv != (__gconv_t) -1)
00886 __gconv_close (domain->conv);
00887 #else
00888 # if HAVE_ICONV
00889 if (domain->conv != (iconv_t) -1)
00890 iconv_close (domain->conv);
00891 # endif
00892 #endif
00893 }
|
|
||||||||||||||||
|
Definition at line 759 of file loadmsgcat.c. 00763 {
00764 /* Find out about the character set the file is encoded with.
00765 This can be found (in textual form) in the entry "". If this
00766 entry does not exist or if this does not contain the `charset='
00767 information, we will assume the charset matches the one the
00768 current locale and we don't have to perform any conversion. */
00769 char *nullentry;
00770 size_t nullentrylen;
00771
00772 /* Preinitialize fields, to avoid recursion during _nl_find_msg. */
00773 domain->codeset_cntr =
00774 (domainbinding != NULL ? domainbinding->codeset_cntr : 0);
00775 #ifdef _LIBC
00776 domain->conv = (__gconv_t) -1;
00777 #else
00778 # if HAVE_ICONV
00779 domain->conv = (iconv_t) -1;
00780 # endif
00781 #endif
00782 domain->conv_tab = NULL;
00783
00784 /* Get the header entry. */
00785 nullentry = _nl_find_msg (domain_file, domainbinding, "", &nullentrylen);
00786
00787 if (nullentry != NULL)
00788 {
00789 #if defined _LIBC || HAVE_ICONV
00790 const char *charsetstr;
00791
00792 charsetstr = strstr (nullentry, "charset=");
00793 if (charsetstr != NULL)
00794 {
00795 size_t len;
00796 char *charset;
00797 const char *outcharset;
00798
00799 charsetstr += strlen ("charset=");
00800 len = strcspn (charsetstr, " \t\n");
00801
00802 charset = (char *) alloca (len + 1);
00803 # if defined _LIBC || HAVE_MEMPCPY
00804 *((char *) mempcpy (charset, charsetstr, len)) = '\0';
00805 # else
00806 memcpy (charset, charsetstr, len);
00807 charset[len] = '\0';
00808 # endif
00809
00810 /* The output charset should normally be determined by the
00811 locale. But sometimes the locale is not used or not correctly
00812 set up, so we provide a possibility for the user to override
00813 this. Moreover, the value specified through
00814 bind_textdomain_codeset overrides both. */
00815 if (domainbinding != NULL && domainbinding->codeset != NULL)
00816 outcharset = domainbinding->codeset;
00817 else
00818 {
00819 outcharset = getenv ("OUTPUT_CHARSET");
00820 if (outcharset == NULL || outcharset[0] == '\0')
00821 {
00822 # ifdef _LIBC
00823 outcharset = (*_nl_current[LC_CTYPE])->values[_NL_ITEM_INDEX (CODESET)].string;
00824 # else
00825 # if HAVE_ICONV
00826 extern const char *locale_charset PARAMS ((void));
00827 outcharset = locale_charset ();
00828 # endif
00829 # endif
00830 }
00831 }
00832
00833 # ifdef _LIBC
00834 /* We always want to use transliteration. */
00835 outcharset = norm_add_slashes (outcharset, "TRANSLIT");
00836 charset = norm_add_slashes (charset, NULL);
00837 if (__gconv_open (outcharset, charset, &domain->conv,
00838 GCONV_AVOID_NOCONV)
00839 != __GCONV_OK)
00840 domain->conv = (__gconv_t) -1;
00841 # else
00842 # if HAVE_ICONV
00843 /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
00844 we want to use transliteration. */
00845 # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \
00846 || _LIBICONV_VERSION >= 0x0105
00847 if (strchr (outcharset, '/') == NULL)
00848 {
00849 char *tmp;
00850
00851 len = strlen (outcharset);
00852 tmp = (char *) alloca (len + 10 + 1);
00853 memcpy (tmp, outcharset, len);
00854 memcpy (tmp + len, "//TRANSLIT", 10 + 1);
00855 outcharset = tmp;
00856
00857 domain->conv = iconv_open (outcharset, charset);
00858
00859 freea (outcharset);
00860 }
00861 else
00862 # endif
00863 domain->conv = iconv_open (outcharset, charset);
00864 # endif
00865 # endif
00866
00867 freea (charset);
00868 }
00869 #endif /* _LIBC || HAVE_ICONV */
00870 }
00871
00872 return nullentry;
00873 }
|
|
||||||||||||
|
Definition at line 899 of file loadmsgcat.c. 00902 {
00903 int fd;
00904 size_t size;
00905 #ifdef _LIBC
00906 struct stat64 st;
00907 #else
00908 struct stat st;
00909 #endif
00910 struct mo_file_header *data = (struct mo_file_header *) -1;
00911 int use_mmap = 0;
00912 struct loaded_domain *domain;
00913 int revision;
00914 const char *nullentry;
00915
00916 domain_file->decided = 1;
00917 domain_file->data = NULL;
00918
00919 /* Note that it would be useless to store domainbinding in domain_file
00920 because domainbinding might be == NULL now but != NULL later (after
00921 a call to bind_textdomain_codeset). */
00922
00923 /* If the record does not represent a valid locale the FILENAME
00924 might be NULL. This can happen when according to the given
00925 specification the locale file name is different for XPG and CEN
00926 syntax. */
00927 if (domain_file->filename == NULL)
00928 return;
00929
00930 /* Try to open the addressed file. */
00931 fd = open (domain_file->filename, O_RDONLY | O_BINARY);
00932 if (fd == -1)
00933 return;
00934
00935 /* We must know about the size of the file. */
00936 if (
00937 #ifdef _LIBC
00938 __builtin_expect (fstat64 (fd, &st) != 0, 0)
00939 #else
00940 __builtin_expect (fstat (fd, &st) != 0, 0)
00941 #endif
00942 || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0)
00943 || __builtin_expect (size < sizeof (struct mo_file_header), 0))
00944 {
00945 /* Something went wrong. */
00946 close (fd);
00947 return;
00948 }
00949
00950 #ifdef HAVE_MMAP
00951 /* Now we are ready to load the file. If mmap() is available we try
00952 this first. If not available or it failed we try to load it. */
00953 data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
00954 MAP_PRIVATE, fd, 0);
00955
00956 if (__builtin_expect (data != (struct mo_file_header *) -1, 1))
00957 {
00958 /* mmap() call was successful. */
00959 close (fd);
00960 use_mmap = 1;
00961 }
00962 #endif
00963
00964 /* If the data is not yet available (i.e. mmap'ed) we try to load
00965 it manually. */
00966 if (data == (struct mo_file_header *) -1)
00967 {
00968 size_t to_read;
00969 char *read_ptr;
00970
00971 data = (struct mo_file_header *) malloc (size);
00972 if (data == NULL)
00973 return;
00974
00975 to_read = size;
00976 read_ptr = (char *) data;
00977 do
00978 {
00979 long int nb = (long int) read (fd, read_ptr, to_read);
00980 if (nb <= 0)
00981 {
00982 #ifdef EINTR
00983 if (nb == -1 && errno == EINTR)
00984 continue;
00985 #endif
00986 close (fd);
00987 return;
00988 }
00989 read_ptr += nb;
00990 to_read -= nb;
00991 }
00992 while (to_read > 0);
00993
00994 close (fd);
00995 }
00996
00997 /* Using the magic number we can test whether it really is a message
00998 catalog file. */
00999 if (__builtin_expect (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED,
01000 0))
01001 {
01002 /* The magic number is wrong: not a message catalog file. */
01003 #ifdef HAVE_MMAP
01004 if (use_mmap)
01005 munmap ((caddr_t) data, size);
01006 else
01007 #endif
01008 free (data);
01009 return;
01010 }
01011
01012 domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
01013 if (domain == NULL)
01014 return;
01015 domain_file->data = domain;
01016
01017 domain->data = (char *) data;
01018 domain->use_mmap = use_mmap;
01019 domain->mmap_size = size;
01020 domain->must_swap = data->magic != _MAGIC;
01021 domain->malloced = NULL;
01022
01023 /* Fill in the information about the available tables. */
01024 revision = W (domain->must_swap, data->revision);
01025 /* We support only the major revision 0. */
01026 switch (revision >> 16)
01027 {
01028 case 0:
01029 domain->nstrings = W (domain->must_swap, data->nstrings);
01030 domain->orig_tab = (const struct string_desc *)
01031 ((char *) data + W (domain->must_swap, data->orig_tab_offset));
01032 domain->trans_tab = (const struct string_desc *)
01033 ((char *) data + W (domain->must_swap, data->trans_tab_offset));
01034 domain->hash_size = W (domain->must_swap, data->hash_tab_size);
01035 domain->hash_tab =
01036 (domain->hash_size > 2
01037 ? (const nls_uint32 *)
01038 ((char *) data + W (domain->must_swap, data->hash_tab_offset))
01039 : NULL);
01040 domain->must_swap_hash_tab = domain->must_swap;
01041
01042 /* Now dispatch on the minor revision. */
01043 switch (revision & 0xffff)
01044 {
01045 case 0:
01046 domain->n_sysdep_strings = 0;
01047 domain->orig_sysdep_tab = NULL;
01048 domain->trans_sysdep_tab = NULL;
01049 break;
01050 case 1:
01051 default:
01052 {
01053 nls_uint32 n_sysdep_strings;
01054
01055 if (domain->hash_tab == NULL)
01056 /* This is invalid. These minor revisions need a hash table. */
01057 goto invalid;
01058
01059 n_sysdep_strings =
01060 W (domain->must_swap, data->n_sysdep_strings);
01061 if (n_sysdep_strings > 0)
01062 {
01063 nls_uint32 n_sysdep_segments;
01064 const struct sysdep_segment *sysdep_segments;
01065 const char **sysdep_segment_values;
01066 const nls_uint32 *orig_sysdep_tab;
01067 const nls_uint32 *trans_sysdep_tab;
01068 size_t memneed;
01069 char *mem;
01070 struct sysdep_string_desc *inmem_orig_sysdep_tab;
01071 struct sysdep_string_desc *inmem_trans_sysdep_tab;
01072 nls_uint32 *inmem_hash_tab;
01073 unsigned int i;
01074
01075 /* Get the values of the system dependent segments. */
01076 n_sysdep_segments =
01077 W (domain->must_swap, data->n_sysdep_segments);
01078 sysdep_segments = (const struct sysdep_segment *)
01079 ((char *) data
01080 + W (domain->must_swap, data->sysdep_segments_offset));
01081 sysdep_segment_values =
01082 alloca (n_sysdep_segments * sizeof (const char *));
01083 for (i = 0; i < n_sysdep_segments; i++)
01084 {
01085 const char *name =
01086 (char *) data
01087 + W (domain->must_swap, sysdep_segments[i].offset);
01088 nls_uint32 namelen =
01089 W (domain->must_swap, sysdep_segments[i].length);
01090
01091 if (!(namelen > 0 && name[namelen - 1] == '\0'))
01092 {
01093 freea (sysdep_segment_values);
01094 goto invalid;
01095 }
01096
01097 sysdep_segment_values[i] = get_sysdep_segment_value (name);
01098 }
01099
01100 orig_sysdep_tab = (const nls_uint32 *)
01101 ((char *) data
01102 + W (domain->must_swap, data->orig_sysdep_tab_offset));
01103 trans_sysdep_tab = (const nls_uint32 *)
01104 ((char *) data
01105 + W (domain->must_swap, data->trans_sysdep_tab_offset));
01106
01107 /* Compute the amount of additional memory needed for the
01108 system dependent strings and the augmented hash table. */
01109 memneed = 2 * n_sysdep_strings
01110 * sizeof (struct sysdep_string_desc)
01111 + domain->hash_size * sizeof (nls_uint32);
01112 for (i = 0; i < 2 * n_sysdep_strings; i++)
01113 {
01114 const struct sysdep_string *sysdep_string =
01115 (const struct sysdep_string *)
01116 ((char *) data
01117 + W (domain->must_swap,
01118 i < n_sysdep_strings
01119 ? orig_sysdep_tab[i]
01120 : trans_sysdep_tab[i - n_sysdep_strings]));
01121 size_t need = 0;
01122 const struct segment_pair *p = sysdep_string->segments;
01123
01124 if (W (domain->must_swap, p->sysdepref) != SEGMENTS_END)
01125 for (p = sysdep_string->segments;; p++)
01126 {
01127 nls_uint32 sysdepref;
01128
01129 need += W (domain->must_swap, p->segsize);
01130
01131 sysdepref = W (domain->must_swap, p->sysdepref);
01132 if (sysdepref == SEGMENTS_END)
01133 break;
01134
01135 if (sysdepref >= n_sysdep_segments)
01136 {
01137 /* Invalid. */
01138 freea (sysdep_segment_values);
01139 goto invalid;
01140 }
01141
01142 need += strlen (sysdep_segment_values[sysdepref]);
01143 }
01144
01145 memneed += need;
01146 }
01147
01148 /* Allocate additional memory. */
01149 mem = (char *) malloc (memneed);
01150 if (mem == NULL)
01151 goto invalid;
01152
01153 domain->malloced = mem;
01154 inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem;
01155 mem += n_sysdep_strings * sizeof (struct sysdep_string_desc);
01156 inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem;
01157 mem += n_sysdep_strings * sizeof (struct sysdep_string_desc);
01158 inmem_hash_tab = (nls_uint32 *) mem;
01159 mem += domain->hash_size * sizeof (nls_uint32);
01160
01161 /* Compute the system dependent strings. */
01162 for (i = 0; i < 2 * n_sysdep_strings; i++)
01163 {
01164 const struct sysdep_string *sysdep_string =
01165 (const struct sysdep_string *)
01166 ((char *) data
01167 + W (domain->must_swap,
01168 i < n_sysdep_strings
01169 ? orig_sysdep_tab[i]
01170 : trans_sysdep_tab[i - n_sysdep_strings]));
01171 const char *static_segments =
01172 (char *) data
01173 + W (domain->must_swap, sysdep_string->offset);
01174 const struct segment_pair *p = sysdep_string->segments;
01175
01176 /* Concatenate the segments, and fill
01177 inmem_orig_sysdep_tab[i] (for i < n_sysdep_strings) and
01178 inmem_trans_sysdep_tab[i-n_sysdep_strings] (for
01179 i >= n_sysdep_strings). */
01180
01181 if (W (domain->must_swap, p->sysdepref) == SEGMENTS_END)
01182 {
01183 /* Only one static segment. */
01184 inmem_orig_sysdep_tab[i].length =
01185 W (domain->must_swap, p->segsize);
01186 inmem_orig_sysdep_tab[i].pointer = static_segments;
01187 }
01188 else
01189 {
01190 inmem_orig_sysdep_tab[i].pointer = mem;
01191
01192 for (p = sysdep_string->segments;; p++)
01193 {
01194 nls_uint32 segsize =
01195 W (domain->must_swap, p->segsize);
01196 nls_uint32 sysdepref =
01197 W (domain->must_swap, p->sysdepref);
01198 size_t n;
01199
01200 if (segsize > 0)
01201 {
01202 memcpy (mem, static_segments, segsize);
01203 mem += segsize;
01204 static_segments += segsize;
01205 }
01206
01207 if (sysdepref == SEGMENTS_END)
01208 break;
01209
01210 n = strlen (sysdep_segment_values[sysdepref]);
01211 memcpy (mem, sysdep_segment_values[sysdepref], n);
01212 mem += n;
01213 }
01214
01215 inmem_orig_sysdep_tab[i].length =
01216 mem - inmem_orig_sysdep_tab[i].pointer;
01217 }
01218 }
01219
01220 /* Compute the augmented hash table. */
01221 for (i = 0; i < domain->hash_size; i++)
01222 inmem_hash_tab[i] =
01223 W (domain->must_swap_hash_tab, domain->hash_tab[i]);
01224 for (i = 0; i < n_sysdep_strings; i++)
01225 {
01226 const char *msgid = inmem_orig_sysdep_tab[i].pointer;
01227 nls_uint32 hash_val = hash_string (msgid);
01228 nls_uint32 idx = hash_val % domain->hash_size;
01229 nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
01230
01231 for (;;)
01232 {
01233 if (inmem_hash_tab[idx] == 0)
01234 {
01235 /* Hash table entry is empty. Use it. */
01236 inmem_hash_tab[idx] = 1 + domain->nstrings + i;
01237 break;
01238 }
01239
01240 if (idx >= domain->hash_size - incr)
01241 idx -= domain->hash_size - incr;
01242 else
01243 idx += incr;
01244 }
01245 }
01246
01247 freea (sysdep_segment_values);
01248
01249 domain->n_sysdep_strings = n_sysdep_strings;
01250 domain->orig_sysdep_tab = inmem_orig_sysdep_tab;
01251 domain->trans_sysdep_tab = inmem_trans_sysdep_tab;
01252
01253 domain->hash_tab = inmem_hash_tab;
01254 domain->must_swap_hash_tab = 0;
01255 }
01256 else
01257 {
01258 domain->n_sysdep_strings = 0;
01259 domain->orig_sysdep_tab = NULL;
01260 domain->trans_sysdep_tab = NULL;
01261 }
01262 }
01263 break;
01264 }
01265 break;
01266 default:
01267 /* This is an invalid revision. */
01268 invalid:
01269 /* This is an invalid .mo file. */
01270 if (domain->malloced)
01271 free (domain->malloced);
01272 #ifdef HAVE_MMAP
01273 if (use_mmap)
01274 munmap ((caddr_t) data, size);
01275 else
01276 #endif
01277 free (data);
01278 free (domain);
01279 domain_file->data = NULL;
01280 return;
01281 }
01282
01283 /* Now initialize the character set converter from the character set
01284 the file is encoded with (found in the header entry) to the domain's
01285 specified character set or the locale's character set. */
01286 nullentry = _nl_init_domain_conv (domain_file, domain, domainbinding);
01287
01288 /* Also look for a plural specification. */
01289 EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);
01290 }
|
|
|
|
|
|
Definition at line 501 of file loadmsgcat.c. 00503 {
00504 /* Test for an ISO C 99 section 7.8.1 format string directive.
00505 Syntax:
00506 P R I { d | i | o | u | x | X }
00507 { { | LEAST | FAST } { 8 | 16 | 32 | 64 } | MAX | PTR } */
00508 /* We don't use a table of 14 times 6 'const char *' strings here, because
00509 data relocations cost startup time. */
00510 if (name[0] == 'P' && name[1] == 'R' && name[2] == 'I')
00511 {
00512 if (name[3] == 'd' || name[3] == 'i' || name[3] == 'o' || name[3] == 'u'
00513 || name[3] == 'x' || name[3] == 'X')
00514 {
00515 if (name[4] == '8' && name[5] == '\0')
00516 {
00517 if (name[3] == 'd')
00518 return PRId8;
00519 if (name[3] == 'i')
00520 return PRIi8;
00521 if (name[3] == 'o')
00522 return PRIo8;
00523 if (name[3] == 'u')
00524 return PRIu8;
00525 if (name[3] == 'x')
00526 return PRIx8;
00527 if (name[3] == 'X')
00528 return PRIX8;
00529 abort ();
00530 }
00531 if (name[4] == '1' && name[5] == '6' && name[6] == '\0')
00532 {
00533 if (name[3] == 'd')
00534 return PRId16;
00535 if (name[3] == 'i')
00536 return PRIi16;
00537 if (name[3] == 'o')
00538 return PRIo16;
00539 if (name[3] == 'u')
00540 return PRIu16;
00541 if (name[3] == 'x')
00542 return PRIx16;
00543 if (name[3] == 'X')
00544 return PRIX16;
00545 abort ();
00546 }
00547 if (name[4] == '3' && name[5] == '2' && name[6] == '\0')
00548 {
00549 if (name[3] == 'd')
00550 return PRId32;
00551 if (name[3] == 'i')
00552 return PRIi32;
00553 if (name[3] == 'o')
00554 return PRIo32;
00555 if (name[3] == 'u')
00556 return PRIu32;
00557 if (name[3] == 'x')
00558 return PRIx32;
00559 if (name[3] == 'X')
00560 return PRIX32;
00561 abort ();
00562 }
00563 if (name[4] == '6' && name[5] == '4' && name[6] == '\0')
00564 {
00565 if (name[3] == 'd')
00566 return PRId64;
00567 if (name[3] == 'i')
00568 return PRIi64;
00569 if (name[3] == 'o')
00570 return PRIo64;
00571 if (name[3] == 'u')
00572 return PRIu64;
00573 if (name[3] == 'x')
00574 return PRIx64;
00575 if (name[3] == 'X')
00576 return PRIX64;
00577 abort ();
00578 }
00579 if (name[4] == 'L' && name[5] == 'E' && name[6] == 'A'
00580 && name[7] == 'S' && name[8] == 'T')
00581 {
00582 if (name[9] == '8' && name[10] == '\0')
00583 {
00584 if (name[3] == 'd')
00585 return PRIdLEAST8;
00586 if (name[3] == 'i')
00587 return PRIiLEAST8;
00588 if (name[3] == 'o')
00589 return PRIoLEAST8;
00590 if (name[3] == 'u')
00591 return PRIuLEAST8;
00592 if (name[3] == 'x')
00593 return PRIxLEAST8;
00594 if (name[3] == 'X')
00595 return PRIXLEAST8;
00596 abort ();
00597 }
00598 if (name[9] == '1' && name[10] == '6' && name[11] == '\0')
00599 {
00600 if (name[3] == 'd')
00601 return PRIdLEAST16;
00602 if (name[3] == 'i')
00603 return PRIiLEAST16;
00604 if (name[3] == 'o')
00605 return PRIoLEAST16;
00606 if (name[3] == 'u')
00607 return PRIuLEAST16;
00608 if (name[3] == 'x')
00609 return PRIxLEAST16;
00610 if (name[3] == 'X')
00611 return PRIXLEAST16;
00612 abort ();
00613 }
00614 if (name[9] == '3' && name[10] == '2' && name[11] == '\0')
00615 {
00616 if (name[3] == 'd')
00617 return PRIdLEAST32;
00618 if (name[3] == 'i')
00619 return PRIiLEAST32;
00620 if (name[3] == 'o')
00621 return PRIoLEAST32;
00622 if (name[3] == 'u')
00623 return PRIuLEAST32;
00624 if (name[3] == 'x')
00625 return PRIxLEAST32;
00626 if (name[3] == 'X')
00627 return PRIXLEAST32;
00628 abort ();
00629 }
00630 if (name[9] == '6' && name[10] == '4' && name[11] == '\0')
00631 {
00632 if (name[3] == 'd')
00633 return PRIdLEAST64;
00634 if (name[3] == 'i')
00635 return PRIiLEAST64;
00636 if (name[3] == 'o')
00637 return PRIoLEAST64;
00638 if (name[3] == 'u')
00639 return PRIuLEAST64;
00640 if (name[3] == 'x')
00641 return PRIxLEAST64;
00642 if (name[3] == 'X')
00643 return PRIXLEAST64;
00644 abort ();
00645 }
00646 }
00647 if (name[4] == 'F' && name[5] == 'A' && name[6] == 'S'
00648 && name[7] == 'T')
00649 {
00650 if (name[8] == '8' && name[9] == '\0')
00651 {
00652 if (name[3] == 'd')
00653 return PRIdFAST8;
00654 if (name[3] == 'i')
00655 return PRIiFAST8;
00656 if (name[3] == 'o')
00657 return PRIoFAST8;
00658 if (name[3] == 'u')
00659 return PRIuFAST8;
00660 if (name[3] == 'x')
00661 return PRIxFAST8;
00662 if (name[3] == 'X')
00663 return PRIXFAST8;
00664 abort ();
00665 }
00666 if (name[8] == '1' && name[9] == '6' && name[10] == '\0')
00667 {
00668 if (name[3] == 'd')
00669 return PRIdFAST16;
00670 if (name[3] == 'i')
00671 return PRIiFAST16;
00672 if (name[3] == 'o')
00673 return PRIoFAST16;
00674 if (name[3] == 'u')
00675 return PRIuFAST16;
00676 if (name[3] == 'x')
00677 return PRIxFAST16;
00678 if (name[3] == 'X')
00679 return PRIXFAST16;
00680 abort ();
00681 }
00682 if (name[8] == '3' && name[9] == '2' && name[10] == '\0')
00683 {
00684 if (name[3] == 'd')
00685 return PRIdFAST32;
00686 if (name[3] == 'i')
00687 return PRIiFAST32;
00688 if (name[3] == 'o')
00689 return PRIoFAST32;
00690 if (name[3] == 'u')
00691 return PRIuFAST32;
00692 if (name[3] == 'x')
00693 return PRIxFAST32;
00694 if (name[3] == 'X')
00695 return PRIXFAST32;
00696 abort ();
00697 }
00698 if (name[8] == '6' && name[9] == '4' && name[10] == '\0')
00699 {
00700 if (name[3] == 'd')
00701 return PRIdFAST64;
00702 if (name[3] == 'i')
00703 return PRIiFAST64;
00704 if (name[3] == 'o')
00705 return PRIoFAST64;
00706 if (name[3] == 'u')
00707 return PRIuFAST64;
00708 if (name[3] == 'x')
00709 return PRIxFAST64;
00710 if (name[3] == 'X')
00711 return PRIXFAST64;
00712 abort ();
00713 }
00714 }
00715 if (name[4] == 'M' && name[5] == 'A' && name[6] == 'X'
00716 && name[7] == '\0')
00717 {
00718 if (name[3] == 'd')
00719 return PRIdMAX;
00720 if (name[3] == 'i')
00721 return PRIiMAX;
00722 if (name[3] == 'o')
00723 return PRIoMAX;
00724 if (name[3] == 'u')
00725 return PRIuMAX;
00726 if (name[3] == 'x')
00727 return PRIxMAX;
00728 if (name[3] == 'X')
00729 return PRIXMAX;
00730 abort ();
00731 }
00732 if (name[4] == 'P' && name[5] == 'T' && name[6] == 'R'
00733 && name[7] == '\0')
00734 {
00735 if (name[3] == 'd')
00736 return PRIdPTR;
00737 if (name[3] == 'i')
00738 return PRIiPTR;
00739 if (name[3] == 'o')
00740 return PRIoPTR;
00741 if (name[3] == 'u')
00742 return PRIuPTR;
00743 if (name[3] == 'x')
00744 return PRIxPTR;
00745 if (name[3] == 'X')
00746 return PRIXPTR;
00747 abort ();
00748 }
00749 }
00750 }
00751 /* Other system dependent strings are not valid. */
00752 return NULL;
00753 }
|
|
|
|
|
|
Definition at line 496 of file loadmsgcat.c. |
1.3.9.1