Mon Jul 29 02:46:23 1996 Ulrich Drepper <drepper@cygnus.com>
authorroland <roland>
Mon, 29 Jul 1996 02:48:00 +0000 (02:48 +0000)
committerroland <roland>
Mon, 29 Jul 1996 02:48:00 +0000 (02:48 +0000)
Add support for the to-be-written internationalized regexp.
This code must be able to use collation symbols and collation
equivalent classes.
* locale/C-collate.c (_nl_C_LC_COLLATE_symbol_hash,
_nl_C_LC_COLLATE_symbol_strings, _nl_C_LC_COLLATE_symbol_classes):
New global variables for collation classes.
* locale/categories.def: Add new descriptions for collation symbols
and collation classes.
* locale/langinfo.h: Add constants for collation symbols and
collation classes.
* locale/lc-collate.c: Add new global variables for collation symbols
and collation classes.
(_nl_postload_collate): Initialize new variables.
* locale/programs/ld-collate.c: Add code to emit tables for
collation symbols and collation classes.
* locale/programs/locales.h: Change prototype for `collate_output'.
* locale/programs/locfile.c (write_all_categories): Call
`collate_output' with new argument.
* locale/localeinfo.h: Add declaration for new global vars.
(union locale_data_value): New member wstr for `wchar_t' strings.
* locale/programs/locale-spec.c: Handle `collate-classes'
keyword and print information about available collation classes.
* locale/strlen-hash.h: New file.  Simple hashing function which
takes a string with known length.

locale/C-collate.c
locale/categories.def
locale/langinfo.h
locale/lc-collate.c
locale/localeinfo.h
locale/programs/ld-collate.c
locale/programs/locale-spec.c
locale/programs/locales.h

index 9535d4f..08fb47b 100644 (file)
@@ -17,14 +17,165 @@ License along with the GNU C Library; see the file COPYING.LIB.  If
 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
+#include <endian.h>
 #include "localeinfo.h"
 
