Fri May 3 03:14:02 1996 Ulrich Drepper <drepper@cygnus.com>
authorroland <roland>
Fri, 3 May 1996 17:42:52 +0000 (17:42 +0000)
committerroland <roland>
Fri, 3 May 1996 17:42:52 +0000 (17:42 +0000)
* intl/dcgettext.c, intl/finddomain.c, intl/gettextP.h,
intl/loadmsgcat.c: Adapt for upcoming gettext-0.10.13.  Some code
is now shared with the locale implementation.

intl/dcgettext.c
intl/finddomain.c
intl/gettextP.h
intl/loadmsgcat.c

index 7d739d3..6c8963f 100644 (file)
@@ -1,8 +1,6 @@
 /* dcgettext.c -- implementation of the dcgettext(3) function
-   Copyright (C) 1995 Free Software Foundation, Inc.
-
-This file is part of the GNU C Library.  Its master source is NOT part of
-the C library, however.  The master source lives in /gd/gnu/lib.
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
 The GNU C Library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public License as
@@ -16,8 +14,8 @@ Library General Public License for more details.
 
 You should have received a copy of the GNU Library General Public
 License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -155,7 +153,7 @@ const char _nl_default_dirname[] = GNULOCALEDIR;
 struct binding *_nl_domain_bindings;
 
 /* Prototypes for local functions.  */
