about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog43
-rw-r--r--ctype/ctype.h31
-rw-r--r--langinfo.h1
-rw-r--r--locale/C-collate.c7
-rw-r--r--locale/C-ctype.c300
-rw-r--r--locale/C-ctype_ct.c793
-rw-r--r--locale/C-ctype_mb.c9
-rw-r--r--locale/C-messages.c17
-rw-r--r--locale/C-monetary.c46
-rw-r--r--locale/C-numeric.c24
-rw-r--r--locale/C-response.c12
-rw-r--r--locale/C-time.c78
-rw-r--r--locale/Makefile13
-rw-r--r--locale/categories.def116
-rw-r--r--locale/langinfo.h165
-rw-r--r--locale/lc-ctype.c51
-rw-r--r--locale/lc-messages.c22
-rw-r--r--locale/lc-monetary.c22
-rw-r--r--locale/lc-numeric.c22
-rw-r--r--locale/lc-time.c22
-rw-r--r--locale/loadlocale.c186
-rw-r--r--locale/localeconv.c49
-rw-r--r--locale/localeinfo.h231
-rw-r--r--locale/nl_langinfo.c63
-rw-r--r--locale/setlocale.c395
-rw-r--r--stdio/printf_fp.c17
-rw-r--r--stdio/vfprintf.c13
-rw-r--r--stdio/vfscanf.c8
-rw-r--r--stdlib/strtod.c24
-rw-r--r--time/asctime.c8
-rw-r--r--time/localtime.c1
-rw-r--r--time/strftime.c27
-rw-r--r--time/tzset.c14
33 files changed, 1639 insertions, 1191 deletions
diff --git a/ChangeLog b/ChangeLog
index 2ce34030a2..215aca09af 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,46 @@
+Sun Mar  5 19:40:13 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
+
+	* locale/localeinfo.h: Rewritten for new locale system, using
+	locale data files and with <langinfo.h> interface.
+	* locale/setlocale.c: Rewritten to use locale data files.
+	* langinfo.h: New file.
+        * locale/langinfo.h: New file.
+        * locale/nl_langinfo.c: New file.
+        * locale/loadlocale.c: New file.
+        * locale/lc-ctype.c: New file.
+        * locale/lc-messages.c: New file.
+        * locale/lc-monetary.c: New file.
+        * locale/lc-numeric.c: New file.
+        * locale/lc-time.c: New file.
+        * locale/categories.def: New file.
+	* locale/Makefile (headers): Remove localeinfo.h.
+	(distribute): New variable; put localeinfo.h here, and categories.def.
+	(routines): Add loadlocale.
+	(categories): New variable.
+	(aux): Use that to get C-category and lc-category.
+	* ctype/ctype.h (_IS*): Use independent bits for all but _ISalnum.
+	* locale/C-ctype.c, locale/C-messages.c: New files.
+ 	* locale/C-monetary.c, locale/C-numeric.c, locale/C-time.c:
+	Default "C" locale data updated for new locale system.
+	* locale/C-collate.c: File removed.
+        * locale/C-ctype_ct.c: File removed.
+        * locale/C-ctype_mb.c: File removed.
+        * locale/C-response.c: File removed.
+	* locale/localeconv.c: Use _NL_CURRENT macro to access locale data.
+	* stdio/printf_fp.c, stdio/vfprintf.c, stdio/vfscanf.c,
+	  stdlib/strtod.c, time/asctime.c, time/strftime.c:
+	Include ../locale/localeinfo.h and use _NL_CURRENT macro to access
+	locale data.
+	* time/localtime.c: Don't include <localeinfo.h>.
+	* time/tzset.c: Don't use locale items for default TZ value or
+	"GMT" string (use "UTC").
+
+	* stdio/vfprintf.c [USE_IN_LIBIO] (PAD): Only call the function if
+ 	WIDTH>0; update DONE.
+
+	* malloc/malloc.c (morecore): Fix last change to calculate by
+ 	blocks instead of bytes.
+
 Fri Mar  3 12:24:52 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
 	* sysdeps/generic/sys/mman.h (__mmap, __munmap): Declare these.
diff --git a/ctype/ctype.h b/ctype/ctype.h
index 0f35d2a1d7..9c97831585 100644
--- a/ctype/ctype.h
+++ b/ctype/ctype.h
@@ -34,20 +34,21 @@ __BEGIN_DECLS
    many things must be changed that use `unsigned short int's.  */
 enum
 {
-  _ISupper = 1 << 0,			/* UPPERCASE.  */
-  _ISlower = 1 << 1,			/* lowercase.  */
-  _IScntrl = 1 << 2,			/* Control character.  */
-  _ISdigit = 1 << 3,			/* Numeric.  */
-  _ISspace = 1 << 4,			/* Whitespace.  */
-  _IShex = 1 << 5,			/* A - F, a - f.  */
-  _ISpunct = 1 << 6,			/* Punctuation.  */
-  _NOgraph = 1 << 7,			/* Printing but nongraphical.  */
-  _ISblank = 1 << 8,			/* Blank (usually SPC and TAB).  */
-  _ISalpha = 1 << 9,			/* Alphabetic.  */
-  _ISalnum = _ISalpha | _ISdigit,	/* Alphanumeric.  */
-  _ISxdigit = _ISdigit | _IShex,	/* Hexadecimal numeric.  */
-  _ISgraph = _ISalnum | _ISpunct,	/* Graphical.  */
-  _ISprint = _ISgraph | _NOgraph	/* Printing.  */
+  _ISupper = 1 << 0,		/* UPPERCASE.  */
+  _ISlower = 1 << 1,		/* lowercase.  */
+  _ISalpha = 1 << 2,	        /* Alphabetic.  */
+  _ISdigit = 1 << 3,		/* Numeric.  */
+  _ISxdigit = 1 << 4,           /* Hexadecimal numeric.  */
+  _ISspace = 1 << 5,		/* Whitespace.  */
+  _ISprint = 1 << 6,            /* Printing.  */
+  _ISgraph = 1 << 7,	        /* Graphical.  */
+  _ISblank = 1 << 8,		/* Blank (usually SPC and TAB).  */
+  _IScntrl = 1 << 9,		/* Control character.  */
+  _ISpunct = 1 << 10,		/* Punctuation.  */
+
+  /* The following are defined in POSIX.2 as being combinations of the
+     classes above.  */
+  _ISalnum = _ISalpha | _ISdigit	/* Alphanumeric.  */
 };
 
 /* These are defined in localeinfo.c.
@@ -115,7 +116,7 @@ extern int toascii __P ((int __c));
 #endif /* Use SVID or use misc.  */
 
 #ifdef	__USE_SVID
-/* These are the same as `toupper' and and `tolower'.  */
+/* These are the same as `toupper' and `tolower'.  */
 __exctype (_toupper);
 __exctype (_tolower);
 #endif
diff --git a/langinfo.h b/langinfo.h
new file mode 100644
index 0000000000..2a81c6ddaf
--- /dev/null
+++ b/langinfo.h
@@ -0,0 +1 @@
+#include <locale/langinfo.h>
diff --git a/locale/C-collate.c b/locale/C-collate.c
deleted file mode 100644
index eddcafa297..0000000000
--- a/locale/C-collate.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <ansidecl.h>
-#include <localeinfo.h>
-#include <stddef.h>
-
-
-CONST struct collate_info __collate_C = { 0, NULL, NULL, NULL };
-CONST struct collate_info *_collate_info = &__collate_C;
diff --git a/locale/C-ctype.c b/locale/C-ctype.c
index 7131a6f78c..2ee9d2cf8b 100644
--- a/locale/C-ctype.c
+++ b/locale/C-ctype.c
@@ -1,14 +1,292 @@
-#include <ansidecl.h>
-#include <localeinfo.h>
-#include <stddef.h>
+/* Generated by GNU locale 0.1.
+   Copyright (C) 1995 Free Software Foundation, Inc.
+This is free software; see the source for copying conditions.
+There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE.  */
 
+#include "localeinfo.h"
+#include <endian.h>
 