+
+const u_int32_t _nl_C_LC_COLLATE_symbol_hash[446] =
+{
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0x00000154u, 0x00000060u, 0xffffffffu, 0xffffffffu,
+  0x0000004fu, 0x0000001au, 0x00000085u, 0x00000030u, 0xffffffffu, 0xffffffffu,
+  0x000002beu, 0x000000fau, 0xffffffffu, 0xffffffffu, 0x0000014eu, 0x0000005eu,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x000000bbu, 0x00000044u,
+  0xffffffffu, 0xffffffffu, 0x000000efu, 0x0000004cu, 0x00000147u, 0x0000005cu,
+  0x000000a0u, 0x0000003eu, 0x00000000u, 0x00000000u, 0x00000038u, 0x00000016u,
+  0x00000094u, 0x00000038u, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0x00000140u, 0x0000005au, 0x0000018cu, 0x00000076u,
+  0x0000007du, 0x0000002cu, 0xffffffffu, 0xffffffffu, 0x00000115u, 0x00000052u,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x00000285u, 0x000000deu,
+  0x00000171u, 0x0000006cu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
+  0x00000289u, 0x000000e2u, 0x000002d8u, 0x000000feu, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x00000022u, 0x00000010u,
+  0x0000028fu, 0x000000e8u, 0x00000069u, 0x00000022u, 0x0000006du, 0x00000024u,
+  0x00000071u, 0x00000026u, 0x00000075u, 0x00000028u, 0xffffffffu, 0xffffffffu,
+  0x00000295u, 0x000000eeu, 0xffffffffu, 0xffffffffu, 0x00000297u, 0x000000f0u,
+  0xffffffffu, 0xffffffffu, 0x00000299u, 0x000000f2u, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x00000213u, 0x000000b6u,
+  0xffffffffu, 0xffffffffu, 0x00000014u, 0x0000000au, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0x00000227u, 0x000000b8u, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x0000015du, 0x00000064u,
+  0xffffffffu, 0xffffffffu, 0x000001ffu, 0x000000a2u, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x0000013au, 0x00000058u,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x00000010u, 0x00000008u,
+  0x000001dfu, 0x00000082u, 0x000001e1u, 0x00000084u, 0x00000167u, 0x00000068u,
+  0x00000004u, 0x00000002u, 0x000001e7u, 0x0000008au, 0x00000186u, 0x00000074u,
+  0x000001ebu, 0x0000008eu, 0x000001edu, 0x00000090u, 0x000001efu, 0x00000092u,
+  0x000001f1u, 0x00000094u, 0x000001f3u, 0x00000096u, 0x000001f5u, 0x00000098u,
+  0x000001f7u, 0x0000009au, 0x000001f9u, 0x0000009cu, 0x000001a5u, 0x0000007au,
+  0x000001fdu, 0x000000a0u, 0x00000030u, 0x00000014u, 0x00000201u, 0x000000a4u,
+  0x00000203u, 0x000000a6u, 0x00000205u, 0x000000a8u, 0x00000207u, 0x000000aau,
+  0x00000209u, 0x000000acu, 0x0000020bu, 0x000000aeu, 0x0000020du, 0x000000b0u,
+  0x0000020fu, 0x000000b2u, 0x00000211u, 0x000000b4u, 0xffffffffu, 0xffffffffu,
+  0x0000009cu, 0x0000003cu, 0xffffffffu, 0xffffffffu, 0x00000098u, 0x0000003au,
+  0x0000016cu, 0x0000006au, 0xffffffffu, 0xffffffffu, 0x00000269u, 0x000000c2u,
+  0x0000026bu, 0x000000c4u, 0x0000026du, 0x000000c6u, 0x0000026fu, 0x000000c8u,
+  0x00000271u, 0x000000cau, 0x00000273u, 0x000000ccu, 0x00000275u, 0x000000ceu,
+  0x00000277u, 0x000000d0u, 0x00000279u, 0x000000d2u, 0x0000027bu, 0x000000d4u,
+  0x0000027du, 0x000000d6u, 0x0000027fu, 0x000000d8u, 0x00000281u, 0x000000dau,
+  0x00000283u, 0x000000dcu, 0x00000090u, 0x00000036u, 0x00000287u, 0x000000e0u,
+  0x0000005fu, 0x0000001cu, 0x0000028bu, 0x000000e4u, 0x0000028du, 0x000000e6u,
+  0x00000089u, 0x00000032u, 0x000001c3u, 0x0000007eu, 0x00000293u, 0x000000ecu,
+  0x00000062u, 0x0000001eu, 0x000001b1u, 0x0000007cu, 0x00000130u, 0x00000056u,
+  0x0000029bu, 0x000000f4u, 0x00000196u, 0x00000078u, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0x00000081u, 0x0000002eu, 0x00000251u, 0x000000beu,
+  0x00000079u, 0x0000002au, 0x0000029du, 0x000000f6u, 0xffffffffu, 0xffffffffu,
+  0x0000025cu, 0x000000c0u, 0xffffffffu, 0xffffffffu, 0x0000002cu, 0x00000012u,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x000000a4u, 0x00000040u,
+  0xffffffffu, 0xffffffffu, 0x000002b0u, 0x000000f8u, 0xffffffffu, 0xffffffffu,
+  0x000000f9u, 0x0000004eu, 0xffffffffu, 0xffffffffu, 0x0000001cu, 0x0000000eu,
+  0xffffffffu, 0xffffffffu, 0x0000017bu, 0x00000070u, 0x0000000cu, 0x00000006u,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x000001e3u, 0x00000086u,
+  0xffffffffu, 0xffffffffu, 0x000001e5u, 0x00000088u, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0x000001d1u, 0x00000080u, 0x000001e9u, 0x0000008cu,
+  0x0000008cu, 0x00000034u, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0x00000291u, 0x000000eau, 0xffffffffu, 0xffffffffu,
+  0x00000008u, 0x00000004u, 0xffffffffu, 0xffffffffu, 0x00000181u, 0x00000072u,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x00000231u, 0x000000bau,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x000000cau, 0x00000046u,
+  0x00000246u, 0x000000bcu, 0xffffffffu, 0xffffffffu, 0x000001fbu, 0x0000009eu,
+  0x000000d6u, 0x00000048u, 0x00000018u, 0x0000000cu, 0xffffffffu, 0xffffffffu,
+  0x00000159u, 0x00000062u, 0xffffffffu, 0xffffffffu, 0x000000aau, 0x00000042u,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x000000e2u, 0x0000004au,
+  0x00000175u, 0x0000006eu, 0xffffffffu, 0xffffffffu, 0x00000104u, 0x00000050u,
+  0x00000065u, 0x00000020u, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x000002d2u, 0x000000fcu,
+  0xffffffffu, 0xffffffffu, 0x00000161u, 0x00000066u, 0x00000045u, 0x00000018u,
+  0xffffffffu, 0xffffffffu, 0x00000127u, 0x00000054u, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
+  0xffffffffu, 0xffffffffu
+};
+
+const char _nl_C_LC_COLLATE_symbol_strings[732] =
+  "NUL\0" "SOH\0" "STX\0" "ETX\0" "EOT\0" "ENQ\0" "ACK\0" "alert\0"
+  "backspace\0" "tab\0" "newline\0" "vertical-tab\0" "form-feed\0"
+  "carriage-return\0" "SI\0" "SO\0" "DLE\0" "DC1\0" "DC2\0" "DC3\0" "DC4\0"
+  "NAK\0" "SYN\0" "ETB\0" "CAN\0" "EM\0" "SUB\0" "ESC\0" "IS4\0" "IS3\0"
+  "IS2\0" "IS1\0" "space\0" "exclamation-mark\0" "quotation-mark\0"
+  "number-sign\0" "dollar-sign\0" "percent-sign\0" "ampersand\0"
+  "apostrophe\0" "left-parenthesis\0" "right-parenthesis\0" "asterisk\0"
+  "plus-sign\0" "comma\0" "hyphen\0" "period\0" "slash\0" "zero\0" "one\0"
+  "two\0" "three\0" "four\0" "five\0" "six\0" "seven\0" "eight\0" "nine\0"
+  "colon\0" "semicolon\0" "less-than-sign\0" "equals-sign\0"
+  "greater-than-sign\0" "question-mark\0" "commercial-at\0" "A\0" "B\0" "C\0"
+  "D\0" "E\0" "F\0" "G\0" "H\0" "I\0" "J\0" "K\0" "L\0" "M\0" "N\0" "O\0"
+  "P\0" "Q\0" "R\0" "S\0" "T\0" "U\0" "V\0" "W\0" "X\0" "Y\0" "Z\0"
+  "left-square-bracket\0" "backslash\0" "right-square-bracket\0"
+  "circumflex\0" "underscore\0" "grave-accent\0" "a\0" "b\0" "c\0" "d\0" "e\0"
+  "f\0" "g\0" "h\0" "i\0" "j\0" "k\0" "l\0" "m\0" "n\0" "o\0" "p\0" "q\0"
+  "r\0" "s\0" "t\0" "u\0" "v\0" "w\0" "x\0" "y\0" "z\0" "left-curly-bracket\0"
+  "vertical-line\0" "right-curly-bracket\0" "tilde\0" "DEL\0";
+
+const u_int32_t _nl_C_LC_COLLATE_symbol_classes[256] =
+{
+  1,   0, 1,   1, 1,   2, 1,   3, 1,   4, 1,   5, 1,   6, 1,   7,
+  1,   8, 1,   9, 1,  10, 1,  11, 1,  12, 1,  13, 1,  14, 1,  15,
+  1,  16, 1,  17, 1,  18, 1,  19, 1,  20, 1,  21, 1,  22, 1,  23,
+  1,  24, 1,  25, 1,  26, 1,  27, 1,  28, 1,  29, 1,  30, 1,  31,
+  1,  32, 1,  33, 1,  34, 1,  35, 1,  36, 1,  37, 1,  38, 1,  39,
+  1,  40, 1,  41, 1,  42, 1,  43, 1,  44, 1,  45, 1,  46, 1,  47,
+  1,  48, 1,  49, 1,  50, 1,  51, 1,  52, 1,  53, 1,  54, 1,  55,
+  1,  56, 1,  57, 1,  58, 1,  59, 1,  60, 1,  61, 1,  62, 1,  63,
+  1,  64, 1,  65, 1,  66, 1,  67, 1,  68, 1,  69, 1,  70, 1,  71,
+  1,  72, 1,  73, 1,  74, 1,  75, 1,  76, 1,  77, 1,  78, 1,  79,
+  1,  80, 1,  81, 1,  82, 1,  83, 1,  84, 1,  85, 1,  86, 1,  87,
+  1,  88, 1,  89, 1,  90, 1,  91, 1,  92, 1,  93, 1,  94, 1,  95,
+  1,  96, 1,  97, 1,  98, 1,  99, 1, 100, 1, 101, 1, 102, 1, 103,
+  1, 104, 1, 105, 1, 106, 1, 107, 1, 108, 1, 109, 1, 110, 1, 111,
+  1, 112, 1, 113, 1, 114, 1, 115, 1, 116, 1, 117, 1, 118, 1, 119,
+  1, 120, 1, 121, 1, 122, 1, 123, 1, 124, 1, 125, 1, 126, 1, 127
+};
+
 const struct locale_data _nl_C_LC_COLLATE =
 {
   _nl_C_name,
   NULL, 0, /* no file mapped */
-  1,
+  21,
   {
-    { word: 0 }
+    { word: 0 },
+    { string: NULL },
+    { word: 0 },
+    { word: 0 },
+    { string: NULL },
+    { string: NULL },
+    { word: 0 },
+    { string: NULL },
+    { string: NULL },
+    { word: 0 },
+    { string: NULL },
+    { string: NULL },
+    { string: NULL },
+    { string: NULL },
+    { string: NULL },
+    { word: 223 },
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+    { string: NULL },
+#endif
+    { string: (const char *) _nl_C_LC_COLLATE_symbol_hash },
+#if __BYTE_ORDER == __BIG_ENDIAN
+    { string: NULL },
+#endif
+    { string: _nl_C_LC_COLLATE_symbol_strings },
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+    { string: NULL },
+#endif
+    { string: (const char *) _nl_C_LC_COLLATE_symbol_classes },
+#if __BYTE_ORDER == __BIG_ENDIAN
+    { string: NULL },
+#endif
   }
 };
