Import GNU gettext 0.10.35
diff --git a/intl/ChangeLog b/intl/ChangeLog
index ecff6f6..1989501 100644
--- a/intl/ChangeLog
+++ b/intl/ChangeLog
@@ -1,3 +1,67 @@
+1998-04-29  Ulrich Drepper  <drepper@cygnus.com>
+
+	* intl/localealias.c (read_alias_file): Use unsigned char for
+	local variables.  Remove unused variable tp.
+	* intl/l10nflist.c (_nl_normalize_codeset): Use unsigned char *
+	for type of codeset.  For loosing Solaris systems.
+	* intl/loadinfo.h: Adapt prototype of _nl_normalize_codeset.
+	* intl/bindtextdom.c (BINDTEXTDOMAIN): Don't define local variable
+	len if not needed.
+	Patches by Jim Meyering.
+
+1998-04-28  Ulrich Drepper  <drepper@cygnus.com>
+
+	* loadmsgcat.c (_nl_load_domain): Don't assign the element use_mmap if
+	mmap is not supported.
+
+	* hash-string.h: Don't include <values.h>.
+
+1998-04-27  Ulrich Drepper  <drepper@cygnus.com>
+
+	* textdomain.c: Use strdup is available.
+
+	* localealias.c: Define HAVE_MEMPCPY so that we can use this
+	function.  Define and use semapahores to protect modfication of
+	global objects when compiling for glibc.  Add code to allow
+	freeing alias table.
+
+	* l10nflist.c: Don't assume stpcpy not being a macro.
+
+	* gettextP.h: Define internal_function macri if not already done.
+	Use glibc byte-swap macros instead of defining SWAP when compiled
+	for glibc.
+	(struct loaded_domain): Add elements to allow unloading.
+
+	* Makefile.in (distclean): Don't remove libintl.h here.
+
+	* bindtextdomain.c: Carry over changes from glibc.  Use strdup if
+	available.
+
+	* dcgettext.c: Don't assume stpcpy not being a macro.  Mark internal
+	functions.  Add memory freeing code for glibc.
+
+	* dgettext.c: Update copyright.
+
+	* explodename.c: Include stdlib.h and string.h only if they exist.
+	Use strings.h eventually.
+
+	* finddomain.c: Mark internal functions.  Use strdup if available.
+	Add memory freeing code for glibc.
+
+1997-10-10 20:00  Ulrich Drepper  <drepper@cygnus.com>
+
+	* libgettext.h: Fix dummy textdomain and bindtextdomain macros.
+	They should return reasonable values.
+	Reported by Tom Tromey <tromey@cygnus.com>.
+
+1997-09-16 03:33  Ulrich Drepper  <drepper@cygnus.com>
+
+	* libgettext.h: Define PARAMS also to `args' if __cplusplus is defined.
+	* intlh.inst.in: Likewise.
+	Reported by Jean-Marc Lasgouttes <Jean-Marc.Lasgouttes@inria.fr>.
+
+	* libintl.glibc: Update from current glibc version.
+
 1997-09-06 02:10  Ulrich Drepper  <drepper@cygnus.com>
 
 	* intlh.inst.in: Reformat copyright.
diff --git a/intl/Makefile.in b/intl/Makefile.in
index 09647de..4bdb186 100644
--- a/intl/Makefile.in
+++ b/intl/Makefile.in
@@ -1,5 +1,5 @@
 # Makefile for directory with message catalog handling in GNU NLS Utilities.
-# Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -79,13 +79,12 @@
 .c.lo:
 	$(LIBTOOL) --mode=compile $(COMPILE) $<
 
-INCLUDES = -I. -I$(srcdir)
+INCLUDES = -I.. -I. -I$(top_srcdir)/intl -I$(top_srcdir)/lib
 
 all: all-@USE_INCLUDED_LIBINTL@
 
 all-yes: libintl.$la intlh.inst
 all-no:
-install-info:
 
 libintl.a: $(OBJECTS)
 	rm -f $@
@@ -151,7 +150,7 @@
 
 info dvi:
 
-$(OBJECTS): config.h libgettext.h
+$(OBJECTS): ../config.h libgettext.h
 bindtextdom.$lo finddomain.$lo loadmsgcat.$lo: gettextP.h gettext.h loadinfo.h
 dcgettext.$lo: gettextP.h gettext.h hash-string.h loadinfo.h
 
@@ -172,7 +171,7 @@
 clean: mostlyclean
 
 distclean: clean
-	rm -f Makefile ID TAGS po2msg.sed po2tbl.sed libintl.h config.log
+	rm -f Makefile ID TAGS po2msg.sed po2tbl.sed
 
 maintainer-clean: distclean
 	@echo "This command is intended for maintainers to use;"
@@ -196,8 +195,9 @@
 dist-libc:
 	tar zcvf intl-glibc.tar.gz $(COMSRCS) $(COMHDRS) libintl.h.glibc
 
-Makefile: Makefile.in config.status
-	CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+Makefile: Makefile.in ../config.status
+	cd .. \
+	  && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
 # The dependency for intlh.inst is different in gettext and all other
 # packages.  Because we cannot you GNU make features we have to solve
diff --git a/intl/bindtextdom.c b/intl/bindtextdom.c
index 9fcb8d9..d9c3f34 100644
--- a/intl/bindtextdom.c
+++ b/intl/bindtextdom.c
@@ -1,5 +1,5 @@
 /* Implementation of the bindtextdomain(3) function
-   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -61,7 +61,9 @@
    prefix.  So we have to make a difference here.  */
 #ifdef _LIBC
 # define BINDTEXTDOMAIN __bindtextdomain
-# define strdup(str) __strdup (str)
+# ifndef strdup
+#  define strdup(str) __strdup (str)
+# endif
 #else
 # define BINDTEXTDOMAIN bindtextdomain__
 #endif
@@ -133,7 +135,9 @@
   else
     {
       /* We have to create a new binding.  */
+#if !defined _LIBC && !defined HAVE_STRDUP
       size_t len;
+#endif
       struct binding *new_binding =
 	(struct binding *) malloc (sizeof (*new_binding));
 
diff --git a/intl/dcgettext.c b/intl/dcgettext.c
index a316bfd..c4c7a2c 100644
--- a/intl/dcgettext.c
+++ b/intl/dcgettext.c
@@ -1,5 +1,5 @@
-/* Implementation of the dcgettext(3) function
-   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Implementation of the dcgettext(3) function.
+   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -91,7 +91,9 @@
    because some ANSI C functions will require linking with this object
    file and the name space must not be polluted.  */
 # define getcwd __getcwd
-# define stpcpy __stpcpy
+# ifndef stpcpy
+#  define stpcpy __stpcpy
+# endif
 #else
 # if !defined HAVE_GETCWD
 char *getwd ();
@@ -162,10 +164,11 @@
 
 /* Prototypes for local functions.  */
 static char *find_msg PARAMS ((struct loaded_l10nfile *domain_file,
-			       const char *msgid));
-static const char *category_to_name PARAMS ((int category));
+			       const char *msgid)) internal_function;
+static const char *category_to_name PARAMS ((int category)) internal_function;
 static const char *guess_category_value PARAMS ((int category,
-						 const char *categoryname));
+						 const char *categoryname))
+     internal_function;
 
 
 /* For those loosing systems which don't have `alloca' we have to add