-static char *find_msg PARAMS ((struct loaded_domain *domain,
+static char *find_msg PARAMS ((struct loaded_l10nfile *domain_file,
                               const char *msgid));
 static const char *category_to_name PARAMS ((int category));
 static const char *guess_category_value PARAMS ((int category,
@@ -180,7 +178,7 @@ DCGETTEXT (domainname, msgid, category)
      const char *msgid;
      int category;
 {
-  struct loaded_domain *domain;
+  struct loaded_l10nfile *domain;
   struct binding *binding;
   const char *categoryname;
   const char *categoryvalue;
@@ -355,18 +353,21 @@ weak_alias (__dcgettext, dcgettext);
 
 
 static char *
-find_msg (domain, msgid)
-     struct loaded_domain *domain;
+find_msg (domain_file, msgid)
+     struct loaded_l10nfile *domain_file;
      const char *msgid;
 {
   size_t top, act, bottom;
+  struct loaded_domain *domain;
 
-  if (domain->decided == 0)
-    _nl_load_domain (domain);
+  if (domain_file->decided == 0)
+    _nl_load_domain (domain_file);
 
-  if (domain->data == NULL)
+  if (domain_file->data == NULL)
     return NULL;
 
+  domain = (struct loaded_domain *) domain_file->data;
+
   /* Locate the MSGID and its translation.  */
   if (domain->hash_size > 2 && domain->hash_tab != NULL)
     {
@@ -439,7 +440,8 @@ find_msg (domain, msgid)
 
 
 /* Return string representation of locale CATEGORY.  */
-static const char *category_to_name (category)
+static const char *
+category_to_name (category)
      int category;
 {
   const char *retval;
index 3ced26f..bb4609e 100644 (file)
@@ -1,9 +1,6 @@
 /* finddomain.c -- handle list of needed message catalogs
-   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-   Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
-
-This file is part of the GNU C Library.  Its master source is NOT part of
-the C library, however.  The master source lives in /gd/gnu/lib.
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
 The GNU C Library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public License as
@@ -17,8 +14,8 @@ Library General Public License for more details.
 
 You should have received a copy of the GNU Library General Public
 License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -71,39 +68,8 @@ void free ();
 # define stpcpy(dest, src) __stpcpy(dest, src)
 #endif
 
-/* Encoding of locale name parts.  */
-#define CEN_REVISION           1
-#define CEN_SPONSOR            2
-#define CEN_SPECIAL            4
-#define XPG_NORM_CODESET       8
-#define XPG_CODESET            16
-#define TERRITORY              32
-#define CEN_AUDIENCE           64
-#define XPG_MODIFIER           128
-
-#define CEN_SPECIFIC   (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE)
-#define XPG_SPECIFIC   (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER)
-
-
 /* List of already loaded domains.  */
-static struct loaded_domain *_nl_loaded_domains;
-
-/* Prototypes for local functions.  */
-static struct loaded_domain *make_entry_rec PARAMS ((const char *dirname,
-                                                    int mask,
-                                                    const char *language,
-                                                    const char *territory,
-                                                    const char *codeset,
-                                                    const char *normalized_codeset,
-                                                    const char *modifier,
-                                                    const char *special,
-                                                    const char *sponsor,
-                                                    const char *revision,
-                                                    const char *domainname,
-                                                    int do_allocate));
-
-/* Normalize name of selected codeset.  */
-static const char *normalize_codeset PARAMS ((const char *codeset));
+static struct loaded_l10nfile *_nl_loaded_domains;
 
 /* Substitution for systems lacking this function in their C library.  */
 #if !_LIBC && !HAVE_STPCPY
@@ -115,29 +81,25 @@ static char *stpcpy__ PARAMS ((char *dest, const char *src));
 /* Return a data structure describing the message catalog described by
    the DOMAINNAME and CATEGORY parameters with respect to the currently
    established bindings.  */
-struct loaded_domain *
+struct loaded_l10nfile *
 _nl_find_domain (dirname, locale, domainname)
      const char *dirname;
      char *locale;
      const char *domainname;
 {
-  enum { undecided, xpg, cen } syntax;
-  struct loaded_domain *retval;
+  struct loaded_l10nfile *retval;
   const char *language;
-  const char *modifier = NULL;
-  const char *territory = NULL;
-  const char *codeset = NULL;
-  const char *normalized_codeset = NULL;
-  const char *special = NULL;
-  const char *sponsor = NULL;
-  const char *revision = NULL;
-  const char *alias_value = NULL;
-  char *cp;
+  const char *modifier;
+  const char *territory;
+  const char *codeset;
+  const char *normalized_codeset;
+  const char *special;
+  const char *sponsor;
+  const char *revision;
+  const char *alias_value;
   int mask;
 
-  /* CATEGORYVALUE now possibly contains a colon separated list of
-     locales.  Each single locale can consist of up to four recognized
-     parts for the XPG syntax:
+  /* LOCALE can consist of up to four recognized parts for the XPG syntax:
 
                language[_territory[.codeset]][@modifier]
 
@@ -160,15 +122,16 @@ _nl_find_domain (dirname, locale, domainname)
 
   /* If we have already tested for this locale entry there has to
      be one data set in the list of loaded domains.  */
-  retval = make_entry_rec (dirname, 0, locale, NULL, NULL, NULL, NULL,
-                          NULL, NULL, NULL, domainname, 0);
+  retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
+                              strlen (dirname) + 1, 0, locale, NULL, NULL,
+                              NULL, NULL, NULL, NULL, NULL, domainname, 0);
   if (retval != NULL)
     {
       /* We know something about this locale.  */
       int cnt;
 
       if (retval->decided == 0)
-       _nl_load_domain (retval); /* @@@ */
+       _nl_load_domain (retval);
 
       if (retval->data != NULL)
        return retval;
@@ -181,8 +144,6 @@ _nl_find_domain (dirname, locale, domainname)
          if (retval->successor[cnt]->data != NULL)
            break;
        }
-
-      /* We really found some usable information.  */
       return cnt >= 0 ? retval : NULL;
       /* NOTREACHED */
     }
@@ -204,123 +165,16 @@ _nl_find_domain (dirname, locale, domainname)
   /* Now we determine the single parts of the locale name.  First
      look for the language.  Termination symbols are `_' and `@' if
      we use XPG4 style, and `_', `+', and `,' if we use CEN syntax.  */
-  mask = 0;
-  syntax = undecided;
-  language = cp = locale;
-  while (cp[0] != '\0' && cp[0] != '_' && cp[0] != '@'
-        && cp[0] != '+' && cp[0] != ',')
-    ++cp;
-
-  if (language == cp)
-    /* This does not make sense: language has to be specified.  Use
-       this entry as it is without exploding.  Perhaps it is an alias.  */
-    cp = strchr (language, '\0');
-  else if (cp[0] == '_')
-    {
-      /* Next is the territory.  */
-      cp[0] = '\0';
-      territory = ++cp;
-
-      while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@'
-            && cp[0] != '+' && cp[0] != ',' && cp[0] != '_')
-       ++cp;
-
-      mask |= TERRITORY;
-
-      if (cp[0] == '.')
-       {
-         /* Next is the codeset.  */
-         syntax = xpg;
-         cp[0] = '\0';
-         codeset = ++cp;
-
-         while (cp[0] != '\0' && cp[0] != '@')
-           ++cp;
-
-         mask |= XPG_CODESET;
-
-         if (codeset != cp && codeset[0] != '\0')
-           {
-             normalized_codeset = normalize_codeset (codeset);
-             if (strcmp (codeset, normalized_codeset) == 0)
-               free ((char *) normalized_codeset);
-             else
-               mask |= XPG_NORM_CODESET;
-           }
-       }
-    }
-
-  if (cp[0] == '@' || (syntax != xpg && cp[0] == '+'))
-    {
-      /* Next is the modifier.  */
-      syntax = cp[0] == '@' ? xpg : cen;
-      cp[0] = '\0';
-      modifier = ++cp;
-
-      while (syntax == cen && cp[0] != '\0' && cp[0] != '+'
-            && cp[0] != ',' && cp[0] != '_')
-       ++cp;
-
-      mask |= XPG_MODIFIER | CEN_AUDIENCE;
-    }
-
-  if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_'))
-    {
-      syntax = cen;
-
-      if (cp[0] == '+')
-       {
-         /* Next is special application (CEN syntax).  */
-         cp[0] = '\0';
-         special = ++cp;
-
-         while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_')
-           ++cp;
-
-         mask |= CEN_SPECIAL;
-       }
-
-      if (cp[0] == ',')
-       {
-         /* Next is sponsor (CEN syntax).  */
-         cp[0] = '\0';
-         sponsor = ++cp;
-
-         while (cp[0] != '\0' && cp[0] != '_')
-           ++cp;
-
-         mask |= CEN_SPONSOR;
-       }
-
-      if (cp[0] == '_')
-       {
-         /* Next is revision (CEN syntax).  */
-         cp[0] = '\0';
-         revision = ++cp;
-
-         mask |= CEN_REVISION;
-       }
-    }
-
-  /* For CEN sytnax values it might be important to have the
-     separator character in the file name, not for XPG syntax.  */
-  if (syntax == xpg)
-    {
-      if (territory != NULL && territory[0] == '\0')
-       mask &= ~TERRITORY;
-
-      if (codeset != NULL && codeset[0] == '\0')
-       mask &= ~XPG_CODESET;
-
-      if (modifier != NULL && modifier[0] == '\0')
-       mask &= ~XPG_MODIFIER;
-    }
+  mask = _nl_explode_name (locale, &language, &modifier, &territory,
+                          &codeset, &normalized_codeset, &special,
+                          &sponsor, &revision);
 
   /* Create all possible locale entries which might be interested in
      generalzation.  */
-  retval = make_entry_rec (dirname, mask, language, territory, codeset,
-                          normalized_codeset, modifier, special, sponsor,
-                          revision, domainname, 1);
+  retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
+                              strlen (dirname) + 1, mask, language, territory,
+                              codeset, normalized_codeset, modifier, special,
+                              sponsor, revision, domainname, 1);
   if (retval == NULL)
     /* This means we are out of core.  */
     return NULL;
@@ -336,12 +190,7 @@ _nl_find_domain (dirname, locale, domainname)
            _nl_load_domain (retval->successor[cnt]);
          if (retval->successor[cnt]->data != NULL)
            break;
-
-         /* Signal that locale is not available.  */
-         retval->successor[cnt] = NULL;
        }
-      if (retval->successor[cnt] == NULL)
-       retval = NULL;
     }
 
   /* The room for an alias was dynamically allocated.  Free it now.  */
@@ -351,215 +200,6 @@ _nl_find_domain (dirname, locale, domainname)
   return retval;
 }
 
-
-static struct loaded_domain *
-make_entry_rec (dirname, mask, language, territory, codeset,
-               normalized_codeset, modifier, special, sponsor, revision,
-               domain, do_allocate)
-     const char *dirname;
-     int mask;
-     const char *language;
-     const char *territory;
-     const char *codeset;
-     const char *normalized_codeset;
-     const char *modifier;
-     const char *special;
-     const char *sponsor;
-     const char *revision;
-     const char *domain;
-     int do_allocate;
-{
-  char *filename = NULL;
-  struct loaded_domain *last = NULL;
-  struct loaded_domain *retval;
-  char *cp;
-  size_t entries;
-  int cnt;
-
-
-  /* Process the current entry described by the MASK only when it is
-     valid.  Because the mask can have in the first call bits from
-     both syntaces set this is necessary to prevent constructing
-     illegal local names.  */
-  /* FIXME: Rewrite because test is necessary only in first round.  */
-  if ((mask & CEN_SPECIFIC) == 0 || (mask & XPG_SPECIFIC) == 0
-      || ((mask & XPG_CODESET) != 0 && (mask & XPG_NORM_CODESET) != 0))
-    {
-      /* Allocate room for the full file name.  */
-      filename = (char *) malloc (strlen (dirname) + 1
-                                 + strlen (language)
-                                 + ((mask & TERRITORY) != 0
-                                    ? strlen (territory) + 1 : 0)
-                                 + ((mask & XPG_CODESET) != 0
-                                    ? strlen (codeset) + 1 : 0)
-                                 + ((mask & XPG_NORM_CODESET) != 0
-                                    ? strlen (normalized_codeset) + 1 : 0)
-                                 + ((mask & XPG_MODIFIER) != 0 ?
-                                    strlen (modifier) + 1 : 0)
-                                 + ((mask & CEN_SPECIAL) != 0
-                                    ? strlen (special) + 1 : 0)
-                                 + ((mask & CEN_SPONSOR) != 0
-                                    ? strlen (sponsor) + 1 : 0)
-                                 + ((mask & CEN_REVISION) != 0
-                                    ? strlen (revision) + 1 : 0) + 1
-                                 + strlen (domain) + 1);
-
-      if (filename == NULL)
-       return NULL;
-
-      retval = NULL;
-      last = NULL;
-
-      /* Construct file name.  */
-      cp = stpcpy (filename, dirname);
-      *cp++ = '/';
-      cp = stpcpy (cp, language);
-
-      if ((mask & TERRITORY) != 0)
-       {
-         *cp++ = '_';
-         cp = stpcpy (cp, territory);
-       }
-      if ((mask & XPG_CODESET) != 0)
-       {
-         *cp++ = '.';
-         cp = stpcpy (cp, codeset);
-       }
-      if ((mask & XPG_NORM_CODESET) != 0)
-       {
-         *cp++ = '.';
-         cp = stpcpy (cp, normalized_codeset);
-       }
-      if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
-       {
-         /* This component can be part of both syntaces but has different
-            leading characters.  For CEN we use `+', else `@'.  */
-         *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
-         cp = stpcpy (cp, modifier);
-       }
-      if ((mask & CEN_SPECIAL) != 0)
-       {
-         *cp++ = '+';
-         cp = stpcpy (cp, special);
-       }
-      if ((mask & CEN_SPONSOR) != 0)
-       {
-         *cp++ = ',';
-         cp = stpcpy (cp, sponsor);
-       }
-      if ((mask & CEN_REVISION) != 0)
-       {
-         *cp++ = '_';
-         cp = stpcpy (cp, revision);
-       }
-
-      *cp++ = '/';
-      stpcpy (cp, domain);
-
-      /* Look in list of already loaded domains whether it is already
-        available.  */
-      last = NULL;
-      for (retval = _nl_loaded_domains; retval != NULL; retval = retval->next)
-       if (retval->filename != NULL)
-         {
-           int compare = strcmp (retval->filename, filename);
-           if (compare == 0)
-             /* We found it!  */
-             break;
-           if (compare < 0)
-             {
-               /* It's not in the list.  */
-               retval = NULL;
-               break;
-             }
-
-           last = retval;
-         }
-
-      if (retval != NULL || do_allocate == 0)
-       {
-         free (filename);
-         return retval;
-       }
-    }
-
-  retval = (struct loaded_domain *) malloc (sizeof (*retval));
-  if (retval == NULL)
-    return NULL;
-
-  retval->filename = filename;
-  retval->decided = 0;
-
-  if (last == NULL)
-    {
-      retval->next = _nl_loaded_domains;
-      _nl_loaded_domains = retval;
-    }
-  else
-    {
-      retval->next = last->next;
-      last->next = retval;
-    }
-
-  entries = 0;
-  for (cnt = 254; cnt >= 0; --cnt)
-    if (cnt < mask && (cnt & ~mask) == 0
-       && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
-       && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
-      retval->successor[entries++] = make_entry_rec (dirname, cnt,
-                                                    language, territory,
-                                                    codeset,
-                                                    normalized_codeset,
-                                                    modifier, special,
-                                                    sponsor, revision,
-                                                    domain, 1);
-  retval->successor[entries] = NULL;
-
-  return retval;
-}
-
-
-static const char *
-normalize_codeset (codeset)
-     const char *codeset;
-{
-  int len = 0;
-  int only_digit = 1;
-  const char *cp;
-  char *retval;
-  char *wp;
-
-  for (cp = codeset; cp[0] != '\0'; ++cp)
-    if (isalnum (cp[0]))
-      {
-       ++len;
-
-       if (isalpha (cp[0]))
-         only_digit = 0;
-      }
-
-  retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1);
-
-  if (retval != NULL)
-    {
-      if (only_digit)
-       wp = stpcpy (retval, "ISO");
-      else
-       wp = retval;
-
-      for (cp = codeset; cp[0] != '\0'; ++cp)
-       if (isalpha (cp[0]))
-         *wp++ = toupper (cp[0]);
-       else if (isdigit (cp[0]))
-         *wp++ = cp[0];
-
-      *wp = '\0';
-    }
-
-  return (const char *) retval;
-}
-
-
 /* @@ begin of epilog @@ */
 
 /* We don't want libintl.a to depend on any other library.  So we
index 34196a0..c37adab 100644 (file)
@@ -1,8 +1,6 @@
 /* gettextP.h -- header describing internals of gettext library
-   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
-This file is part of the GNU C Library.  Its master source is NOT part of
-the C library, however.  The master source lives in /gd/gnu/lib.
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
 The GNU C Library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public License as
@@ -16,12 +14,14 @@ Library General Public License for more details.
 
 You should have received a copy of the GNU Library General Public
 License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 #ifndef _GETTEXTP_H
 #define _GETTEXTP_H
 
+#include "loadinfo.h"
+
 /* @@ end of prolog @@ */
 
 #ifndef PARAMS
@@ -49,12 +49,6 @@ SWAP (i)
 
 struct loaded_domain
 {
-  struct loaded_domain *next;
-  struct loaded_domain *successor[63];
-
-  const char *filename;
-  int decided;
-
   const char *data;
   int must_swap;
   nls_uint32 nstrings;
@@ -71,12 +65,10 @@ struct binding
   char *dirname;
 };
 
-struct loaded_domain *_nl_find_domain PARAMS ((const char *__dirname,
-                                              char *__locale,
-                                              const char *__domainname));
-void _nl_load_domain PARAMS ((struct loaded_domain *__domain));
-
-const char *_nl_expand_alias PARAMS ((const char *__name));
+struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname,
+                                                char *__locale,
+                                                const char *__domainname));
+void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain));
 
 /* @@ begin of epilog @@ */
 