index d3caef2..4caef24 100644 (file)
@@ -43,15 +43,27 @@ DEFINE_CATEGORY
 (
  LC_COLLATE, "LC_COLLATE",
  (
-  DEFINE_ELEMENT (_NL_COLLATE_NRULES,      "collate-nrules",      std, word)
-  DEFINE_ELEMENT (_NL_COLLATE_RULES,       "collate-rules",       std, string)
-  DEFINE_ELEMENT (_NL_COLLATE_HASH_SIZE,   "collate-hash-size",   std, word)
-  DEFINE_ELEMENT (_NL_COLLATE_HASH_LAYERS, "collate-hash-layers", std, word)
-  DEFINE_ELEMENT (_NL_COLLATE_TABLE_EB,    "collate-table-eb",    std, string)
-  DEFINE_ELEMENT (_NL_COLLATE_TABLE_EL,    "collate-table-el",    std, string)
-  DEFINE_ELEMENT (_NL_COLLATE_UNDEFINED,   "collate-undefined",   std, word)
-  DEFINE_ELEMENT (_NL_COLLATE_EXTRA_EB,    "collate-extra-eb",    std, string)
-  DEFINE_ELEMENT (_NL_COLLATE_EXTRA_EL,    "collate-extra-el",    std, string)
+  DEFINE_ELEMENT (_NL_COLLATE_NRULES,           "collate-nrules",           std, word)
+  DEFINE_ELEMENT (_NL_COLLATE_RULES,            "collate-rules",            std, string)
+  DEFINE_ELEMENT (_NL_COLLATE_HASH_SIZE,        "collate-hash-size",        std, word)
+  DEFINE_ELEMENT (_NL_COLLATE_HASH_LAYERS,    "collate-hash-layers",      std, word)
+  DEFINE_ELEMENT (_NL_COLLATE_TABLE_EB,       "collate-table-eb",         std, string)
+  DEFINE_ELEMENT (_NL_COLLATE_TABLE_EL,       "collate-table-el",         std, string)
+  DEFINE_ELEMENT (_NL_COLLATE_UNDEFINED,      "collate-undefined",        std, word)
+  DEFINE_ELEMENT (_NL_COLLATE_EXTRA_EB,       "collate-extra-eb",         std, string)
+  DEFINE_ELEMENT (_NL_COLLATE_EXTRA_EL,       "collate-extra-el",         std, string)
+  DEFINE_ELEMENT (_NL_COLLATE_ELEM_HASH_SIZE, "collate-elem-hash-size",   std, word)
+  DEFINE_ELEMENT (_NL_COLLATE_ELEM_HASH_EB,   "collate-elem-hash-eb",     std, string)
+  DEFINE_ELEMENT (_NL_COLLATE_ELEM_HASH_EL,   "collate-elem-hash-el",     std, string)
+  DEFINE_ELEMENT (_NL_COLLATE_ELEM_STR_POOL,  "collate-elem-str-pool",    std, string)
+  DEFINE_ELEMENT (_NL_COLLATE_ELEM_VAL_EB,    "collate-elem-val-eb", std, string)
+  DEFINE_ELEMENT (_NL_COLLATE_ELEM_VAL_EL,    "collate-elem-val-el", std, string)
+  DEFINE_ELEMENT (_NL_COLLATE_SYMB_HASH_SIZE, "collate-symb-hash-size",   std, word)
+  DEFINE_ELEMENT (_NL_COLLATE_SYMB_HASH_EB,   "collate-symb-hash-eb",     std, string)
+  DEFINE_ELEMENT (_NL_COLLATE_SYMB_HASH_EL,   "collate-symb-hash-el",     std, string)
+  DEFINE_ELEMENT (_NL_COLLATE_SYMB_STR_POOL,  "collate-symb-str-pool",    std, string)
+  DEFINE_ELEMENT (_NL_COLLATE_SYMB_CLASS_EB,  "collate-symb-class-eb",    std, string)
+  DEFINE_ELEMENT (_NL_COLLATE_SYMB_CLASS_EL,  "collate-symb-class-el",    std, string)
   ), _nl_postload_collate, collate_input, NULL, NULL)
 
 