@@ -388,6 +391,7 @@
 
 
 static char *
+internal_function
 find_msg (domain_file, msgid)
      struct loaded_l10nfile *domain_file;
      const char *msgid;
@@ -476,6 +480,7 @@
 
 /* Return string representation of locale CATEGORY.  */
 static const char *
+internal_function
 category_to_name (category)
      int category;
 {
@@ -535,6 +540,7 @@
 
 /* Guess value of current locale from value of the environment variables.  */
 static const char *
+internal_function
 guess_category_value (category, categoryname)
      int category;
      const char *categoryname;
@@ -591,3 +597,28 @@
   return dest - 1;
 }
 #endif
+
+
+#ifdef _LIBC
+/* If we want to free all resources we have to do some work at
+   program's end.  */
+static void __attribute__ ((unused))
+free_mem (void)
+{
+  struct binding *runp;
+
+  for (runp = _nl_domain_bindings; runp != NULL; runp = runp->next)
+    {
+      free (runp->domainname);
+      if (runp->dirname != _nl_default_dirname)
+	/* Yes, this is a pointer comparison.  */
+	free (runp->dirname);
+    }
+
+  if (_nl_current_default_domain != _nl_default_default_domain)
+    /* Yes, again a pointer comparison.  */
+    free ((char *) _nl_current_default_domain);
+}
+
+text_set_element (__libc_subfreeres, free_mem);
+#endif
diff --git a/intl/dgettext.c b/intl/dgettext.c
index 2fde677..0510c2b 100644
--- a/intl/dgettext.c
+++ b/intl/dgettext.c
@@ -1,19 +1,19 @@
-/* dgettext.c -- implementation of the dgettext(3) function
-   Copyright (C) 1995 Software Foundation, Inc.
+/* Implementation of the dgettext(3) function
+   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program; if 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>
diff --git a/intl/explodename.c b/intl/explodename.c
index 37c46e9..8066dc2 100644
--- a/intl/explodename.c
+++ b/intl/explodename.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
    Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
    This program is free software; you can redistribute it and/or modify
@@ -19,8 +19,15 @@
 # include <config.h>
 #endif
 
-#include <stdlib.h>
-#include <string.h>
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#endif
+
+#if defined HAVE_STRING_H || defined _LIBC
+# include <string.h>
+#else
+# include <strings.h>
+#endif
 #include <sys/types.h>
 
 #include "loadinfo.h"
diff --git a/intl/finddomain.c b/intl/finddomain.c
index ec85d4d..81ea29b 100644
--- a/intl/finddomain.c
+++ b/intl/finddomain.c
@@ -1,5 +1,5 @@
 /* Handle list of needed message catalogs
-   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
    Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
    This program is free software; you can redistribute it and/or modify
@@ -70,6 +70,7 @@
    the DOMAINNAME and CATEGORY parameters with respect to the currently
    established bindings.  */
 struct loaded_l10nfile *