index 0f5bfd5..1daf72a 100644 (file)
@@ -1,8 +1,6 @@
 /* loadmsgcat.c -- load needed message catalogs
-   Copyright (C) 1995 Software Foundation, Inc.
-
-This file is part of the GNU C Library.  Its master source is NOT part of
-the C library, however.  The master source lives in /gd/gnu/lib.
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
 The GNU C Library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public License as
@@ -16,8 +14,8 @@ Library General Public License for more details.
 
 You should have received a copy of the GNU Library General Public
 License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -65,8 +63,8 @@ int _nl_msg_cat_cntr;
 /* Load the message catalogs specified by FILENAME.  If it is no valid
    message catalog do nothing.  */
 void
-_nl_load_domain (domain)
-     struct loaded_domain *domain;
+_nl_load_domain (domain_file)
+     struct loaded_l10nfile *domain_file;
 {
   int fd;
   struct stat st;
@@ -75,19 +73,20 @@ _nl_load_domain (domain)
     || defined _LIBC
   int use_mmap = 0;
 #endif
+  struct loaded_domain *domain;
 
-  domain->decided = 1;
-  domain->data = NULL;
+  domain_file->decided = 1;
+  domain_file->data = NULL;
 
   /* If the record does not represent a valid locale the FILENAME
      might be NULL.  This can happen when according to the given
      specification the locale file name is different for XPG and CEN
      syntax.  */
-  if (domain->filename == NULL)
+  if (domain_file->filename == NULL)
     return;
 
   /* Try to open the addressed file.  */
-  fd = open (domain->filename, O_RDONLY);
+  fd = open (domain_file->filename, O_RDONLY);
   if (fd == -1)
     return;
 
@@ -160,6 +159,12 @@ _nl_load_domain (domain)
       return;
     }
 
+  domain_file->data
+    = (struct loaded_domain *) malloc (sizeof (struct loaded_domain *));
+  if (domain->data == NULL)
+    return;
+
+  domain = (struct loaded_domain *) domain_file->data;
   domain->data = (char *) data;
   domain->must_swap = data->magic != _MAGIC;
 
@@ -185,11 +190,12 @@ _nl_load_domain (domain)
       else
 #endif
        free (data);
-      domain->data = NULL;
+      free (domain);
+      domain_file->data = NULL;
       return;
     }
 
   /* Show that one domain is changed.  This might make some cached
-     translation invalid.  */
+     translations invalid.  */
   ++_nl_msg_cat_cntr;
 }