@@ -62,19 +74,20 @@ DEFINE_CATEGORY
 (
  LC_CTYPE, "LC_CTYPE",
  (
-  DEFINE_ELEMENT (_NL_CTYPE_CLASS,      "ctype-class",       std, string)
-  DEFINE_ELEMENT (_NL_CTYPE_TOUPPER_EB,  "ctype-toupper-eb",  std, string)
-  DEFINE_ELEMENT (_NL_CTYPE_TOLOWER_EB,  "ctype-tolower-eb",  std, string)
-  DEFINE_ELEMENT (_NL_CTYPE_TOUPPER_EL,  "ctype-toupper-el",  std, string)
-  DEFINE_ELEMENT (_NL_CTYPE_TOLOWER_EL,  "ctype-tolower-el",  std, string)
-  DEFINE_ELEMENT (_NL_CTYPE_NAMES_EB,   "ctype-names-eb",    std, string)
-  DEFINE_ELEMENT (_NL_CTYPE_NAMES_EL,   "ctype-names-eb",    std, string)
-  DEFINE_ELEMENT (_NL_CTYPE_HASH_SIZE,  "ctype-hash-size",   std, word)
-  DEFINE_ELEMENT (_NL_CTYPE_HASH_LAYERS, "ctype-hash-layers", std, word)
-  DEFINE_ELEMENT (_NL_CTYPE_CLASS_NAMES, "ctype-class-names", std, string)
-  DEFINE_ELEMENT (_NL_CTYPE_MAP_NAMES,  "ctype-map-names",   std, string)
-  DEFINE_ELEMENT (_NL_CTYPE_WIDTH,      "ctype-width",       std, bytearray)
-  DEFINE_ELEMENT (_NL_CTYPE_MB_CUR_MAX,         "ctype-mb-cur-max",  std, word)
+  DEFINE_ELEMENT (_NL_CTYPE_CLASS,       "ctype-class",        std, string)
+  DEFINE_ELEMENT (_NL_CTYPE_TOUPPER_EB,   "ctype-toupper-eb",   std, string)
+  DEFINE_ELEMENT (_NL_CTYPE_TOLOWER_EB,   "ctype-tolower-eb",   std, string)
+  DEFINE_ELEMENT (_NL_CTYPE_TOUPPER_EL,   "ctype-toupper-el",   std, string)
+  DEFINE_ELEMENT (_NL_CTYPE_TOLOWER_EL,   "ctype-tolower-el",   std, string)
+  DEFINE_ELEMENT (_NL_CTYPE_NAMES_EB,    "ctype-names-eb",     std, string)
+  DEFINE_ELEMENT (_NL_CTYPE_NAMES_EL,    "ctype-names-eb",     std, string)
+  DEFINE_ELEMENT (_NL_CTYPE_HASH_SIZE,   "ctype-hash-size",    std, word)
+  DEFINE_ELEMENT (_NL_CTYPE_HASH_LAYERS,  "ctype-hash-layers",  std, word)
+  DEFINE_ELEMENT (_NL_CTYPE_CLASS_NAMES,  "ctype-class-names",  std, string)
+  DEFINE_ELEMENT (_NL_CTYPE_MAP_NAMES,   "ctype-map-names",    std, string)
+  DEFINE_ELEMENT (_NL_CTYPE_WIDTH,       "ctype-width",        std, bytearray)
+  DEFINE_ELEMENT (_NL_CTYPE_MB_CUR_MAX,          "ctype-mb-cur-max",   std, word)
+  DEFINE_ELEMENT (_NL_CTYPE_CODESET_NAME, "ctype-codeset-name", std, string)
   ), _nl_postload_ctype, ctype_input, ctype_check, ctype_output)
 
 
index 4f0a58f..90aee3d 100644 (file)
@@ -115,6 +115,18 @@ typedef enum
   _NL_COLLATE_UNDEFINED,
   _NL_COLLATE_EXTRA_EB,
   _NL_COLLATE_EXTRA_EL,
+  _NL_COLLATE_ELEM_HASH_SIZE,
+  _NL_COLLATE_ELEM_HASH_EB,
+  _NL_COLLATE_ELEM_HASH_EL,
+  _NL_COLLATE_ELEM_STR_POOL,
+  _NL_COLLATE_ELEM_VAL_EB,
+  _NL_COLLATE_ELEM_VAL_EL,
+  _NL_COLLATE_SYMB_HASH_SIZE,
+  _NL_COLLATE_SYMB_HASH_EB,
+  _NL_COLLATE_SYMB_HASH_EL,
+  _NL_COLLATE_SYMB_STR_POOL,
+  _NL_COLLATE_SYMB_CLASS_EB,
+  _NL_COLLATE_SYMB_CLASS_EL,
   _NL_NUM_LC_COLLATE,
 
   /* LC_CTYPE category: character classification.
@@ -181,7 +193,7 @@ typedef enum
    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));
+extern char *nl_langinfo __P ((nl_item __item));
 
 
 __END_DECLS
index 23643b2..aefdaa8 100644 (file)
@@ -20,12 +20,28 @@ Boston, MA 02111-1307, USA.  */
 #include "localeinfo.h"
 #include <endian.h>
 