+internal_function
 _nl_find_domain (dirname, locale, domainname)
      const char *dirname;
      char *locale;
@@ -95,9 +96,9 @@
 
 	language[_territory][+audience][+special][,[sponsor][_revision]]
 
-     Beside the first all of them are allowed to be missing.  If the
-     full specified locale is not found, the less specific one are
-     looked for.  The various part will be stripped of according to
+     Beside the first part all of them are allowed to be missing.  If
+     the full specified locale is not found, the less specific one are
+     looked for.  The various parts will be stripped off according to
      the following order:
 		(1) revision
 		(2) sponsor
@@ -142,12 +143,18 @@
   alias_value = _nl_expand_alias (locale);
   if (alias_value != NULL)
     {
+#if defined _LIBC || defined HAVE_STRDUP
+      locale = strdup (alias_value);
+      if (locale == NULL)
+	return NULL;
+#else
       size_t len = strlen (alias_value) + 1;
       locale = (char *) malloc (len);
       if (locale == NULL)
 	return NULL;
 
       memcpy (locale, alias_value, len);
+#endif
     }
 
   /* Now we determine the single parts of the locale name.  First
@@ -187,3 +194,23 @@
 
   return retval;
 }
+
+
+#ifdef _LIBC
+static void __attribute__ ((unused))
+free_mem (void)
+{
+  struct loaded_l10nfile *runp = _nl_loaded_domains;
+
+  while (runp != NULL)
+    {
+      struct loaded_l10nfile *here = runp;
+      if (runp->data != NULL)
+	_nl_unload_domain ((struct loaded_domain *) runp->data);
+      runp = runp->next;
+      free (here);
+    }
+}
+
+text_set_element (__libc_subfreeres, free_mem);
+#endif
diff --git a/intl/gettext.c b/intl/gettext.c
index 1336d21..d929f98 100644
--- a/intl/gettext.c
+++ b/intl/gettext.c
@@ -1,4 +1,4 @@
-/* Implementation of gettext(3) function
+/* Implementation of gettext(3) function.
    Copyright (C) 1995, 1997 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
diff --git a/intl/gettext.h b/intl/gettext.h
index 6b4b9e3..3cd23d7 100644
--- a/intl/gettext.h
+++ b/intl/gettext.h
@@ -1,4 +1,4 @@
-/* Internal header for GNU gettext internationalization functions
+/* Internal header for GNU gettext internationalization functions.
    Copyright (C) 1995, 1997 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
diff --git a/intl/gettextP.h b/intl/gettextP.h
index bb8d552..00c5203 100644
--- a/intl/gettextP.h
+++ b/intl/gettextP.h
@@ -1,5 +1,6 @@
 /* Header describing internals of gettext library
-   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -30,11 +31,19 @@
 # endif
 #endif
 
+#ifndef internal_function
+# define internal_function
+#endif
+
 #ifndef W
 # define W(flag, data) ((flag) ? SWAP (data) : (data))
 #endif
 
 
+#ifdef _LIBC
+# include <byteswap.h>
+# define SWAP(i) bswap_32 (i)
+#else
 static nls_uint32 SWAP PARAMS ((nls_uint32 i));
 
 static inline nls_uint32
@@ -43,11 +52,14 @@
 {
   return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
 }
+#endif
 
 
 struct loaded_domain
 {
   const char *data;
+  int use_mmap;
+  size_t mmap_size;
   int must_swap;
   nls_uint32 nstrings;
   struct string_desc *orig_tab;
@@ -65,8 +77,12 @@
 
 struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname,
 						 char *__locale,
-						 const char *__domainname));
-void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain));
+						 const char *__domainname))
+     internal_function;
+void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain))
+     internal_function;
+void _nl_unload_domain PARAMS ((struct loaded_domain *__domain))
+     internal_function;
 
 /* @@ begin of epilog @@ */
 