-extern CONST struct ctype_ctype_info __ctype_ctype_C;
-extern CONST struct ctype_mbchar_info __ctype_mbchar_C;
-CONST struct ctype_info __ctype_C =
-  {
-    (struct ctype_ctype_info*)&__ctype_ctype_C,
-    (struct ctype_mbchar_info*) &__ctype_mbchar_C
-  };
+#if BYTE_ORDER == BIG_ENDIAN
+const char _nl_C_LC_CTYPE_class[] =
+  /* 0x00 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0x06 */ "\004\000" "\004\000" "\004\000" "\024\001" "\024\000" "\024\000"
+  /* 0x0c */ "\024\000" "\024\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0x12 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0x18 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0x1e */ "\004\000" "\004\000" "\220\001" "\100\000" "\100\000" "\100\000"
+  /* 0x24 */ "\100\000" "\100\000" "\100\000" "\100\000" "\100\000" "\100\000"
+  /* 0x2a */ "\100\000" "\100\000" "\100\000" "\100\000" "\100\000" "\100\000"
+  /* 0x30 */ "\050\000" "\050\000" "\050\000" "\050\000" "\050\000" "\050\000"
+  /* 0x36 */ "\050\000" "\050\000" "\050\000" "\050\000" "\100\000" "\100\000"
+  /* 0x3c */ "\100\000" "\100\000" "\100\000" "\100\000" "\100\000" "\041\000"
+  /* 0x42 */ "\041\000" "\041\000" "\041\000" "\041\000" "\041\000" "\001\000"
+  /* 0x48 */ "\001\000" "\001\000" "\001\000" "\001\000" "\001\000" "\001\000"
+  /* 0x4e */ "\001\000" "\001\000" "\001\000" "\001\000" "\001\000" "\001\000"
+  /* 0x54 */ "\001\000" "\001\000" "\001\000" "\001\000" "\001\000" "\001\000"
+  /* 0x5a */ "\001\000" "\100\000" "\100\000" "\100\000" "\100\000" "\100\000"
+  /* 0x60 */ "\100\000" "\042\000" "\042\000" "\042\000" "\042\000" "\042\000"
+  /* 0x66 */ "\042\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0x6c */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0x72 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0x78 */ "\002\000" "\002\000" "\002\000" "\100\000" "\100\000" "\100\000"
+  /* 0x7e */ "\100\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0x84 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0x8a */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0x90 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0x96 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0x9c */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xa2 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xa8 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xae */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xb4 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xba */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xc0 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xc6 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xcc */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xd2 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xd8 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xde */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xe4 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xea */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xf0 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xf6 */ "\004\000" "\004\000" "\004\000" "\004\000" "\004\000" "\004\000"
+  /* 0xfc */ "\004\000" "\004\000" "\004\000" "\004\000";
+const char _nl_C_LC_CTYPE_toupper[] =
+  /* 0x00 */ "\000\000" "\001\000" "\002\000" "\003\000" "\004\000" "\005\000"
+  /* 0x06 */ "\006\000" "\007\000" "\010\000" "\011\000" "\012\000" "\013\000"
+  /* 0x0c */ "\014\000" "\015\000" "\016\000" "\017\000" "\020\000" "\021\000"
+  /* 0x12 */ "\022\000" "\023\000" "\024\000" "\025\000" "\026\000" "\027\000"
+  /* 0x18 */ "\030\000" "\031\000" "\032\000" "\033\000" "\034\000" "\035\000"
+  /* 0x1e */ "\036\000" "\037\000" "\040\000" "\041\000" "\042\000" "\043\000"
+  /* 0x24 */ "\044\000" "\045\000" "\046\000" "\047\000" "\050\000" "\051\000"
+  /* 0x2a */ "\052\000" "\053\000" "\054\000" "\055\000" "\056\000" "\057\000"
+  /* 0x30 */ "\060\000" "\061\000" "\062\000" "\063\000" "\064\000" "\065\000"
+  /* 0x36 */ "\066\000" "\067\000" "\070\000" "\071\000" "\072\000" "\073\000"
+  /* 0x3c */ "\074\000" "\075\000" "\076\000" "\077\000" "\100\000" "\101\000"
+  /* 0x42 */ "\102\000" "\103\000" "\104\000" "\105\000" "\106\000" "\107\000"
+  /* 0x48 */ "\110\000" "\111\000" "\112\000" "\113\000" "\114\000" "\115\000"
+  /* 0x4e */ "\116\000" "\117\000" "\120\000" "\121\000" "\122\000" "\123\000"
+  /* 0x54 */ "\124\000" "\125\000" "\126\000" "\127\000" "\130\000" "\131\000"
+  /* 0x5a */ "\132\000" "\133\000" "\134\000" "\135\000" "\136\000" "\137\000"
+  /* 0x60 */ "\140\000" "\101\000" "\102\000" "\103\000" "\104\000" "\105\000"
+  /* 0x66 */ "\106\000" "\107\000" "\110\000" "\111\000" "\112\000" "\113\000"
+  /* 0x6c */ "\114\000" "\115\000" "\116\000" "\117\000" "\120\000" "\121\000"
+  /* 0x72 */ "\122\000" "\123\000" "\124\000" "\125\000" "\126\000" "\127\000"
+  /* 0x78 */ "\130\000" "\131\000" "\132\000" "\173\000" "\174\000" "\175\000"
+  /* 0x7e */ "\176\000" "\177\000" "\200\000" "\201\000" "\202\000" "\203\000"
+  /* 0x84 */ "\204\000" "\205\000" "\206\000" "\207\000" "\210\000" "\211\000"
+  /* 0x8a */ "\212\000" "\213\000" "\214\000" "\215\000" "\216\000" "\217\000"
+  /* 0x90 */ "\220\000" "\221\000" "\222\000" "\223\000" "\224\000" "\225\000"
+  /* 0x96 */ "\226\000" "\227\000" "\230\000" "\231\000" "\232\000" "\233\000"
+  /* 0x9c */ "\234\000" "\235\000" "\236\000" "\237\000" "\240\000" "\241\000"
+  /* 0xa2 */ "\242\000" "\243\000" "\244\000" "\245\000" "\246\000" "\247\000"
+  /* 0xa8 */ "\250\000" "\251\000" "\252\000" "\253\000" "\254\000" "\255\000"
+  /* 0xae */ "\256\000" "\257\000" "\260\000" "\261\000" "\262\000" "\263\000"
+  /* 0xb4 */ "\264\000" "\265\000" "\266\000" "\267\000" "\270\000" "\271\000"
+  /* 0xba */ "\272\000" "\273\000" "\274\000" "\275\000" "\276\000" "\277\000"
+  /* 0xc0 */ "\300\000" "\301\000" "\302\000" "\303\000" "\304\000" "\305\000"
+  /* 0xc6 */ "\306\000" "\307\000" "\310\000" "\311\000" "\312\000" "\313\000"
+  /* 0xcc */ "\314\000" "\315\000" "\316\000" "\317\000" "\320\000" "\321\000"
+  /* 0xd2 */ "\322\000" "\323\000" "\324\000" "\325\000" "\326\000" "\327\000"
+  /* 0xd8 */ "\330\000" "\331\000" "\332\000" "\333\000" "\334\000" "\335\000"
+  /* 0xde */ "\336\000" "\337\000" "\340\000" "\341\000" "\342\000" "\343\000"
+  /* 0xe4 */ "\344\000" "\345\000" "\346\000" "\347\000" "\350\000" "\351\000"
+  /* 0xea */ "\352\000" "\353\000" "\354\000" "\355\000" "\356\000" "\357\000"
+  /* 0xf0 */ "\360\000" "\361\000" "\362\000" "\363\000" "\364\000" "\365\000"
+  /* 0xf6 */ "\366\000" "\367\000" "\370\000" "\371\000" "\372\000" "\373\000"
+  /* 0xfc */ "\374\000" "\375\000" "\376\000" "\377\000";
+const char _nl_C_LC_CTYPE_tolower[] =
+  /* 0x00 */ "\000\000" "\001\000" "\002\000" "\003\000" "\004\000" "\005\000"
+  /* 0x06 */ "\006\000" "\007\000" "\010\000" "\011\000" "\012\000" "\013\000"
+  /* 0x0c */ "\014\000" "\015\000" "\016\000" "\017\000" "\020\000" "\021\000"
+  /* 0x12 */ "\022\000" "\023\000" "\024\000" "\025\000" "\026\000" "\027\000"
+  /* 0x18 */ "\030\000" "\031\000" "\032\000" "\033\000" "\034\000" "\035\000"
+  /* 0x1e */ "\036\000" "\037\000" "\040\000" "\041\000" "\042\000" "\043\000"
+  /* 0x24 */ "\044\000" "\045\000" "\046\000" "\047\000" "\050\000" "\051\000"
+  /* 0x2a */ "\052\000" "\053\000" "\054\000" "\055\000" "\056\000" "\057\000"
+  /* 0x30 */ "\060\000" "\061\000" "\062\000" "\063\000" "\064\000" "\065\000"
+  /* 0x36 */ "\066\000" "\067\000" "\070\000" "\071\000" "\072\000" "\073\000"
+  /* 0x3c */ "\074\000" "\075\000" "\076\000" "\077\000" "\100\000" "\141\000"
+  /* 0x42 */ "\142\000" "\143\000" "\144\000" "\145\000" "\146\000" "\147\000"
+  /* 0x48 */ "\150\000" "\151\000" "\152\000" "\153\000" "\154\000" "\155\000"
+  /* 0x4e */ "\156\000" "\157\000" "\160\000" "\161\000" "\162\000" "\163\000"
+  /* 0x54 */ "\164\000" "\165\000" "\166\000" "\167\000" "\170\000" "\171\000"
+  /* 0x5a */ "\172\000" "\133\000" "\134\000" "\135\000" "\136\000" "\137\000"
+  /* 0x60 */ "\140\000" "\141\000" "\142\000" "\143\000" "\144\000" "\145\000"
+  /* 0x66 */ "\146\000" "\147\000" "\150\000" "\151\000" "\152\000" "\153\000"
+  /* 0x6c */ "\154\000" "\155\000" "\156\000" "\157\000" "\160\000" "\161\000"
+  /* 0x72 */ "\162\000" "\163\000" "\164\000" "\165\000" "\166\000" "\167\000"
+  /* 0x78 */ "\170\000" "\171\000" "\172\000" "\173\000" "\174\000" "\175\000"
+  /* 0x7e */ "\176\000" "\177\000" "\200\000" "\201\000" "\202\000" "\203\000"
+  /* 0x84 */ "\204\000" "\205\000" "\206\000" "\207\000" "\210\000" "\211\000"
+  /* 0x8a */ "\212\000" "\213\000" "\214\000" "\215\000" "\216\000" "\217\000"
+  /* 0x90 */ "\220\000" "\221\000" "\222\000" "\223\000" "\224\000" "\225\000"
+  /* 0x96 */ "\226\000" "\227\000" "\230\000" "\231\000" "\232\000" "\233\000"
+  /* 0x9c */ "\234\000" "\235\000" "\236\000" "\237\000" "\240\000" "\241\000"
+  /* 0xa2 */ "\242\000" "\243\000" "\244\000" "\245\000" "\246\000" "\247\000"
+  /* 0xa8 */ "\250\000" "\251\000" "\252\000" "\253\000" "\254\000" "\255\000"
+  /* 0xae */ "\256\000" "\257\000" "\260\000" "\261\000" "\262\000" "\263\000"
+  /* 0xb4 */ "\264\000" "\265\000" "\266\000" "\267\000" "\270\000" "\271\000"
+  /* 0xba */ "\272\000" "\273\000" "\274\000" "\275\000" "\276\000" "\277\000"
+  /* 0xc0 */ "\300\000" "\301\000" "\302\000" "\303\000" "\304\000" "\305\000"
+  /* 0xc6 */ "\306\000" "\307\000" "\310\000" "\311\000" "\312\000" "\313\000"
+  /* 0xcc */ "\314\000" "\315\000" "\316\000" "\317\000" "\320\000" "\321\000"
+  /* 0xd2 */ "\322\000" "\323\000" "\324\000" "\325\000" "\326\000" "\327\000"
+  /* 0xd8 */ "\330\000" "\331\000" "\332\000" "\333\000" "\334\000" "\335\000"
+  /* 0xde */ "\336\000" "\337\000" "\340\000" "\341\000" "\342\000" "\343\000"
+  /* 0xe4 */ "\344\000" "\345\000" "\346\000" "\347\000" "\350\000" "\351\000"
+  /* 0xea */ "\352\000" "\353\000" "\354\000" "\355\000" "\356\000" "\357\000"
+  /* 0xf0 */ "\360\000" "\361\000" "\362\000" "\363\000" "\364\000" "\365\000"
+  /* 0xf6 */ "\366\000" "\367\000" "\370\000" "\371\000" "\372\000" "\373\000"
+  /* 0xfc */ "\374\000" "\375\000" "\376\000" "\377\000" ;
+#elif BYTE_ORDER == LITTLE_ENDIAN
+const char _nl_C_LC_CTYPE_class[] =
+  /* 0x00 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0x06 */ "\000\004" "\000\004" "\000\004" "\001\024" "\000\024" "\000\024"
+  /* 0x0c */ "\000\024" "\000\024" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0x12 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0x18 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0x1e */ "\000\004" "\000\004" "\001\220" "\000\100" "\000\100" "\000\100"
+  /* 0x24 */ "\000\100" "\000\100" "\000\100" "\000\100" "\000\100" "\000\100"
+  /* 0x2a */ "\000\100" "\000\100" "\000\100" "\000\100" "\000\100" "\000\100"
+  /* 0x30 */ "\000\050" "\000\050" "\000\050" "\000\050" "\000\050" "\000\050"
+  /* 0x36 */ "\000\050" "\000\050" "\000\050" "\000\050" "\000\100" "\000\100"
+  /* 0x3c */ "\000\100" "\000\100" "\000\100" "\000\100" "\000\100" "\000\041"
+  /* 0x42 */ "\000\041" "\000\041" "\000\041" "\000\041" "\000\041" "\000\001"
+  /* 0x48 */ "\000\001" "\000\001" "\000\001" "\000\001" "\000\001" "\000\001"
+  /* 0x4e */ "\000\001" "\000\001" "\000\001" "\000\001" "\000\001" "\000\001"
+  /* 0x54 */ "\000\001" "\000\001" "\000\001" "\000\001" "\000\001" "\000\001"
+  /* 0x5a */ "\000\001" "\000\100" "\000\100" "\000\100" "\000\100" "\000\100"
+  /* 0x60 */ "\000\100" "\000\042" "\000\042" "\000\042" "\000\042" "\000\042"
+  /* 0x66 */ "\000\042" "\000\002" "\000\002" "\000\002" "\000\002" "\000\002"
+  /* 0x6c */ "\000\002" "\000\002" "\000\002" "\000\002" "\000\002" "\000\002"
+  /* 0x72 */ "\000\002" "\000\002" "\000\002" "\000\002" "\000\002" "\000\002"
+  /* 0x78 */ "\000\002" "\000\002" "\000\002" "\000\100" "\000\100" "\000\100"
+  /* 0x7e */ "\000\100" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0x84 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0x8a */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0x90 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0x96 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0x9c */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xa2 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xa8 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xae */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xb4 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xba */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xc0 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xc6 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xcc */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xd2 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xd8 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xde */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xe4 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xea */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xf0 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xf6 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+  /* 0xfc */ "\000\004" "\000\004" "\000\004" "\000\004";
+const char _nl_C_LC_CTYPE_toupper[] =
+  /* 0x00 */ "\000\000" "\000\001" "\000\002" "\000\003" "\000\004" "\000\005"
+  /* 0x06 */ "\000\006" "\000\007" "\000\010" "\000\011" "\000\012" "\000\013"
+  /* 0x0c */ "\000\014" "\000\015" "\000\016" "\000\017" "\000\020" "\000\021"
+  /* 0x12 */ "\000\022" "\000\023" "\000\024" "\000\025" "\000\026" "\000\027"
+  /* 0x18 */ "\000\030" "\000\031" "\000\032" "\000\033" "\000\034" "\000\035"
+  /* 0x1e */ "\000\036" "\000\037" "\000\040" "\000\041" "\000\042" "\000\043"
+  /* 0x24 */ "\000\044" "\000\045" "\000\046" "\000\047" "\000\050" "\000\051"
+  /* 0x2a */ "\000\052" "\000\053" "\000\054" "\000\055" "\000\056" "\000\057"
+  /* 0x30 */ "\000\060" "\000\061" "\000\062" "\000\063" "\000\064" "\000\065"
+  /* 0x36 */ "\000\066" "\000\067" "\000\070" "\000\071" "\000\072" "\000\073"
+  /* 0x3c */ "\000\074" "\000\075" "\000\076" "\000\077" "\000\100" "\000\101"
+  /* 0x42 */ "\000\102" "\000\103" "\000\104" "\000\105" "\000\106" "\000\107"
+  /* 0x48 */ "\000\110" "\000\111" "\000\112" "\000\113" "\000\114" "\000\115"
+  /* 0x4e */ "\000\116" "\000\117" "\000\120" "\000\121" "\000\122" "\000\123"
+  /* 0x54 */ "\000\124" "\000\125" "\000\126" "\000\127" "\000\130" "\000\131"
+  /* 0x5a */ "\000\132" "\000\133" "\000\134" "\000\135" "\000\136" "\000\137"
+  /* 0x60 */ "\000\140" "\000\101" "\000\102" "\000\103" "\000\104" "\000\105"
+  /* 0x66 */ "\000\106" "\000\107" "\000\110" "\000\111" "\000\112" "\000\113"
+  /* 0x6c */ "\000\114" "\000\115" "\000\116" "\000\117" "\000\120" "\000\121"
+  /* 0x72 */ "\000\122" "\000\123" "\000\124" "\000\125" "\000\126" "\000\127"
+  /* 0x78 */ "\000\130" "\000\131" "\000\132" "\000\173" "\000\174" "\000\175"
+  /* 0x7e */ "\000\176" "\000\177" "\000\200" "\000\201" "\000\202" "\000\203"
+  /* 0x84 */ "\000\204" "\000\205" "\000\206" "\000\207" "\000\210" "\000\211"
+  /* 0x8a */ "\000\212" "\000\213" "\000\214" "\000\215" "\000\216" "\000\217"
+  /* 0x90 */ "\000\220" "\000\221" "\000\222" "\000\223" "\000\224" "\000\225"
+  /* 0x96 */ "\000\226" "\000\227" "\000\230" "\000\231" "\000\232" "\000\233"
+  /* 0x9c */ "\000\234" "\000\235" "\000\236" "\000\237" "\000\240" "\000\241"
+  /* 0xa2 */ "\000\242" "\000\243" "\000\244" "\000\245" "\000\246" "\000\247"
+  /* 0xa8 */ "\000\250" "\000\251" "\000\252" "\000\253" "\000\254" "\000\255"
+  /* 0xae */ "\000\256" "\000\257" "\000\260" "\000\261" "\000\262" "\000\263"
+  /* 0xb4 */ "\000\264" "\000\265" "\000\266" "\000\267" "\000\270" "\000\271"
+  /* 0xba */ "\000\272" "\000\273" "\000\274" "\000\275" "\000\276" "\000\277"
+  /* 0xc0 */ "\000\300" "\000\301" "\000\302" "\000\303" "\000\304" "\000\305"
+  /* 0xc6 */ "\000\306" "\000\307" "\000\310" "\000\311" "\000\312" "\000\313"
+  /* 0xcc */ "\000\314" "\000\315" "\000\316" "\000\317" "\000\320" "\000\321"
+  /* 0xd2 */ "\000\322" "\000\323" "\000\324" "\000\325" "\000\326" "\000\327"
+  /* 0xd8 */ "\000\330" "\000\331" "\000\332" "\000\333" "\000\334" "\000\335"
+  /* 0xde */ "\000\336" "\000\337" "\000\340" "\000\341" "\000\342" "\000\343"
+  /* 0xe4 */ "\000\344" "\000\345" "\000\346" "\000\347" "\000\350" "\000\351"
+  /* 0xea */ "\000\352" "\000\353" "\000\354" "\000\355" "\000\356" "\000\357"
+  /* 0xf0 */ "\000\360" "\000\361" "\000\362" "\000\363" "\000\364" "\000\365"
+  /* 0xf6 */ "\000\366" "\000\367" "\000\370" "\000\371" "\000\372" "\000\373"
+  /* 0xfc */ "\000\374" "\000\375" "\000\376" "\000\377" ;
+const char _nl_C_LC_CTYPE_tolower[] =
+  /* 0x00 */ "\000\000" "\000\001" "\000\002" "\000\003" "\000\004" "\000\005"
+  /* 0x06 */ "\000\006" "\000\007" "\000\010" "\000\011" "\000\012" "\000\013"
+  /* 0x0c */ "\000\014" "\000\015" "\000\016" "\000\017" "\000\020" "\000\021"
+  /* 0x12 */ "\000\022" "\000\023" "\000\024" "\000\025" "\000\026" "\000\027"
+  /* 0x18 */ "\000\030" "\000\031" "\000\032" "\000\033" "\000\034" "\000\035"
+  /* 0x1e */ "\000\036" "\000\037" "\000\040" "\000\041" "\000\042" "\000\043"
+  /* 0x24 */ "\000\044" "\000\045" "\000\046" "\000\047" "\000\050" "\000\051"
+  /* 0x2a */ "\000\052" "\000\053" "\000\054" "\000\055" "\000\056" "\000\057"
+  /* 0x30 */ "\000\060" "\000\061" "\000\062" "\000\063" "\000\064" "\000\065"
+  /* 0x36 */ "\000\066" "\000\067" "\000\070" "\000\071" "\000\072" "\000\073"
+  /* 0x3c */ "\000\074" "\000\075" "\000\076" "\000\077" "\000\100" "\000\141"
+  /* 0x42 */ "\000\142" "\000\143" "\000\144" "\000\145" "\000\146" "\000\147"
+  /* 0x48 */ "\000\150" "\000\151" "\000\152" "\000\153" "\000\154" "\000\155"
+  /* 0x4e */ "\000\156" "\000\157" "\000\160" "\000\161" "\000\162" "\000\163"
+  /* 0x54 */ "\000\164" "\000\165" "\000\166" "\000\167" "\000\170" "\000\171"
+  /* 0x5a */ "\000\172" "\000\133" "\000\134" "\000\135" "\000\136" "\000\137"
+  /* 0x60 */ "\000\140" "\000\141" "\000\142" "\000\143" "\000\144" "\000\145"
+  /* 0x66 */ "\000\146" "\000\147" "\000\150" "\000\151" "\000\152" "\000\153"
+  /* 0x6c */ "\000\154" "\000\155" "\000\156" "\000\157" "\000\160" "\000\161"
+  /* 0x72 */ "\000\162" "\000\163" "\000\164" "\000\165" "\000\166" "\000\167"
+  /* 0x78 */ "\000\170" "\000\171" "\000\172" "\000\173" "\000\174" "\000\175"
+  /* 0x7e */ "\000\176" "\000\177" "\000\200" "\000\201" "\000\202" "\000\203"
+  /* 0x84 */ "\000\204" "\000\205" "\000\206" "\000\207" "\000\210" "\000\211"
+  /* 0x8a */ "\000\212" "\000\213" "\000\214" "\000\215" "\000\216" "\000\217"
+  /* 0x90 */ "\000\220" "\000\221" "\000\222" "\000\223" "\000\224" "\000\225"
+  /* 0x96 */ "\000\226" "\000\227" "\000\230" "\000\231" "\000\232" "\000\233"
+  /* 0x9c */ "\000\234" "\000\235" "\000\236" "\000\237" "\000\240" "\000\241"
+  /* 0xa2 */ "\000\242" "\000\243" "\000\244" "\000\245" "\000\246" "\000\247"
+  /* 0xa8 */ "\000\250" "\000\251" "\000\252" "\000\253" "\000\254" "\000\255"
+  /* 0xae */ "\000\256" "\000\257" "\000\260" "\000\261" "\000\262" "\000\263"
+  /* 0xb4 */ "\000\264" "\000\265" "\000\266" "\000\267" "\000\270" "\000\271"
+  /* 0xba */ "\000\272" "\000\273" "\000\274" "\000\275" "\000\276" "\000\277"
+  /* 0xc0 */ "\000\300" "\000\301" "\000\302" "\000\303" "\000\304" "\000\305"
+  /* 0xc6 */ "\000\306" "\000\307" "\000\310" "\000\311" "\000\312" "\000\313"
+  /* 0xcc */ "\000\314" "\000\315" "\000\316" "\000\317" "\000\320" "\000\321"
+  /* 0xd2 */ "\000\322" "\000\323" "\000\324" "\000\325" "\000\326" "\000\327"
+  /* 0xd8 */ "\000\330" "\000\331" "\000\332" "\000\333" "\000\334" "\000\335"
+  /* 0xde */ "\000\336" "\000\337" "\000\340" "\000\341" "\000\342" "\000\343"
+  /* 0xe4 */ "\000\344" "\000\345" "\000\346" "\000\347" "\000\350" "\000\351"
+  /* 0xea */ "\000\352" "\000\353" "\000\354" "\000\355" "\000\356" "\000\357"
+  /* 0xf0 */ "\000\360" "\000\361" "\000\362" "\000\363" "\000\364" "\000\365"
+  /* 0xf6 */ "\000\366" "\000\367" "\000\370" "\000\371" "\000\372" "\000\373"
+  /* 0xfc */ "\000\374" "\000\375" "\000\376" "\000\377" ;
+#else
+#error "BYTE_ORDER" BYTE_ORDER not handled.
+#endif
 