+
+extern const u_int32_t _nl_C_LC_COLLATE_symbol_hash[];
+extern const char _nl_C_LC_COLLATE_symbol_strings[];
+extern const u_int32_t _nl_C_LC_COLLATE_symbol_classes[];
+
+
 _NL_CURRENT_DEFINE (LC_COLLATE);
 
-const u_int32_t *__collate_table;
-const u_int32_t *__collate_extra;
+const u_int32_t *__collate_table = NULL;
+const u_int32_t *__collate_extra = NULL;
+
+const u_int32_t *__collate_element_hash = NULL;
+const char *__collate_element_strings = NULL;
+const wchar_t *__collate_element_values = NULL;
 
+const u_int32_t *__collate_symbol_hash = _nl_C_LC_COLLATE_symbol_hash;
+const char *__collate_symbol_strings = _nl_C_LC_COLLATE_symbol_strings;
+const u_int32_t *__collate_symbol_classes = _nl_C_LC_COLLATE_symbol_classes;
 
+
+/* We are called after loading LC_CTYPE data to load it into
+   the variables used by the collation functions and regex.  */
 void
 _nl_postload_collate (void)
 {
@@ -44,4 +60,12 @@ _nl_postload_collate (void)
 
   __collate_table = current (bo (TABLE));
   __collate_extra = current (bo (EXTRA));
+
+  __collate_element_hash = current (bo (ELEM_HASH));
+  __collate_element_strings = (const char *) current (ELEM_STR_POOL);
+  __collate_element_values = (const wchar_t *) current (bo (ELEM_VAL));
+
+  __collate_symbol_hash = current (bo (SYMB_HASH));
+  __collate_symbol_strings = (const char *) current (SYMB_STR_POOL);
+  __collate_symbol_classes = current (bo (SYMB_CLASS));
 }
index d24a9da..7a035c8 100644 (file)
@@ -44,6 +44,7 @@ struct locale_data
   unsigned int nstrings;       /* Number of strings below.  */
   union locale_data_value
   {
+    const wchar_t *wstr;
     const char *string;
     unsigned int word;
   }
@@ -119,5 +120,11 @@ extern void _nl_free_locale (const struct locale_data *);
 /* Global variables for LC_COLLATE category data.  */
 extern const u_int32_t *__collate_table;
 extern const u_int32_t *__collate_extra;
+extern const u_int32_t *__collate_element_hash;
+extern const char *__collate_element_strings;
+extern const wchar_t *__collate_element_values;
+extern const u_int32_t *__collate_symbol_hash;
+extern const char *__collate_symbol_strings;
+extern const u_int32_t *__collate_symbol_classes;
 
 #endif /* localeinfo.h */
index 4bdf0b2..77e9465 100644 (file)
@@ -1,6 +1,6 @@
 /* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
-Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>.
+Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
 The GNU C Library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public License as
@@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA.  */
 #include "locales.h"
 #include "simple-hash.h"
 #include "stringtrans.h"
+#include "strlen-hash.h"
 
 /* Uncomment the following line in the production version.  */
 /* #define NDEBUG 1 */
@@ -83,7 +84,7 @@ typedef struct element_t
 } element_t;
 
 
-/* The real definition of the struct for the LC_CTYPE locale.  */
+/* The real definition of the struct for the LC_COLLATE locale.  */
 struct locale_collate_t
 {
   /* Collate symbol table.  Simple mapping to number.  */
@@ -275,15 +276,13 @@ collate_finish (struct localedef_t *locale, struct charset_t *charset)
   collate->undefined_len = 2;  /* For the name: 1 x wchar_t + L'\0'.  */
   for (cnt = 0; cnt < collate->nrules; ++cnt)
     collate->undefined_len += 1 + collate->undefined.ordering[cnt];
-
-  /* Collating symbols are not used anymore.  */
-  (void) delete_hash (&collate->symbols);
 }
 
 
 
 void