diff --git a/intl/hash-string.h b/intl/hash-string.h
index e66e841..cacb38e 100644
--- a/intl/hash-string.h
+++ b/intl/hash-string.h
@@ -16,10 +16,6 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#ifdef HAVE_VALUES_H
-# include <values.h>
-#endif
-
 /* @@ end of prolog @@ */
 
 #ifndef PARAMS
diff --git a/intl/intlh.inst.in b/intl/intlh.inst.in
index 62d323c..27cf6c7 100644
--- a/intl/intlh.inst.in
+++ b/intl/intlh.inst.in
@@ -26,7 +26,7 @@
 #define __USE_GNU_GETTEXT 1
 
 #ifndef PARAMS
-# if __STDC__
+# if __STDC__ || defined __cplusplus
 #  define PARAMS(args) args
 # else
 #  define PARAMS(args) ()
diff --git a/intl/l10nflist.c b/intl/l10nflist.c
index 4e2bc13..9c7dc18 100644
--- a/intl/l10nflist.c
+++ b/intl/l10nflist.c
@@ -1,6 +1,6 @@
 /* Handle list of needed message catalogs
    Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
-   Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -65,7 +65,9 @@
 /* Rename the non ANSI C functions.  This is required by the standard
    because some ANSI C functions will require linking with this object
    file and the name space must not be polluted.  */
-# define stpcpy(dest, src) __stpcpy(dest, src)
+# ifndef stpcpy
+#  define stpcpy(dest, src) __stpcpy(dest, src)
+# endif
 #else
 # ifndef HAVE_STPCPY
 static char *stpcpy PARAMS ((char *dest, const char *src));
@@ -350,7 +352,7 @@
    names.  */
 const char *
 _nl_normalize_codeset (codeset, name_len)