-CONST struct ctype_info *_ctype_info = &__ctype_C;
+
+const struct locale_data _nl_C_LC_CTYPE = 
+{
+  NULL, 0, /* no file mapped */
+  6,
+#if BYTE_ORDER == BIG_ENDIAN
+  _nl_C_LC_CTYPE_class, _nl_C_LC_CTYPE_toupper,	_nl_C_LC_CTYPE_tolower,
+#endif
+  NULL, NULL, NULL,
+#if BYTE_ORDER == LITTLE_ENDIAN
+  _nl_C_LC_CTYPE_class, _nl_C_LC_CTYPE_toupper,	_nl_C_LC_CTYPE_tolower,
+#endif
+};
diff --git a/locale/C-ctype_ct.c b/locale/C-ctype_ct.c
deleted file mode 100644
index b77e809a52..0000000000
--- a/locale/C-ctype_ct.c
+++ /dev/null
@@ -1,793 +0,0 @@
-#include <ansidecl.h>
-#include <localeinfo.h>
-#include <stddef.h>
-#include <ctype.h>
-
-CONST unsigned short int __ctype_b_C[] =
-  {
-    0,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl|_ISspace|_ISblank,
-    _IScntrl|_ISspace,
-    _IScntrl|_ISspace,
-    _IScntrl|_ISspace,
-    _IScntrl|_ISspace,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _ISspace|_NOgraph|_ISblank,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISdigit|_IShex,
-    _ISdigit|_IShex,
-    _ISdigit|_IShex,
-    _ISdigit|_IShex,
-    _ISdigit|_IShex,
-    _ISdigit|_IShex,
-    _ISdigit|_IShex,
-    _ISdigit|_IShex,
-    _ISdigit|_IShex,
-    _ISdigit|_IShex,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISalpha|_ISupper|_IShex,
-    _ISalpha|_ISupper|_IShex,
-    _ISalpha|_ISupper|_IShex,
-    _ISalpha|_ISupper|_IShex,
-    _ISalpha|_ISupper|_IShex,
-    _ISalpha|_ISupper|_IShex,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISalpha|_ISupper,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISalpha|_ISlower|_IShex,
-    _ISalpha|_ISlower|_IShex,
-    _ISalpha|_ISlower|_IShex,
-    _ISalpha|_ISlower|_IShex,
-    _ISalpha|_ISlower|_IShex,
-    _ISalpha|_ISlower|_IShex,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISalpha|_ISlower,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _ISpunct,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-    _IScntrl,
-  };
-CONST short int __ctype_tolower_C[] =
-  {
-    -1,
-    0000,
-    0001,
-    0002,
-    0003,
-    0004,
-    0005,
-    0006,
-    0007,
-    0010,
-    0011,
-    0012,
-    0013,
-    0014,
-    0015,
-    0016,
-    0017,
-    0020,
-    0021,
-    0022,
-    0023,
-    0024,
-    0025,
-    0026,
-    0027,
-    0030,
-    0031,
-    0032,
-    0033,
-    0034,
-    0035,
-    0036,
-    0037,
-    0040,
-    '!',
-    '"',
-    '#',
-    '$',
-    '%',
-    '&',
-    '\'',
-    '(',
-    ')',
-    '*',
-    '+',
-    ',',
-    '-',
-    '.',
-    '/',
-    '0',
-    '1',
-    '2',
-    '3',
-    '4',
-    '5',
-    '6',
-    '7',
-    '8',
-    '9',
-    ':',
-    ';',
-    '<',
-    '=',
-    '>',
-    '?',
-    '@',
-    'a',
-    'b',
-    'c',
-    'd',
-    'e',
-    'f',
-    'g',
-    'h',
-    'i',
-    'j',
-    'k',
-    'l',
-    'm',
-    'n',
-    'o',
-    'p',
-    'q',
-    'r',
-    's',
-    't',
-    'u',
-    'v',
-    'w',
-    'x',
-    'y',
-    'z',
-    '[',
-    '\\',
-    ']',
-    '^',
-    '_',
-    '`',
-    'a',
-    'b',
-    'c',
-    'd',
-    'e',
-    'f',
-    'g',
-    'h',
-    'i',
-    'j',
-    'k',
-    'l',
-    'm',
-    'n',
-    'o',
-    'p',
-    'q',
-    'r',
-    's',
-    't',
-    'u',
-    'v',
-    'w',
-    'x',
-    'y',
-    'z',
-    '{',
-    '|',
-    '}',
-    '~',
-    0177,
-    0200,
-    0201,
-    0202,
-    0203,
-    0204,
-    0205,
-    0206,
-    0207,
-    0210,
-    0211,
-    0212,
-    0213,
-    0214,
-    0215,
-    0216,
-    0217,
-    0220,
-    0221,
-    0222,
-    0223,
-    0224,
-    0225,
-    0226,
-    0227,
-    0230,
-    0231,
-    0232,
-    0233,
-    0234,
-    0235,
-    0236,
-    0237,
-    0240,
-    0241,
-    0242,
-    0243,
-    0244,
-    0245,
-    0246,
-    0247,
-    0250,
-    0251,
-    0252,
-    0253,
-    0254,
-    0255,
-    0256,
-    0257,
-    0260,
-    0261,
-    0262,
-    0263,
-    0264,
-    0265,
-    0266,
-    0267,
-    0270,
-    0271,
-    0272,
-    0273,
-    0274,
-    0275,
-    0276,
-    0277,
-    0300,
-    0301,
-    0302,
-    0303,
-    0304,
-    0305,
-    0306,
-    0307,
-    0310,
-    0311,
-    0312,
-    0313,
-    0314,
-    0315,
-    0316,
-    0317,
-    0320,
-    0321,
-    0322,
-    0323,
-    0324,
-    0325,
-    0326,
-    0327,
-    0330,
-    0331,
-    0332,
-    0333,
-    0334,
-    0335,
-    0336,
-    0337,
-    0340,
-    0341,
-    0342,
-    0343,
-    0344,
-    0345,
-    0346,
-    0347,
-    0350,
-    0351,
-    0352,
-    0353,
-    0354,
-    0355,
-    0356,
-    0357,
-    0360,
-    0361,
-    0362,
-    0363,
-    0364,
-    0365,
-    0366,
-    0367,
-    0370,
-    0371,
-    0372,
-    0373,
-    0374,
-    0375,
-    0376,
-    0377,
-  };
-CONST short int __ctype_toupper_C[] =
-  {
-    -1,
-    0000,
-    0001,
-    0002,
-    0003,
-    0004,
-    0005,
-    0006,
-    0007,
-    0010,
-    0011,
-    0012,
-    0013,
-    0014,
-    0015,
-    0016,
-    0017,
-    0020,
-    0021,
-    0022,
-    0023,
-    0024,
-    0025,
-    0026,
-    0027,
-    0030,
-    0031,
-    0032,
-    0033,
-    0034,
-    0035,
-    0036,
-    0037,
-    0040,
-    '!',
-    '"',
-    '#',
-    '$',
-    '%',
-    '&',
-    '\'',
-    '(',
-    ')',
-    '*',
-    '+',
-    ',',
-    '-',
-    '.',
-    '/',
-    '0',
-    '1',
-    '2',
-    '3',
-    '4',
-    '5',
-    '6',
-    '7',
-    '8',
-    '9',
-    ':',
-    ';',
-    '<',
-    '=',
-    '>',
-    '?',
-    '@',
-    'A',
-    'B',
-    'C',
-    'D',
-    'E',
-    'F',
-    'G',
-    'H',
-    'I',
-    'J',
-    'K',
-    'L',
-    'M',
-    'N',
-    'O',
-    'P',
-    'Q',
-    'R',
-    'S',
-    'T',
-    'U',
-    'V',
-    'W',
-    'X',
-    'Y',
-    'Z',
-    '[',
-    '\\',
-    ']',
-    '^',
-    '_',
-    '`',
-    'A',
-    'B',
-    'C',
-    'D',
-    'E',
-    'F',
-    'G',
-    'H',
-    'I',
-    'J',
-    'K',
-    'L',
-    'M',
-    'N',
-    'O',
-    'P',
-    'Q',
-    'R',
-    'S',
-    'T',
-    'U',
-    'V',
-    'W',
-    'X',
-    'Y',
-    'Z',
-    '{',
-    '|',
-    '}',
-    '~',
-    0177,
-    0200,
-    0201,
-    0202,
-    0203,
-    0204,
-    0205,
-    0206,
-    0207,
-    0210,
-    0211,
-    0212,
-    0213,
-    0214,
-    0215,
-    0216,
-    0217,
-    0220,
-    0221,
-    0222,
-    0223,
-    0224,
-    0225,
-    0226,
-    0227,
-    0230,
-    0231,
-    0232,
-    0233,
-    0234,
-    0235,
-    0236,
-    0237,
-    0240,
-    0241,
-    0242,
-    0243,
-    0244,
-    0245,
-    0246,
-    0247,
-    0250,
-    0251,
-    0252,
-    0253,
-    0254,
-    0255,
-    0256,
-    0257,
-    0260,
-    0261,
-    0262,
-    0263,
-    0264,
-    0265,
-    0266,
-    0267,
-    0270,
-    0271,
-    0272,
-    0273,
-    0274,
-    0275,
-    0276,
-    0277,
-    0300,
-    0301,
-    0302,
-    0303,
-    0304,
-    0305,
-    0306,
-    0307,
-    0310,
-    0311,
-    0312,
-    0313,
-    0314,
-    0315,
-    0316,
-    0317,
-    0320,
-    0321,
-    0322,
-    0323,
-    0324,
-    0325,
-    0326,
-    0327,
-    0330,
-    0331,
-    0332,
-    0333,
-    0334,
-    0335,
-    0336,
-    0337,
-    0340,
-    0341,
-    0342,
-    0343,
-    0344,
-    0345,
-    0346,
-    0347,
-    0350,
-    0351,
-    0352,
-    0353,
-    0354,
-    0355,
-    0356,
-    0357,
-    0360,
-    0361,
-    0362,
-    0363,
-    0364,
-    0365,
-    0366,
-    0367,
-    0370,
-    0371,
-    0372,
-    0373,
-    0374,
-    0375,
-    0376,
-    0377,
-  };
-
-
-CONST struct ctype_ctype_info __ctype_ctype_C =
-  {
-    (unsigned short int *) __ctype_b_C,
-    (short int *) __ctype_tolower_C,
-    (short int *) __ctype_toupper_C
-  };
diff --git a/locale/C-ctype_mb.c b/locale/C-ctype_mb.c
deleted file mode 100644
index fb2309a88d..0000000000
--- a/locale/C-ctype_mb.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <ansidecl.h>
-#include <localeinfo.h>
-#include <stddef.h>
-
-
-CONST struct ctype_mbchar_info __ctype_mbchar_C =
-  {
-    0, NULL
-  };
diff --git a/locale/C-messages.c b/locale/C-messages.c
new file mode 100644
index 0000000000..d72958fc23
--- /dev/null
+++ b/locale/C-messages.c
@@ -0,0 +1,17 @@
+/* Generated by GNU locale 0.1.
+   Copyright (C) 1995 Free Software Foundation, Inc.
+This is free software; see the source for copying conditions.
+There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE.  */
+
+#include "localeinfo.h"
+
+const struct locale_data _nl_C_LC_MESSAGES =
+{
+  NULL, 0, /* no file mapped */
+  4,
+  "[yY][[:alpha:]]",
+  "[nN][[:alpha:]]",
+  "",
+  "",
+};
diff --git a/locale/C-monetary.c b/locale/C-monetary.c
index 1e5990f317..085ab017a2 100644
--- a/locale/C-monetary.c
+++ b/locale/C-monetary.c
@@ -1,22 +1,28 @@
-#include <ansidecl.h>
-#include <localeinfo.h>
-#include <stddef.h>
+/* Generated by GNU locale 0.1.
+   Copyright (C) 1995 Free Software Foundation, Inc.
+This is free software; see the source for copying conditions.
+There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE.  */
 