-collate_output (struct localedef_t *locale, const char *output_path)
+collate_output (struct localedef_t *locale, struct charset_t *charset,
+               const char *output_path)
 {
   struct locale_collate_t *collate = locale->categories[LC_COLLATE].collate;
   u_int32_t table_size, table_best, level_best, sum_best;
@@ -296,10 +295,29 @@ collate_output (struct localedef_t *locale, const char *output_path)
   struct locale_file data;
   u_int32_t idx[nelems];
   struct obstack non_simple;
+  struct obstack string_pool;
   size_t cnt, entry_size;
   u_int32_t undefined_offset = UINT_MAX;
   u_int32_t *table, *extra, *table2, *extra2;
   size_t extra_len;
+  u_int32_t element_hash_tab_size;
+  u_int32_t *element_hash_tab;
+  u_int32_t *element_hash_tab_ob;
+  u_int32_t element_string_pool_size;
+  char *element_string_pool;
+  u_int32_t element_value_size;
+  wchar_t *element_value;
+  wchar_t *element_value_ob;
+  u_int32_t symbols_hash_tab_size;
+  u_int32_t *symbols_hash_tab;
+  u_int32_t *symbols_hash_tab_ob;
+  u_int32_t symbols_string_pool_size;
+  char *symbols_string_pool;
+  u_int32_t symbols_class_size;
+  u_int32_t *symbols_class;
+  u_int32_t *symbols_class_ob;
+  hash_table *hash_tab;
+  unsigned int dummy_weights[collate->nrules + 1];
 
   sum_best = UINT_MAX;
   table_best = 0xffff;
@@ -342,6 +360,7 @@ Computing table size for collation information might take a while..."),
   fputs (_(" done\n"), stderr);
 
   obstack_init (&non_simple);
+  obstack_init (&string_pool);
 
   data.magic = LIMAGIC (LC_COLLATE);
   data.n = nelems;
@@ -608,6 +627,258 @@ Computing table size for collation information might take a while..."),
   for (cnt = 0; cnt < extra_len / sizeof (u_int32_t); ++cnt)
     extra2[cnt] = SWAPU32 (extra2[cnt]);
 
+  /* We need a simple hashing table to get a collation-element->chars
+     mapping.  We again use internal hasing using a secondary hashing
+     function.
+
+     Each string has an associate hashing value V, computed by a
+     fixed function.  To locate the string we use open addressing with
+     double hashing.  The first index will be V % M, where M is the
+     size of the hashing table.  If no entry is found, iterating with
+     a second, independent hashing function takes place.  This second
+     value will be 1 + V % (M - 2).  The approximate number of probes
+     will be
+
+         for unsuccessful search: (1 - N / M) ^ -1
+         for successful search:   - (N / M) ^ -1 * ln (1 - N / M)
+
+     where N is the number of keys.
+
+     If we now choose M to be the next prime bigger than 4 / 3 * N,
+     we get the values 4 and 1.85 resp.  Because unsuccesful searches
+     are unlikely this is a good value.  Formulas: [Knuth, The Art of
+     Computer Programming, Volume 3, Sorting and Searching, 1973,
+     Addison Wesley]  */
+  if (collate->elements.filled == 0)
+    {
+      /* We don't need any element table since there are no collating
+        elements.  */
+      element_hash_tab_size = 0;
+      element_hash_tab = NULL;
+      element_hash_tab_ob = NULL;
+      element_string_pool_size = 0;
+      element_string_pool = NULL;
+      element_value_size = 0;
+      element_value = NULL;
+      element_value_ob = NULL;
+    }
+  else
+    {
+      void *ptr;               /* Running pointer.  */
+      const char *key;         /* Key for current bucket.  */
+      size_t keylen;           /* Length of key data.  */
+      const element_t *data;   /* Data, i.e., the character sequence.  */
+
+      element_hash_tab_size = next_prime ((collate->elements.filled * 4) / 3);
+      if (element_hash_tab_size < 7)
+       /* We need a minimum to make the following code work.  */
+       element_hash_tab_size = 7;
+
+      element_hash_tab = obstack_alloc (&non_simple, (2 * element_hash_tab_size
+                                                     * sizeof (u_int32_t)));
+      memset (element_hash_tab, '\377', (2 * element_hash_tab_size
+                                        * sizeof (u_int32_t)));
+
+      ptr = NULL;
+      while (iterate_table (&collate->elements, &ptr, (const void **) &key,
+                           &keylen, (void **) &data) == 0)
+       {
+         size_t hash_val = hash_string (key, keylen);
+         size_t idx = hash_val % element_hash_tab_size;
+
+         if (element_hash_tab[2 * idx] != (~((u_int32_t) 0)))
+           {
+             /* We need the second hashing function.  */
+             size_t c = 1 + (hash_val % (element_hash_tab_size - 2));
+
+             do
+               if (idx >= element_hash_tab_size - c)
+                 idx -= element_hash_tab_size - c;
+               else
+                 idx += c;
+             while (element_hash_tab[2 * idx] != (~((u_int32_t) 0)));
+           }
+
+         element_hash_tab[2 * idx] = obstack_object_size (&non_simple);
+         element_hash_tab[2 * idx + 1] = (obstack_object_size (&string_pool)
+                                          / sizeof (wchar_t));
+
+         obstack_grow0 (&non_simple, key, keylen);
+         obstack_grow (&string_pool, data->name,
+                       (wcslen (data->name) + 1) * sizeof (wchar_t));
+       }
+
+      if (obstack_object_size (&non_simple) % 4 != 0)
+       obstack_blank (&non_simple,
+                      4 - (obstack_object_size (&non_simple) % 4));
+      element_string_pool_size = obstack_object_size (&non_simple);
+      element_string_pool = obstack_finish (&non_simple);
+
+      element_value_size = obstack_object_size (&string_pool);
+      element_value = obstack_finish (&string_pool);
+
+      /* Create the tables for the other byte order.  */
+      element_hash_tab_ob = obstack_alloc (&non_simple,
+                                          (2 * element_hash_tab_size
+                                           * sizeof (u_int32_t)));
+      for (cnt = 0; cnt < 2 * element_hash_tab_size; ++cnt)
+       element_hash_tab_ob[cnt] = SWAPU32 (element_hash_tab[cnt]);
+
+      element_value_ob = obstack_alloc (&string_pool, element_value_size);
+      if (sizeof (wchar_t) != 4)
+       {
+         fputs ("sizeof (wchar_t) != 4 currently not handled", stderr);
+         abort ();
+       }
+      for (cnt = 0; cnt < element_value_size / 4; ++cnt)
+       element_value_ob[cnt] = SWAPU32 (element_value[cnt]);
+    }
+
+  /* Store collation elements as map to collation class.  There are
+     three kinds of symbols:
+       - simple characters
+       - collation elements
+       - collation symbols
+     We need to make a table which lets the user to access the primary
+     weight based on the symbol string.  */
+  symbols_hash_tab_size = next_prime ((4 * (charset->char_table.filled
+                                           + collate->elements.filled
+                                           + collate->symbols.filled)) / 3);
+  symbols_hash_tab = obstack_alloc (&non_simple, (2 * symbols_hash_tab_size
+                                                 * sizeof (u_int32_t)));
+  memset (symbols_hash_tab, '\377', (2 * symbols_hash_tab_size
+                                    * sizeof (u_int32_t)));
+
+  /* Now fill the array.  First the symbols from the character set,
+     then the collation elements and last the collation symbols.  */
+  hash_tab = &charset->char_table;
+  while (1)
+    {
+      void *ptr;       /* Running pointer.  */
+      const char *key; /* Key for current bucket.  */
+      size_t keylen;   /* Length of key data.  */
+      void *data;      /* Data.  */
+
+      ptr = NULL;
+      while (iterate_table (hash_tab, &ptr, (const void **) &key,
+                           &keylen, (void **) &data) == 0)
+       {
+         size_t hash_val;
+         size_t idx;
+         u_int32_t word;
+         unsigned int *weights;
+
+         if (hash_tab == &charset->char_table
+             || hash_tab == &collate->elements)
+           {
+             element_t *lastp, *firstp;
+             wchar_t dummy_name[2];
+             const wchar_t *name;
+             size_t name_len;
+
+             if (hash_tab == &charset->char_table)
+               {
+                 dummy_name[0] = (wchar_t) ((unsigned long int) data);
+                 dummy_name[1] = L'\0';
+                 name = dummy_name;
+                 name_len = sizeof (wchar_t);
+               }
+             else
+               {
+                 element_t *elemp = (element_t *) data;
+                 name = elemp->name;
+                 name_len = wcslen (name) * sizeof (wchar_t);
+               }
+
+             /* First check whether this character is used at all.  */
+             if (find_entry (&collate->result, name, name_len,
+                             (void *) &firstp) < 0)
+               /* The symbol is not directly mentioned in the collation.
+                  I.e., we use the value for UNDEFINED.  */
+               lastp = &collate->undefined;
+             else
+               {
+                 /* The entry for the simple character is always found at
+                    the end.  */
+                 lastp = firstp;
+                 while (lastp->next != NULL && wcscmp (name, lastp->name))
+                   lastp = lastp->next;
+               }
+
+             weights = lastp->ordering;
+           }
+         else
+           {
+             dummy_weights[0] = 1;
+             dummy_weights[collate->nrules]
+               = (unsigned int) ((unsigned long int) data);
+
+             weights = dummy_weights;
+           }
+
+         /* In LASTP->ordering we now have the collation class.
+            Determine the place in the hashing table next.  */
+         hash_val = hash_string (key, keylen);
+         idx = hash_val % symbols_hash_tab_size;
+
+         if (symbols_hash_tab[2 * idx] != (~((u_int32_t) 0)))
+           {
+             /* We need the second hashing function.  */
+             size_t c = 1 + (hash_val % (symbols_hash_tab_size - 2));
+
+             do
+               if (idx >= symbols_hash_tab_size - c)
+                 idx -= symbols_hash_tab_size - c;
+               else
+                 idx += c;
+             while (symbols_hash_tab[2 * idx] != (~((u_int32_t) 0)));
+           }
+
+         symbols_hash_tab[2 * idx] = obstack_object_size (&string_pool);
+         symbols_hash_tab[2 * idx + 1] = (obstack_object_size (&non_simple)
+                                          / sizeof (u_int32_t));
+
+         obstack_grow0 (&string_pool, key, keylen);
+         /* Adding the first weight looks complicated.  We have to deal
+            with the kind it is stored and with the fact that original
+            form uses `unsigned int's while we need `u_int32_t' here.  */
+         word = weights[0];
+         obstack_grow (&non_simple, &word, sizeof (u_int32_t));
+         for (cnt = 0; cnt < weights[0]; ++cnt)
+           {
+             word = weights[collate->nrules + cnt];
+             obstack_grow (&non_simple, &word, sizeof (u_int32_t));
+           }
+       }
+
+      if (hash_tab == &charset->char_table)
+       hash_tab = &collate->elements;
+      else if (hash_tab == &collate->elements)
+       hash_tab = &collate->symbols;
+      else
+       break;
+    }
+
+  /* Now we have the complete tables.  */
+  if (obstack_object_size (&string_pool) % 4 != 0)
+    obstack_blank (&non_simple, 4 - (obstack_object_size (&string_pool) % 4));
+  symbols_string_pool_size = obstack_object_size (&string_pool);
+  symbols_string_pool = obstack_finish (&string_pool);
+
+  symbols_class_size = obstack_object_size (&non_simple);
+  symbols_class = obstack_finish (&non_simple);
+
+  /* Generate tables with other byte order.  */
+  symbols_hash_tab_ob = obstack_alloc (&non_simple, (2 * symbols_hash_tab_size
+                                                    * sizeof (u_int32_t)));
+  for (cnt = 0; cnt < 2 * symbols_hash_tab_size; ++cnt)
+    symbols_hash_tab_ob[cnt] = SWAPU32 (symbols_hash_tab[cnt]);
+
+  symbols_class_ob = obstack_alloc (&non_simple, symbols_class_size);
+  for (cnt = 0; cnt < symbols_class_size / 4; ++cnt)
+    symbols_class_ob[cnt] = SWAPU32 (symbols_class[cnt]);
+
+
   /* Store table adresses and lengths.   */
 #if __BYTE_ORDER == __BIG_ENDIAN
   iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_TABLE_EB)].iov_base = table;