-     const char *codeset;
+     const unsigned char *codeset;
      size_t name_len;
 {
   int len = 0;
diff --git a/intl/libgettext.h b/intl/libgettext.h
index 0d4de4d..3a92960 100644
--- a/intl/libgettext.h
+++ b/intl/libgettext.h
@@ -1,5 +1,5 @@
 /* Message catalogs for internationalization.
-   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -20,8 +20,8 @@
    include protection above.  But the systems header might perhaps also
    define _LIBINTL_H and therefore we have to protect the definition here.  */
 
-#if !defined (_LIBINTL_H) || !defined (_LIBGETTEXT_H)
-#if !defined (_LIBINTL_H)
+#if !defined _LIBINTL_H || !defined _LIBGETTEXT_H
+#ifndef _LIBINTL_H
 # define _LIBINTL_H	1
 #endif
 #define _LIBGETTEXT_H	1
@@ -44,7 +44,7 @@
 /* @@ end of prolog @@ */
 
 #ifndef PARAMS
-# if __STDC__
+# if __STDC__ || defined __cplusplus
 #  define PARAMS(args) args
 # else
 #  define PARAMS(args) ()
@@ -168,8 +168,8 @@
 # define gettext(Msgid) (Msgid)
 # define dgettext(Domainname, Msgid) (Msgid)
 # define dcgettext(Domainname, Msgid, Category) (Msgid)
-# define textdomain(Domainname) while (0) /* nothing */
-# define bindtextdomain(Domainname, Dirname) while (0) /* nothing */
+# define textdomain(Domainname) ((char *) Domainname)
+# define bindtextdomain(Domainname, Dirname) ((char *) Dirname)
 
 #endif
 
diff --git a/intl/libintl.glibc b/intl/libintl.glibc
index 8e5b8f9..2c8e8a4 100644
--- a/intl/libintl.glibc
+++ b/intl/libintl.glibc
@@ -1,33 +1,31 @@
-/* libgettext.h -- Message catalogs for internationalization.
-Copyright (C) 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-Contributed by Ulrich Drepper.
-This file is derived from the file libgettext.h in the GNU gettext package.
+/* Message catalogs for internationalization.
+   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+   This file is derived from the file libgettext.h in the GNU gettext package.
 
-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
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   This file is part of the GNU C Library.  Its master source is NOT part of
+   the C library, however.
 
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+   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
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-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., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   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., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #ifndef _LIBINTL_H
 #define _LIBINTL_H	1
+
 #include <features.h>
 
-#include <locale.h>
-
-#define __need_NULL
-#include <stddef.h>
-
 /* We define an additional symbol to signal that we use the GNU
    implementation of gettext.  */
 #define __USE_GNU_GETTEXT 1
@@ -70,8 +68,16 @@
 
 
 /* Optimized version of the function above.  */
-#if defined __OPTIMIZED
-/* These must be a macro.  Inlined functions are useless because the
+#if defined __OPTIMIZE__
+
+/* We need NULL for `gettext'.  */
+# define __need_NULL
+# include <stddef.h>
+
+/* We need LC_MESSAGES for `dgettext'.  */
+# include <locale.h>
+
+/* These must be macros.  Inlined functions are useless because the
    `__builtin_constant_p' predicate in dcgettext would always return
    false.  */
 
@@ -81,13 +87,16 @@
   dcgettext (domainname, msgid, LC_MESSAGES)
 
 # if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+/* Variable defined in loadmsgcat.c which gets incremented every time a
+   new catalog is loaded.  */
+extern int _nl_msg_cat_cntr;
+
 #  define dcgettext(domainname, msgid, category)			      \
   (__extension__							      \
    ({									      \
-     char *result;							      \
+     char *__result;							      \
      if (__builtin_constant_p (msgid))					      \
        {								      \
-	 extern int _nl_msg_cat_cntr;					      \
 	 static char *__translation__;					      \
 	 static int __catalog_counter__;				      \
 	 if (! __translation__ || __catalog_counter__ != _nl_msg_cat_cntr)    \
@@ -96,11 +105,11 @@
 	       __dcgettext ((domainname), (msgid), (category));		      \
 	     __catalog_counter__ = _nl_msg_cat_cntr;			      \
 	   }								      \
-	 result = __translation__;					      \
+	 __result = __translation__;					      \
        }								      \
      else								      \
-       result = __dcgettext ((domainname), (msgid), (category));	      \
-     result;								      \
+       __result = __dcgettext ((domainname), (msgid), (category));	      \
+     __result;								      \
     }))
 # endif
 #endif /* Optimizing. */