+#include "localeinfo.h"
 
-CONST struct monetary_info __monetary_C =
-  {
-    (char *) "", (char *) "",
-    (char *) "", (char *) "",
-    (char *) "",
-    (char *) "", (char *) "",
-    CHAR_MAX,
-    CHAR_MAX,
-    CHAR_MAX,
-    CHAR_MAX,
-    CHAR_MAX,
-    CHAR_MAX,
-    CHAR_MAX,
-    CHAR_MAX
-  };
-
-CONST struct monetary_info *_monetary_info = &__monetary_C;
+const struct locale_data _nl_C_LC_MONETARY =
+{
+  NULL, 0, /* no file mapped */
+  15,
+  "",
+  "",
+  "",
+  "",
+  "\377",
+  "",
+  "",
+  "\377",
+  "\377",
+  "\377",
+  "\377",
+  "\377",
+  "\377",
+  "\377",
+  "\377",
+};
diff --git a/locale/C-numeric.c b/locale/C-numeric.c
index 890ab37d16..712c3a6239 100644
--- a/locale/C-numeric.c
+++ b/locale/C-numeric.c
@@ -1,12 +1,16 @@
-#include <ansidecl.h>
-#include <localeinfo.h>
-#include <stddef.h>
+/* Generated by GNU locale 0.1.
+   Copyright (C) 1995 Free Software Foundation, Inc.
+This is free software; see the source for copying conditions.
+There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE.  */
 
+#include "localeinfo.h"
 
-CONST struct numeric_info __numeric_C =
-  {
-    (char *) ".", (char *) "",
-    (char *) ""
-  };
-
-CONST struct numeric_info *_numeric_info = &__numeric_C;
+const struct locale_data _nl_C_LC_NUMERIC =
+{
+  NULL, 0, /* no file mapped */
+  3,
+  ".",
+  "",
+  "\377",
+};
diff --git a/locale/C-response.c b/locale/C-response.c
deleted file mode 100644
index d823886b34..0000000000
--- a/locale/C-response.c
+++ /dev/null
@@ -1,12 +0,0 @@
-#include <ansidecl.h>
-#include <localeinfo.h>
-#include <stddef.h>
-
-
-CONST struct response_info __response_C =
-  {
-    (char *) "[yY][[:alpha:]]",
-    (char *) "[nN][[:alpha:]]"
-  };
-
-CONST struct response_info *_response_info = &__response_C;
diff --git a/locale/C-time.c b/locale/C-time.c
index 43930612ef..5329ae65fb 100644
--- a/locale/C-time.c
+++ b/locale/C-time.c
@@ -1,25 +1,57 @@
-/* Built-in time information for `C' locale,
-   generated Thu Jan  1 00:00:00 1970 by li2c.  */
+/* Generated by GNU locale 0.1.
+   Copyright (C) 1995 Free Software Foundation, Inc.
+This is free software; see the source for copying conditions.
+There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE.  */
 
-#include <ansidecl.h>
-#include <localeinfo.h>
-#include <stddef.h>
+#include "localeinfo.h"
 
-
-CONST struct time_info __time_C =
-  {
-    { 
-(char *) "Sun", (char *) "Mon", (char *) "Tue", (char *) "Wed", (char *) "Thu", (char *) "Fri", (char *) "Sat",  },
-
-    { 
-(char *) "Sunday", (char *) "Monday", (char *) "Tuesday", (char *) "Wednesday", (char *) "Thursday", (char *) "Friday", (char *) "Saturday",  },
-    { 
-(char *) "Jan", (char *) "Feb", (char *) "Mar", (char *) "Apr", (char *) "May", (char *) "Jun", (char *) "Jul", (char *) "Aug", (char *) "Sep", (char *) "Oct", (char *) "Nov", (char *) "Dec",  },
-    { 
-(char *) "January", (char *) "February", (char *) "March", (char *) "April", (char *) "May", (char *) "June", (char *) "July", (char *) "August", (char *) "September", (char *) "October", (char *) "November", (char *) "December",  },
-    { (char *) "AM", (char *) "PM" },
-    (char *) "%a %b %d %H:%M:%S %Y", (char *) "%m/%d/%y", (char *) "%H:%M:%S",
-    (char *) "GMT", (char *) ""
-  };
-
-CONST struct time_info *_time_info = &__time_C;
+const struct locale_data _nl_C_LC_TIME =
+{
+  NULL, 0, /* no file mapped */
+  44,
+  "Sun",
+  "Mon",
+  "Tue",
+  "Wed",
+  "Thu",
+  "Fri",
+  "Sat",
+  "Sunday",
+  "Monday",
+  "Tuesday",
+  "Wednesday",
+  "Thursday",
+  "Friday",
+  "Saturday",
+  "Jan",
+  "Feb",
+  "Mar",
+  "Apr",
+  "May",
+  "Jun",
+  "Jul",
+  "Aug",
+  "Sep",
+  "Oct",
+  "Nov",
+  "Dec",
+  "January",
+  "February",
+  "March",
+  "April",
+  "May",
+  "June",
+  "July",
+  "August",
+  "September",
+  "October",
+  "November",
+  "December",
+  "AM",
+  "PM",
+  "%a %b %d %H:%M:%S %Y",
+  "%m/%d/%y",
+  "%H:%M:%S",
+  NULL,
+};
diff --git a/locale/Makefile b/locale/Makefile
index 630b96032f..ec80014c99 100644
--- a/locale/Makefile
+++ b/locale/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+# Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -21,11 +21,10 @@
 #
 subdir	:= locale
 
-headers	:= locale.h localeinfo.h
-
-routines	:= setlocale localeconv
-aux		:= C-collate C-ctype C-ctype_ct C-ctype_mb \
-		   C-monetary C-numeric C-response C-time
-
+headers		:= locale.h
+distribute	:= localeinfo.h categories.def
+routines	:= setlocale loadlocale localeconv
+categories	:= ctype messages monetary numeric time # collate
+aux		= $(categories:%=lc-%) $(categories:%=C-%)
 
 include ../Rules