@@ -642,12 +913,124 @@ Computing table size for collation information might take a while..."),
   iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_UNDEFINED)].iov_base = &undefined_offset;
   iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_UNDEFINED)].iov_len = sizeof (u_int32_t);
 
+
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_HASH_SIZE)].iov_base
+    = &element_hash_tab_size;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_HASH_SIZE)].iov_len
+    = sizeof (u_int32_t);
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_HASH_EB)].iov_base
+    = element_hash_tab;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_HASH_EB)].iov_len
+    = 2 * element_hash_tab_size * sizeof (u_int32_t);
+
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_HASH_EL)].iov_base
+    = element_hash_tab_ob;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_HASH_EL)].iov_len
+    = 2 * element_hash_tab_size * sizeof (u_int32_t);
+#else
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_HASH_EL)].iov_base
+    = element_hash_tab;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_HASH_EL)].iov_len
+    = 2 * element_hash_tab_size * sizeof (u_int32_t);
+
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_HASH_EB)].iov_base
+    = element_hash_tab_ob;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_HASH_EB)].iov_len
+    = 2 * element_hash_tab_size * sizeof (u_int32_t);
+#endif
+
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_STR_POOL)].iov_base
+    = element_string_pool;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_STR_POOL)].iov_len
+    = element_string_pool_size;
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_VAL_EB)].iov_base
+    = element_value;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_VAL_EB)].iov_len
+    = element_value_size;
+
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_VAL_EL)].iov_base
+    = element_value_ob;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_VAL_EL)].iov_len
+    = element_value_size;
+#else
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_VAL_EL)].iov_base
+    = element_value;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_VAL_EL)].iov_len
+    = element_value_size;
+
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_VAL_EB)].iov_base
+    = element_value_ob;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_VAL_EB)].iov_len
+    = element_value_size;
+#endif
+
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZE)].iov_base
+    = &symbols_hash_tab_size;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZE)].iov_len
+    = sizeof (u_int32_t);
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_EB)].iov_base
+    = symbols_hash_tab;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_EB)].iov_len
+    = 2 * symbols_hash_tab_size * sizeof (u_int32_t);
+
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_EL)].iov_base
+    = symbols_hash_tab_ob;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_EL)].iov_len
+    = 2 * symbols_hash_tab_size * sizeof (u_int32_t);
+#else
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_EL)].iov_base
+    = symbols_hash_tab;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_EL)].iov_len
+    = 2 * symbols_hash_tab_size * sizeof (u_int32_t);
+
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_EB)].iov_base
+    = symbols_hash_tab_ob;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_EB)].iov_len
+    = 2 * symbols_hash_tab_size * sizeof (u_int32_t);
+#endif
+
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_STR_POOL)].iov_base
+    = symbols_string_pool;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_STR_POOL)].iov_len
+    = symbols_string_pool_size;
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_CLASS_EB)].iov_base
+    = symbols_class;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_ELEM_CLASS_EB)].iov_len
+    = symbols_class_size;
+
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_CLASS_EL)].iov_base
+    = symbols_class_ob;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_CLASS_EL)].iov_len
+    = symbols_class_size;
+#else
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_CLASS_EL)].iov_base
+    = symbols_class;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_CLASS_EL)].iov_len
+    = symbols_class_size;
+
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_CLASS_EB)].iov_base
+    = symbols_class_ob;
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_SYMB_CLASS_EB)].iov_len
+    = symbols_class_size;
+#endif
+
   /* Update idx array.  */
   idx[0] = iov[0].iov_len + iov[1].iov_len;
   for (cnt = 1; cnt < nelems; ++cnt)
     idx[cnt] = idx[cnt - 1] + iov[1 + cnt].iov_len;
 
   write_locale_data (output_path, "LC_COLLATE", 2 + nelems, iov);