diff --git a/intl/loadinfo.h b/intl/loadinfo.h
index c67c2eb..f4ebf6d 100644
--- a/intl/loadinfo.h
+++ b/intl/loadinfo.h
@@ -1,3 +1,21 @@
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
 #ifndef PARAMS
 # if __STDC__
 #  define PARAMS(args) args
@@ -32,7 +50,7 @@
 };
 
 
-extern const char *_nl_normalize_codeset PARAMS ((const char *codeset,
+extern const char *_nl_normalize_codeset PARAMS ((const unsigned char *codeset,
 						  size_t name_len));
 
 extern struct loaded_l10nfile *
diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c
index 73e90a9..515892d 100644
--- a/intl/loadmsgcat.c
+++ b/intl/loadmsgcat.c
@@ -1,5 +1,5 @@
-/* Load needed message catalogs
-   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Load needed message catalogs.
+   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -44,7 +44,6 @@
 /* Rename the non ISO C functions.  This is required by the standard
    because some ISO C functions will require linking with this object
    file and the name space must not be polluted.  */
-# define fstat  __fstat
 # define open   __open
 # define close  __close
 # define read   __read
@@ -61,10 +60,12 @@
 /* Load the message catalogs specified by FILENAME.  If it is no valid
    message catalog do nothing.  */
 void
+internal_function
 _nl_load_domain (domain_file)
      struct loaded_l10nfile *domain_file;
 {
   int fd;
+  size_t size;
   struct stat st;
   struct mo_file_header *data = (struct mo_file_header *) -1;
 #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
@@ -90,7 +91,8 @@
 
   /* We must know about the size of the file.  */
   if (fstat (fd, &st) != 0
-      && st.st_size < (off_t) sizeof (struct mo_file_header))
+      || (size = (size_t) st.st_size) != st.st_size
+      || size < sizeof (struct mo_file_header))
     {
       /* Something went wrong.  */
       close (fd);
@@ -101,7 +103,7 @@
     || defined _LIBC
   /* Now we are ready to load the file.  If mmap() is available we try
      this first.  If not available or it failed we try to load it.  */
-  data = (struct mo_file_header *) mmap (NULL, st.st_size, PROT_READ,
+  data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
 					 MAP_PRIVATE, fd, 0);
 
   if (data != (struct mo_file_header *) -1)
@@ -116,14 +118,14 @@
      it manually.  */
   if (data == (struct mo_file_header *) -1)
     {
-      off_t to_read;
+      size_t to_read;
       char *read_ptr;
 
-      data = (struct mo_file_header *) malloc (st.st_size);
+      data = (struct mo_file_header *) malloc (size);
       if (data == NULL)
 	return;
 
-      to_read = st.st_size;
+      to_read = size;
       read_ptr = (char *) data;
       do
 	{
@@ -150,7 +152,7 @@
 #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
     || defined _LIBC
       if (use_mmap)
-	munmap ((caddr_t) data, st.st_size);
+	munmap ((caddr_t) data, size);
       else
 #endif
 	free (data);
@@ -164,6 +166,11 @@
 
   domain = (struct loaded_domain *) domain_file->data;
   domain->data = (char *) data;
+#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
+    || defined _LIBC
+  domain->use_mmap = use_mmap;
+#endif
+  domain->mmap_size = size;
   domain->must_swap = data->magic != _MAGIC;
 
   /* Fill in the information about the available tables.  */
@@ -184,7 +191,7 @@
 #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
     || defined _LIBC
       if (use_mmap)
-	munmap ((caddr_t) data, st.st_size);
+	munmap ((caddr_t) data, size);
       else
 #endif
 	free (data);
@@ -197,3 +204,19 @@
      translations invalid.  */
   ++_nl_msg_cat_cntr;
 }
+
+
+#ifdef _LIBC
+void
+internal_function
+_nl_unload_domain (domain)
+     struct loaded_domain *domain;
+{
+  if (domain->use_mmap)
+    munmap ((caddr_t) domain->data, domain->mmap_size);
+  else
+    free ((void *) domain->data);
+
+  free (domain);
+}
+#endif
diff --git a/intl/localealias.c b/intl/localealias.c
index 00d9194..bca555a 100644
--- a/intl/localealias.c
+++ b/intl/localealias.c
@@ -1,5 +1,5 @@
-/* Handle aliases for locale names
-   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Handle aliases for locale names.
+   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
    Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
    This program is free software; you can redistribute it and/or modify
@@ -79,6 +79,14 @@
    because some ANSI C functions will require linking with this object
    file and the name space must not be polluted.  */
 # define strcasecmp __strcasecmp
+
+# define mempcpy __mempcpy
+# define HAVE_MEMPCPY	1
+
+/* We need locking here since we can be called from different places.  */
+# include <bits/libc-lock.h>
+
+__libc_lock_define_initialized (static, lock);
 #endif
 
 
@@ -125,13 +133,17 @@
 };
 
 
+static char *string_space = NULL;
+static size_t string_space_act = 0;
+static size_t string_space_max = 0;
 static struct alias_map *map;
 static size_t nmap = 0;
 static size_t maxmap = 0;
 
 
 /* Prototypes for local functions.  */
-static size_t read_alias_file PARAMS ((const char *fname, int fname_len));
+static size_t read_alias_file PARAMS ((const char *fname, int fname_len))
+     internal_function;
 static void extend_alias_table PARAMS ((void));
 static int alias_compare PARAMS ((const struct alias_map *map1,
 				  const struct alias_map *map2));
@@ -143,8 +155,13 @@
 {
   static const char *locale_alias_path = LOCALE_ALIAS_PATH;
   struct alias_map *retval;
+  const char *result = NULL;
   size_t added;
 
+#ifdef _LIBC
+  __libc_lock_lock (lock);
+#endif
+
   do
     {
       struct alias_map item;
@@ -162,7 +179,10 @@
 
       /* We really found an alias.  Return the value.  */
       if (retval != NULL)
-	return retval->value;
+	{
+	  result = retval->value;
+	  break;
+	}
 
       /* Perhaps we can find another alias file.  */
       added = 0;
@@ -183,11 +203,16 @@
     }
   while (added != 0);
 
-  return NULL;
+#ifdef _LIBC
+  __libc_lock_unlock (lock);
+#endif
+
+  return result;
 }
 
 
 static size_t
+internal_function
 read_alias_file (fname, fname_len)
      const char *fname;
      int fname_len;
@@ -202,8 +227,13 @@
 
   full_fname = (char *) alloca (fname_len + sizeof aliasfile);
   ADD_BLOCK (block_list, full_fname);
+#ifdef HAVE_MEMPCPY
+  mempcpy (mempcpy (full_fname, fname, fname_len),
+	   aliasfile, sizeof aliasfile);
+#else
   memcpy (full_fname, fname, fname_len);
   memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile);
+#endif
 
   fp = fopen (full_fname, "r");
   if (fp == NULL)
@@ -220,15 +250,28 @@
 	 b) these fields must be usable as file names and so must not
 	    be that long
        */
-      char buf[BUFSIZ];
-      char *alias;
-      char *value;
-      char *cp;
+      unsigned char buf[BUFSIZ];
+      unsigned char *alias;
+      unsigned char *value;
+      unsigned char *cp;
 
-      if (fgets (buf, BUFSIZ, fp) == NULL)
+      if (fgets (buf, sizeof buf, fp) == NULL)
 	/* EOF reached.  */
 	break;
 
+      /* Possibly not the whole line fits into the buffer.  Ignore
+	 the rest of the line.  */
+      if (strchr (buf, '\n') == NULL)
+	{
+	  char altbuf[BUFSIZ];
+	  do
+	    if (fgets (altbuf, sizeof altbuf, fp) == NULL)
+	      /* Make sure the inner loop will be left.  The outer loop
+		 will exit at the `feof' test.  */
+	      break;
+	  while (strchr (altbuf, '\n') == NULL);
+	}
+
       cp = buf;
       /* Ignore leading white space.  */
       while (isspace (cp[0]))
@@ -250,8 +293,8 @@
 
 	  if (cp[0] != '\0')
 	    {
-	      char *tp;
-	      size_t len;
+	      size_t alias_len;
+	      size_t value_len;
 
 	      value = cp++;
 	      while (cp[0] != '\0' && !isspace (cp[0]))
@@ -271,42 +314,37 @@
 	      if (nmap >= maxmap)
 		extend_alias_table ();
 
-	      /* We cannot depend on strdup available in the libc.  Sigh!  */
-	      len = strlen (alias) + 1;
-	      tp = (char *) malloc (len);
-	      if (tp == NULL)
-		{
-		  FREE_BLOCKS (block_list);
-		  return added;
-		}
-	      memcpy (tp, alias, len);
-	      map[nmap].alias = tp;
+	      alias_len = strlen (alias) + 1;
+	      value_len = strlen (value) + 1;
 
-	      len = strlen (value) + 1;
-	      tp = (char *) malloc (len);
-	      if (tp == NULL)
+	      if (string_space_act + alias_len + value_len > string_space_max)
 		{
-		  FREE_BLOCKS (block_list);
-		  return added;
+		  /* Increase size of memory pool.  */
+		  size_t new_size = (string_space_max
+				     + (alias_len + value_len > 1024
+					? alias_len + value_len : 1024));
+		  char *new_pool = (char *) realloc (string_space, new_size);
+		  if (new_pool == NULL)
+		    {
+		      FREE_BLOCKS (block_list);
+		      return added;
+		    }
+		  string_space = new_pool;
+		  string_space_max = new_size;
 		}
-	      memcpy (tp, value, len);
-	      map[nmap].value = tp;
+
+	      map[nmap].alias = memcpy (&string_space[string_space_act],
+					alias, alias_len);
+	      string_space_act += alias_len;
+
+	      map[nmap].value = memcpy (&string_space[string_space_act],
+					value, value_len);
+	      string_space_act += value_len;
 
 	      ++nmap;
 	      ++added;
 	    }
 	}