diff --git a/locale/categories.def b/locale/categories.def
new file mode 100644
index 0000000000..166f4b28fc
--- /dev/null
+++ b/locale/categories.def
@@ -0,0 +1,116 @@
+/* Definition of all available locale categories and their items.  -*- C -*-
+Copyright (C) 1995 Free Software Foundation, Inc.
+
+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.
+
+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., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/* These definitions are used by the locale-related files in the C library
+   and the programs `localedef' and `locale'.
+
+   The general format of the descriptions is like this:
+
+     DEFINE_CATEGORY (ID, name, ( items ), setlocale-postload,
+		      locale-input, locale-check, locale-output)
+
+   where items itself is an array of entries in the form
+
+     { ID, name, value-type, min, max }
+
+   The usage of the load, check, output functions depends on the individual
+   program code which loads this file.
+
+   The various value types for the items are `string', `stringarray', `byte'
+   and `bytearray'.  These cover all possiblee values in the current locale
+   definitions.  `min' and `max' can be individually used again.  */
+
+#ifndef NO_POSTLOAD
+#define NO_POSTLOAD NULL
+#endif
+
+DEFINE_CATEGORY (LC_COLLATE, "LC_COLLATE",
+		   (
+		     { 0 }	/* No data encoding yet.  */
+		   ), NO_POSTLOAD, collate_input, NULL, NULL )
+
+
+/* The actual definition of ctype is meaningless here.  It is hard coded in
+   the code because it has to be handled very specially.  Only the names of
+   the functions are important.  */
+DEFINE_CATEGORY (LC_CTYPE, "LC_CTYPE",
+		   (
+		     { _NL_CTYPE_CLASS_EB, "ctype-class-eb", string },
+		     { _NL_CTYPE_TOUPPER_EB, "ctype-toupper-eb", string },
+		     { _NL_CTYPE_TOLOWER_EB, "ctype-tolower-eb", string },
+		     { _NL_CTYPE_CLASS_EL, "ctype-class-el", string },
+		     { _NL_CTYPE_TOUPPER_EL, "ctype-toupper-el", string },
+		     { _NL_CTYPE_TOLOWER_EL, "ctype-tolower-el", string },
+		     { 0 }
+		   ), _nl_postload_ctype,
+		 ctype_input, ctype_check, ctype_output )
+
+
+DEFINE_CATEGORY (LC_MONETARY, "LC_MONETARY",
+		   (
+		     { INT_CURR_SYMBOL,   "int_curr_symbol",   string },
+		     { CURRENCY_SYMBOL,   "currency_symbol",   string },
+		     { MON_DECIMAL_POINT, "mon_decimal_point", string },
+		     { MON_THOUSANDS_SEP, "mon_thousands_sep", string },
+		     { MON_GROUPING,      "mon_grouping",      bytearray },
+		     { POSITIVE_SIGN,     "positive_sign",     string },
+		     { NEGATIVE_SIGN,     "negative_sign",     string },
+		     { INT_FRAC_DIGITS,   "int_frac_digits",   byte },
+		     { FRAC_DIGITS,       "frac_digits",       byte },
+		     { P_CS_PRECEDES,     "p_cs_precedes",     byte, 0, 1 },
+		     { P_SEP_BY_SPACE,    "p_sep_by_space",    byte, 0, 2 },
+		     { N_CS_PRECEDES,     "n_cs_precedes",     byte, 0, 1 },
+		     { N_SEP_BY_SPACE,    "n_sep_by_space",    byte, 0, 2 },
+		     { P_SIGN_POSN,       "p_sign_posn",       byte, 0, 4 },
+		     { N_SIGN_POSN,       "n_sign_posn",       byte, 0, 4 },
+		     { 0 }
+		   ), NO_POSTLOAD, NULL, monetary_check, NULL )
+
+
+DEFINE_CATEGORY (LC_NUMERIC, "LC_NUMERIC",
+		   (
+		     { DECIMAL_POINT, "decimal_point", string },
+		     { THOUSANDS_SEP, "thousands_sep", string },
+		     { GROUPING,      "grouping",      bytearray },
+		     { 0 }
+		   ), NO_POSTLOAD, NULL, numeric_check, NULL)
+
+
+DEFINE_CATEGORY (LC_TIME, "LC_TIME",
+		   (
+		     { ABDAY_1,    "abday",      stringarray,  7,  7 },
+		     { DAY_1,      "day",        stringarray,  7,  7 },
+		     { ABMON_1,    "abmon",      stringarray, 12, 12 },
+		     { MON_1,      "mon",        stringarray, 12, 12 },
+		     { AM_STR,     "am_pm",      stringarray,  2,  2 },
+		     { D_T_FMT,    "d_t_fmt",    string },
+		     { D_FMT,      "d_fmt",      string },
+		     { T_FMT,      "t_fmt",      string },
+		     { T_FMT_AMPM, "t_fmt_ampm", string },
+		     { 0 }
+		   ), NO_POSTLOAD, NULL, NULL, NULL )
+
+
+DEFINE_CATEGORY (LC_MESSAGES, "LC_MESSAGES",
+		   (
+		     { YESEXPR, "yesexpr", string },
+		     { NOEXPR,  "noexpr",  string },
+		     { YESSTR,  "yesstr",  string },
+		     { NOSTR,   "nostr",   string },
+		     { 0 }
+		   ), NO_POSTLOAD, NULL, messages_check, NULL )
diff --git a/locale/langinfo.h b/locale/langinfo.h
new file mode 100644
index 0000000000..cf3b8c054b
--- /dev/null
+++ b/locale/langinfo.h
@@ -0,0 +1,165 @@
+/* nl_langinfo -- Access to locale-dependent parameters.
+Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+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.
+
+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., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#ifndef _LANGINFO_H
+#define	_LANGINFO_H 1
+
+#include <locale.h>		/* Define the LC_* category names.  */
+
+__BEGIN_DECLS
+
+/* Construct an `nl_item' value for `nl_langinfo' from a locale category
+   (LC_*) and an item index within the category.  Some code may depend on
+   the item values within a category increasing monotonically with the
+   indices.  */
+#define _NL_ITEM(category, index)	(((category) << 16) | (index))
+
+/* Extract the category and item index from a constructed `nl_item' value.  */
+#define _NL_ITEM_CATEGORY(item)		((int) (item) >> 16)
+#define _NL_ITEM_INDEX(item)		((int) (item) & 0xffff)
+
+
+/* Enumeration of locale items that can be queried with `nl_langinfo'.  */
+typedef enum
+{
+  /* LC_TIME category: date and time formatting.  */
+
+  /* Abbreviated days of the week. */
+  ABDAY_1 = _NL_ITEM (LC_TIME, 0), /* Sun */
+  ABDAY_2,
+  ABDAY_3,
+  ABDAY_4,
+  ABDAY_5,
+  ABDAY_6,
+  ABDAY_7,
+
+  /* Long-named days of the week. */
+  DAY_1,			/* Sunday */
+  DAY_2,			/* Monday */
+  DAY_3,			/* Tuesday */
+  DAY_4,			/* Wednesday */
+  DAY_5,			/* Thursday */
+  DAY_6,			/* Friday */
+  DAY_7,			/* Saturday */
+
+  /* Abbreviated month names.  */
+  ABMON_1,			/* Jan */
+  ABMON_2,
+  ABMON_3,
+  ABMON_4,
+  ABMON_5,
+  ABMON_6,
+  ABMON_7,
+  ABMON_8,
+  ABMON_9,
+  ABMON_10,
+  ABMON_11,
+  ABMON_12,
+
+  /* Long month names.  */
+  MON_1,			/* January */
+  MON_2,
+  MON_3,
+  MON_4,
+  MON_5,
+  MON_6,
+  MON_7,
+  MON_8,
+  MON_9,
+  MON_10,
+  MON_11,
+  MON_12,
+
+  AM_STR,			/* Ante meridian string.  */
+  PM_STR,			/* Post meridian string.  */
+
+  D_T_FMT,			/* Date and time format for strftime.  */
+  D_FMT,			/* Date format for strftime.  */
+  T_FMT,			/* Time format for strftime.  */
+  T_FMT_AMPM,			/* 12-hour time format for strftime.  */
+
+  ERA,				/* Alternate era.  */
+  ERA_YEAR,			/* Year in alternate era format.  */
+  ERA_D_FMT,			/* Date in alternate ear format.  */
+  ALT_DIGITS,			/* Alternate symbols for digits.  */
+
+  _NL_NUM_LC_TIME,		/* Number of indices in LC_TIME category.  */
+
+  /* LC_CTYPE category: character classification.
+     This information is accessed by the functions in <ctype.h>.
+     These `nl_langinfo' names are used internally.  */
+  _NL_CTYPE_CLASS_EB = _NL_ITEM (LC_CTYPE, 0),
+  _NL_CTYPE_TOUPPER_EB,
+  _NL_CTYPE_TOLOWER_EB,
+  _NL_CTYPE_CLASS_EL,
+  _NL_CTYPE_TOUPPER_EL,
+  _NL_CTYPE_TOLOWER_EL,
+  _NL_NUM_LC_CTYPE,
+
+  /* LC_MONETARY category: formatting of monetary quantities.
+     These items each correspond to a member of `struct lconv',
+     defined in <locale.h>.  */
+  INT_CURR_SYMBOL = _NL_ITEM (LC_MONETARY, 0),
+  CURRENCY_SYMBOL,
+  MON_DECIMAL_POINT,
+  MON_THOUSANDS_SEP,
+  MON_GROUPING,
+  POSITIVE_SIGN,
+  NEGATIVE_SIGN,
+  INT_FRAC_DIGITS,
+  FRAC_DIGITS,
+  P_CS_PRECEDES,
+  P_SEP_BY_SPACE,
+  N_CS_PRECEDES,
+  N_SEP_BY_SPACE,
+  P_SIGN_POSN,
+  N_SIGN_POSN,
+  _NL_NUM_LC_MONETARY,
+
+  /* LC_NUMERIC category: formatting of numbers.
+     These also correspond to members of `struct lconv'; see <locale.h>.  */
+  DECIMAL_POINT = _NL_ITEM (LC_NUMERIC, 0),
+  THOUSANDS_SEP,
+  GROUPING,
+  _NL_NUM_LC_NUMERIC,
+
+  YESEXPR = _NL_ITEM (LC_MESSAGES, 0), /* Regex matching ``yes'' input.  */
+  NOEXPR,			/* Regex matching ``no'' input.  */
+  YESSTR,			/* Output string for ``yes''.  */
+  NOSTR,			/* Output string for ``no''.  */
+  _NL_NUM_LC_MESSAGES,
+
+  /* Stubs for unfinished categories.  */
+  _NL_NUM_LC_COLLATE = 0,
+
+} nl_item;
+
+
+/* Return the current locale's value for ITEM.
+   If ITEM is invalid, an empty string is returned.
+
+   The string returned will not change until `setlocale' is called;
+   it is usually in read-only memory and cannot be modified.  */
+
+extern char *nl_langinfo __P ((nl_item item));
+
+
+__END_DECLS
+
+#endif	/* langinfo.h */
diff --git a/locale/lc-ctype.c b/locale/lc-ctype.c
new file mode 100644
index 0000000000..9b72ad16eb
--- /dev/null
+++ b/locale/lc-ctype.c
@@ -0,0 +1,51 @@
+/* Define current locale data for LC_CTYPE category.
+Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+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.
+
+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., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include "localeinfo.h"
+#include <ctype.h>
+#include <endian.h>
+
+_NL_CURRENT_DEFINE (LC_CTYPE);
+
+/* We are called after loading LC_CTYPE data to load it into
+   the variables used by the ctype.h macros.
+
+   There are three arrays of short ints which need to be indexable
+   from -128 to 255 inclusive.  Stored in the locale data file are
+   a copy of each for each byte order.  */
+
+void
+_nl_postload_ctype (void)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+#define bo(x) x##_EB
+#elif BYTE_ORDER == LITTLE_ENDIAN
+#define bo(x) x##_EL
+#else
+#error bizarre byte order
+#endif
+
+#define current(unsigned,x) \
+  ((const unsigned short int *) _NL_CURRENT (LC_CTYPE, bo(_NL_CTYPE_##x)) \
+   + 128)
+
+  __ctype_b = current (unsigned, CLASS);
+  __ctype_toupper = current (, TOUPPER);
+  __ctype_tolower = current (, TOLOWER);
+}
diff --git a/locale/lc-messages.c b/locale/lc-messages.c
new file mode 100644
index 0000000000..b7e9bbfd3a
--- /dev/null
+++ b/locale/lc-messages.c
@@ -0,0 +1,22 @@
+/* Define current locale data for LC_MESSAGES category.
+Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+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.
+
+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., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include "localeinfo.h"
+
+_NL_CURRENT_DEFINE (LC_MESSAGES);
diff --git a/locale/lc-monetary.c b/locale/lc-monetary.c
new file mode 100644
index 0000000000..f29f29a4b6
--- /dev/null
+++ b/locale/lc-monetary.c
@@ -0,0 +1,22 @@
+/* Define current locale data for LC_MONETARY category.
+Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+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.
+
+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., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include "localeinfo.h"
+
+_NL_CURRENT_DEFINE (LC_MONETARY);
diff --git a/locale/lc-numeric.c b/locale/lc-numeric.c
new file mode 100644
index 0000000000..19e9d966bc
--- /dev/null
+++ b/locale/lc-numeric.c
@@ -0,0 +1,22 @@
+/* Define current locale data for LC_NUMERIC category.
+Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+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.
+
+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., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include "localeinfo.h"
+
+_NL_CURRENT_DEFINE (LC_NUMERIC);
diff --git a/locale/lc-time.c b/locale/lc-time.c
new file mode 100644
index 0000000000..7b84f99dc2
--- /dev/null
+++ b/locale/lc-time.c
@@ -0,0 +1,22 @@
+/* Define current locale data for LC_TIME category.
+Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+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.
+
+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., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include "localeinfo.h"
+
+_NL_CURRENT_DEFINE (LC_TIME);
diff --git a/locale/loadlocale.c b/locale/loadlocale.c
new file mode 100644
index 0000000000..24959a59e8
--- /dev/null
+++ b/locale/loadlocale.c
@@ -0,0 +1,186 @@
+/* Functions to read locale data files.
+Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+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.
+
+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., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include "localeinfo.h"
+
+const size_t _nl_category_num_items[] =
+  {
+#define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
+    [category] = _NL_NUM_##category,
+#include "categories.def"
+#undef	DEFINE_CATEGORY
+  };
+
+struct locale_data *
+_nl_load_locale (int category, char **name)
+{
+  char *file;
+  int fd;
+  struct
+    {
+      unsigned int magic;
+      unsigned int nstrings;
+      unsigned int strindex[0];
+    } *filedata;
+  struct stat st;
+  struct locale_data *newdata;
+  int swap = 0;
+  inline unsigned int SWAP (const unsigned int *inw)
+    {
+      const unsigned char *inc = (const unsigned char *) inw;
+      if (!swap)
+	return *inw;
+      return (inc[3] << 24) | (inc[2] << 16) | (inc[1] << 8) | inc[0];
+    }
+  unsigned int i;
+
+  if ((*name)[0] == '\0')
+    {
+      *name = getenv (_nl_category_names[category]);
+      if (! *name || (*name) == '\0')
+	*name = getenv ("LANG");
+      if (! *name || (*name) == '\0')
+	*name = (char *) "local";
+    }
+
+/* XXX can't use asprintf here */
+  if (asprintf (&file, "%s%s/%s",
+		strchr (*name, '/') != NULL ? "" : "/share/locale/", /* XXX */
+		*name, _nl_category_names[category]) == -1)
+    return NULL;
+
+  fd = __open (file, O_RDONLY);
+  free (file);
+  if (fd < 0)
+    return NULL;
+  if (__fstat (fd, &st) < 0)
+    goto puntfd;
+
+  {
+    /* Map in the file's data.  */
+    int save = errno;
+    filedata = (void *) __mmap ((caddr_t) 0, st.st_size,
+				PROT_READ, MAP_FILE|MAP_COPY, fd, 0);
+    if (filedata == (void *) -1)
+      {
+	if (errno == ENOSYS)
+	  {
+	    /* No mmap; allocate a buffer and read from the file.  */
+	    filedata = malloc (st.st_size);
+	    if (filedata)
+	      {
+		off_t to_read = st.st_size;
+		ssize_t nread;
+		char *p = (char *) filedata;
+		while (to_read > 0)
+		  {
+		    nread = __read (fd, p, to_read);
+		    if (nread <= 0)
+		      {
+			free (filedata);
+			if (nread == 0)
+			  errno = EINVAL; /* Bizarreness going on.  */
+			goto puntfd;
+		      }
+		    p += nread;
+		    to_read -= nread;
+		  }
+	      }
+	    else
+	      goto puntfd;
+	    errno = save;
+	  }
+	else
+	  goto puntfd;
+      }
+  }
+
+  if (filedata->magic == LIMAGIC (category))
+    /* Good data file in our byte order.  */
+    swap = 0;
+  else
+    {
+      /* Try the other byte order.  */
+      swap = 1;
+      if (SWAP (&filedata->magic) != LIMAGIC (category))
+	/* Bad data file in either byte order.  */
+	{
+	puntmap:
+	  __munmap ((caddr_t) filedata, st.st_size);
+	puntfd:
+	  __close (fd);
+	  return NULL;
+	}
+    }
+
+#define W(word)	SWAP (&(word))
+
+  if (W (filedata->nstrings) < _nl_category_num_items[category] ||
+      (sizeof *filedata + W (filedata->nstrings) * sizeof (unsigned int)
+       >= st.st_size))
+    {
+      /* Insufficient data.  */
+      errno = EINVAL;
+      goto puntmap;
+    }
+
+  newdata = malloc (sizeof *newdata +
+		    W (filedata->nstrings) * sizeof (char *));
+  if (! newdata)
+    goto puntmap;
+
+  newdata->filedata = (void *) filedata;
+  newdata->filesize = st.st_size;
+  newdata->nstrings = W (filedata->nstrings);
+  for (i = 0; i < newdata->nstrings; ++i)
+    {
+      unsigned int idx = W (filedata->strindex[i]);
+      if (idx >= newdata->filesize)
+	{
+	  free (newdata);
+	  errno = EINVAL;
+	  goto puntmap;
+	}
+      newdata->strings[i] = newdata->filedata + idx;
+    }
+
+  return newdata;
+}
+
+void
+_nl_free_locale (struct locale_data *data)
+{
+  int save = errno;
+  if (__munmap ((caddr_t) data->filedata, data->filesize) < 0)
+    {
+      if (errno == ENOSYS)
+	free ((void *) data->filedata);
+      errno = save;
+    }
+  free (data);
+}
+
diff --git a/locale/localeconv.c b/locale/localeconv.c
index 1f15165fb3..d846210b7b 100644
--- a/locale/localeconv.c
+++ b/locale/localeconv.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -16,36 +16,37 @@ 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.  */
 