+
+  obstack_free (&non_simple, NULL);
+  obstack_free (&string_pool, NULL);
 }
 
 
@@ -729,7 +1112,7 @@ collate_element_from (struct linereader *lr, struct localedef_t *locale,
 
   if (elemp->name[0] == L'\0' || elemp->name[1] == L'\0')
     {
-      lr_error (lr, _("illegal colltion element"));
+      lr_error (lr, _("illegal collation element"));
       return;
     }
 
@@ -762,8 +1145,7 @@ collate_element_from (struct linereader *lr, struct localedef_t *locale,
            {
              if (set_entry (&collate->result, elemp->name, sizeof (wchar_t),
                             elemp) < 0)
-               error (EXIT_FAILURE, 0,
-                      _("\
+               error (EXIT_FAILURE, 0, _("\
 error while inserting collation element into hash table"));
            }
          else
@@ -1019,7 +1401,7 @@ line before ellipsis does not contain definition for character constant"));
     }
 
   /* Now it's time to handle the ellipsis in the previous line.  We do
-     this only when the last line contained an definition for an
+     this only when the last line contained an definition for a
      character, the current line also defines an character, the
      character code for the later is bigger than the former.  */
   if (collate->was_ellipsis)
index e408421..c595524 100644 (file)
@@ -92,4 +92,37 @@ locale_special (const char *name, int show_category_name,
       putchar ('\n');
       return;
     }
+
+  if (strcmp (name, "collate-classes") == 0)
+    {
+      size_t nelem = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZE);
+      size_t cnt;
+      int first = 1;
+
+      if (show_category_name)
+       puts ("LC_COLLATE");
+      if (show_keyword_name)
+       fputs ("collate-classes=", stdout);
+
+      for (cnt = 0; cnt < nelem; ++cnt)
+       if (__collate_symbol_hash[2 * cnt] != 0xffffffff)
+         {
+           printf ("%s<%s>", first ? "" : ",",
+                   &__collate_symbol_strings[__collate_symbol_hash[2 * cnt]]);
+#if 1
+           {
+             size_t idx = __collate_symbol_hash[2 * cnt + 1];
+             size_t cls;
+
+             putchar ('=');
+             for (cls = 0; cls < __collate_symbol_classes[idx]; ++cls)
+               printf ("%s%d", cls == 0 ? "" : ":",
+                       __collate_symbol_classes[idx + 1 + cls]);
+           }
+#endif
+           first = 0;
+         }
+      putchar ('\n');
+      return;
+    }
 }
index 9fe85e9..95e166e 100644 (file)
@@ -122,7 +122,8 @@ void collate_startup (struct linereader *lr, struct localedef_t *locale,
 void collate_finish (struct localedef_t *locale,
                     struct charset_t *charset);
 
-void collate_output (struct localedef_t *locale, const char *output_path);
+void collate_output (struct localedef_t *locale, struct charset_t *charset,
+                    const char *output_path);
 
 void collate_element_to (struct linereader *lr, struct localedef_t *locale,
                         struct token *code, struct charset_t *charset);