-
-      /* Possibly not the whole line fits into the buffer.  Ignore
-	 the rest of the line.  */
-      while (strchr (cp, '\n') == NULL)
-	{
-	  cp = buf;
-	  if (fgets (buf, BUFSIZ, fp) == NULL)
-	    /* Make sure the inner loop will be left.  The outer loop
-	       will exit at the `feof' test.  */
-	    *cp = '\n';
-	}
     }
 
   /* Should we test for ferror()?  I think we have to silently ignore
@@ -329,22 +367,30 @@
   struct alias_map *new_map;
 
   new_size = maxmap == 0 ? 100 : 2 * maxmap;
-  new_map = (struct alias_map *) malloc (new_size
-					 * sizeof (struct alias_map));
+  new_map = (struct alias_map *) realloc (map, (new_size
+						* sizeof (struct alias_map)));
   if (new_map == NULL)
     /* Simply don't extend: we don't have any more core.  */
     return;
 
-  memcpy (new_map, map, nmap * sizeof (struct alias_map));
-
-  if (maxmap != 0)
-    free (map);
-
   map = new_map;
   maxmap = new_size;
 }
 
 
+#ifdef _LIBC
+static void __attribute__ ((unused))
+free_mem (void)
+{
+  if (string_space != NULL)
+    free (string_space);
+  if (map != NULL)
+    free (map);
+}
+text_set_element (__libc_subfreeres, free_mem);
+#endif
+
+
 static int
 alias_compare (map1, map2)
      const struct alias_map *map1;
diff --git a/intl/textdomain.c b/intl/textdomain.c
index 55d9340..8855746 100644
--- a/intl/textdomain.c
+++ b/intl/textdomain.c
@@ -1,5 +1,5 @@
-/* Implementation of the textdomain(3) function
-   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Implementation of the textdomain(3) function.
+   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
    Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
    This program is free software; you can redistribute it and/or modify
@@ -54,7 +54,9 @@
    prefix.  So we have to make a difference here.  */
 #ifdef _LIBC
 # define TEXTDOMAIN __textdomain
-# define strdup(str) __strdup (str)
+# ifndef strdup
+#  define strdup(str) __strdup (str)
+# endif
 #else
 # define TEXTDOMAIN textdomain__
 #endif