-#include <ansidecl.h>
-#include <localeinfo.h>
 #include <locale.h>
-
+#include "localeinfo.h"
 
 /* Return monetary and numeric information about the current locale.  */
 struct lconv *
-DEFUN_VOID(localeconv)
+localeconv __P ((void))
 {
   static struct lconv result;
 
-  result.decimal_point = (char *) _numeric_info->decimal_point;
-  result.thousands_sep = (char *) _numeric_info->thousands_sep;
-  result.grouping = (char *) _numeric_info->grouping;
-
-  result.int_curr_symbol = (char *) _monetary_info->int_curr_symbol;
-  result.currency_symbol = (char *) _monetary_info->currency_symbol;
-  result.mon_decimal_point = (char *) _monetary_info->mon_decimal_point;
-  result.mon_thousands_sep = (char *) _monetary_info->mon_thousands_sep;
-  result.mon_grouping = (char *) _monetary_info->mon_grouping;
-  result.positive_sign = (char *) _monetary_info->positive_sign;
-  result.negative_sign = (char *) _monetary_info->negative_sign;
-  result.int_frac_digits = _monetary_info->int_frac_digits;
-  result.frac_digits = _monetary_info->frac_digits;
-  result.p_cs_precedes = _monetary_info->p_cs_precedes;
-  result.p_sep_by_space = _monetary_info->p_sep_by_space;
-  result.n_cs_precedes = _monetary_info->p_cs_precedes;
-  result.n_sep_by_space = _monetary_info->n_sep_by_space;
-  result.p_sign_posn = _monetary_info->p_sign_posn;
-  result.n_sign_posn = _monetary_info->n_sign_posn;
+  result.decimal_point = (char *) _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+  result.thousands_sep = (char *) _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
+  result.grouping = (char *) _NL_CURRENT (LC_NUMERIC, GROUPING);
+
+  result.int_curr_symbol = (char *) _NL_CURRENT (LC_MONETARY, INT_CURR_SYMBOL);
+  result.currency_symbol = (char *) _NL_CURRENT (LC_MONETARY, CURRENCY_SYMBOL);
+  result.mon_decimal_point = (char *) _NL_CURRENT (LC_MONETARY,
+						   MON_DECIMAL_POINT);
+  result.mon_thousands_sep = (char *) _NL_CURRENT (LC_MONETARY,
+						   MON_THOUSANDS_SEP);
+  result.mon_grouping = (char *) _NL_CURRENT (LC_MONETARY, MON_GROUPING);
+  result.positive_sign = (char *) _NL_CURRENT (LC_MONETARY, POSITIVE_SIGN);
+  result.negative_sign = (char *) _NL_CURRENT (LC_MONETARY, NEGATIVE_SIGN);
+  result.int_frac_digits = *(char *) _NL_CURRENT (LC_MONETARY,
+						  INT_FRAC_DIGITS);
+  result.frac_digits = *(char *) _NL_CURRENT (LC_MONETARY, FRAC_DIGITS);
+  result.p_cs_precedes = *(char *) _NL_CURRENT (LC_MONETARY, P_CS_PRECEDES);
+  result.p_sep_by_space = *(char *) _NL_CURRENT (LC_MONETARY, P_SEP_BY_SPACE);
+  result.n_cs_precedes = *(char *) _NL_CURRENT (LC_MONETARY, P_CS_PRECEDES);
+  result.n_sep_by_space = *(char *) _NL_CURRENT (LC_MONETARY, N_SEP_BY_SPACE);
+  result.p_sign_posn = *(char *) _NL_CURRENT (LC_MONETARY, P_SIGN_POSN);
+  result.n_sign_posn = *(char *) _NL_CURRENT (LC_MONETARY, N_SIGN_POSN);
 
   return &result;
 }
diff --git a/locale/localeinfo.h b/locale/localeinfo.h
index 5ba5fefa05..bb4738eb5a 100644
--- a/locale/localeinfo.h
+++ b/locale/localeinfo.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+/* localeinfo.h -- declarations for internal libc locale interfaces
+Copyright (C) 1995 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -13,196 +14,54 @@ 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, 1992 Free Software Foundation, Inc., 675 Mass Ave,
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-/* Locale-specific information.  */
+#ifndef _LOCALEINFO_H
+#define _LOCALEINFO_H 1
 
-#ifndef	_LOCALEINFO_H
+#include <stddef.h>
+#include <langinfo.h>
+#include <sys/types.h>
 
-#define	_LOCALEINFO_H	1
+/* Magic number at the beginning of a locale data file for CATEGORY.  */
+#define	LIMAGIC(category)	(0x051472CA ^ (category))
 
-#define	__need_size_t
-#define	__need_wchar_t
-#include <stddef.h>
-#include <limits.h>
-
-
-/* Change these if the `wchar_t' type is changed.  */
-#define	WCHAR_MAX	((wchar_t) UCHAR_MAX)
-
-
-/* Used by multibyte char functions.  */
-typedef struct
-{
-  char *string;			/* Bytes.  */
-  size_t len;			/* # of bytes.  */
-  long int shift;		/* # of mb_char's to shift.  */
-} mb_char;
-
-struct ctype_mbchar_info
-{
-  size_t mb_max;		/* Max MB char length.  */
-  mb_char *mb_chars;		/* MB chars.  */
-};
-
-struct ctype_ctype_info
-{
-  unsigned short int *ctype_b;	/* Characteristics.  */
-  short int *ctype_tolower;	/* Case mappings.  */
-  short int *ctype_toupper;	/* Case mappings.  */
-};
-
-struct ctype_info
-{
-  struct ctype_ctype_info *ctype;
-  struct ctype_mbchar_info *mbchar;
-};
-
-extern __const struct ctype_info *_ctype_info;
-
-/* These are necessary because they are used in a header file.  */
-extern __const unsigned short int *__ctype_b;
-extern __const short int *__ctype_tolower;
-extern __const short int *__ctype_toupper;
-
-
-/* Used by strcoll and strxfrm.  */
-typedef struct
-{
-  unsigned char *values;
-  size_t nvalues;
-} literal_value;
-
-typedef struct
-{
-  union
+/* Structure describing locale data in core for a category.  */
+struct locale_data
   {
-    literal_value literal;
-    /* %%% This may become a regex_t in the future.  */
-    char *regexp;
-  } replace, with;
-  unsigned int regexp:1;
-} subst;
-
-struct collate_info
-{
-  size_t nsubsts;
-  subst *substs;
-
-  unsigned char *values;
-  unsigned char *offsets;
-};
-
-extern __const struct collate_info *_collate_info;
-
-
-/* Used by strtod, atof.  */
-struct numeric_info
-{
-  char *decimal_point;
-  char *thousands_sep;
-  char *grouping;
-};
-
-extern __const struct numeric_info *_numeric_info;
-
-
-/* Used in the return value of localeconv.  */
-struct monetary_info
-{
-  char *int_curr_symbol;
-  char *currency_symbol;
-  char *mon_decimal_point;
-  char *mon_thousands_sep;
-  char *mon_grouping;
-  char *positive_sign;
-  char *negative_sign;
-  char int_frac_digits;
-  char frac_digits;
-  char p_cs_precedes;
-  char p_sep_by_space;
-  char n_cs_precedes;
-  char n_sep_by_space;
-  char p_sign_posn;
-  char n_sign_posn;
-};
-
-extern __const struct monetary_info *_monetary_info;
-
-
-/* Used by strftime, asctime.  */
-struct time_info
-{
-  char *abbrev_wkday[7];	/* Short weekday names.  */
-  char *full_wkday[7];		/* Full weekday names.  */
-  char *abbrev_month[12];	/* Short month names.  */
-  char *full_month[12];		/* Full month names.  */
-  char *ampm[2];		/* "AM" and "PM" strings.  */
-
-  char *date_time;		/* Appropriate date and time format.  */
-  char *date;			/* Appropriate date format.  */
-  char *time;			/* Appropriate time format.  */
-
-  char *ut0;			/* Name for GMT.  */
-  char *tz;			/* Default TZ value.  */
-};
-
-extern __const struct time_info *_time_info;
-
-struct response_info
-{
-  /* Regexp for affirmative answers.  */
-  char *yesexpr;
-
-  /* Regexp for negative answers.  */
-  char *noexpr;
-};
-
-extern __const struct response_info *_response_info;
-
-/* Locale structure.  */
-typedef struct
-{
-  char *name;
-  int categories;
-
-  unsigned int allocated:1;
-
-  int subcategories;
-  size_t num_sublocales;
-  struct sub_locale *sublocales;
-
-  __ptr_t *info;
-} locale;
-
-typedef struct sub_locale
-{
-  unsigned int pointer:1;
-
-  int categories;
-  char *name;
-
-  locale *locale;
-} sublocale;
-
-
-/* This is the magic number that localeinfo object files begin with.
-   In case you're wondering why I chose the value 0x051472CA, it's
-   because I was born on 05-14-72 in Oakland, CA.  */
-#define	LIMAGIC		0x051472CA
-/* This is the magic number that precedes each category-specific section
-   of a localeinfo object file.  It's the arbitrary magic number above,
-   but modified by the category so that it's different from the per-file
-   magic number and unique for each category.  */
-#define	CATEGORY_MAGIC(x)	(LIMAGIC ^ (x))
-
-extern __const char *__lidir, *__lidefault;
-
-extern locale *__find_locale __P ((int categories, __const char *name));
-extern locale *__new_locale __P ((locale *));
-extern locale *__localefile __P ((__const char *file));
-extern void __free_locale __P ((locale *));
+    const char *filedata;	/* Region mapping the file data.  */
+    off_t filesize;		/* Size of the file (and the region).  */
+
+    unsigned int nstrings;	/* Number of strings below.  */
+    const char *strings[0];	/* Items, usually pointers into `filedata'.  */
+  };
+
+
+/* For each category declare the variable for the current locale data.  */
+#define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
+extern const struct locale_data *_nl_current_##category;
+#include "categories.def"
+#undef	DEFINE_CATEGORY
+
+extern const char *const _nl_category_names[LC_ALL];
+
+/* Extract the current CATEGORY locale's string for ITEM.  */
+#define _NL_CURRENT(category, item) \
+  (_nl_current_##category->strings[_NL_ITEM_INDEX (item)])
+
+/* This is used in lc-CATEGORY.c to define _nl_current_CATEGORY.  */
+#define _NL_CURRENT_DEFINE(category) \
+  extern const struct locale_data _nl_C_##category; \
+  const struct locale_data *nl_current_##category = &_nl_C_##category
+
+/* Load the locale data for CATEGORY from the file specified by *NAME.
+   If *NAME is "", use environment variables as specified by POSIX,
+   and fill in *NAME with the actual name used.  */
+extern struct locale_data *_nl_load_locale (int category, char **name);
+
+/* Free the locale data read in by a `_nl_load_locale' call.  */
+extern void _nl_free_locale (struct locale_data *);
 
 
-#endif /* localeinfo.h  */
+#endif	/* localeinfo.h */
diff --git a/locale/nl_langinfo.c b/locale/nl_langinfo.c
new file mode 100644
index 0000000000..4d02abf49e
--- /dev/null
+++ b/locale/nl_langinfo.c
@@ -0,0 +1,63 @@
+/* nl_langinfo -- User interface for extracting locale-dependent parameters.
+Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+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.
+
+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., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <langinfo.h>
+
+/* This array duplicates `_nl_current' defined in setlocale.c; but since
+   the references here are not weak references, this guarantees that the
+   data for all the categories will be linked in.  */
+
+static const struct locale_data * *const nldata[] =
+{
+#define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
+  [category] = &_nl_current_##category,
+#include "categories.def"
+#undef	DEFINE_CATEGORY
+};
+
+
+/* Return a string with the data for locale-dependent parameter ITEM.  */
+
+char *
+nl_langinfo (item)
+     nl_item item;
+{
+  int category = _NL_ITEM_CATEGORY (item);
+  unsigned int index = _NL_ITEM_INDEX (item);
+  const struct locale_data *data;
+
+  if (category < 0 || category >= LC_ALL)
+    {
+      /* Bogus category: bogus item.  */
+      errno = EINVAL;
+      return NULL;
+    }
+
+  data = nldata[category];
+
+  if (index >= data->nstrings)
+    {
+      /* Bogus index for this category: bogus item.  */
+      errno = EINVAL;
+      return NULL;
+    }
+
+  /* Return the string for the specified item.  */
+  return (char *) nldata->strings[index];
+}
diff --git a/locale/setlocale.c b/locale/setlocale.c
index 784ccb1272..79d22ab98d 100644
--- a/locale/setlocale.c
+++ b/locale/setlocale.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -16,30 +16,389 @@ 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.  */
 
-#include <ansidecl.h>
-#include <localeinfo.h>
 #include <errno.h>
-#include <locale.h>
 #include <string.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <langinfo.h>
+#include "localeinfo.h"
+
+/* For each category declare two external variables (with weak references):
+     extern const struct locale_data *_nl_current_CATEGORY;
+   This points to the current locale's in-core data for CATEGORY.
+     extern const struct locale_data _nl_C_CATEGORY;
+   This contains the built-in "C"/"POSIX" locale's data for CATEGORY.
+   Both are weak references; if &_nl_current_CATEGORY is zero,
+   then nothing is using the locale data.  */
+#define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
+extern const struct locale_data *_nl_current_##category;		      \
+extern const struct locale_data _nl_C_##category;			      \
+weak_symbol (_nl_current_##category) weak_symbol (_nl_C_##category)
+#include "categories.def"
+#undef	DEFINE_CATEGORY
+
+/* Array indexed by category of pointers to _nl_current_CATEGORY slots.
+   Elements are zero for categories whose data is never used.  */
+const struct locale_data * *const _nl_current[] =
+{
+#define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
+  [category] = &_nl_current_##category,
+#include "categories.def"
+#undef	DEFINE_CATEGORY
+};
+
+/* Array indexed by category of pointers to _nl_C_CATEGORY slots.
+   Elements are zero for categories whose data is never used.  */
+const struct locale_data *const _nl_C[] =
+{
+#define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
+  [category] = &_nl_C_##category,
+#include "categories.def"
+#undef	DEFINE_CATEGORY
+};
+
+
+/* Define an array of category names (also the environment variable names),
+   indexed by integral category.  */
+const char *const _nl_category_names[] =
+  {
+#define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
+    [category] = category_name,
+#include "categories.def"
+#undef	DEFINE_CATEGORY
+  };
+/* An array of their lengths, for convenience.  */
+const size_t _nl_category_name_sizes[] =
+  {
+#define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
+    [category] = sizeof (category_name) - 1,
+#include "categories.def"
+#undef	DEFINE_CATEGORY
+  };
 
 
-/* Switch to the locale called NAME in CATEGORY.
-   Return a string describing the locale.  This string can
-   be used as the NAME argument in a later call.
-   If NAME is NULL, don't switch locales, but return the current one.
-   If NAME is "", switch to a locale based on the environment variables,
-   as per POSIX.  Return NULL on error.  */
+/* Declare the postload functions used below.  */
+#undef	NO_POSTLOAD
+#define NO_POSTLOAD _nl_postload_ctype /* Harmless thing known to exist.  */
+#define DEFINE_CATEGORY(category, category_name, items, postload, b, c, d) \
+extern void postload (void);
+#include "categories.def"
+#undef	DEFINE_CATEGORY
+#undef	NO_POSTLOAD
+
+/* Define an array indexed by category of postload functions to call after
+   loading and installing that category's data.  */
+void (*const _nl_category_postload[]) (void) =
+  {
+#define DEFINE_CATEGORY(category, category_name, items, postload, b, c, d) \
+    [category] = postload,
+#include "categories.def"
+#undef	DEFINE_CATEGORY
+  };
+
+
+const char _nl_C_name[] = "C";
+
+/* Name of current locale for each individual category.
+   Each is malloc'd unless it is nl_C_name.  */
+const char *_nl_current_names[] =
+  {
+#define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
+    _nl_C_name,
+#include "categories.def"
+#undef	DEFINE_CATEGORY
+  };
+
+/* Composite LC_ALL name for current locale.
+   This is malloc'd unless it's _nl_C_name.  */
+char *_nl_current_composite_name = (char *) _nl_C_name;
+
+
+/* Switch to the locale called NAME in CATEGORY.  Return a string
+   describing the locale.  This string can be used as the NAME argument in
+   a later call.  If NAME is NULL, don't switch locales, but return the
+   current one.  If NAME is "", switch to a locale based on the environment
+   variables, as per POSIX.  Return NULL on error.  */
+
 char *
-DEFUN(setlocale, (category, name), int category AND CONST char *name)
+setlocale (int category, const char *name)
 {
-  /* Braindead implementation until I finish the fancy one.  */
+  /* Return a malloc'd copy of STRING.  */
+  char *copy (const char *string)
+    {
+      size_t len = strlen (string) + 1;
+      char *new = malloc (len);
+      return new ? memcpy (new, string, len) : NULL;
+    }
+
+  /* Construct a new composite name.  */
+  char *new_composite_name (int category, char *newnames[LC_ALL])
+  {
+    size_t lens[LC_ALL], cumlen = 0;
+    int i;
+    char *new, *p;
+    int same = 1;
+
+    for (i = 0; i < LC_ALL; ++i)
+      {
+	char *name = (category == LC_ALL ? newnames[i] :
+		      category == i ? newnames[0] :
+		      (char *) _nl_current_names[i]);
+	lens[i] = strlen (name);
+	cumlen += _nl_category_name_sizes[i] + 1 + lens[i] + 1;
+	if (i > 0 && same && strcmp (name, newnames[0]))
+	  same = 0;
+      }
+
+    if (same)
+      {
+	/* All the categories use the same name.  */
+	new = malloc (lens[0] + 1);
+	if (! new)
+	  {
+	    if (!strcmp (newnames[0], "C") || !strcmp (newnames[0], "POSIX"))
+	      return (char *) _nl_C_name;
+	    return NULL;
+	  }
+	memcpy (new, newnames[0], lens[0] + 1);
+	return new;
+      }
+
+    new = malloc (cumlen);
+    if (! new)
+      return NULL;
+    p = new;
+    for (i = 0; i < LC_ALL; ++i)
+      {
+	/* Add "CATEGORY=NAME;" to the string.  */
+	char *name = (category == LC_ALL ? newnames[i] :
+		      category == i ? newnames[0] :
+		      (char *) _nl_current_names[i]);
+	memcpy (p, _nl_category_names[i], _nl_category_name_sizes[i]);
+	p += _nl_category_name_sizes[i];
+	*p++ = '=';
+	memcpy (p, name, lens[i]);
+	p += lens[i];
+	*p++ = ';';
+      }
+    p[-1] = '\0';		/* Clobber the last ';'.  */
+    return new;
+  }
+  /* Put COMPOSITE in _nl_current_composite_name and free the old value.  */
+  void setcomposite (char *composite)
+    {
+      char *old = _nl_current_composite_name;
+      _nl_current_composite_name = composite;
+      if (old != _nl_C_name)
+	free (old);
+    }
+  /* Put NAME in _nl_current_names and free the old value.  */
+  void setname (int category, const char *name)
+    {
+      const char *oldname = _nl_current_names[category];
+      _nl_current_names[category] = name;
+      if (oldname != _nl_C_name)
+	free ((char *) oldname);
+    }
+  /* Put DATA in *_nl_current[CATEGORY] and free the old value.  */
+  void setdata (int category, struct locale_data *data)
+    {
+      if (_nl_current[category])
+	{
+	  const struct locale_data *olddata = *_nl_current[category];
+	  *_nl_current[category] = data;
+	  if (_nl_category_postload[category])
+	    (*_nl_category_postload[category]) ();
+	  if (olddata != _nl_C[category])
+	    _nl_free_locale ((struct locale_data *) olddata);
+	}
+    }
+
+  const char *current_name;
+  char *composite;
+
+  if (category < 0 || category > LC_ALL)
+    {
+      errno = EINVAL;
+      return NULL;
+    }
+
+  if (category == LC_ALL)
+    current_name = _nl_current_composite_name;
+  else
+    current_name = _nl_current_names[category];
+
+  if (name == NULL)
+    /* Return the name of the current locale.  */
+    return (char *) current_name;
+
+  if (name == current_name)
+    /* Changing to the same thing.  */
+    return (char *) current_name;
+
+  if (category == LC_ALL)
+    {
+      const size_t len = strlen (name) + 1;
+      char *newnames[LC_ALL];
+      char *p;
+      struct locale_data *newdata[LC_ALL];
+
+      /* Set all name pointers to the argument name.  */
+      for (category = 0; category < LC_ALL; ++category)
+	newnames[category] = (char *) name;
+
+      p = strchr (name, ';');
+      if (p)
+	{
+	  /* This is a composite name.  Make a local copy and split it up.  */
+	  int i;
+	  char *n = alloca (len);
+	  memcpy (n, name, len);
+
+	  while (p = strchr (n, '='))
+	    {
+	      for (i = 0; i < LC_ALL; ++i)
+		if (_nl_category_name_sizes[i] == p - n &&
+		    !memcmp (_nl_category_names[i], n, p - n))
+		  break;
+	      if (i == LC_ALL)
+		{
+		  /* Bogus category name.  */
+		  errno = EINVAL;
+		  return NULL;
+		}
+	      if (i < LC_ALL)
+		{
+		  /* Found the category this clause sets.  */
+		  char *end = strchr (++p, ';');
+		  newnames[i] = p;
+		  if (end)
+		    {
+		      /* Examine the next clause.  */
+		      *end = '\0';
+		      n = end + 1;
+		    }
+		  else
+		    /* This was the last clause.  We are done.  */
+		    break;
+		}
+	    }
+
+	  for (i = 0; i < LC_ALL; ++i)
+	    if (newnames[i] == name)
+	      /* The composite name did not specify all categories.  */
+	      return NULL;
+	}
+	
+      /* Load the new data for each category.  */
+      while (category-- > 0)
+	/* Only actually load the data if anything will use it.  */
+	if (_nl_current[category])
+	  {
+	    newdata[category] = _nl_load_locale (category,
+						 &newnames[category]);
+	    if (newdata[category])
+	      newnames[category] = copy (newnames[category]);
+	    if (! newdata[category] || ! newnames[category])
+	      {
+		if (!strcmp (newnames[category], "C") ||
+		    !strcmp (newnames[category], "POSIX"))
+		  {
+		    /* Loading from a file failed, but this is a request
+		       for the default locale.  Use the built-in data.  */
+		    if (! newdata[category])
+		      newdata[category]
+			= (struct locale_data *) _nl_C[category];
+		    newnames[category] = (char *) _nl_C_name;
+		  }
+		else
+		  {
+		    /* Loading this part of the locale failed.
+		       Abort the composite load.  */
+		  abort_composite:
+		    while (++category < LC_ALL)
+		      {
+			if (_nl_current[category])
+			  _nl_free_locale (newdata[category]);
+			if (newnames[category] != _nl_C_name)
+			  free (newnames[category]);
+		      }
+		    return NULL;
+		  }
+	      }
+	  }
+	else
+	  {
+	    /* The data is never used; just change the name.  */
+	    newnames[category] = copy (newnames[category]);
+	    if (! newnames[category])
+	      {
+		if (!strcmp (newnames[category], "C") ||
+		    !strcmp (newnames[category], "POSIX"))
+		  newnames[category] = (char *) _nl_C_name;
+		else
+		  {
+		    while (++category < LC_ALL)
+		      if (newnames[category] != _nl_C_name)
+			free (newnames[category]);
+		  }
+	      }
+	  }
+
+      composite = new_composite_name (LC_ALL, newnames);
+      if (! composite)
+	{
+	  category = -1;
+	  goto abort_composite;
+	}
+
+      /* Now we have loaded all the new data.  Put it in place.  */
+      for (; category < LC_ALL; ++category)
+	{
+	  setdata (category, newdata[category]);
+	  setname (category, newnames[category]);
+	}
+      setcomposite (composite);
+
+      return composite;
+    }
+  else
+    {
+      char *newname = copy (name);
+      if (! newname)
+	{
+	  if (!strcmp (name, "C") || !strcmp (name, "POSIX"))
+	    newname = (char *) _nl_C_name;
+	  else
+	    return NULL;
+	}
+
+      composite = new_composite_name (category, &newname);
+      if (! composite)
+	{
+	  if (newname != _nl_C_name)
+	    free (newname);
+	  return NULL;
+	}
 
-  if (name == NULL || name[0] == '\0')
-    return (char *) "C";
+      /* Only actually load the data if anything will use it.  */
+      if (_nl_current[category])
+	{
+	  struct locale_data *newdata = _nl_load_locale (category,
+							 (char **) &name);
+	  if (! newdata)
+	    {
+	      if (!strcmp (name, "C") || !strcmp (name, "POSIX"))
+		newdata = (struct locale_data *) _nl_C[category];
+	      else
+		return NULL;
+	    }
+	  setdata (category, newdata);
+	}
 
-  if (!strcmp(name, "C") || !strcmp(name, "POSIX"))
-    return (char *) name;
+      setname (category, newname);
+      setcomposite (composite);
 
-  errno = EINVAL;
-  return NULL;
+      return newname;
+    }
 }
diff --git a/stdio/printf_fp.c b/stdio/printf_fp.c
index ddf025721b..10018f01b8 100644
--- a/stdio/printf_fp.c
+++ b/stdio/printf_fp.c
@@ -32,7 +32,8 @@ Cambridge, MA 02139, USA.  */
 #include <gmp.h>
 #include <gmp-impl.h>
 #include <longlong.h>
-#include <localeinfo.h>
+#include "../locale/localeinfo.h"
+#include <limits.h>
 #include <math.h>
 #include <printf.h>
 #include <stdarg.h>
@@ -227,22 +228,22 @@ __printf_fp (fp, info, args)
 
 
   /* Figure out the decimal point character.  */
-  if (mbtowc (&decimal, _numeric_info->decimal_point,
-	      strlen (_numeric_info->decimal_point)) <= 0)
-    decimal = (wchar_t) *_numeric_info->decimal_point;
+  if (mbtowc (&decimal, _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT),
+	      strlen (_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT))) <= 0)
+    decimal = (wchar_t) *_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
 
 
   if (info->group)
     {
-      grouping = _numeric_info->grouping; /* Cache the grouping info array.  */
+      grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
       if (*grouping <= 0 || *grouping == CHAR_MAX)
 	grouping = NULL;
       else
 	{
 	  /* Figure out the thousands seperator character.  */
-	  if (mbtowc (&thousands_sep, _numeric_info->thousands_sep,
-		      strlen (_numeric_info->thousands_sep)) <= 0)
-	    thousands_sep = (wchar_t) *_numeric_info->thousands_sep;
+	  if (mbtowc (&thousands_sep, _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP),
+		      strlen (_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP))) <= 0)
+	    thousands_sep = (wchar_t) *_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
 	  if (thousands_sep == L'\0')
 	    grouping = NULL;
 	}
diff --git a/stdio/vfprintf.c b/stdio/vfprintf.c
index 1b773e7b02..125e17975f 100644
--- a/stdio/vfprintf.c
+++ b/stdio/vfprintf.c
@@ -17,7 +17,7 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#include <localeinfo.h>
+#include "../locale/localeinfo.h"
 #include <ctype.h>
 #include <errno.h>
 #include <float.h>
@@ -38,7 +38,8 @@ Cambridge, MA 02139, USA.  */
 /* This code is for use in libio.  */
 #include <libioP.h>
 #define PUT(f, s, n)	_IO_sputn (f, s, n)
-#define PAD(padchar)	_IO_padn (s, padchar, width)
+#define PAD(padchar)	\
+  (width > 0 ? (_IO_padn (s, padchar, width), done += width) : 0)
 #define PUTC(c, f)	_IO_putc(c, f)
 #define vfprintf	_IO_vfprintf
 #define size_t		_IO_size_t
@@ -159,10 +160,10 @@ DEFUN(vfprintf, (s, format, args),
   (void) mblen ((char *) NULL, 0);
 
   /* Figure out the thousands seperator character.  */
-  if (mbtowc (&thousands_sep, _numeric_info->thousands_sep,
-	      strlen (_numeric_info->thousands_sep)) <= 0)
-    thousands_sep = (wchar_t) *_numeric_info->thousands_sep;
-  grouping = _numeric_info->grouping; /* Cache the grouping info array.  */
+  if (mbtowc (&thousands_sep, _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP),
+	      strlen (_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP))) <= 0)
+    thousands_sep = (wchar_t) *_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
+  grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
   if (*grouping == '\0' || thousands_sep == L'\0')
     grouping = NULL;
 
diff --git a/stdio/vfscanf.c b/stdio/vfscanf.c
index 10baa94ecc..47781ed566 100644
--- a/stdio/vfscanf.c
+++ b/stdio/vfscanf.c
@@ -17,7 +17,7 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#include <localeinfo.h>
+#include "../locale/localeinfo.h"
 #include <errno.h>
 #include <limits.h>
 #include <ctype.h>
@@ -93,9 +93,9 @@ DEFUN(__vfscanf, (s, format, arg),
     }
 
   /* Figure out the decimal point character.  */
-  if (mbtowc(&decimal, _numeric_info->decimal_point,
-	     strlen(_numeric_info->decimal_point)) <= 0)
-    decimal = (wchar_t) *_numeric_info->decimal_point;
+  if (mbtowc(&decimal, _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT),
+	     strlen (_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT))) <= 0)
+    decimal = (wchar_t) *_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
 
   c = inchar();
 
diff --git a/stdlib/strtod.c b/stdlib/strtod.c
index fa22ae9fe8..2f0e972893 100644
--- a/stdlib/strtod.c
+++ b/stdlib/strtod.c
@@ -34,14 +34,14 @@ Cambridge, MA 02139, USA.  */
 #include <ctype.h>
 #include <errno.h>
 #include <float.h>
-#include <localeinfo.h>
+#include "../locale/localeinfo.h"
 #include <math.h>
 #include <stdlib.h>
-#include "gmp.h"
-#include "gmp-impl.h"
+#include "../stdio/gmp.h"
+#include "../stdio/gmp-impl.h"
 #include <gmp-mparam.h>
-#include "longlong.h"
-#include "fpioconst.h"
+#include "../stdio/longlong.h"
+#include "../stdio/fpioconst.h"
 
 #define NDEBUG 1
 #include <assert.h>
@@ -350,15 +350,15 @@ STRTOF (nptr, endptr)
   /* Return with no conversion if the grouping of [STARTP,CP) is bad.  */
 #define	CHECK_GROUPING if (! grouping_ok (startp, cp)) RETURN (0.0, nptr); else
 
-  grouping = _numeric_info->grouping; /* Cache the grouping info array.  */
+  grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
   if (*grouping <= 0 || *grouping == CHAR_MAX)
     grouping = NULL;
   else
     {
       /* Figure out the thousands seperator character.  */
-      if (mbtowc (&thousands_sep, _numeric_info->thousands_sep,
-		  strlen (_numeric_info->thousands_sep)) <= 0)
-	thousands = (wchar_t) *_numeric_info->thousands_sep;
+      if (mbtowc (&thousands_sep, _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP),
+		  strlen (_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP))) <= 0)
+	thousands = (wchar_t) *_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
       if (thousands == L'\0')
 	grouping = NULL;
     }
@@ -369,9 +369,9 @@ STRTOF (nptr, endptr)
 #endif
 
   /* Find the locale's decimal point character.  */
-  if (mbtowc (&decimal, _numeric_info->decimal_point,
-	      strlen (_numeric_info->decimal_point)) <= 0)
-    decimal = (wchar_t) *_numeric_info->decimal_point;
+  if (mbtowc (&decimal, _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT),
+	      strlen (_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT))) <= 0)
+    decimal = (wchar_t) *_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
 
 
   /* Prepare number representation.  */
diff --git a/time/asctime.c b/time/asctime.c
index 3337c74388..644df3277f 100644
--- a/time/asctime.c
+++ b/time/asctime.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -17,7 +17,7 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#include <localeinfo.h>
+#include "../locale/localeinfo.h"
 #include <errno.h>
 #include <stdio.h>
 #include <time.h>
@@ -39,9 +39,9 @@ DEFUN(asctime, (tp), CONST struct tm *tp)
   
   if (sprintf (result, format,
 	       (tp->tm_wday < 0 || tp->tm_wday >= 7 ?
-		"???" : _time_info->abbrev_wkday[tp->tm_wday]),
+		"???" : _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday)),
 	       (tp->tm_mon < 0 || tp->tm_mon >= 12 ?
-		"???" : _time_info->abbrev_month[tp->tm_mon]),
+		"???" : _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon)),
 	       tp->tm_mday, tp->tm_hour, tp->tm_min,
 	       tp->tm_sec, 1900 + tp->tm_year) < 0)
     return NULL;
diff --git a/time/localtime.c b/time/localtime.c
index 3377b80197..a729b974a6 100644
--- a/time/localtime.c
+++ b/time/localtime.c
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#include <localeinfo.h>
 #include <stddef.h>
 #include <ctype.h>
 #include <stdio.h>
diff --git a/time/strftime.c b/time/strftime.c
index ccc19c72b0..625508c72e 100644
--- a/time/strftime.c
+++ b/time/strftime.c
@@ -3,7 +3,7 @@
    _
 */
 
-/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -22,7 +22,7 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#include <localeinfo.h>
+#include "../locale/localeinfo.h"
 #include <ctype.h>
 #include <limits.h>
 #include <stddef.h>
@@ -90,19 +90,20 @@ DEFUN(strftime, (s, maxsize, format, tp),
       char *s AND size_t maxsize AND
       CONST char *format AND register CONST struct tm *tp)
 {
-  CONST char *CONST a_wkday = _time_info->abbrev_wkday[tp->tm_wday];
-  CONST char *CONST f_wkday = _time_info->full_wkday[tp->tm_wday];
-  CONST char *CONST a_month = _time_info->abbrev_month[tp->tm_mon];
-  CONST char *CONST f_month = _time_info->full_month[tp->tm_mon];
+  CONST char *CONST a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday);
+  CONST char *CONST f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday);
+  CONST char *CONST a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon);
+  CONST char *CONST f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon);
   size_t aw_len = strlen(a_wkday);
   size_t am_len = strlen(a_month);
   size_t wkday_len = strlen(f_wkday);
   size_t month_len = strlen(f_month);
   int hour12 = tp->tm_hour;
-  CONST char *CONST ampm = _time_info->ampm[hour12 >= 12];
-  size_t ap_len = strlen(ampm);
-  CONST unsigned int y_week0 = week(tp, 0);
-  CONST unsigned int y_week1 = week(tp, 1);
+  CONST char *CONST ampm = _NL_CURRENT (LC_TIME,
+					hour12 > 12 ? PM_STR : AM_STR);
+  size_t ap_len = strlen (ampm);
+  CONST unsigned int y_week0 = week (tp, 0);
+  CONST unsigned int y_week1 = week (tp, 1);
   CONST char *zone;
   size_t zonelen;
   register size_t i = 0;
@@ -172,7 +173,7 @@ DEFUN(strftime, (s, maxsize, format, tp),
 	  break;
 
 	case 'c':
-	  subfmt = _time_info->date_time;
+	  subfmt = _NL_CURRENT (LC_TIME, D_T_FMT);
 	subformat:
 	  {
 	    size_t len = strftime (p, maxsize - i, subfmt, tp);
@@ -265,11 +266,11 @@ DEFUN(strftime, (s, maxsize, format, tp),
 	  break;
 
 	case 'X':
-	  subfmt = _time_info->time;
+	  subfmt = _NL_CURRENT (LC_TIME, T_FMT);
 	  goto subformat;
 
 	case 'x':
-	  subfmt = _time_info->date;
+	  subfmt = _NL_CURRENT (LC_TIME, D_FMT);
 	  goto subformat;
 
 	case 'Y':
diff --git a/time/tzset.c b/time/tzset.c
index e4d5209e88..3eac151f22 100644
--- a/time/tzset.c
+++ b/time/tzset.c
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#include <localeinfo.h>
 #include <ctype.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -112,21 +111,20 @@ DEFUN_VOID(__tzset)
     }
 
   if (tz == NULL || *tz == '\0')
-    tz = _time_info->tz;
-  if (tz == NULL || *tz == '\0')
     {
       __tzfile_read((char *) NULL);
       if (!__use_tzfile)
 	{
-	  size_t len = strlen(_time_info->ut0) + 1;
+	  const char UTC[] = "UTC";
+	  size_t len = sizeof UTC;
 	  tz_rules[0].name = (char *) malloc(len);
 	  if (tz_rules[0].name == NULL)
 	    return;
 	  tz_rules[1].name = (char *) malloc(len);
 	  if (tz_rules[1].name == NULL)
 	    return;
-	  memcpy((PTR) tz_rules[0].name, _time_info->ut0, len);
-	  memcpy((PTR) tz_rules[1].name, _time_info->ut0, len);
+	  memcpy ((PTR) tz_rules[0].name, UTC, len);
+	  memcpy ((PTR) tz_rules[1].name, UTC, len);
 	  tz_rules[0].type = tz_rules[1].type = J0;
 	  tz_rules[0].m = tz_rules[0].n = tz_rules[0].d = 0;
 	  tz_rules[1].m = tz_rules[1].n = tz_rules[1].d = 0;
@@ -139,7 +137,7 @@ DEFUN_VOID(__tzset)
       return;
     }
 
-  /* Clear out old state and reset to unnamed GMT.  */
+  /* Clear out old state and reset to unnamed UTC.  */
   memset (tz_rules, 0, sizeof tz_rules);
   tz_rules[0].name = tz_rules[1].name = (char *) "";
 
@@ -165,7 +163,7 @@ DEFUN_VOID(__tzset)
 
   tz += l;
 
-  /* Figure out the standard offset from GMT.  */
+  /* Figure out the standard offset from UTC.  */
   if (*tz == '\0' || (*tz != '+' && *tz != '-' && !isdigit(*tz)))
     return;