Browse Source

New locale support (in development). Supports LC_CTYPE, LC_NUMERIC,
LC_TIME, LC_MONETARY, and LC_MESSAGES for the SUSv3 items. Also,
nl_langinfo() when real locale support is enabled.
New implementation of ctype.h.
New implementation of wctype.h.
New implementation of most of the string functions (smaller).
New implementation of the wcs/wmem functions. These are untested, but
they're also just preprocessor-modified versions ot the corresponding
str/mem functions.
Tweaked qsort and new bsearch.

Stuff still pending:
stdlib.h and wchar.h mb<->wc functions. I actually have working
versions of the stdlib ones, but the reentrant versions from
wchar.h require some reworking.
Basic replacement and translit support for wc->mb conversions.
(groundwork laid).
Simple-minded collate support such as was provided by the previous
locale implementation. (mostly done -- 8-bit codesets only)
Shared mmaping of the locale data and strerror message text.

Manuel Novoa III 22 years ago
parent
commit
d07fdf8b9e
57 changed files with 11677 additions and 1766 deletions
  1. 5 1
      Makefile
  2. 5 0
      Rules.mak
  3. 14 0
      extra/locale/.cvsignore
  4. 288 0
      extra/locale/LOCALES
  5. 64 22
      extra/locale/README
  6. 128 0
      extra/locale/charmaps/ASCII.pairs
  7. 255 0
      extra/locale/charmaps/CP1251.pairs
  8. 256 0
      extra/locale/charmaps/ISO-8859-1.pairs
  9. 256 0
      extra/locale/charmaps/ISO-8859-10.pairs
  10. 256 0
      extra/locale/charmaps/ISO-8859-13.pairs
  11. 256 0
      extra/locale/charmaps/ISO-8859-14.pairs
  12. 256 0
      extra/locale/charmaps/ISO-8859-15.pairs
  13. 256 0
      extra/locale/charmaps/ISO-8859-16.pairs
  14. 256 0
      extra/locale/charmaps/ISO-8859-2.pairs
  15. 249 0
      extra/locale/charmaps/ISO-8859-3.pairs
  16. 256 0
      extra/locale/charmaps/ISO-8859-4.pairs
  17. 256 0
      extra/locale/charmaps/ISO-8859-5.pairs
  18. 211 0
      extra/locale/charmaps/ISO-8859-6.pairs
  19. 250 0
      extra/locale/charmaps/ISO-8859-7.pairs
  20. 220 0
      extra/locale/charmaps/ISO-8859-8.pairs
  21. 256 0
      extra/locale/charmaps/ISO-8859-9.pairs
  22. 256 0
      extra/locale/charmaps/KOI8-R.pairs
  23. 256 0
      extra/locale/charmaps/KOI8-U.pairs
  24. 215 0
      extra/locale/charmaps/TIS-620.pairs
  25. 0 207
      extra/locale/gen_collate_from_glibc.c
  26. 0 277
      extra/locale/gen_ctype_from_glibc.c
  27. 1254 0
      extra/locale/gen_locale.c
  28. 237 0
      extra/locale/gen_mmap.c
  29. 729 0
      extra/locale/gen_wc8bit.c
  30. 833 0
      extra/locale/gen_wctype.c
  31. 72 0
      extra/locale/lmmtolso.c
  32. 89 0
      extra/locale/locale_mmap.h
  33. 110 66
      include/ctype.h
  34. 2 2
      include/inttypes.h
  35. 28 8
      include/langinfo.h
  36. 0 2
      include/libgen.h
  37. 100 20
      include/locale.h
  38. 5 7
      include/stdint.h
  39. 6 6
      include/stdlib.h
  40. 3 0
      libc/misc/Makefile
  41. 1 4
      libc/misc/ctype/Makefile
  42. 237 249
      libc/misc/ctype/ctype.c
  43. 0 517
      libc/misc/ctype/ctype_C.c
  44. 12 0
      libc/misc/internals/__uClibc_main.c
  45. 10 5
      libc/misc/locale/Makefile
  46. 0 22
      libc/misc/locale/_locale.h
  47. 447 272
      libc/misc/locale/locale.c
  48. 0 52
      libc/misc/locale/localeconv.c
  49. 47 0
      libc/misc/wctype/Makefile
  50. 480 0
      libc/misc/wctype/wctype.c
  51. 3 2
      libc/stdlib/Makefile
  52. 169 12
      libc/stdlib/stdlib.c
  53. 42 13
      libc/string/Makefile
  54. 1273 0
      libc/string/wstring.c
  55. 1 0
      libc/sysdeps/linux/common/bits/.cvsignore
  56. 250 0
      libc/sysdeps/linux/common/bits/uClibc_ctype.h
  57. 261 0
      libc/sysdeps/linux/common/bits/uClibc_locale.h

+ 5 - 1
Makefile

@@ -174,10 +174,14 @@ uClibc_config: Makefile Config
 	fi
 	@if [ "$(HAS_LOCALE)" = "true" ] ; then \
 	    echo "#define __UCLIBC_HAS_LOCALE__ 1" >> include/bits/uClibc_config.h ; \
-	    echo "#define __UCLIBC_LOCALE_DIR \""$(LOCALE_DIR)"\"" >> include/bits/uClibc_config.h ; \
 	else \
 	    echo "#undef __UCLIBC_HAS_LOCALE__" >> include/bits/uClibc_config.h ; \
 	fi
+	@if [ "$(HAS_WCHAR)" = "true" ] ; then \
+	    echo "#define __UCLIBC_HAS_WCHAR__ 1" >> include/bits/uClibc_config.h ; \
+	else \
+	    echo "#undef __UCLIBC_HAS_WCHAR__" >> include/bits/uClibc_config.h ; \
+	fi
 	@if [ "$(HAVE_ELF)" = "false" ] ; then \
 	    echo "#undef HAVE_ELF" >> include/bits/uClibc_config.h ; \
 	else \

+ 5 - 0
Rules.mak

@@ -117,6 +117,11 @@ ifeq ($(strip $(INCLUDE_THREADS)),true)
     CFLAGS  += -D_LIBC_REENTRANT
 endif
 
+# Locale support is required for wide char support.
+ifneq ($(strip $(HAS_LOCALE)),true)
+    HAS_WCHAR:=false
+endif
+
 # TARGET_PREFIX is the directory under which which the uClibc runtime
 # environment will be installed and used on the target system.   The 
 # result will look something like the following:

+ 14 - 0
extra/locale/.cvsignore

@@ -0,0 +1,14 @@
+lmmtolso
+gen_wctype
+wctables.h
+gen_wc8bit
+c8tables.h
+gen_locale
+locale_tables.h
+locale.mmap
+gen_mmap
+lt_defines.h
+locale_data.c
+uClibc_locale_data.h
+codesets.txt
+locales.txt

+ 288 - 0
extra/locale/LOCALES

@@ -0,0 +1,288 @@
+# First some @modifier mappings.  Internally, the modifier is signaled by
+# replacing '_' in the locale name with a unique identifying character.
+# For example, internally we map "ca_ES@euro" to "caeES".  This allows for
+# smaller code and easier processing of locale names.
+
+@euro e
+@cyrillic c
+
+#---------------------------------------------------------------------------
+# Next, set to {y}es to enable and {n}o to disable the UTF-8 and the 8-bit
+# codeset locales.  Of course, you must have built the c8tables.h and
+# the wctables.h files appropriately.
+
+
+UTF-8 yes
+8-BIT yes
+
+#---------------------------------------------------------------------------
+# Now the locales
+
+af_ZA ISO-8859-1
+ar_AE ISO-8859-6
+ar_BH ISO-8859-6
+ar_DZ ISO-8859-6
+ar_EG ISO-8859-6
+ar_IN UTF-8
+ar_IQ ISO-8859-6
+ar_JO ISO-8859-6
+ar_KW ISO-8859-6
+ar_LB ISO-8859-6
+ar_LY ISO-8859-6
+ar_MA ISO-8859-6
+ar_OM ISO-8859-6
+ar_QA ISO-8859-6
+ar_SA ISO-8859-6
+ar_SD ISO-8859-6
+ar_SY ISO-8859-6
+ar_TN ISO-8859-6
+ar_YE ISO-8859-6
+be_BY CP1251
+bg_BG CP1251
+ca_ES ISO-8859-1
+ca_ES@euro ISO-8859-15
+cs_CZ ISO-8859-2
+da_DK ISO-8859-1
+de_AT ISO-8859-1
+de_AT@euro ISO-8859-15
+de_BE ISO-8859-1
+de_BE@euro ISO-8859-15
+de_CH ISO-8859-1
+de_DE ISO-8859-1
+de_DE@euro ISO-8859-15
+de_LU ISO-8859-1
+de_LU@euro ISO-8859-15
+el_GR ISO-8859-7
+en_AU ISO-8859-1
+en_BW ISO-8859-1
+en_CA ISO-8859-1
+en_DK ISO-8859-1
+en_GB ISO-8859-1
+en_HK ISO-8859-1
+en_IE ISO-8859-1
+en_IE@euro ISO-8859-15
+en_IN UTF-8
+en_NZ ISO-8859-1
+en_PH ISO-8859-1
+en_SG ISO-8859-1
+en_US ISO-8859-1
+en_ZA ISO-8859-1
+en_ZW ISO-8859-1
+es_AR ISO-8859-1
+es_BO ISO-8859-1
+es_CL ISO-8859-1
+es_CO ISO-8859-1
+es_CR ISO-8859-1
+es_DO ISO-8859-1
+es_EC ISO-8859-1
+es_ES ISO-8859-1
+es_ES@euro ISO-8859-15
+es_GT ISO-8859-1
+es_HN ISO-8859-1
+es_MX ISO-8859-1
+es_NI ISO-8859-1
+es_PA ISO-8859-1
+es_PE ISO-8859-1
+es_PR ISO-8859-1
+es_PY ISO-8859-1
+es_SV ISO-8859-1
+es_US ISO-8859-1
+es_UY ISO-8859-1
+es_VE ISO-8859-1
+et_EE ISO-8859-1
+eu_ES ISO-8859-1
+eu_ES@euro ISO-8859-15
+fa_IR UTF-8
+fi_FI ISO-8859-1
+fi_FI@euro ISO-8859-15
+fo_FO ISO-8859-1
+fr_BE ISO-8859-1
+fr_BE@euro ISO-8859-15
+fr_CA ISO-8859-1
+fr_CH ISO-8859-1
+fr_FR ISO-8859-1
+fr_FR@euro ISO-8859-15
+fr_LU ISO-8859-1
+fr_LU@euro ISO-8859-15
+ga_IE ISO-8859-1
+ga_IE@euro ISO-8859-15
+gl_ES ISO-8859-1
+gl_ES@euro ISO-8859-15
+gv_GB ISO-8859-1
+he_IL ISO-8859-8
+hi_IN UTF-8
+hr_HR ISO-8859-2
+hu_HU ISO-8859-2
+id_ID ISO-8859-1
+is_IS ISO-8859-1
+it_CH ISO-8859-1
+it_IT ISO-8859-1
+it_IT@euro ISO-8859-15
+iw_IL ISO-8859-8
+kl_GL ISO-8859-1
+ko_KR.UTF-8 UTF-8
+kw_GB ISO-8859-1
+lt_LT ISO-8859-13
+lv_LV ISO-8859-13
+mk_MK ISO-8859-5
+mr_IN UTF-8
+ms_MY ISO-8859-1
+mt_MT ISO-8859-3
+nl_BE ISO-8859-1
+nl_BE@euro ISO-8859-15
+nl_NL ISO-8859-1
+nl_NL@euro ISO-8859-15
+nn_NO ISO-8859-1
+no_NO ISO-8859-1
+pl_PL ISO-8859-2
+pt_BR ISO-8859-1
+pt_PT ISO-8859-1
+pt_PT@euro ISO-8859-15
+ro_RO ISO-8859-2
+ru_RU ISO-8859-5
+ru_RU.KOI8-R KOI8-R
+ru_UA KOI8-U
+sk_SK ISO-8859-2
+sl_SI ISO-8859-2
+sq_AL ISO-8859-1
+sr_YU ISO-8859-2
+sr_YU@cyrillic ISO-8859-5
+sv_FI ISO-8859-1
+sv_FI@euro ISO-8859-15
+sv_SE ISO-8859-1
+ta_IN UTF-8
+te_IN UTF-8
+th_TH TIS-620
+tr_TR ISO-8859-9
+uk_UA KOI8-U
+vi_VN UTF-8
+ar_AE.UTF-8 UTF-8
+ar_BH.UTF-8 UTF-8
+ar_DZ.UTF-8 UTF-8
+ar_EG.UTF-8 UTF-8
+ar_IQ.UTF-8 UTF-8
+ar_JO.UTF-8 UTF-8
+ar_KW.UTF-8 UTF-8
+ar_LB.UTF-8 UTF-8
+ar_LY.UTF-8 UTF-8
+ar_MA.UTF-8 UTF-8
+ar_OM.UTF-8 UTF-8
+ar_QA.UTF-8 UTF-8
+ar_SA.UTF-8 UTF-8
+ar_SD.UTF-8 UTF-8
+ar_SY.UTF-8 UTF-8
+ar_TN.UTF-8 UTF-8
+ar_YE.UTF-8 UTF-8
+be_BY.UTF-8 UTF-8
+bg_BG.UTF-8 UTF-8
+ca_ES.UTF-8 UTF-8
+ca_ES.UTF-8@euro UTF-8
+cs_CZ.UTF-8 UTF-8
+da_DK.UTF-8 UTF-8
+de_AT.UTF-8 UTF-8
+de_AT.UTF-8@euro UTF-8
+de_BE.UTF-8 UTF-8
+de_BE.UTF-8@euro UTF-8
+de_CH.UTF-8 UTF-8
+de_DE.UTF-8 UTF-8
+de_DE.UTF-8@euro UTF-8
+de_LU.UTF-8 UTF-8
+de_LU.UTF-8@euro UTF-8
+el_GR.UTF-8 UTF-8
+en_AU.UTF-8 UTF-8
+en_BW.UTF-8 UTF-8
+en_CA.UTF-8 UTF-8
+en_DK.UTF-8 UTF-8
+en_GB.UTF-8 UTF-8
+en_HK.UTF-8 UTF-8
+en_IE.UTF-8 UTF-8
+en_IE.UTF-8@euro UTF-8
+en_NZ.UTF-8 UTF-8
+en_PH.UTF-8 UTF-8
+en_SG.UTF-8 UTF-8
+en_US.UTF-8 UTF-8
+en_ZA.UTF-8 UTF-8
+en_ZW.UTF-8 UTF-8
+es_AR.UTF-8 UTF-8
+es_BO.UTF-8 UTF-8
+es_CL.UTF-8 UTF-8
+es_CO.UTF-8 UTF-8
+es_CR.UTF-8 UTF-8
+es_DO.UTF-8 UTF-8
+es_EC.UTF-8 UTF-8
+es_ES.UTF-8 UTF-8
+es_ES.UTF-8@euro UTF-8
+es_GT.UTF-8 UTF-8
+es_HN.UTF-8 UTF-8
+es_MX.UTF-8 UTF-8
+es_NI.UTF-8 UTF-8
+es_PA.UTF-8 UTF-8
+es_PE.UTF-8 UTF-8
+es_PR.UTF-8 UTF-8
+es_PY.UTF-8 UTF-8
+es_SV.UTF-8 UTF-8
+es_US.UTF-8 UTF-8
+es_UY.UTF-8 UTF-8
+es_VE.UTF-8 UTF-8
+et_EE.UTF-8 UTF-8
+eu_ES.UTF-8 UTF-8
+eu_ES.UTF-8@euro UTF-8
+fi_FI.UTF-8 UTF-8
+fi_FI.UTF-8@euro UTF-8
+fo_FO.UTF-8 UTF-8
+fr_BE.UTF-8 UTF-8
+fr_BE.UTF-8@euro UTF-8
+fr_CA.UTF-8 UTF-8
+fr_CH.UTF-8 UTF-8
+fr_FR.UTF-8 UTF-8
+fr_FR.UTF-8@euro UTF-8
+fr_LU.UTF-8 UTF-8
+fr_LU.UTF-8@euro UTF-8
+ga_IE.UTF-8 UTF-8
+ga_IE.UTF-8@euro UTF-8
+gl_ES.UTF-8 UTF-8
+gl_ES.UTF-8@euro UTF-8
+gv_GB.UTF-8 UTF-8
+he_IL.UTF-8 UTF-8
+hr_HR.UTF-8 UTF-8
+hu_HU.UTF-8 UTF-8
+id_ID.UTF-8 UTF-8
+is_IS.UTF-8 UTF-8
+it_CH.UTF-8 UTF-8
+it_IT.UTF-8 UTF-8
+it_IT.UTF-8@euro UTF-8
+iw_IL.UTF-8 UTF-8
+kl_GL.UTF-8 UTF-8
+kw_GB.UTF-8 UTF-8
+lt_LT.UTF-8 UTF-8
+lv_LV.UTF-8 UTF-8
+mk_MK.UTF-8 UTF-8
+ms_MY.UTF-8 UTF-8
+mt_MT.UTF-8 UTF-8
+nl_BE.UTF-8 UTF-8
+nl_BE.UTF-8@euro UTF-8
+nl_NL.UTF-8 UTF-8
+nl_NL.UTF-8@euro UTF-8
+nn_NO.UTF-8 UTF-8
+no_NO.UTF-8 UTF-8
+pl_PL.UTF-8 UTF-8
+pt_BR.UTF-8 UTF-8
+pt_PT.UTF-8 UTF-8
+pt_PT.UTF-8@euro UTF-8
+ro_RO.UTF-8 UTF-8
+ru_RU.UTF-8 UTF-8
+ru_UA.UTF-8 UTF-8
+sk_SK.UTF-8 UTF-8
+sl_SI.UTF-8 UTF-8
+sq_AL.UTF-8 UTF-8
+sr_YU.UTF-8 UTF-8
+sr_YU.UTF-8@cyrillic UTF-8
+sv_FI.UTF-8 UTF-8
+sv_FI.UTF-8@euro UTF-8
+sv_SE.UTF-8 UTF-8
+th_TH.UTF-8 UTF-8
+tr_TR.UTF-8 UTF-8
+uk_UA.UTF-8 UTF-8
+zh_CN.UTF-8 UTF-8
+zh_HK.UTF-8 UTF-8
+zh_TW.UTF-8 UTF-8

+ 64 - 22
extra/locale/README

@@ -1,29 +1,71 @@
+Warning!!!   Warning!!!   Warning!!!   Warning!!!   Warning!!!   Warning!!!
+Warning!!!   Warning!!!   Warning!!!   Warning!!!   Warning!!!   Warning!!!
 
-The programs gen_ctype_from_glibc.c and gen_collate_from_glibc.c
-will generate data files which can be
-used by uClibc ctype, strcoll and setlocale functions to support locales.
-From the comments:
+The programs in this directory are strictly cut-and-paste hack jobs to
+extract the data I needed from glibc's locale database.  I'm ashamed to
+even let them into the light of day, and I consider them complete garbage.
 
-/*
- * Generator locale ctype tables
- * You must have already setuped locale for worked libc (libc5 or glibc)
- *
- * This programm scan /usr/share/locale directories and write
- * ./LOCALE/LC_CTYPE files for system with uclibc
- *
- * Written by Vladimir Oleynik <vodz@usa.net> 2001
- */
+However, they are currently necessary to build the data needed for the
+locale support I've implemented, so I'm forced to include them here.
 
+NOTE: While its possible to use this stuff for native != target arch,
+you'll have to either write a converter to account for endianess and
+struct padding issues, or run the mmap file generator on your target
+arch.  But all these programs will be rewritten at some point.
 
-Sample usage to dump all the data files in a tmp directory:
+All that being said, LC_CTYPE support has been added and supports the
+ctype.h and wctype.h function.  Also, LC_TIME, LC_MONETARY, LC_NUMERIC,
+and LC_MESSAGES are supported wrt SUSv3.  localeconv() works in both
+real and stub locale modes.  nl_langinfo() currently only works with
+real locales enabled.  That will be fixed though.  wc->mb unsupported
+char replacement and basic translit support is on the way as well.
+Finally, some basic 8-bit codeset LC_COLLATE support should be in place
+in the next week or two (similar to what was in the previous locale
+implementation).
 
-gcc gen_ctype_from_glibc.c -o gen_ctype_from_glibc
-gcc gen_collate_from_glibc.c -o gen_ctype_from_glibc
+Also, as one can probably guess, I'm working towards having the locale
+data accessed via a shared mmap.  That will allow non-mmu platforms
+to use this without the current bloat.
 
-mkdir tmp
-cd tmp
-../gen_ctype_from_glibc -d /usr/share/locale -c
-../gen_collate_from_glibc
+Currently, the output of size for my locale_data.o file is
+  text    data     bss     dec     hex filename
+  59072       4       0   59076    e6c4 extra/locale/locale_data.o
+which is for the C locale (automatic of course) + all codesets in
+charmaps/ and all 268 locales in LOCALES.  I estimate that the
+translit support for those 8-bit codesets will add another 7-10k.
 
-Then just move the directory or directories you need (not the .c files)
-to the uClibc locale file directory you set in Config.
+One difference of note is that the special case upper/lower mappings
+in the turkish locale are currently not implemented.  That will be
+fixed.
+
+Manuel
+
+Warning!!!   Warning!!!   Warning!!!   Warning!!!   Warning!!!   Warning!!!
+Warning!!!   Warning!!!   Warning!!!   Warning!!!   Warning!!!   Warning!!!
+
+
+1) In the toplevel dir,  'make headers uClibc_config'  .
+
+2) Create a codesets.txt file in this dir listing the codesets you want
+   to support.  The easiest way to do this is to edit the output of
+	'find ./charmaps -name "*.pairs" > codesets.txt'.
+   NOTE: UTF-8 support is always included if you build with wide chars enabled.
+   NOTE: The files in charmaps/ were created from glibc's charmap files
+         with the awk script at the end of this file.  You can add others
+	 but only single byte codesets are supported.
+
+3) Create a locales.txt file to select the locales you want to support.
+   You can copy and edit the LOCALES file for example.  Other locales could
+   added provided you've included the appropriate codesets in step 2.
+   NOTE: You have to have the approprite locales available for glibc!
+
+4) Run make here.
+
+5) Continue building uClibc from the toplevel dir.
+
+
+
+
+Script used to generate the charmaps/*.pairs files:
+
+cat $1 | awk 'BEGIN { i = 0 } ; { if ($1 == "CHARMAP") i=1 ; else if ($1 == "END") i=0 ; else if (i==1) { sub("/","0",$2) ; sub("<U","0x",$1) ; sub(">","",$1) ; print "{", $2, ",", $1, "}," } }'

+ 128 - 0
extra/locale/charmaps/ASCII.pairs

@@ -0,0 +1,128 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },

+ 255 - 0
extra/locale/charmaps/CP1251.pairs

@@ -0,0 +1,255 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x0402 },
+{ 0x81 , 0x0403 },
+{ 0x82 , 0x201A },
+{ 0x83 , 0x0453 },
+{ 0x84 , 0x201E },
+{ 0x85 , 0x2026 },
+{ 0x86 , 0x2020 },
+{ 0x87 , 0x2021 },
+{ 0x88 , 0x20AC },
+{ 0x89 , 0x2030 },
+{ 0x8a , 0x0409 },
+{ 0x8b , 0x2039 },
+{ 0x8c , 0x040A },
+{ 0x8d , 0x040C },
+{ 0x8e , 0x040B },
+{ 0x8f , 0x040F },
+{ 0x90 , 0x0452 },
+{ 0x91 , 0x2018 },
+{ 0x92 , 0x2019 },
+{ 0x93 , 0x201C },
+{ 0x94 , 0x201D },
+{ 0x95 , 0x2022 },
+{ 0x96 , 0x2013 },
+{ 0x97 , 0x2014 },
+{ 0x99 , 0x2122 },
+{ 0x9a , 0x0459 },
+{ 0x9b , 0x203A },
+{ 0x9c , 0x045A },
+{ 0x9d , 0x045C },
+{ 0x9e , 0x045B },
+{ 0x9f , 0x045F },
+{ 0xa0 , 0x00A0 },
+{ 0xa1 , 0x040E },
+{ 0xa2 , 0x045E },
+{ 0xa3 , 0x0408 },
+{ 0xa4 , 0x00A4 },
+{ 0xa5 , 0x0490 },
+{ 0xa6 , 0x00A6 },
+{ 0xa7 , 0x00A7 },
+{ 0xa8 , 0x0401 },
+{ 0xa9 , 0x00A9 },
+{ 0xaa , 0x0404 },
+{ 0xab , 0x00AB },
+{ 0xac , 0x00AC },
+{ 0xad , 0x00AD },
+{ 0xae , 0x00AE },
+{ 0xaf , 0x0407 },
+{ 0xb0 , 0x00B0 },
+{ 0xb1 , 0x00B1 },
+{ 0xb2 , 0x0406 },
+{ 0xb3 , 0x0456 },
+{ 0xb4 , 0x0491 },
+{ 0xb5 , 0x00B5 },
+{ 0xb6 , 0x00B6 },
+{ 0xb7 , 0x00B7 },
+{ 0xb8 , 0x0451 },
+{ 0xb9 , 0x2116 },
+{ 0xba , 0x0454 },
+{ 0xbb , 0x00BB },
+{ 0xbc , 0x0458 },
+{ 0xbd , 0x0405 },
+{ 0xbe , 0x0455 },
+{ 0xbf , 0x0457 },
+{ 0xc0 , 0x0410 },
+{ 0xc1 , 0x0411 },
+{ 0xc2 , 0x0412 },
+{ 0xc3 , 0x0413 },
+{ 0xc4 , 0x0414 },
+{ 0xc5 , 0x0415 },
+{ 0xc6 , 0x0416 },
+{ 0xc7 , 0x0417 },
+{ 0xc8 , 0x0418 },
+{ 0xc9 , 0x0419 },
+{ 0xca , 0x041A },
+{ 0xcb , 0x041B },
+{ 0xcc , 0x041C },
+{ 0xcd , 0x041D },
+{ 0xce , 0x041E },
+{ 0xcf , 0x041F },
+{ 0xd0 , 0x0420 },
+{ 0xd1 , 0x0421 },
+{ 0xd2 , 0x0422 },
+{ 0xd3 , 0x0423 },
+{ 0xd4 , 0x0424 },
+{ 0xd5 , 0x0425 },
+{ 0xd6 , 0x0426 },
+{ 0xd7 , 0x0427 },
+{ 0xd8 , 0x0428 },
+{ 0xd9 , 0x0429 },
+{ 0xda , 0x042A },
+{ 0xdb , 0x042B },
+{ 0xdc , 0x042C },
+{ 0xdd , 0x042D },
+{ 0xde , 0x042E },
+{ 0xdf , 0x042F },
+{ 0xe0 , 0x0430 },
+{ 0xe1 , 0x0431 },
+{ 0xe2 , 0x0432 },
+{ 0xe3 , 0x0433 },
+{ 0xe4 , 0x0434 },
+{ 0xe5 , 0x0435 },
+{ 0xe6 , 0x0436 },
+{ 0xe7 , 0x0437 },
+{ 0xe8 , 0x0438 },
+{ 0xe9 , 0x0439 },
+{ 0xea , 0x043A },
+{ 0xeb , 0x043B },
+{ 0xec , 0x043C },
+{ 0xed , 0x043D },
+{ 0xee , 0x043E },
+{ 0xef , 0x043F },
+{ 0xf0 , 0x0440 },
+{ 0xf1 , 0x0441 },
+{ 0xf2 , 0x0442 },
+{ 0xf3 , 0x0443 },
+{ 0xf4 , 0x0444 },
+{ 0xf5 , 0x0445 },
+{ 0xf6 , 0x0446 },
+{ 0xf7 , 0x0447 },
+{ 0xf8 , 0x0448 },
+{ 0xf9 , 0x0449 },
+{ 0xfa , 0x044A },
+{ 0xfb , 0x044B },
+{ 0xfc , 0x044C },
+{ 0xfd , 0x044D },
+{ 0xfe , 0x044E },
+{ 0xff , 0x044F },

+ 256 - 0
extra/locale/charmaps/ISO-8859-1.pairs

@@ -0,0 +1,256 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x0080 },
+{ 0x81 , 0x0081 },
+{ 0x82 , 0x0082 },
+{ 0x83 , 0x0083 },
+{ 0x84 , 0x0084 },
+{ 0x85 , 0x0085 },
+{ 0x86 , 0x0086 },
+{ 0x87 , 0x0087 },
+{ 0x88 , 0x0088 },
+{ 0x89 , 0x0089 },
+{ 0x8a , 0x008A },
+{ 0x8b , 0x008B },
+{ 0x8c , 0x008C },
+{ 0x8d , 0x008D },
+{ 0x8e , 0x008E },
+{ 0x8f , 0x008F },
+{ 0x90 , 0x0090 },
+{ 0x91 , 0x0091 },
+{ 0x92 , 0x0092 },
+{ 0x93 , 0x0093 },
+{ 0x94 , 0x0094 },
+{ 0x95 , 0x0095 },
+{ 0x96 , 0x0096 },
+{ 0x97 , 0x0097 },
+{ 0x98 , 0x0098 },
+{ 0x99 , 0x0099 },
+{ 0x9a , 0x009A },
+{ 0x9b , 0x009B },
+{ 0x9c , 0x009C },
+{ 0x9d , 0x009D },
+{ 0x9e , 0x009E },
+{ 0x9f , 0x009F },
+{ 0xa0 , 0x00A0 },
+{ 0xa1 , 0x00A1 },
+{ 0xa2 , 0x00A2 },
+{ 0xa3 , 0x00A3 },
+{ 0xa4 , 0x00A4 },
+{ 0xa5 , 0x00A5 },
+{ 0xa6 , 0x00A6 },
+{ 0xa7 , 0x00A7 },
+{ 0xa8 , 0x00A8 },
+{ 0xa9 , 0x00A9 },
+{ 0xaa , 0x00AA },
+{ 0xab , 0x00AB },
+{ 0xac , 0x00AC },
+{ 0xad , 0x00AD },
+{ 0xae , 0x00AE },
+{ 0xaf , 0x00AF },
+{ 0xb0 , 0x00B0 },
+{ 0xb1 , 0x00B1 },
+{ 0xb2 , 0x00B2 },
+{ 0xb3 , 0x00B3 },
+{ 0xb4 , 0x00B4 },
+{ 0xb5 , 0x00B5 },
+{ 0xb6 , 0x00B6 },
+{ 0xb7 , 0x00B7 },
+{ 0xb8 , 0x00B8 },
+{ 0xb9 , 0x00B9 },
+{ 0xba , 0x00BA },
+{ 0xbb , 0x00BB },
+{ 0xbc , 0x00BC },
+{ 0xbd , 0x00BD },
+{ 0xbe , 0x00BE },
+{ 0xbf , 0x00BF },
+{ 0xc0 , 0x00C0 },
+{ 0xc1 , 0x00C1 },
+{ 0xc2 , 0x00C2 },
+{ 0xc3 , 0x00C3 },
+{ 0xc4 , 0x00C4 },
+{ 0xc5 , 0x00C5 },
+{ 0xc6 , 0x00C6 },
+{ 0xc7 , 0x00C7 },
+{ 0xc8 , 0x00C8 },
+{ 0xc9 , 0x00C9 },
+{ 0xca , 0x00CA },
+{ 0xcb , 0x00CB },
+{ 0xcc , 0x00CC },
+{ 0xcd , 0x00CD },
+{ 0xce , 0x00CE },
+{ 0xcf , 0x00CF },
+{ 0xd0 , 0x00D0 },
+{ 0xd1 , 0x00D1 },
+{ 0xd2 , 0x00D2 },
+{ 0xd3 , 0x00D3 },
+{ 0xd4 , 0x00D4 },
+{ 0xd5 , 0x00D5 },
+{ 0xd6 , 0x00D6 },
+{ 0xd7 , 0x00D7 },
+{ 0xd8 , 0x00D8 },
+{ 0xd9 , 0x00D9 },
+{ 0xda , 0x00DA },
+{ 0xdb , 0x00DB },
+{ 0xdc , 0x00DC },
+{ 0xdd , 0x00DD },
+{ 0xde , 0x00DE },
+{ 0xdf , 0x00DF },
+{ 0xe0 , 0x00E0 },
+{ 0xe1 , 0x00E1 },
+{ 0xe2 , 0x00E2 },
+{ 0xe3 , 0x00E3 },
+{ 0xe4 , 0x00E4 },
+{ 0xe5 , 0x00E5 },
+{ 0xe6 , 0x00E6 },
+{ 0xe7 , 0x00E7 },
+{ 0xe8 , 0x00E8 },
+{ 0xe9 , 0x00E9 },
+{ 0xea , 0x00EA },
+{ 0xeb , 0x00EB },
+{ 0xec , 0x00EC },
+{ 0xed , 0x00ED },
+{ 0xee , 0x00EE },
+{ 0xef , 0x00EF },
+{ 0xf0 , 0x00F0 },
+{ 0xf1 , 0x00F1 },
+{ 0xf2 , 0x00F2 },
+{ 0xf3 , 0x00F3 },
+{ 0xf4 , 0x00F4 },
+{ 0xf5 , 0x00F5 },
+{ 0xf6 , 0x00F6 },
+{ 0xf7 , 0x00F7 },
+{ 0xf8 , 0x00F8 },
+{ 0xf9 , 0x00F9 },
+{ 0xfa , 0x00FA },
+{ 0xfb , 0x00FB },
+{ 0xfc , 0x00FC },
+{ 0xfd , 0x00FD },
+{ 0xfe , 0x00FE },
+{ 0xff , 0x00FF },

+ 256 - 0
extra/locale/charmaps/ISO-8859-10.pairs

@@ -0,0 +1,256 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x0080 },
+{ 0x81 , 0x0081 },
+{ 0x82 , 0x0082 },
+{ 0x83 , 0x0083 },
+{ 0x84 , 0x0084 },
+{ 0x85 , 0x0085 },
+{ 0x86 , 0x0086 },
+{ 0x87 , 0x0087 },
+{ 0x88 , 0x0088 },
+{ 0x89 , 0x0089 },
+{ 0x8a , 0x008A },
+{ 0x8b , 0x008B },
+{ 0x8c , 0x008C },
+{ 0x8d , 0x008D },
+{ 0x8e , 0x008E },
+{ 0x8f , 0x008F },
+{ 0x90 , 0x0090 },
+{ 0x91 , 0x0091 },
+{ 0x92 , 0x0092 },
+{ 0x93 , 0x0093 },
+{ 0x94 , 0x0094 },
+{ 0x95 , 0x0095 },
+{ 0x96 , 0x0096 },
+{ 0x97 , 0x0097 },
+{ 0x98 , 0x0098 },
+{ 0x99 , 0x0099 },
+{ 0x9a , 0x009A },
+{ 0x9b , 0x009B },
+{ 0x9c , 0x009C },
+{ 0x9d , 0x009D },
+{ 0x9e , 0x009E },
+{ 0x9f , 0x009F },
+{ 0xa0 , 0x00A0 },
+{ 0xa1 , 0x0104 },
+{ 0xa2 , 0x0112 },
+{ 0xa3 , 0x0122 },
+{ 0xa4 , 0x012A },
+{ 0xa5 , 0x0128 },
+{ 0xa6 , 0x0136 },
+{ 0xa7 , 0x00A7 },
+{ 0xa8 , 0x013B },
+{ 0xa9 , 0x0110 },
+{ 0xaa , 0x0160 },
+{ 0xab , 0x0166 },
+{ 0xac , 0x017D },
+{ 0xad , 0x00AD },
+{ 0xae , 0x016A },
+{ 0xaf , 0x014A },
+{ 0xb0 , 0x00B0 },
+{ 0xb1 , 0x0105 },
+{ 0xb2 , 0x0113 },
+{ 0xb3 , 0x0123 },
+{ 0xb4 , 0x012B },
+{ 0xb5 , 0x0129 },
+{ 0xb6 , 0x0137 },
+{ 0xb7 , 0x00B7 },
+{ 0xb8 , 0x013C },
+{ 0xb9 , 0x0111 },
+{ 0xba , 0x0161 },
+{ 0xbb , 0x0167 },
+{ 0xbc , 0x017E },
+{ 0xbd , 0x2015 },
+{ 0xbe , 0x016B },
+{ 0xbf , 0x014B },
+{ 0xc0 , 0x0100 },
+{ 0xc1 , 0x00C1 },
+{ 0xc2 , 0x00C2 },
+{ 0xc3 , 0x00C3 },
+{ 0xc4 , 0x00C4 },
+{ 0xc5 , 0x00C5 },
+{ 0xc6 , 0x00C6 },
+{ 0xc7 , 0x012E },
+{ 0xc8 , 0x010C },
+{ 0xc9 , 0x00C9 },
+{ 0xca , 0x0118 },
+{ 0xcb , 0x00CB },
+{ 0xcc , 0x0116 },
+{ 0xcd , 0x00CD },
+{ 0xce , 0x00CE },
+{ 0xcf , 0x00CF },
+{ 0xd0 , 0x00D0 },
+{ 0xd1 , 0x0145 },
+{ 0xd2 , 0x014C },
+{ 0xd3 , 0x00D3 },
+{ 0xd4 , 0x00D4 },
+{ 0xd5 , 0x00D5 },
+{ 0xd6 , 0x00D6 },
+{ 0xd7 , 0x0168 },
+{ 0xd8 , 0x00D8 },
+{ 0xd9 , 0x0172 },
+{ 0xda , 0x00DA },
+{ 0xdb , 0x00DB },
+{ 0xdc , 0x00DC },
+{ 0xdd , 0x00DD },
+{ 0xde , 0x00DE },
+{ 0xdf , 0x00DF },
+{ 0xe0 , 0x0101 },
+{ 0xe1 , 0x00E1 },
+{ 0xe2 , 0x00E2 },
+{ 0xe3 , 0x00E3 },
+{ 0xe4 , 0x00E4 },
+{ 0xe5 , 0x00E5 },
+{ 0xe6 , 0x00E6 },
+{ 0xe7 , 0x012F },
+{ 0xe8 , 0x010D },
+{ 0xe9 , 0x00E9 },
+{ 0xea , 0x0119 },
+{ 0xeb , 0x00EB },
+{ 0xec , 0x0117 },
+{ 0xed , 0x00ED },
+{ 0xee , 0x00EE },
+{ 0xef , 0x00EF },
+{ 0xf0 , 0x00F0 },
+{ 0xf1 , 0x0146 },
+{ 0xf2 , 0x014D },
+{ 0xf3 , 0x00F3 },
+{ 0xf4 , 0x00F4 },
+{ 0xf5 , 0x00F5 },
+{ 0xf6 , 0x00F6 },
+{ 0xf7 , 0x0169 },
+{ 0xf8 , 0x00F8 },
+{ 0xf9 , 0x0173 },
+{ 0xfa , 0x00FA },
+{ 0xfb , 0x00FB },
+{ 0xfc , 0x00FC },
+{ 0xfd , 0x00FD },
+{ 0xfe , 0x00FE },
+{ 0xff , 0x0138 },

+ 256 - 0
extra/locale/charmaps/ISO-8859-13.pairs

@@ -0,0 +1,256 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x0080 },
+{ 0x81 , 0x0081 },
+{ 0x82 , 0x0082 },
+{ 0x83 , 0x0083 },
+{ 0x84 , 0x0084 },
+{ 0x85 , 0x0085 },
+{ 0x86 , 0x0086 },
+{ 0x87 , 0x0087 },
+{ 0x88 , 0x0088 },
+{ 0x89 , 0x0089 },
+{ 0x8a , 0x008A },
+{ 0x8b , 0x008B },
+{ 0x8c , 0x008C },
+{ 0x8d , 0x008D },
+{ 0x8e , 0x008E },
+{ 0x8f , 0x008F },
+{ 0x90 , 0x0090 },
+{ 0x91 , 0x0091 },
+{ 0x92 , 0x0092 },
+{ 0x93 , 0x0093 },
+{ 0x94 , 0x0094 },
+{ 0x95 , 0x0095 },
+{ 0x96 , 0x0096 },
+{ 0x97 , 0x0097 },
+{ 0x98 , 0x0098 },
+{ 0x99 , 0x0099 },
+{ 0x9a , 0x009A },
+{ 0x9b , 0x009B },
+{ 0x9c , 0x009C },
+{ 0x9d , 0x009D },
+{ 0x9e , 0x009E },
+{ 0x9f , 0x009F },
+{ 0xa0 , 0x00A0 },
+{ 0xa1 , 0x201D },
+{ 0xa2 , 0x00A2 },
+{ 0xa3 , 0x00A3 },
+{ 0xa4 , 0x00A4 },
+{ 0xa5 , 0x201E },
+{ 0xa6 , 0x00A6 },
+{ 0xa7 , 0x00A7 },
+{ 0xa8 , 0x00D8 },
+{ 0xa9 , 0x00A9 },
+{ 0xaa , 0x0156 },
+{ 0xab , 0x00AB },
+{ 0xac , 0x00AC },
+{ 0xad , 0x00AD },
+{ 0xae , 0x00AE },
+{ 0xaf , 0x00C6 },
+{ 0xb0 , 0x00B0 },
+{ 0xb1 , 0x00B1 },
+{ 0xb2 , 0x00B2 },
+{ 0xb3 , 0x00B3 },
+{ 0xb4 , 0x201C },
+{ 0xb5 , 0x00B5 },
+{ 0xb6 , 0x00B6 },
+{ 0xb7 , 0x00B7 },
+{ 0xb8 , 0x00F8 },
+{ 0xb9 , 0x00B9 },
+{ 0xba , 0x0157 },
+{ 0xbb , 0x00BB },
+{ 0xbc , 0x00BC },
+{ 0xbd , 0x00BD },
+{ 0xbe , 0x00BE },
+{ 0xbf , 0x00E6 },
+{ 0xc0 , 0x0104 },
+{ 0xc1 , 0x012E },
+{ 0xc2 , 0x0100 },
+{ 0xc3 , 0x0106 },
+{ 0xc4 , 0x00C4 },
+{ 0xc5 , 0x00C5 },
+{ 0xc6 , 0x0118 },
+{ 0xc7 , 0x0112 },
+{ 0xc8 , 0x010C },
+{ 0xc9 , 0x00C9 },
+{ 0xca , 0x0179 },
+{ 0xcb , 0x0116 },
+{ 0xcc , 0x0122 },
+{ 0xcd , 0x0136 },
+{ 0xce , 0x012A },
+{ 0xcf , 0x013B },
+{ 0xd0 , 0x0160 },
+{ 0xd1 , 0x0143 },
+{ 0xd2 , 0x0145 },
+{ 0xd3 , 0x00D3 },
+{ 0xd4 , 0x014C },
+{ 0xd5 , 0x00D5 },
+{ 0xd6 , 0x00D6 },
+{ 0xd7 , 0x00D7 },
+{ 0xd8 , 0x0172 },
+{ 0xd9 , 0x0141 },
+{ 0xda , 0x015A },
+{ 0xdb , 0x016A },
+{ 0xdc , 0x00DC },
+{ 0xdd , 0x017B },
+{ 0xde , 0x017D },
+{ 0xdf , 0x00DF },
+{ 0xe0 , 0x0105 },
+{ 0xe1 , 0x012F },
+{ 0xe2 , 0x0101 },
+{ 0xe3 , 0x0107 },
+{ 0xe4 , 0x00E4 },
+{ 0xe5 , 0x00E5 },
+{ 0xe6 , 0x0119 },
+{ 0xe7 , 0x0113 },
+{ 0xe8 , 0x010D },
+{ 0xe9 , 0x00E9 },
+{ 0xea , 0x017A },
+{ 0xeb , 0x0117 },
+{ 0xec , 0x0123 },
+{ 0xed , 0x0137 },
+{ 0xee , 0x012B },
+{ 0xef , 0x013C },
+{ 0xf0 , 0x0161 },
+{ 0xf1 , 0x0144 },
+{ 0xf2 , 0x0146 },
+{ 0xf3 , 0x00F3 },
+{ 0xf4 , 0x014D },
+{ 0xf5 , 0x00F5 },
+{ 0xf6 , 0x00F6 },
+{ 0xf7 , 0x00F7 },
+{ 0xf8 , 0x0173 },
+{ 0xf9 , 0x0142 },
+{ 0xfa , 0x015B },
+{ 0xfb , 0x016B },
+{ 0xfc , 0x00FC },
+{ 0xfd , 0x017C },
+{ 0xfe , 0x017E },
+{ 0xff , 0x2019 },

+ 256 - 0
extra/locale/charmaps/ISO-8859-14.pairs

@@ -0,0 +1,256 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x0080 },
+{ 0x81 , 0x0081 },
+{ 0x82 , 0x0082 },
+{ 0x83 , 0x0083 },
+{ 0x84 , 0x0084 },
+{ 0x85 , 0x0085 },
+{ 0x86 , 0x0086 },
+{ 0x87 , 0x0087 },
+{ 0x88 , 0x0088 },
+{ 0x89 , 0x0089 },
+{ 0x8a , 0x008A },
+{ 0x8b , 0x008B },
+{ 0x8c , 0x008C },
+{ 0x8d , 0x008D },
+{ 0x8e , 0x008E },
+{ 0x8f , 0x008F },
+{ 0x90 , 0x0090 },
+{ 0x91 , 0x0091 },
+{ 0x92 , 0x0092 },
+{ 0x93 , 0x0093 },
+{ 0x94 , 0x0094 },
+{ 0x95 , 0x0095 },
+{ 0x96 , 0x0096 },
+{ 0x97 , 0x0097 },
+{ 0x98 , 0x0098 },
+{ 0x99 , 0x0099 },
+{ 0x9a , 0x009A },
+{ 0x9b , 0x009B },
+{ 0x9c , 0x009C },
+{ 0x9d , 0x009D },
+{ 0x9e , 0x009E },
+{ 0x9f , 0x009F },
+{ 0xa0 , 0x00A0 },
+{ 0xa1 , 0x1E02 },
+{ 0xa2 , 0x1E03 },
+{ 0xa3 , 0x00A3 },
+{ 0xa4 , 0x010A },
+{ 0xa5 , 0x010B },
+{ 0xa6 , 0x1E0A },
+{ 0xa7 , 0x00A7 },
+{ 0xa8 , 0x1E80 },
+{ 0xa9 , 0x00A9 },
+{ 0xaa , 0x1E82 },
+{ 0xab , 0x1E0B },
+{ 0xac , 0x1EF2 },
+{ 0xad , 0x00AD },
+{ 0xae , 0x00AE },
+{ 0xaf , 0x0178 },
+{ 0xb0 , 0x1E1E },
+{ 0xb1 , 0x1E1F },
+{ 0xb2 , 0x0120 },
+{ 0xb3 , 0x0121 },
+{ 0xb4 , 0x1E40 },
+{ 0xb5 , 0x1E41 },
+{ 0xb6 , 0x00B6 },
+{ 0xb7 , 0x1E56 },
+{ 0xb8 , 0x1E81 },
+{ 0xb9 , 0x1E57 },
+{ 0xba , 0x1E83 },
+{ 0xbb , 0x1E60 },
+{ 0xbc , 0x1EF3 },
+{ 0xbd , 0x1E84 },
+{ 0xbe , 0x1E85 },
+{ 0xbf , 0x1E61 },
+{ 0xc0 , 0x00C0 },
+{ 0xc1 , 0x00C1 },
+{ 0xc2 , 0x00C2 },
+{ 0xc3 , 0x00C3 },
+{ 0xc4 , 0x00C4 },
+{ 0xc5 , 0x00C5 },
+{ 0xc6 , 0x00C6 },
+{ 0xc7 , 0x00C7 },
+{ 0xc8 , 0x00C8 },
+{ 0xc9 , 0x00C9 },
+{ 0xca , 0x00CA },
+{ 0xcb , 0x00CB },
+{ 0xcc , 0x00CC },
+{ 0xcd , 0x00CD },
+{ 0xce , 0x00CE },
+{ 0xcf , 0x00CF },
+{ 0xd0 , 0x0174 },
+{ 0xd1 , 0x00D1 },
+{ 0xd2 , 0x00D2 },
+{ 0xd3 , 0x00D3 },
+{ 0xd4 , 0x00D4 },
+{ 0xd5 , 0x00D5 },
+{ 0xd6 , 0x00D6 },
+{ 0xd7 , 0x1E6A },
+{ 0xd8 , 0x00D8 },
+{ 0xd9 , 0x00D9 },
+{ 0xda , 0x00DA },
+{ 0xdb , 0x00DB },
+{ 0xdc , 0x00DC },
+{ 0xdd , 0x00DD },
+{ 0xde , 0x0176 },
+{ 0xdf , 0x00DF },
+{ 0xe0 , 0x00E0 },
+{ 0xe1 , 0x00E1 },
+{ 0xe2 , 0x00E2 },
+{ 0xe3 , 0x00E3 },
+{ 0xe4 , 0x00E4 },
+{ 0xe5 , 0x00E5 },
+{ 0xe6 , 0x00E6 },
+{ 0xe7 , 0x00E7 },
+{ 0xe8 , 0x00E8 },
+{ 0xe9 , 0x00E9 },
+{ 0xea , 0x00EA },
+{ 0xeb , 0x00EB },
+{ 0xec , 0x00EC },
+{ 0xed , 0x00ED },
+{ 0xee , 0x00EE },
+{ 0xef , 0x00EF },
+{ 0xf0 , 0x0175 },
+{ 0xf1 , 0x00F1 },
+{ 0xf2 , 0x00F2 },
+{ 0xf3 , 0x00F3 },
+{ 0xf4 , 0x00F4 },
+{ 0xf5 , 0x00F5 },
+{ 0xf6 , 0x00F6 },
+{ 0xf7 , 0x1E6B },
+{ 0xf8 , 0x00F8 },
+{ 0xf9 , 0x00F9 },
+{ 0xfa , 0x00FA },
+{ 0xfb , 0x00FB },
+{ 0xfc , 0x00FC },
+{ 0xfd , 0x00FD },
+{ 0xfe , 0x0177 },
+{ 0xff , 0x00FF },

+ 256 - 0
extra/locale/charmaps/ISO-8859-15.pairs

@@ -0,0 +1,256 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x0080 },
+{ 0x81 , 0x0081 },
+{ 0x82 , 0x0082 },
+{ 0x83 , 0x0083 },
+{ 0x84 , 0x0084 },
+{ 0x85 , 0x0085 },
+{ 0x86 , 0x0086 },
+{ 0x87 , 0x0087 },
+{ 0x88 , 0x0088 },
+{ 0x89 , 0x0089 },
+{ 0x8a , 0x008A },
+{ 0x8b , 0x008B },
+{ 0x8c , 0x008C },
+{ 0x8d , 0x008D },
+{ 0x8e , 0x008E },
+{ 0x8f , 0x008F },
+{ 0x90 , 0x0090 },
+{ 0x91 , 0x0091 },
+{ 0x92 , 0x0092 },
+{ 0x93 , 0x0093 },
+{ 0x94 , 0x0094 },
+{ 0x95 , 0x0095 },
+{ 0x96 , 0x0096 },
+{ 0x97 , 0x0097 },
+{ 0x98 , 0x0098 },
+{ 0x99 , 0x0099 },
+{ 0x9a , 0x009A },
+{ 0x9b , 0x009B },
+{ 0x9c , 0x009C },
+{ 0x9d , 0x009D },
+{ 0x9e , 0x009E },
+{ 0x9f , 0x009F },
+{ 0xa0 , 0x00A0 },
+{ 0xa1 , 0x00A1 },
+{ 0xa2 , 0x00A2 },
+{ 0xa3 , 0x00A3 },
+{ 0xa4 , 0x20AC },
+{ 0xa5 , 0x00A5 },
+{ 0xa6 , 0x0160 },
+{ 0xa7 , 0x00A7 },
+{ 0xa8 , 0x0161 },
+{ 0xa9 , 0x00A9 },
+{ 0xaa , 0x00AA },
+{ 0xab , 0x00AB },
+{ 0xac , 0x00AC },
+{ 0xad , 0x00AD },
+{ 0xae , 0x00AE },
+{ 0xaf , 0x00AF },
+{ 0xb0 , 0x00B0 },
+{ 0xb1 , 0x00B1 },
+{ 0xb2 , 0x00B2 },
+{ 0xb3 , 0x00B3 },
+{ 0xb4 , 0x017D },
+{ 0xb5 , 0x00B5 },
+{ 0xb6 , 0x00B6 },
+{ 0xb7 , 0x00B7 },
+{ 0xb8 , 0x017E },
+{ 0xb9 , 0x00B9 },
+{ 0xba , 0x00BA },
+{ 0xbb , 0x00BB },
+{ 0xbc , 0x0152 },
+{ 0xbd , 0x0153 },
+{ 0xbe , 0x0178 },
+{ 0xbf , 0x00BF },
+{ 0xc0 , 0x00C0 },
+{ 0xc1 , 0x00C1 },
+{ 0xc2 , 0x00C2 },
+{ 0xc3 , 0x00C3 },
+{ 0xc4 , 0x00C4 },
+{ 0xc5 , 0x00C5 },
+{ 0xc6 , 0x00C6 },
+{ 0xc7 , 0x00C7 },
+{ 0xc8 , 0x00C8 },
+{ 0xc9 , 0x00C9 },
+{ 0xca , 0x00CA },
+{ 0xcb , 0x00CB },
+{ 0xcc , 0x00CC },
+{ 0xcd , 0x00CD },
+{ 0xce , 0x00CE },
+{ 0xcf , 0x00CF },
+{ 0xd0 , 0x00D0 },
+{ 0xd1 , 0x00D1 },
+{ 0xd2 , 0x00D2 },
+{ 0xd3 , 0x00D3 },
+{ 0xd4 , 0x00D4 },
+{ 0xd5 , 0x00D5 },
+{ 0xd6 , 0x00D6 },
+{ 0xd7 , 0x00D7 },
+{ 0xd8 , 0x00D8 },
+{ 0xd9 , 0x00D9 },
+{ 0xda , 0x00DA },
+{ 0xdb , 0x00DB },
+{ 0xdc , 0x00DC },
+{ 0xdd , 0x00DD },
+{ 0xde , 0x00DE },
+{ 0xdf , 0x00DF },
+{ 0xe0 , 0x00E0 },
+{ 0xe1 , 0x00E1 },
+{ 0xe2 , 0x00E2 },
+{ 0xe3 , 0x00E3 },
+{ 0xe4 , 0x00E4 },
+{ 0xe5 , 0x00E5 },
+{ 0xe6 , 0x00E6 },
+{ 0xe7 , 0x00E7 },
+{ 0xe8 , 0x00E8 },
+{ 0xe9 , 0x00E9 },
+{ 0xea , 0x00EA },
+{ 0xeb , 0x00EB },
+{ 0xec , 0x00EC },
+{ 0xed , 0x00ED },
+{ 0xee , 0x00EE },
+{ 0xef , 0x00EF },
+{ 0xf0 , 0x00F0 },
+{ 0xf1 , 0x00F1 },
+{ 0xf2 , 0x00F2 },
+{ 0xf3 , 0x00F3 },
+{ 0xf4 , 0x00F4 },
+{ 0xf5 , 0x00F5 },
+{ 0xf6 , 0x00F6 },
+{ 0xf7 , 0x00F7 },
+{ 0xf8 , 0x00F8 },
+{ 0xf9 , 0x00F9 },
+{ 0xfa , 0x00FA },
+{ 0xfb , 0x00FB },
+{ 0xfc , 0x00FC },
+{ 0xfd , 0x00FD },
+{ 0xfe , 0x00FE },
+{ 0xff , 0x00FF },

+ 256 - 0
extra/locale/charmaps/ISO-8859-16.pairs

@@ -0,0 +1,256 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x0080 },
+{ 0x81 , 0x0081 },
+{ 0x82 , 0x0082 },
+{ 0x83 , 0x0083 },
+{ 0x84 , 0x0084 },
+{ 0x85 , 0x0085 },
+{ 0x86 , 0x0086 },
+{ 0x87 , 0x0087 },
+{ 0x88 , 0x0088 },
+{ 0x89 , 0x0089 },
+{ 0x8a , 0x008A },
+{ 0x8b , 0x008B },
+{ 0x8c , 0x008C },
+{ 0x8d , 0x008D },
+{ 0x8e , 0x008E },
+{ 0x8f , 0x008F },
+{ 0x90 , 0x0090 },
+{ 0x91 , 0x0091 },
+{ 0x92 , 0x0092 },
+{ 0x93 , 0x0093 },
+{ 0x94 , 0x0094 },
+{ 0x95 , 0x0095 },
+{ 0x96 , 0x0096 },
+{ 0x97 , 0x0097 },
+{ 0x98 , 0x0098 },
+{ 0x99 , 0x0099 },
+{ 0x9a , 0x009A },
+{ 0x9b , 0x009B },
+{ 0x9c , 0x009C },
+{ 0x9d , 0x009D },
+{ 0x9e , 0x009E },
+{ 0x9f , 0x009F },
+{ 0xa0 , 0x00A0 },
+{ 0xa1 , 0x0104 },
+{ 0xa2 , 0x0105 },
+{ 0xa3 , 0x0141 },
+{ 0xa4 , 0x20AC },
+{ 0xa5 , 0x00AB },
+{ 0xa6 , 0x0160 },
+{ 0xa7 , 0x00A7 },
+{ 0xa8 , 0x0161 },
+{ 0xa9 , 0x00A9 },
+{ 0xaa , 0x0218 },
+{ 0xab , 0x201E },
+{ 0xac , 0x0179 },
+{ 0xad , 0x00AD },
+{ 0xae , 0x017A },
+{ 0xaf , 0x017B },
+{ 0xb0 , 0x00B0 },
+{ 0xb1 , 0x00B1 },
+{ 0xb2 , 0x010C },
+{ 0xb3 , 0x0142 },
+{ 0xb4 , 0x017D },
+{ 0xb5 , 0x201D },
+{ 0xb6 , 0x00B6 },
+{ 0xb7 , 0x00B7 },
+{ 0xb8 , 0x017E },
+{ 0xb9 , 0x010D },
+{ 0xba , 0x0219 },
+{ 0xbb , 0x00BB },
+{ 0xbc , 0x0152 },
+{ 0xbd , 0x0153 },
+{ 0xbe , 0x0178 },
+{ 0xbf , 0x017C },
+{ 0xc0 , 0x00C0 },
+{ 0xc1 , 0x00C1 },
+{ 0xc2 , 0x00C2 },
+{ 0xc3 , 0x0102 },
+{ 0xc4 , 0x00C4 },
+{ 0xc5 , 0x0106 },
+{ 0xc6 , 0x00C6 },
+{ 0xc7 , 0x00C7 },
+{ 0xc8 , 0x00C8 },
+{ 0xc9 , 0x00C9 },
+{ 0xca , 0x00CA },
+{ 0xcb , 0x00CB },
+{ 0xcc , 0x00CC },
+{ 0xcd , 0x00CD },
+{ 0xce , 0x00CE },
+{ 0xcf , 0x00CF },
+{ 0xd0 , 0x0110 },
+{ 0xd1 , 0x0143 },
+{ 0xd2 , 0x00D2 },
+{ 0xd3 , 0x00D3 },
+{ 0xd4 , 0x00D4 },
+{ 0xd5 , 0x0150 },
+{ 0xd6 , 0x00D6 },
+{ 0xd7 , 0x015A },
+{ 0xd8 , 0x0170 },
+{ 0xd9 , 0x00D9 },
+{ 0xda , 0x00DA },
+{ 0xdb , 0x00DB },
+{ 0xdc , 0x00DC },
+{ 0xdd , 0x0118 },
+{ 0xde , 0x021A },
+{ 0xdf , 0x00DF },
+{ 0xe0 , 0x00E0 },
+{ 0xe1 , 0x00E1 },
+{ 0xe2 , 0x00E2 },
+{ 0xe3 , 0x0103 },
+{ 0xe4 , 0x00E4 },
+{ 0xe5 , 0x0107 },
+{ 0xe6 , 0x00E6 },
+{ 0xe7 , 0x00E7 },
+{ 0xe8 , 0x00E8 },
+{ 0xe9 , 0x00E9 },
+{ 0xea , 0x00EA },
+{ 0xeb , 0x00EB },
+{ 0xec , 0x00EC },
+{ 0xed , 0x00ED },
+{ 0xee , 0x00EE },
+{ 0xef , 0x00EF },
+{ 0xf0 , 0x0111 },
+{ 0xf1 , 0x0144 },
+{ 0xf2 , 0x00F2 },
+{ 0xf3 , 0x00F3 },
+{ 0xf4 , 0x00F4 },
+{ 0xf5 , 0x0151 },
+{ 0xf6 , 0x00F6 },
+{ 0xf7 , 0x015B },
+{ 0xf8 , 0x0171 },
+{ 0xf9 , 0x00F9 },
+{ 0xfa , 0x00FA },
+{ 0xfb , 0x00FB },
+{ 0xfc , 0x00FC },
+{ 0xfd , 0x0119 },
+{ 0xfe , 0x021B },
+{ 0xff , 0x00FF },

+ 256 - 0
extra/locale/charmaps/ISO-8859-2.pairs

@@ -0,0 +1,256 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x0080 },
+{ 0x81 , 0x0081 },
+{ 0x82 , 0x0082 },
+{ 0x83 , 0x0083 },
+{ 0x84 , 0x0084 },
+{ 0x85 , 0x0085 },
+{ 0x86 , 0x0086 },
+{ 0x87 , 0x0087 },
+{ 0x88 , 0x0088 },
+{ 0x89 , 0x0089 },
+{ 0x8a , 0x008A },
+{ 0x8b , 0x008B },
+{ 0x8c , 0x008C },
+{ 0x8d , 0x008D },
+{ 0x8e , 0x008E },
+{ 0x8f , 0x008F },
+{ 0x90 , 0x0090 },
+{ 0x91 , 0x0091 },
+{ 0x92 , 0x0092 },
+{ 0x93 , 0x0093 },
+{ 0x94 , 0x0094 },
+{ 0x95 , 0x0095 },
+{ 0x96 , 0x0096 },
+{ 0x97 , 0x0097 },
+{ 0x98 , 0x0098 },
+{ 0x99 , 0x0099 },
+{ 0x9a , 0x009A },
+{ 0x9b , 0x009B },
+{ 0x9c , 0x009C },
+{ 0x9d , 0x009D },
+{ 0x9e , 0x009E },
+{ 0x9f , 0x009F },
+{ 0xa0 , 0x00A0 },
+{ 0xa1 , 0x0104 },
+{ 0xa2 , 0x02D8 },
+{ 0xa3 , 0x0141 },
+{ 0xa4 , 0x00A4 },
+{ 0xa5 , 0x013D },
+{ 0xa6 , 0x015A },
+{ 0xa7 , 0x00A7 },
+{ 0xa8 , 0x00A8 },
+{ 0xa9 , 0x0160 },
+{ 0xaa , 0x015E },
+{ 0xab , 0x0164 },
+{ 0xac , 0x0179 },
+{ 0xad , 0x00AD },
+{ 0xae , 0x017D },
+{ 0xaf , 0x017B },
+{ 0xb0 , 0x00B0 },
+{ 0xb1 , 0x0105 },
+{ 0xb2 , 0x02DB },
+{ 0xb3 , 0x0142 },
+{ 0xb4 , 0x00B4 },
+{ 0xb5 , 0x013E },
+{ 0xb6 , 0x015B },
+{ 0xb7 , 0x02C7 },
+{ 0xb8 , 0x00B8 },
+{ 0xb9 , 0x0161 },
+{ 0xba , 0x015F },
+{ 0xbb , 0x0165 },
+{ 0xbc , 0x017A },
+{ 0xbd , 0x02DD },
+{ 0xbe , 0x017E },
+{ 0xbf , 0x017C },
+{ 0xc0 , 0x0154 },
+{ 0xc1 , 0x00C1 },
+{ 0xc2 , 0x00C2 },
+{ 0xc3 , 0x0102 },
+{ 0xc4 , 0x00C4 },
+{ 0xc5 , 0x0139 },
+{ 0xc6 , 0x0106 },
+{ 0xc7 , 0x00C7 },
+{ 0xc8 , 0x010C },
+{ 0xc9 , 0x00C9 },
+{ 0xca , 0x0118 },
+{ 0xcb , 0x00CB },
+{ 0xcc , 0x011A },
+{ 0xcd , 0x00CD },
+{ 0xce , 0x00CE },
+{ 0xcf , 0x010E },
+{ 0xd0 , 0x0110 },
+{ 0xd1 , 0x0143 },
+{ 0xd2 , 0x0147 },
+{ 0xd3 , 0x00D3 },
+{ 0xd4 , 0x00D4 },
+{ 0xd5 , 0x0150 },
+{ 0xd6 , 0x00D6 },
+{ 0xd7 , 0x00D7 },
+{ 0xd8 , 0x0158 },
+{ 0xd9 , 0x016E },
+{ 0xda , 0x00DA },
+{ 0xdb , 0x0170 },
+{ 0xdc , 0x00DC },
+{ 0xdd , 0x00DD },
+{ 0xde , 0x0162 },
+{ 0xdf , 0x00DF },
+{ 0xe0 , 0x0155 },
+{ 0xe1 , 0x00E1 },
+{ 0xe2 , 0x00E2 },
+{ 0xe3 , 0x0103 },
+{ 0xe4 , 0x00E4 },
+{ 0xe5 , 0x013A },
+{ 0xe6 , 0x0107 },
+{ 0xe7 , 0x00E7 },
+{ 0xe8 , 0x010D },
+{ 0xe9 , 0x00E9 },
+{ 0xea , 0x0119 },
+{ 0xeb , 0x00EB },
+{ 0xec , 0x011B },
+{ 0xed , 0x00ED },
+{ 0xee , 0x00EE },
+{ 0xef , 0x010F },
+{ 0xf0 , 0x0111 },
+{ 0xf1 , 0x0144 },
+{ 0xf2 , 0x0148 },
+{ 0xf3 , 0x00F3 },
+{ 0xf4 , 0x00F4 },
+{ 0xf5 , 0x0151 },
+{ 0xf6 , 0x00F6 },
+{ 0xf7 , 0x00F7 },
+{ 0xf8 , 0x0159 },
+{ 0xf9 , 0x016F },
+{ 0xfa , 0x00FA },
+{ 0xfb , 0x0171 },
+{ 0xfc , 0x00FC },
+{ 0xfd , 0x00FD },
+{ 0xfe , 0x0163 },
+{ 0xff , 0x02D9 },

+ 249 - 0
extra/locale/charmaps/ISO-8859-3.pairs

@@ -0,0 +1,249 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x0080 },
+{ 0x81 , 0x0081 },
+{ 0x82 , 0x0082 },
+{ 0x83 , 0x0083 },
+{ 0x84 , 0x0084 },
+{ 0x85 , 0x0085 },
+{ 0x86 , 0x0086 },
+{ 0x87 , 0x0087 },
+{ 0x88 , 0x0088 },
+{ 0x89 , 0x0089 },
+{ 0x8a , 0x008A },
+{ 0x8b , 0x008B },
+{ 0x8c , 0x008C },
+{ 0x8d , 0x008D },
+{ 0x8e , 0x008E },
+{ 0x8f , 0x008F },
+{ 0x90 , 0x0090 },
+{ 0x91 , 0x0091 },
+{ 0x92 , 0x0092 },
+{ 0x93 , 0x0093 },
+{ 0x94 , 0x0094 },
+{ 0x95 , 0x0095 },
+{ 0x96 , 0x0096 },
+{ 0x97 , 0x0097 },
+{ 0x98 , 0x0098 },
+{ 0x99 , 0x0099 },
+{ 0x9a , 0x009A },
+{ 0x9b , 0x009B },
+{ 0x9c , 0x009C },
+{ 0x9d , 0x009D },
+{ 0x9e , 0x009E },
+{ 0x9f , 0x009F },
+{ 0xa0 , 0x00A0 },
+{ 0xa1 , 0x0126 },
+{ 0xa2 , 0x02D8 },
+{ 0xa3 , 0x00A3 },
+{ 0xa4 , 0x00A4 },
+{ 0xa6 , 0x0124 },
+{ 0xa7 , 0x00A7 },
+{ 0xa8 , 0x00A8 },
+{ 0xa9 , 0x0130 },
+{ 0xaa , 0x015E },
+{ 0xab , 0x011E },
+{ 0xac , 0x0134 },
+{ 0xad , 0x00AD },
+{ 0xaf , 0x017B },
+{ 0xb0 , 0x00B0 },
+{ 0xb1 , 0x0127 },
+{ 0xb2 , 0x00B2 },
+{ 0xb3 , 0x00B3 },
+{ 0xb4 , 0x00B4 },
+{ 0xb5 , 0x00B5 },
+{ 0xb6 , 0x0125 },
+{ 0xb7 , 0x00B7 },
+{ 0xb8 , 0x00B8 },
+{ 0xb9 , 0x0131 },
+{ 0xba , 0x015F },
+{ 0xbb , 0x011F },
+{ 0xbc , 0x0135 },
+{ 0xbd , 0x00BD },
+{ 0xbf , 0x017C },
+{ 0xc0 , 0x00C0 },
+{ 0xc1 , 0x00C1 },
+{ 0xc2 , 0x00C2 },
+{ 0xc4 , 0x00C4 },
+{ 0xc5 , 0x010A },
+{ 0xc6 , 0x0108 },
+{ 0xc7 , 0x00C7 },
+{ 0xc8 , 0x00C8 },
+{ 0xc9 , 0x00C9 },
+{ 0xca , 0x00CA },
+{ 0xcb , 0x00CB },
+{ 0xcc , 0x00CC },
+{ 0xcd , 0x00CD },
+{ 0xce , 0x00CE },
+{ 0xcf , 0x00CF },
+{ 0xd1 , 0x00D1 },
+{ 0xd2 , 0x00D2 },
+{ 0xd3 , 0x00D3 },
+{ 0xd4 , 0x00D4 },
+{ 0xd5 , 0x0120 },
+{ 0xd6 , 0x00D6 },
+{ 0xd7 , 0x00D7 },
+{ 0xd8 , 0x011C },
+{ 0xd9 , 0x00D9 },
+{ 0xda , 0x00DA },
+{ 0xdb , 0x00DB },
+{ 0xdc , 0x00DC },
+{ 0xdd , 0x016C },
+{ 0xde , 0x015C },
+{ 0xdf , 0x00DF },
+{ 0xe0 , 0x00E0 },
+{ 0xe1 , 0x00E1 },
+{ 0xe2 , 0x00E2 },
+{ 0xe4 , 0x00E4 },
+{ 0xe5 , 0x010B },
+{ 0xe6 , 0x0109 },
+{ 0xe7 , 0x00E7 },
+{ 0xe8 , 0x00E8 },
+{ 0xe9 , 0x00E9 },
+{ 0xea , 0x00EA },
+{ 0xeb , 0x00EB },
+{ 0xec , 0x00EC },
+{ 0xed , 0x00ED },
+{ 0xee , 0x00EE },
+{ 0xef , 0x00EF },
+{ 0xf1 , 0x00F1 },
+{ 0xf2 , 0x00F2 },
+{ 0xf3 , 0x00F3 },
+{ 0xf4 , 0x00F4 },
+{ 0xf5 , 0x0121 },
+{ 0xf6 , 0x00F6 },
+{ 0xf7 , 0x00F7 },
+{ 0xf8 , 0x011D },
+{ 0xf9 , 0x00F9 },
+{ 0xfa , 0x00FA },
+{ 0xfb , 0x00FB },
+{ 0xfc , 0x00FC },
+{ 0xfd , 0x016D },
+{ 0xfe , 0x015D },
+{ 0xff , 0x02D9 },

+ 256 - 0
extra/locale/charmaps/ISO-8859-4.pairs

@@ -0,0 +1,256 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x0080 },
+{ 0x81 , 0x0081 },
+{ 0x82 , 0x0082 },
+{ 0x83 , 0x0083 },
+{ 0x84 , 0x0084 },
+{ 0x85 , 0x0085 },
+{ 0x86 , 0x0086 },
+{ 0x87 , 0x0087 },
+{ 0x88 , 0x0088 },
+{ 0x89 , 0x0089 },
+{ 0x8a , 0x008A },
+{ 0x8b , 0x008B },
+{ 0x8c , 0x008C },
+{ 0x8d , 0x008D },
+{ 0x8e , 0x008E },
+{ 0x8f , 0x008F },
+{ 0x90 , 0x0090 },
+{ 0x91 , 0x0091 },
+{ 0x92 , 0x0092 },
+{ 0x93 , 0x0093 },
+{ 0x94 , 0x0094 },
+{ 0x95 , 0x0095 },
+{ 0x96 , 0x0096 },
+{ 0x97 , 0x0097 },
+{ 0x98 , 0x0098 },
+{ 0x99 , 0x0099 },
+{ 0x9a , 0x009A },
+{ 0x9b , 0x009B },
+{ 0x9c , 0x009C },
+{ 0x9d , 0x009D },
+{ 0x9e , 0x009E },
+{ 0x9f , 0x009F },
+{ 0xa0 , 0x00A0 },
+{ 0xa1 , 0x0104 },
+{ 0xa2 , 0x0138 },
+{ 0xa3 , 0x0156 },
+{ 0xa4 , 0x00A4 },
+{ 0xa5 , 0x0128 },
+{ 0xa6 , 0x013B },
+{ 0xa7 , 0x00A7 },
+{ 0xa8 , 0x00A8 },
+{ 0xa9 , 0x0160 },
+{ 0xaa , 0x0112 },
+{ 0xab , 0x0122 },
+{ 0xac , 0x0166 },
+{ 0xad , 0x00AD },
+{ 0xae , 0x017D },
+{ 0xaf , 0x00AF },
+{ 0xb0 , 0x00B0 },
+{ 0xb1 , 0x0105 },
+{ 0xb2 , 0x02DB },
+{ 0xb3 , 0x0157 },
+{ 0xb4 , 0x00B4 },
+{ 0xb5 , 0x0129 },
+{ 0xb6 , 0x013C },
+{ 0xb7 , 0x02C7 },
+{ 0xb8 , 0x00B8 },
+{ 0xb9 , 0x0161 },
+{ 0xba , 0x0113 },
+{ 0xbb , 0x0123 },
+{ 0xbc , 0x0167 },
+{ 0xbd , 0x014A },
+{ 0xbe , 0x017E },
+{ 0xbf , 0x014B },
+{ 0xc0 , 0x0100 },
+{ 0xc1 , 0x00C1 },
+{ 0xc2 , 0x00C2 },
+{ 0xc3 , 0x00C3 },
+{ 0xc4 , 0x00C4 },
+{ 0xc5 , 0x00C5 },
+{ 0xc6 , 0x00C6 },
+{ 0xc7 , 0x012E },
+{ 0xc8 , 0x010C },
+{ 0xc9 , 0x00C9 },
+{ 0xca , 0x0118 },
+{ 0xcb , 0x00CB },
+{ 0xcc , 0x0116 },
+{ 0xcd , 0x00CD },
+{ 0xce , 0x00CE },
+{ 0xcf , 0x012A },
+{ 0xd0 , 0x0110 },
+{ 0xd1 , 0x0145 },
+{ 0xd2 , 0x014C },
+{ 0xd3 , 0x0136 },
+{ 0xd4 , 0x00D4 },
+{ 0xd5 , 0x00D5 },
+{ 0xd6 , 0x00D6 },
+{ 0xd7 , 0x00D7 },
+{ 0xd8 , 0x00D8 },
+{ 0xd9 , 0x0172 },
+{ 0xda , 0x00DA },
+{ 0xdb , 0x00DB },
+{ 0xdc , 0x00DC },
+{ 0xdd , 0x0168 },
+{ 0xde , 0x016A },
+{ 0xdf , 0x00DF },
+{ 0xe0 , 0x0101 },
+{ 0xe1 , 0x00E1 },
+{ 0xe2 , 0x00E2 },
+{ 0xe3 , 0x00E3 },
+{ 0xe4 , 0x00E4 },
+{ 0xe5 , 0x00E5 },
+{ 0xe6 , 0x00E6 },
+{ 0xe7 , 0x012F },
+{ 0xe8 , 0x010D },
+{ 0xe9 , 0x00E9 },
+{ 0xea , 0x0119 },
+{ 0xeb , 0x00EB },
+{ 0xec , 0x0117 },
+{ 0xed , 0x00ED },
+{ 0xee , 0x00EE },
+{ 0xef , 0x012B },
+{ 0xf0 , 0x0111 },
+{ 0xf1 , 0x0146 },
+{ 0xf2 , 0x014D },
+{ 0xf3 , 0x0137 },
+{ 0xf4 , 0x00F4 },
+{ 0xf5 , 0x00F5 },
+{ 0xf6 , 0x00F6 },
+{ 0xf7 , 0x00F7 },
+{ 0xf8 , 0x00F8 },
+{ 0xf9 , 0x0173 },
+{ 0xfa , 0x00FA },
+{ 0xfb , 0x00FB },
+{ 0xfc , 0x00FC },
+{ 0xfd , 0x0169 },
+{ 0xfe , 0x016B },
+{ 0xff , 0x02D9 },

+ 256 - 0
extra/locale/charmaps/ISO-8859-5.pairs

@@ -0,0 +1,256 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x0080 },
+{ 0x81 , 0x0081 },
+{ 0x82 , 0x0082 },
+{ 0x83 , 0x0083 },
+{ 0x84 , 0x0084 },
+{ 0x85 , 0x0085 },
+{ 0x86 , 0x0086 },
+{ 0x87 , 0x0087 },
+{ 0x88 , 0x0088 },
+{ 0x89 , 0x0089 },
+{ 0x8a , 0x008A },
+{ 0x8b , 0x008B },
+{ 0x8c , 0x008C },
+{ 0x8d , 0x008D },
+{ 0x8e , 0x008E },
+{ 0x8f , 0x008F },
+{ 0x90 , 0x0090 },
+{ 0x91 , 0x0091 },
+{ 0x92 , 0x0092 },
+{ 0x93 , 0x0093 },
+{ 0x94 , 0x0094 },
+{ 0x95 , 0x0095 },
+{ 0x96 , 0x0096 },
+{ 0x97 , 0x0097 },
+{ 0x98 , 0x0098 },
+{ 0x99 , 0x0099 },
+{ 0x9a , 0x009A },
+{ 0x9b , 0x009B },
+{ 0x9c , 0x009C },
+{ 0x9d , 0x009D },
+{ 0x9e , 0x009E },
+{ 0x9f , 0x009F },
+{ 0xa0 , 0x00A0 },
+{ 0xa1 , 0x0401 },
+{ 0xa2 , 0x0402 },
+{ 0xa3 , 0x0403 },
+{ 0xa4 , 0x0404 },
+{ 0xa5 , 0x0405 },
+{ 0xa6 , 0x0406 },
+{ 0xa7 , 0x0407 },
+{ 0xa8 , 0x0408 },
+{ 0xa9 , 0x0409 },
+{ 0xaa , 0x040A },
+{ 0xab , 0x040B },
+{ 0xac , 0x040C },
+{ 0xad , 0x00AD },
+{ 0xae , 0x040E },
+{ 0xaf , 0x040F },
+{ 0xb0 , 0x0410 },
+{ 0xb1 , 0x0411 },
+{ 0xb2 , 0x0412 },
+{ 0xb3 , 0x0413 },
+{ 0xb4 , 0x0414 },
+{ 0xb5 , 0x0415 },
+{ 0xb6 , 0x0416 },
+{ 0xb7 , 0x0417 },
+{ 0xb8 , 0x0418 },
+{ 0xb9 , 0x0419 },
+{ 0xba , 0x041A },
+{ 0xbb , 0x041B },
+{ 0xbc , 0x041C },
+{ 0xbd , 0x041D },
+{ 0xbe , 0x041E },
+{ 0xbf , 0x041F },
+{ 0xc0 , 0x0420 },
+{ 0xc1 , 0x0421 },
+{ 0xc2 , 0x0422 },
+{ 0xc3 , 0x0423 },
+{ 0xc4 , 0x0424 },
+{ 0xc5 , 0x0425 },
+{ 0xc6 , 0x0426 },
+{ 0xc7 , 0x0427 },
+{ 0xc8 , 0x0428 },
+{ 0xc9 , 0x0429 },
+{ 0xca , 0x042A },
+{ 0xcb , 0x042B },
+{ 0xcc , 0x042C },
+{ 0xcd , 0x042D },
+{ 0xce , 0x042E },
+{ 0xcf , 0x042F },
+{ 0xd0 , 0x0430 },
+{ 0xd1 , 0x0431 },
+{ 0xd2 , 0x0432 },
+{ 0xd3 , 0x0433 },
+{ 0xd4 , 0x0434 },
+{ 0xd5 , 0x0435 },
+{ 0xd6 , 0x0436 },
+{ 0xd7 , 0x0437 },
+{ 0xd8 , 0x0438 },
+{ 0xd9 , 0x0439 },
+{ 0xda , 0x043A },
+{ 0xdb , 0x043B },
+{ 0xdc , 0x043C },
+{ 0xdd , 0x043D },
+{ 0xde , 0x043E },
+{ 0xdf , 0x043F },
+{ 0xe0 , 0x0440 },
+{ 0xe1 , 0x0441 },
+{ 0xe2 , 0x0442 },
+{ 0xe3 , 0x0443 },
+{ 0xe4 , 0x0444 },
+{ 0xe5 , 0x0445 },
+{ 0xe6 , 0x0446 },
+{ 0xe7 , 0x0447 },
+{ 0xe8 , 0x0448 },
+{ 0xe9 , 0x0449 },
+{ 0xea , 0x044A },
+{ 0xeb , 0x044B },
+{ 0xec , 0x044C },
+{ 0xed , 0x044D },
+{ 0xee , 0x044E },
+{ 0xef , 0x044F },
+{ 0xf0 , 0x2116 },
+{ 0xf1 , 0x0451 },
+{ 0xf2 , 0x0452 },
+{ 0xf3 , 0x0453 },
+{ 0xf4 , 0x0454 },
+{ 0xf5 , 0x0455 },
+{ 0xf6 , 0x0456 },
+{ 0xf7 , 0x0457 },
+{ 0xf8 , 0x0458 },
+{ 0xf9 , 0x0459 },
+{ 0xfa , 0x045A },
+{ 0xfb , 0x045B },
+{ 0xfc , 0x045C },
+{ 0xfd , 0x00A7 },
+{ 0xfe , 0x045E },
+{ 0xff , 0x045F },

+ 211 - 0
extra/locale/charmaps/ISO-8859-6.pairs

@@ -0,0 +1,211 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x0080 },
+{ 0x81 , 0x0081 },
+{ 0x82 , 0x0082 },
+{ 0x83 , 0x0083 },
+{ 0x84 , 0x0084 },
+{ 0x85 , 0x0085 },
+{ 0x86 , 0x0086 },
+{ 0x87 , 0x0087 },
+{ 0x88 , 0x0088 },
+{ 0x89 , 0x0089 },
+{ 0x8a , 0x008A },
+{ 0x8b , 0x008B },
+{ 0x8c , 0x008C },
+{ 0x8d , 0x008D },
+{ 0x8e , 0x008E },
+{ 0x8f , 0x008F },
+{ 0x90 , 0x0090 },
+{ 0x91 , 0x0091 },
+{ 0x92 , 0x0092 },
+{ 0x93 , 0x0093 },
+{ 0x94 , 0x0094 },
+{ 0x95 , 0x0095 },
+{ 0x96 , 0x0096 },
+{ 0x97 , 0x0097 },
+{ 0x98 , 0x0098 },
+{ 0x99 , 0x0099 },
+{ 0x9a , 0x009A },
+{ 0x9b , 0x009B },
+{ 0x9c , 0x009C },
+{ 0x9d , 0x009D },
+{ 0x9e , 0x009E },
+{ 0x9f , 0x009F },
+{ 0xa0 , 0x00A0 },
+{ 0xa4 , 0x00A4 },
+{ 0xac , 0x060C },
+{ 0xad , 0x00AD },
+{ 0xbb , 0x061B },
+{ 0xbf , 0x061F },
+{ 0xc1 , 0x0621 },
+{ 0xc2 , 0x0622 },
+{ 0xc3 , 0x0623 },
+{ 0xc4 , 0x0624 },
+{ 0xc5 , 0x0625 },
+{ 0xc6 , 0x0626 },
+{ 0xc7 , 0x0627 },
+{ 0xc8 , 0x0628 },
+{ 0xc9 , 0x0629 },
+{ 0xca , 0x062A },
+{ 0xcb , 0x062B },
+{ 0xcc , 0x062C },
+{ 0xcd , 0x062D },
+{ 0xce , 0x062E },
+{ 0xcf , 0x062F },
+{ 0xd0 , 0x0630 },
+{ 0xd1 , 0x0631 },
+{ 0xd2 , 0x0632 },
+{ 0xd3 , 0x0633 },
+{ 0xd4 , 0x0634 },
+{ 0xd5 , 0x0635 },
+{ 0xd6 , 0x0636 },
+{ 0xd7 , 0x0637 },
+{ 0xd8 , 0x0638 },
+{ 0xd9 , 0x0639 },
+{ 0xda , 0x063A },
+{ 0xe0 , 0x0640 },
+{ 0xe1 , 0x0641 },
+{ 0xe2 , 0x0642 },
+{ 0xe3 , 0x0643 },
+{ 0xe4 , 0x0644 },
+{ 0xe5 , 0x0645 },
+{ 0xe6 , 0x0646 },
+{ 0xe7 , 0x0647 },
+{ 0xe8 , 0x0648 },
+{ 0xe9 , 0x0649 },
+{ 0xea , 0x064A },
+{ 0xeb , 0x064B },
+{ 0xec , 0x064C },
+{ 0xed , 0x064D },
+{ 0xee , 0x064E },
+{ 0xef , 0x064F },
+{ 0xf0 , 0x0650 },
+{ 0xf1 , 0x0651 },
+{ 0xf2 , 0x0652 },

+ 250 - 0
extra/locale/charmaps/ISO-8859-7.pairs

@@ -0,0 +1,250 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x0080 },
+{ 0x81 , 0x0081 },
+{ 0x82 , 0x0082 },
+{ 0x83 , 0x0083 },
+{ 0x84 , 0x0084 },
+{ 0x85 , 0x0085 },
+{ 0x86 , 0x0086 },
+{ 0x87 , 0x0087 },
+{ 0x88 , 0x0088 },
+{ 0x89 , 0x0089 },
+{ 0x8a , 0x008A },
+{ 0x8b , 0x008B },
+{ 0x8c , 0x008C },
+{ 0x8d , 0x008D },
+{ 0x8e , 0x008E },
+{ 0x8f , 0x008F },
+{ 0x90 , 0x0090 },
+{ 0x91 , 0x0091 },
+{ 0x92 , 0x0092 },
+{ 0x93 , 0x0093 },
+{ 0x94 , 0x0094 },
+{ 0x95 , 0x0095 },
+{ 0x96 , 0x0096 },
+{ 0x97 , 0x0097 },
+{ 0x98 , 0x0098 },
+{ 0x99 , 0x0099 },
+{ 0x9a , 0x009A },
+{ 0x9b , 0x009B },
+{ 0x9c , 0x009C },
+{ 0x9d , 0x009D },
+{ 0x9e , 0x009E },
+{ 0x9f , 0x009F },
+{ 0xa0 , 0x00A0 },
+{ 0xa1 , 0x2018 },
+{ 0xa2 , 0x2019 },
+{ 0xa3 , 0x00A3 },
+{ 0xa6 , 0x00A6 },
+{ 0xa7 , 0x00A7 },
+{ 0xa8 , 0x00A8 },
+{ 0xa9 , 0x00A9 },
+{ 0xab , 0x00AB },
+{ 0xac , 0x00AC },
+{ 0xad , 0x00AD },
+{ 0xaf , 0x2015 },
+{ 0xb0 , 0x00B0 },
+{ 0xb1 , 0x00B1 },
+{ 0xb2 , 0x00B2 },
+{ 0xb3 , 0x00B3 },
+{ 0xb4 , 0x0384 },
+{ 0xb5 , 0x0385 },
+{ 0xb6 , 0x0386 },
+{ 0xb7 , 0x00B7 },
+{ 0xb8 , 0x0388 },
+{ 0xb9 , 0x0389 },
+{ 0xba , 0x038A },
+{ 0xbb , 0x00BB },
+{ 0xbc , 0x038C },
+{ 0xbd , 0x00BD },
+{ 0xbe , 0x038E },
+{ 0xbf , 0x038F },
+{ 0xc0 , 0x0390 },
+{ 0xc1 , 0x0391 },
+{ 0xc2 , 0x0392 },
+{ 0xc3 , 0x0393 },
+{ 0xc4 , 0x0394 },
+{ 0xc5 , 0x0395 },
+{ 0xc6 , 0x0396 },
+{ 0xc7 , 0x0397 },
+{ 0xc8 , 0x0398 },
+{ 0xc9 , 0x0399 },
+{ 0xca , 0x039A },
+{ 0xcb , 0x039B },
+{ 0xcc , 0x039C },
+{ 0xcd , 0x039D },
+{ 0xce , 0x039E },
+{ 0xcf , 0x039F },
+{ 0xd0 , 0x03A0 },
+{ 0xd1 , 0x03A1 },
+{ 0xd3 , 0x03A3 },
+{ 0xd4 , 0x03A4 },
+{ 0xd5 , 0x03A5 },
+{ 0xd6 , 0x03A6 },
+{ 0xd7 , 0x03A7 },
+{ 0xd8 , 0x03A8 },
+{ 0xd9 , 0x03A9 },
+{ 0xda , 0x03AA },
+{ 0xdb , 0x03AB },
+{ 0xdc , 0x03AC },
+{ 0xdd , 0x03AD },
+{ 0xde , 0x03AE },
+{ 0xdf , 0x03AF },
+{ 0xe0 , 0x03B0 },
+{ 0xe1 , 0x03B1 },
+{ 0xe2 , 0x03B2 },
+{ 0xe3 , 0x03B3 },
+{ 0xe4 , 0x03B4 },
+{ 0xe5 , 0x03B5 },
+{ 0xe6 , 0x03B6 },
+{ 0xe7 , 0x03B7 },
+{ 0xe8 , 0x03B8 },
+{ 0xe9 , 0x03B9 },
+{ 0xea , 0x03BA },
+{ 0xeb , 0x03BB },
+{ 0xec , 0x03BC },
+{ 0xed , 0x03BD },
+{ 0xee , 0x03BE },
+{ 0xef , 0x03BF },
+{ 0xf0 , 0x03C0 },
+{ 0xf1 , 0x03C1 },
+{ 0xf2 , 0x03C2 },
+{ 0xf3 , 0x03C3 },
+{ 0xf4 , 0x03C4 },
+{ 0xf5 , 0x03C5 },
+{ 0xf6 , 0x03C6 },
+{ 0xf7 , 0x03C7 },
+{ 0xf8 , 0x03C8 },
+{ 0xf9 , 0x03C9 },
+{ 0xfa , 0x03CA },
+{ 0xfb , 0x03CB },
+{ 0xfc , 0x03CC },
+{ 0xfd , 0x03CD },
+{ 0xfe , 0x03CE },

+ 220 - 0
extra/locale/charmaps/ISO-8859-8.pairs

@@ -0,0 +1,220 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x0080 },
+{ 0x81 , 0x0081 },
+{ 0x82 , 0x0082 },
+{ 0x83 , 0x0083 },
+{ 0x84 , 0x0084 },
+{ 0x85 , 0x0085 },
+{ 0x86 , 0x0086 },
+{ 0x87 , 0x0087 },
+{ 0x88 , 0x0088 },
+{ 0x89 , 0x0089 },
+{ 0x8a , 0x008A },
+{ 0x8b , 0x008B },
+{ 0x8c , 0x008C },
+{ 0x8d , 0x008D },
+{ 0x8e , 0x008E },
+{ 0x8f , 0x008F },
+{ 0x90 , 0x0090 },
+{ 0x91 , 0x0091 },
+{ 0x92 , 0x0092 },
+{ 0x93 , 0x0093 },
+{ 0x94 , 0x0094 },
+{ 0x95 , 0x0095 },
+{ 0x96 , 0x0096 },
+{ 0x97 , 0x0097 },
+{ 0x98 , 0x0098 },
+{ 0x99 , 0x0099 },
+{ 0x9a , 0x009A },
+{ 0x9b , 0x009B },
+{ 0x9c , 0x009C },
+{ 0x9d , 0x009D },
+{ 0x9e , 0x009E },
+{ 0x9f , 0x009F },
+{ 0xa0 , 0x00A0 },
+{ 0xa2 , 0x00A2 },
+{ 0xa3 , 0x00A3 },
+{ 0xa4 , 0x00A4 },
+{ 0xa5 , 0x00A5 },
+{ 0xa6 , 0x00A6 },
+{ 0xa7 , 0x00A7 },
+{ 0xa8 , 0x00A8 },
+{ 0xa9 , 0x00A9 },
+{ 0xaa , 0x00D7 },
+{ 0xab , 0x00AB },
+{ 0xac , 0x00AC },
+{ 0xad , 0x00AD },
+{ 0xae , 0x00AE },
+{ 0xaf , 0x00AF },
+{ 0xb0 , 0x00B0 },
+{ 0xb1 , 0x00B1 },
+{ 0xb2 , 0x00B2 },
+{ 0xb3 , 0x00B3 },
+{ 0xb4 , 0x00B4 },
+{ 0xb5 , 0x00B5 },
+{ 0xb6 , 0x00B6 },
+{ 0xb7 , 0x00B7 },
+{ 0xb8 , 0x00B8 },
+{ 0xb9 , 0x00B9 },
+{ 0xba , 0x00F7 },
+{ 0xbb , 0x00BB },
+{ 0xbc , 0x00BC },
+{ 0xbd , 0x00BD },
+{ 0xbe , 0x00BE },
+{ 0xdf , 0x2017 },
+{ 0xe0 , 0x05D0 },
+{ 0xe1 , 0x05D1 },
+{ 0xe2 , 0x05D2 },
+{ 0xe3 , 0x05D3 },
+{ 0xe4 , 0x05D4 },
+{ 0xe5 , 0x05D5 },
+{ 0xe6 , 0x05D6 },
+{ 0xe7 , 0x05D7 },
+{ 0xe8 , 0x05D8 },
+{ 0xe9 , 0x05D9 },
+{ 0xea , 0x05DA },
+{ 0xeb , 0x05DB },
+{ 0xec , 0x05DC },
+{ 0xed , 0x05DD },
+{ 0xee , 0x05DE },
+{ 0xef , 0x05DF },
+{ 0xf0 , 0x05E0 },
+{ 0xf1 , 0x05E1 },
+{ 0xf2 , 0x05E2 },
+{ 0xf3 , 0x05E3 },
+{ 0xf4 , 0x05E4 },
+{ 0xf5 , 0x05E5 },
+{ 0xf6 , 0x05E6 },
+{ 0xf7 , 0x05E7 },
+{ 0xf8 , 0x05E8 },
+{ 0xf9 , 0x05E9 },
+{ 0xfa , 0x05EA },
+{ 0xfd , 0x200E },
+{ 0xfe , 0x200F },

+ 256 - 0
extra/locale/charmaps/ISO-8859-9.pairs

@@ -0,0 +1,256 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x0080 },
+{ 0x81 , 0x0081 },
+{ 0x82 , 0x0082 },
+{ 0x83 , 0x0083 },
+{ 0x84 , 0x0084 },
+{ 0x85 , 0x0085 },
+{ 0x86 , 0x0086 },
+{ 0x87 , 0x0087 },
+{ 0x88 , 0x0088 },
+{ 0x89 , 0x0089 },
+{ 0x8a , 0x008A },
+{ 0x8b , 0x008B },
+{ 0x8c , 0x008C },
+{ 0x8d , 0x008D },
+{ 0x8e , 0x008E },
+{ 0x8f , 0x008F },
+{ 0x90 , 0x0090 },
+{ 0x91 , 0x0091 },
+{ 0x92 , 0x0092 },
+{ 0x93 , 0x0093 },
+{ 0x94 , 0x0094 },
+{ 0x95 , 0x0095 },
+{ 0x96 , 0x0096 },
+{ 0x97 , 0x0097 },
+{ 0x98 , 0x0098 },
+{ 0x99 , 0x0099 },
+{ 0x9a , 0x009A },
+{ 0x9b , 0x009B },
+{ 0x9c , 0x009C },
+{ 0x9d , 0x009D },
+{ 0x9e , 0x009E },
+{ 0x9f , 0x009F },
+{ 0xa0 , 0x00A0 },
+{ 0xa1 , 0x00A1 },
+{ 0xa2 , 0x00A2 },
+{ 0xa3 , 0x00A3 },
+{ 0xa4 , 0x00A4 },
+{ 0xa5 , 0x00A5 },
+{ 0xa6 , 0x00A6 },
+{ 0xa7 , 0x00A7 },
+{ 0xa8 , 0x00A8 },
+{ 0xa9 , 0x00A9 },
+{ 0xaa , 0x00AA },
+{ 0xab , 0x00AB },
+{ 0xac , 0x00AC },
+{ 0xad , 0x00AD },
+{ 0xae , 0x00AE },
+{ 0xaf , 0x00AF },
+{ 0xb0 , 0x00B0 },
+{ 0xb1 , 0x00B1 },
+{ 0xb2 , 0x00B2 },
+{ 0xb3 , 0x00B3 },
+{ 0xb4 , 0x00B4 },
+{ 0xb5 , 0x00B5 },
+{ 0xb6 , 0x00B6 },
+{ 0xb7 , 0x00B7 },
+{ 0xb8 , 0x00B8 },
+{ 0xb9 , 0x00B9 },
+{ 0xba , 0x00BA },
+{ 0xbb , 0x00BB },
+{ 0xbc , 0x00BC },
+{ 0xbd , 0x00BD },
+{ 0xbe , 0x00BE },
+{ 0xbf , 0x00BF },
+{ 0xc0 , 0x00C0 },
+{ 0xc1 , 0x00C1 },
+{ 0xc2 , 0x00C2 },
+{ 0xc3 , 0x00C3 },
+{ 0xc4 , 0x00C4 },
+{ 0xc5 , 0x00C5 },
+{ 0xc6 , 0x00C6 },
+{ 0xc7 , 0x00C7 },
+{ 0xc8 , 0x00C8 },
+{ 0xc9 , 0x00C9 },
+{ 0xca , 0x00CA },
+{ 0xcb , 0x00CB },
+{ 0xcc , 0x00CC },
+{ 0xcd , 0x00CD },
+{ 0xce , 0x00CE },
+{ 0xcf , 0x00CF },
+{ 0xd0 , 0x011E },
+{ 0xd1 , 0x00D1 },
+{ 0xd2 , 0x00D2 },
+{ 0xd3 , 0x00D3 },
+{ 0xd4 , 0x00D4 },
+{ 0xd5 , 0x00D5 },
+{ 0xd6 , 0x00D6 },
+{ 0xd7 , 0x00D7 },
+{ 0xd8 , 0x00D8 },
+{ 0xd9 , 0x00D9 },
+{ 0xda , 0x00DA },
+{ 0xdb , 0x00DB },
+{ 0xdc , 0x00DC },
+{ 0xdd , 0x0130 },
+{ 0xde , 0x015E },
+{ 0xdf , 0x00DF },
+{ 0xe0 , 0x00E0 },
+{ 0xe1 , 0x00E1 },
+{ 0xe2 , 0x00E2 },
+{ 0xe3 , 0x00E3 },
+{ 0xe4 , 0x00E4 },
+{ 0xe5 , 0x00E5 },
+{ 0xe6 , 0x00E6 },
+{ 0xe7 , 0x00E7 },
+{ 0xe8 , 0x00E8 },
+{ 0xe9 , 0x00E9 },
+{ 0xea , 0x00EA },
+{ 0xeb , 0x00EB },
+{ 0xec , 0x00EC },
+{ 0xed , 0x00ED },
+{ 0xee , 0x00EE },
+{ 0xef , 0x00EF },
+{ 0xf0 , 0x011F },
+{ 0xf1 , 0x00F1 },
+{ 0xf2 , 0x00F2 },
+{ 0xf3 , 0x00F3 },
+{ 0xf4 , 0x00F4 },
+{ 0xf5 , 0x00F5 },
+{ 0xf6 , 0x00F6 },
+{ 0xf7 , 0x00F7 },
+{ 0xf8 , 0x00F8 },
+{ 0xf9 , 0x00F9 },
+{ 0xfa , 0x00FA },
+{ 0xfb , 0x00FB },
+{ 0xfc , 0x00FC },
+{ 0xfd , 0x0131 },
+{ 0xfe , 0x015F },
+{ 0xff , 0x00FF },

+ 256 - 0
extra/locale/charmaps/KOI8-R.pairs

@@ -0,0 +1,256 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x2500 },
+{ 0x81 , 0x2502 },
+{ 0x82 , 0x250C },
+{ 0x83 , 0x2510 },
+{ 0x84 , 0x2514 },
+{ 0x85 , 0x2518 },
+{ 0x86 , 0x251C },
+{ 0x87 , 0x2524 },
+{ 0x88 , 0x252C },
+{ 0x89 , 0x2534 },
+{ 0x8a , 0x253C },
+{ 0x8b , 0x2580 },
+{ 0x8c , 0x2584 },
+{ 0x8d , 0x2588 },
+{ 0x8e , 0x258C },
+{ 0x8f , 0x2590 },
+{ 0x90 , 0x2591 },
+{ 0x91 , 0x2592 },
+{ 0x92 , 0x2593 },
+{ 0x93 , 0x2320 },
+{ 0x94 , 0x25A0 },
+{ 0x95 , 0x2219 },
+{ 0x96 , 0x221A },
+{ 0x97 , 0x2248 },
+{ 0x98 , 0x2264 },
+{ 0x99 , 0x2265 },
+{ 0x9a , 0x00A0 },
+{ 0x9b , 0x2321 },
+{ 0x9c , 0x00B0 },
+{ 0x9d , 0x00B2 },
+{ 0x9e , 0x00B7 },
+{ 0x9f , 0x00F7 },
+{ 0xa0 , 0x2550 },
+{ 0xa1 , 0x2551 },
+{ 0xa2 , 0x2552 },
+{ 0xa3 , 0x0451 },
+{ 0xa4 , 0x2553 },
+{ 0xa5 , 0x2554 },
+{ 0xa6 , 0x2555 },
+{ 0xa7 , 0x2556 },
+{ 0xa8 , 0x2557 },
+{ 0xa9 , 0x2558 },
+{ 0xaa , 0x2559 },
+{ 0xab , 0x255A },
+{ 0xac , 0x255B },
+{ 0xad , 0x255C },
+{ 0xae , 0x255D },
+{ 0xaf , 0x255E },
+{ 0xb0 , 0x255F },
+{ 0xb1 , 0x2560 },
+{ 0xb2 , 0x2561 },
+{ 0xb3 , 0x0401 },
+{ 0xb4 , 0x2562 },
+{ 0xb5 , 0x2563 },
+{ 0xb6 , 0x2564 },
+{ 0xb7 , 0x2565 },
+{ 0xb8 , 0x2566 },
+{ 0xb9 , 0x2567 },
+{ 0xba , 0x2568 },
+{ 0xbb , 0x2569 },
+{ 0xbc , 0x256A },
+{ 0xbd , 0x256B },
+{ 0xbe , 0x256C },
+{ 0xbf , 0x00A9 },
+{ 0xc0 , 0x044E },
+{ 0xc1 , 0x0430 },
+{ 0xc2 , 0x0431 },
+{ 0xc3 , 0x0446 },
+{ 0xc4 , 0x0434 },
+{ 0xc5 , 0x0435 },
+{ 0xc6 , 0x0444 },
+{ 0xc7 , 0x0433 },
+{ 0xc8 , 0x0445 },
+{ 0xc9 , 0x0438 },
+{ 0xca , 0x0439 },
+{ 0xcb , 0x043A },
+{ 0xcc , 0x043B },
+{ 0xcd , 0x043C },
+{ 0xce , 0x043D },
+{ 0xcf , 0x043E },
+{ 0xd0 , 0x043F },
+{ 0xd1 , 0x044F },
+{ 0xd2 , 0x0440 },
+{ 0xd3 , 0x0441 },
+{ 0xd4 , 0x0442 },
+{ 0xd5 , 0x0443 },
+{ 0xd6 , 0x0436 },
+{ 0xd7 , 0x0432 },
+{ 0xd8 , 0x044C },
+{ 0xd9 , 0x044B },
+{ 0xda , 0x0437 },
+{ 0xdb , 0x0448 },
+{ 0xdc , 0x044D },
+{ 0xdd , 0x0449 },
+{ 0xde , 0x0447 },
+{ 0xdf , 0x044A },
+{ 0xe0 , 0x042E },
+{ 0xe1 , 0x0410 },
+{ 0xe2 , 0x0411 },
+{ 0xe3 , 0x0426 },
+{ 0xe4 , 0x0414 },
+{ 0xe5 , 0x0415 },
+{ 0xe6 , 0x0424 },
+{ 0xe7 , 0x0413 },
+{ 0xe8 , 0x0425 },
+{ 0xe9 , 0x0418 },
+{ 0xea , 0x0419 },
+{ 0xeb , 0x041A },
+{ 0xec , 0x041B },
+{ 0xed , 0x041C },
+{ 0xee , 0x041D },
+{ 0xef , 0x041E },
+{ 0xf0 , 0x041F },
+{ 0xf1 , 0x042F },
+{ 0xf2 , 0x0420 },
+{ 0xf3 , 0x0421 },
+{ 0xf4 , 0x0422 },
+{ 0xf5 , 0x0423 },
+{ 0xf6 , 0x0416 },
+{ 0xf7 , 0x0412 },
+{ 0xf8 , 0x042C },
+{ 0xf9 , 0x042B },
+{ 0xfa , 0x0417 },
+{ 0xfb , 0x0428 },
+{ 0xfc , 0x042D },
+{ 0xfd , 0x0429 },
+{ 0xfe , 0x0427 },
+{ 0xff , 0x042A },

+ 256 - 0
extra/locale/charmaps/KOI8-U.pairs

@@ -0,0 +1,256 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0x80 , 0x2500 },
+{ 0x81 , 0x2502 },
+{ 0x82 , 0x250C },
+{ 0x83 , 0x2510 },
+{ 0x84 , 0x2514 },
+{ 0x85 , 0x2518 },
+{ 0x86 , 0x251C },
+{ 0x87 , 0x2524 },
+{ 0x88 , 0x252C },
+{ 0x89 , 0x2534 },
+{ 0x8a , 0x253C },
+{ 0x8b , 0x2580 },
+{ 0x8c , 0x2584 },
+{ 0x8d , 0x2588 },
+{ 0x8e , 0x258C },
+{ 0x8f , 0x2590 },
+{ 0x90 , 0x2591 },
+{ 0x91 , 0x2592 },
+{ 0x92 , 0x2593 },
+{ 0x93 , 0x2320 },
+{ 0x94 , 0x25A0 },
+{ 0x95 , 0x2219 },
+{ 0x96 , 0x221A },
+{ 0x97 , 0x2248 },
+{ 0x98 , 0x2264 },
+{ 0x99 , 0x2265 },
+{ 0x9a , 0x00A0 },
+{ 0x9b , 0x2321 },
+{ 0x9c , 0x00B0 },
+{ 0x9d , 0x00B2 },
+{ 0x9e , 0x00B7 },
+{ 0x9f , 0x00F7 },
+{ 0xa0 , 0x2550 },
+{ 0xa1 , 0x2551 },
+{ 0xa2 , 0x2552 },
+{ 0xa3 , 0x0451 },
+{ 0xa4 , 0x0454 },
+{ 0xa5 , 0x2554 },
+{ 0xa6 , 0x0456 },
+{ 0xa7 , 0x0457 },
+{ 0xa8 , 0x2557 },
+{ 0xa9 , 0x2558 },
+{ 0xaa , 0x2559 },
+{ 0xab , 0x255A },
+{ 0xac , 0x255B },
+{ 0xad , 0x0491 },
+{ 0xae , 0x255D },
+{ 0xaf , 0x255E },
+{ 0xb0 , 0x255F },
+{ 0xb1 , 0x2560 },
+{ 0xb2 , 0x2561 },
+{ 0xb3 , 0x0401 },
+{ 0xb4 , 0x0404 },
+{ 0xb5 , 0x2563 },
+{ 0xb6 , 0x0406 },
+{ 0xb7 , 0x0407 },
+{ 0xb8 , 0x2566 },
+{ 0xb9 , 0x2567 },
+{ 0xba , 0x2568 },
+{ 0xbb , 0x2569 },
+{ 0xbc , 0x256A },
+{ 0xbd , 0x0490 },
+{ 0xbe , 0x256C },
+{ 0xbf , 0x00A9 },
+{ 0xc0 , 0x044E },
+{ 0xc1 , 0x0430 },
+{ 0xc2 , 0x0431 },
+{ 0xc3 , 0x0446 },
+{ 0xc4 , 0x0434 },
+{ 0xc5 , 0x0435 },
+{ 0xc6 , 0x0444 },
+{ 0xc7 , 0x0433 },
+{ 0xc8 , 0x0445 },
+{ 0xc9 , 0x0438 },
+{ 0xca , 0x0439 },
+{ 0xcb , 0x043A },
+{ 0xcc , 0x043B },
+{ 0xcd , 0x043C },
+{ 0xce , 0x043D },
+{ 0xcf , 0x043E },
+{ 0xd0 , 0x043F },
+{ 0xd1 , 0x044F },
+{ 0xd2 , 0x0440 },
+{ 0xd3 , 0x0441 },
+{ 0xd4 , 0x0442 },
+{ 0xd5 , 0x0443 },
+{ 0xd6 , 0x0436 },
+{ 0xd7 , 0x0432 },
+{ 0xd8 , 0x044C },
+{ 0xd9 , 0x044B },
+{ 0xda , 0x0437 },
+{ 0xdb , 0x0448 },
+{ 0xdc , 0x044D },
+{ 0xdd , 0x0449 },
+{ 0xde , 0x0447 },
+{ 0xdf , 0x044A },
+{ 0xe0 , 0x042E },
+{ 0xe1 , 0x0410 },
+{ 0xe2 , 0x0411 },
+{ 0xe3 , 0x0426 },
+{ 0xe4 , 0x0414 },
+{ 0xe5 , 0x0415 },
+{ 0xe6 , 0x0424 },
+{ 0xe7 , 0x0413 },
+{ 0xe8 , 0x0425 },
+{ 0xe9 , 0x0418 },
+{ 0xea , 0x0419 },
+{ 0xeb , 0x041A },
+{ 0xec , 0x041B },
+{ 0xed , 0x041C },
+{ 0xee , 0x041D },
+{ 0xef , 0x041E },
+{ 0xf0 , 0x041F },
+{ 0xf1 , 0x042F },
+{ 0xf2 , 0x0420 },
+{ 0xf3 , 0x0421 },
+{ 0xf4 , 0x0422 },
+{ 0xf5 , 0x0423 },
+{ 0xf6 , 0x0416 },
+{ 0xf7 , 0x0412 },
+{ 0xf8 , 0x042C },
+{ 0xf9 , 0x042B },
+{ 0xfa , 0x0417 },
+{ 0xfb , 0x0428 },
+{ 0xfc , 0x042D },
+{ 0xfd , 0x0429 },
+{ 0xfe , 0x0427 },
+{ 0xff , 0x042A },

+ 215 - 0
extra/locale/charmaps/TIS-620.pairs

@@ -0,0 +1,215 @@
+{ 0x00 , 0x0000 },
+{ 0x01 , 0x0001 },
+{ 0x02 , 0x0002 },
+{ 0x03 , 0x0003 },
+{ 0x04 , 0x0004 },
+{ 0x05 , 0x0005 },
+{ 0x06 , 0x0006 },
+{ 0x07 , 0x0007 },
+{ 0x08 , 0x0008 },
+{ 0x09 , 0x0009 },
+{ 0x0a , 0x000A },
+{ 0x0b , 0x000B },
+{ 0x0c , 0x000C },
+{ 0x0d , 0x000D },
+{ 0x0e , 0x000E },
+{ 0x0f , 0x000F },
+{ 0x10 , 0x0010 },
+{ 0x11 , 0x0011 },
+{ 0x12 , 0x0012 },
+{ 0x13 , 0x0013 },
+{ 0x14 , 0x0014 },
+{ 0x15 , 0x0015 },
+{ 0x16 , 0x0016 },
+{ 0x17 , 0x0017 },
+{ 0x18 , 0x0018 },
+{ 0x19 , 0x0019 },
+{ 0x1a , 0x001A },
+{ 0x1b , 0x001B },
+{ 0x1c , 0x001C },
+{ 0x1d , 0x001D },
+{ 0x1e , 0x001E },
+{ 0x1f , 0x001F },
+{ 0x20 , 0x0020 },
+{ 0x21 , 0x0021 },
+{ 0x22 , 0x0022 },
+{ 0x23 , 0x0023 },
+{ 0x24 , 0x0024 },
+{ 0x25 , 0x0025 },
+{ 0x26 , 0x0026 },
+{ 0x27 , 0x0027 },
+{ 0x28 , 0x0028 },
+{ 0x29 , 0x0029 },
+{ 0x2a , 0x002A },
+{ 0x2b , 0x002B },
+{ 0x2c , 0x002C },
+{ 0x2d , 0x002D },
+{ 0x2e , 0x002E },
+{ 0x2f , 0x002F },
+{ 0x30 , 0x0030 },
+{ 0x31 , 0x0031 },
+{ 0x32 , 0x0032 },
+{ 0x33 , 0x0033 },
+{ 0x34 , 0x0034 },
+{ 0x35 , 0x0035 },
+{ 0x36 , 0x0036 },
+{ 0x37 , 0x0037 },
+{ 0x38 , 0x0038 },
+{ 0x39 , 0x0039 },
+{ 0x3a , 0x003A },
+{ 0x3b , 0x003B },
+{ 0x3c , 0x003C },
+{ 0x3d , 0x003D },
+{ 0x3e , 0x003E },
+{ 0x3f , 0x003F },
+{ 0x40 , 0x0040 },
+{ 0x41 , 0x0041 },
+{ 0x42 , 0x0042 },
+{ 0x43 , 0x0043 },
+{ 0x44 , 0x0044 },
+{ 0x45 , 0x0045 },
+{ 0x46 , 0x0046 },
+{ 0x47 , 0x0047 },
+{ 0x48 , 0x0048 },
+{ 0x49 , 0x0049 },
+{ 0x4a , 0x004A },
+{ 0x4b , 0x004B },
+{ 0x4c , 0x004C },
+{ 0x4d , 0x004D },
+{ 0x4e , 0x004E },
+{ 0x4f , 0x004F },
+{ 0x50 , 0x0050 },
+{ 0x51 , 0x0051 },
+{ 0x52 , 0x0052 },
+{ 0x53 , 0x0053 },
+{ 0x54 , 0x0054 },
+{ 0x55 , 0x0055 },
+{ 0x56 , 0x0056 },
+{ 0x57 , 0x0057 },
+{ 0x58 , 0x0058 },
+{ 0x59 , 0x0059 },
+{ 0x5a , 0x005A },
+{ 0x5b , 0x005B },
+{ 0x5c , 0x005C },
+{ 0x5d , 0x005D },
+{ 0x5e , 0x005E },
+{ 0x5f , 0x005F },
+{ 0x60 , 0x0060 },
+{ 0x61 , 0x0061 },
+{ 0x62 , 0x0062 },
+{ 0x63 , 0x0063 },
+{ 0x64 , 0x0064 },
+{ 0x65 , 0x0065 },
+{ 0x66 , 0x0066 },
+{ 0x67 , 0x0067 },
+{ 0x68 , 0x0068 },
+{ 0x69 , 0x0069 },
+{ 0x6a , 0x006A },
+{ 0x6b , 0x006B },
+{ 0x6c , 0x006C },
+{ 0x6d , 0x006D },
+{ 0x6e , 0x006E },
+{ 0x6f , 0x006F },
+{ 0x70 , 0x0070 },
+{ 0x71 , 0x0071 },
+{ 0x72 , 0x0072 },
+{ 0x73 , 0x0073 },
+{ 0x74 , 0x0074 },
+{ 0x75 , 0x0075 },
+{ 0x76 , 0x0076 },
+{ 0x77 , 0x0077 },
+{ 0x78 , 0x0078 },
+{ 0x79 , 0x0079 },
+{ 0x7a , 0x007A },
+{ 0x7b , 0x007B },
+{ 0x7c , 0x007C },
+{ 0x7d , 0x007D },
+{ 0x7e , 0x007E },
+{ 0x7f , 0x007F },
+{ 0xa1 , 0x0E01 },
+{ 0xa2 , 0x0E02 },
+{ 0xa3 , 0x0E03 },
+{ 0xa4 , 0x0E04 },
+{ 0xa5 , 0x0E05 },
+{ 0xa6 , 0x0E06 },
+{ 0xa7 , 0x0E07 },
+{ 0xa8 , 0x0E08 },
+{ 0xa9 , 0x0E09 },
+{ 0xaa , 0x0E0A },
+{ 0xab , 0x0E0B },
+{ 0xac , 0x0E0C },
+{ 0xad , 0x0E0D },
+{ 0xae , 0x0E0E },
+{ 0xaf , 0x0E0F },
+{ 0xb0 , 0x0E10 },
+{ 0xb1 , 0x0E11 },
+{ 0xb2 , 0x0E12 },
+{ 0xb3 , 0x0E13 },
+{ 0xb4 , 0x0E14 },
+{ 0xb5 , 0x0E15 },
+{ 0xb6 , 0x0E16 },
+{ 0xb7 , 0x0E17 },
+{ 0xb8 , 0x0E18 },
+{ 0xb9 , 0x0E19 },
+{ 0xba , 0x0E1A },
+{ 0xbb , 0x0E1B },
+{ 0xbc , 0x0E1C },
+{ 0xbd , 0x0E1D },
+{ 0xbe , 0x0E1E },
+{ 0xbf , 0x0E1F },
+{ 0xc0 , 0x0E20 },
+{ 0xc1 , 0x0E21 },
+{ 0xc2 , 0x0E22 },
+{ 0xc3 , 0x0E23 },
+{ 0xc4 , 0x0E24 },
+{ 0xc5 , 0x0E25 },
+{ 0xc6 , 0x0E26 },
+{ 0xc7 , 0x0E27 },
+{ 0xc8 , 0x0E28 },
+{ 0xc9 , 0x0E29 },
+{ 0xca , 0x0E2A },
+{ 0xcb , 0x0E2B },
+{ 0xcc , 0x0E2C },
+{ 0xcd , 0x0E2D },
+{ 0xce , 0x0E2E },
+{ 0xcf , 0x0E2F },
+{ 0xd0 , 0x0E30 },
+{ 0xd1 , 0x0E31 },
+{ 0xd2 , 0x0E32 },
+{ 0xd3 , 0x0E33 },
+{ 0xd4 , 0x0E34 },
+{ 0xd5 , 0x0E35 },
+{ 0xd6 , 0x0E36 },
+{ 0xd7 , 0x0E37 },
+{ 0xd8 , 0x0E38 },
+{ 0xd9 , 0x0E39 },
+{ 0xda , 0x0E3A },
+{ 0xdf , 0x0E3F },
+{ 0xe0 , 0x0E40 },
+{ 0xe1 , 0x0E41 },
+{ 0xe2 , 0x0E42 },
+{ 0xe3 , 0x0E43 },
+{ 0xe4 , 0x0E44 },
+{ 0xe5 , 0x0E45 },
+{ 0xe6 , 0x0E46 },
+{ 0xe7 , 0x0E47 },
+{ 0xe8 , 0x0E48 },
+{ 0xe9 , 0x0E49 },
+{ 0xea , 0x0E4A },
+{ 0xeb , 0x0E4B },
+{ 0xec , 0x0E4C },
+{ 0xed , 0x0E4D },
+{ 0xee , 0x0E4E },
+{ 0xef , 0x0E4F },
+{ 0xf0 , 0x0E50 },
+{ 0xf1 , 0x0E51 },
+{ 0xf2 , 0x0E52 },
+{ 0xf3 , 0x0E53 },
+{ 0xf4 , 0x0E54 },
+{ 0xf5 , 0x0E55 },
+{ 0xf6 , 0x0E56 },
+{ 0xf7 , 0x0E57 },
+{ 0xf8 , 0x0E58 },
+{ 0xf9 , 0x0E59 },
+{ 0xfa , 0x0E5A },
+{ 0xfb , 0x0E5B },

+ 0 - 207
extra/locale/gen_collate_from_glibc.c

@@ -1,207 +0,0 @@
-/*
- * Generator collate table from glibc special for Uclibc.
- * Author Vladimir Oleynik. vodz@usa.net (c) 2001
- *
- * Require setuped work non-C LC_COLLATE
- * This programm created ./LOCALE/LC_COLLATE file for Uclibc
- * setlocale() and strcoll().
- * Without argument this programm used setlocale(LC_COLLATE, "") -
- * equivalent result setlocale(LC_COLLATE, getenv("LC_XXX"))
- *
- * Also, this programm have russian koi8 collate for test
- * working Uclibc ;-)
- *
- */
-
-#include <ctype.h>
-#include <string.h>
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/stat.h>   /* mkdir() */
-#include <errno.h>
-
-
-/* For strong test russian locale LC_COLLATE="ru_RU.KOI8-R" */
-static const unsigned char koi8_weights[256] = {
-  0,   99,  100,  101,  102,  103,  104,  105,
-106,    2,    5,    3,    6,    4,  107,  108,
-109,  110,  111,  112,  113,  114,  115,  116,
-117,  118,  119,  120,  121,  122,  123,  124,
-  1,   12,   21,   34,   30,   35,   33,   20,
- 22,   23,   31,   36,    9,    8,   15,   14,
-127,  128,  129,  131,  132,  133,  134,  135,
-136,  137,   11,   10,   38,   40,   42,   13,
- 29,  138,  140,  142,  144,  146,  148,  150,
-152,  154,  156,  158,  160,  162,  164,  166,
-168,  170,  172,  174,  176,  178,  180,  182,
-184,  186,  188,   24,   32,   25,   17,    7,
- 16,  139,  141,  143,  145,  147,  149,  151,
-153,  155,  157,  159,  161,  163,  165,  167,
-169,  171,  173,  175,  177,  179,  181,  183,
-185,  187,  189,   26,   43,   27,   18,  125,
- 50,   52,   54,   58,   62,   66,   70,   74,
- 78,   82,   86,   90,   91,   92,   93,   94,
- 95,   96,   97,   48,   98,   45,   46,   47,
- 39,   41,  126,   49,   44,  130,   19,   37,
- 51,   53,   55,  203,   56,   57,   59,   60,
- 61,   63,   64,   65,   67,   68,   69,   71,
- 72,   73,   75,  202,   76,   77,   79,   80,
- 81,   83,   84,   85,   87,   88,   89,   28,
-253,  191,  193,  237,  199,  201,  233,  197,
-235,  209,  211,  213,  215,  217,  219,  221,
-223,  255,  225,  227,  229,  231,  205,  195,
-249,  247,  207,  241,  251,  243,  239,  245,
-252,  190,  192,  236,  198,  200,  232,  196,
-234,  208,  210,  212,  214,  216,  218,  220,
-222,  254,  224,  226,  228,  230,  204,  194,
-248,  246,  206,  240,  250,  242,  238,  244
-};
-
-int gen_weights(const char *collate)
-{
-	int weights[256];
-	int i,j;
-	char probe_str1[2];
-	char probe_str2[2];
-	char print_buf[16];
-	int  retcode = 0;
-	unsigned char out_weights[256];
-	FILE *out;
-
-	memset(weights, 0, sizeof(weights));
-	probe_str1[1]=probe_str2[1]=0;
-
-	for(i=0; i<256; i++) {
-		probe_str1[0] = i;
-		for(j=0; j<256; j++) {
-			probe_str2[0] = j;
-			if(strcoll(probe_str1, probe_str2)>0) {
-				weights[i]++;
-				if(i==j) {
-					fprintf(stderr, "\
-\nWarning! c1=%d == c2, but strcoll returned greater zero\n", i);
-				retcode++;
-				}
-			}
-		}
-	}
-	for(i=0; i<256; ) {
-		if(isprint(i))
-			sprintf(print_buf, " '%c'", i);
-		 else {
-			if(i=='\0')
-				strcpy(print_buf, "'\\0'");
-			else if(i=='\a')
-				strcpy(print_buf, "'\\a'");
-			else if(i=='\b')
-				strcpy(print_buf, "'\\b'");
-			else if(i=='\f')
-				strcpy(print_buf, "'\\f'");
-			else if(i=='\r')
-				strcpy(print_buf, "'\\r'");
-			else if(i=='\t')
-				strcpy(print_buf, "'\\t'");
-			else sprintf(print_buf, " x%02X", i);
-			}
-		printf("weights[%s] = %3d ", print_buf, weights[i]);
-		i++;
-		if( (i%4) == 0)
-			printf("\n");
-		}
-
-	for(i=0; i<256; i++) {
-		if(weights[i]<0 || weights[i]>=256) {
-			fprintf(stderr, "Hmm, weights[%d]=%d\n", i, weights[i]);
-			retcode++;
-		}
-		for(j=0; j<256; j++) {
-			if(i==j)
-				continue;
-			if(weights[i]==weights[j]) {
-				fprintf(stderr, "\
-Warning! c1=%d c2=%d and strcoll returned equivalent weight\n", i, j);
-			retcode++;
-			}
-		}
-	}
-	if(retcode)
-		return 1;
-
-	if(strcasecmp(collate, "ru_RU.KOI8-R")==0 ||
-				strcmp(collate, "ru_RU")==0 ||
-					strcmp(collate, "koi8-r")==0) {
-		for(i=0; i<256; i++)
-			if(weights[i]!=koi8_weights[i]) {
-				fprintf(stderr, "\
-Error koi8-r collate compare, glibc weights[%d]=%d but current generation %d\n",
-					i, koi8_weights[i], weights[i]);
-				retcode++;
-			}
-		if(retcode)
-			return 5;
-	}
-	for(i=0; i<256; i++)
-		out_weights[i] = weights[i];
-	out = fopen("LC_COLLATE", "w");
-	if(out == NULL) {
-		fprintf(stderr, "Can`t create ./%s/LC_COLLATE file\n", collate);
-		return 10;
-	}
-	if(fwrite(out_weights, 1, 256, out)!=256) {
-		fprintf(stderr, "IO error in process write ./%s/LC_COLLATE file\n", collate);
-		return 11;
-	}
-	return 0;
-}
-
-int main(int argc, char **argv)
-{
-	char *locale;
-	char *slr;
-	char *collate;
-
-	if(argc<1 || argc>2) {
-		fprintf(stderr, "Usage: %s [locale]\n", argv[0]);
-	}
-	locale = argc==1 ? "" : argv[1];
-
-	collate = setlocale(LC_COLLATE, locale);
-	fprintf(stderr, "setlocale(LC_COLLATE, \"%s\") returned %s\n", locale, collate);
-	if(collate==0) {
-		fprintf(stderr, "Can`t set LC_COLLATE\n");
-		return 2;
-		}
-	if(strcmp(collate, "C")==0) {
-		fprintf(stderr, "\
-LC_COLLATE=\"C\" is trivial and not interesting for this programm\n");
-		return 3;
-	}
-	slr = setlocale(LC_CTYPE, locale);
-	fprintf(stderr, "setlocale(LC_CTYPE, \"%s\") returned %s\n", locale, slr);
-	if(slr==0) {
-		slr = setlocale(LC_CTYPE, "POSIX");
-		if(slr==0) {
-			fprintf(stderr, "Hmm, can`t set setlocale(LC_CTYPE, \"POSIX\")\n");
-			return 4;
-		}
-	}
-	if(mkdir(collate, 0755)!=0 && errno!=EEXIST) {
-		fprintf(stderr, "Can`t make directory %s\n", collate);
-		return 6;
-	}
-	if(chdir(collate)) {
-		fprintf(stderr, "Hmm, can`t change directory to %s\n", collate);
-		return 7;
-	}
-	if(gen_weights(collate)) {
-		if(chdir("..")) {
-			fprintf(stderr, "Hmm, can`t change to current directory\n");
-			return 7;
-		}
-		rmdir(collate);
-		return 1;
-	}
-	return 0;
-}

+ 0 - 277
extra/locale/gen_ctype_from_glibc.c

@@ -1,277 +0,0 @@
-/*
- * Generator locale ctype tables
- * You must have already setuped locale for worked libc (libc5 or glibc)
- *
- * This programm scan /usr/share/locale directories and write
- * ./LOCALE/LC_CTYPE files for system with uclibc
- *
- * Written by Vladimir Oleynik <vodz@usa.net> 2001
- * Base on ideas Nickolay Saukh  <nms@ussr.EU.net>
- *
- */
-
-#include <locale.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "../../libc/misc/locale/_locale.h"
-
-
-#define DEFAULT_LOCALE_DIR      "/usr/share/locale/"
-
-#define DEF_OUT_NAME            "LC_CTYPE"
-
-#define CURRENT_SUPPORT_MAX (LOCALE_BUF_SIZE/2)
-
-
-unsigned char x2type[CURRENT_SUPPORT_MAX];
-
-unsigned char x2trans[CURRENT_SUPPORT_MAX];
-
-
-
-int
-write_out (outname)
-     unsigned char *outname;
-{
-  FILE *ofp = fopen (outname, "w");
-
-  if (ofp == NULL) {
-    fprintf (stderr, "Can`t write `%s\n", outname);
-    return 1;
-  }
-
-  fwrite (x2type, sizeof (x2type), 1, ofp);
-  fwrite (x2trans, sizeof (x2trans), 1, ofp);
-  fclose (ofp);
-  return 0;
-}
-
-
-typedef struct bbits_ {
-    int bbits;
-    char *bb_name;
-  } bbits_t;
-
-
-bbits_t basic_bits[] =
-{
-  {ISprint , "ISprint" },
-  {ISupper , "ISupper" },
-  {ISlower , "ISlower" },
-  {IScntrl , "IScntrl" },
-  {ISspace , "ISspace" },
-  {ISpunct , "ISpunct" },
-  {ISalpha , "ISalpha" },
-  {ISxdigit, "ISxdigit"},
-  {0, NULL}
-};
-
-
-void
-ctab_out (char *oun)
-{
-  int i;
-  char *outname;
-  FILE *fout;
-
-  outname = alloca(strlen(oun)+strlen("ctype_.c")+1);
-  if(outname==0) {
-	perror("");
-	exit(1);
-	}
-  strcpy(outname, "ctype_");
-  strcat(outname, oun);
-  strcat(outname, ".c");
-
-  fout = fopen (outname, "w");
-
-  if (fout == NULL)
-    {
-      perror ("");
-      return;
-    }
-
-  fprintf (fout, "const unsigned char _uc_ctype_b_C[LOCALE_BUF_SIZE] = {\n");
-
-  for (i = 0; i < CURRENT_SUPPORT_MAX; i++)
-    {
-      if(i)
-	fprintf (fout, ",\n");
-      fprintf (fout, "\t/* 0x%02x, %d, 0%o */\t", i, i, i);
-      if (x2type[i])
-	{
-	  int dirty = 0;
-	  bbits_t *tb = basic_bits;
-
-	  while (tb->bbits)
-	    {
-	      if (x2type[i] & tb->bbits)
-		{
-		  if (dirty)
-		    fputs ("|", fout);
-		  fputs (tb->bb_name, fout);
-		  dirty = 1;
-		}
-	      tb++;
-	    }
-	}
-      else
-	fputs ("0", fout);
-    }
-
-  fputs (",\n\n", fout);
-
-  fprintf (fout, "/* _uc_ctype_trans_C */\n\n");
-
-  for (i = 0; i < CURRENT_SUPPORT_MAX; i++)
-    {
-      if(i)
-	fprintf (fout, ",\n");
-      fprintf (fout, "\t/* 0x%02x, %d, 0%o */\t0x%02x", i, i, i, x2trans[i]);
-    }
-  fputs ("\n};\n", fout);
-
-  (void) fclose (fout);
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  int i,l;
-  char *outname = DEF_OUT_NAME;
-  char *search_dir = DEFAULT_LOCALE_DIR;
-  char *full_path = 0;
-  DIR *dir;
-  struct dirent *next;
-  char *t;
-  int  err=0;
-  char *ln;
-  int  generate_c_code = 1;
-
-  while ((i = getopt (argc, argv, "d:o:c")) != EOF) {
-      switch (i) {
-	case 'o':
-	  outname = optarg;
-	  break;
-	case 'd':
-	  search_dir = optarg;
-	  break;
-	case 'c':
-	  generate_c_code = 0;
-	  break;
-	default:
-	  optind = i = -1;
-	  break;
-	}
-	if(i<0)
-	  break;
-    }
-
-  if (argc > optind) {
-      fprintf (stderr,
-"Usage: %s [-d search_dir] [-o output_name] [-c]\n\
-Defaults:\n\
-  search_dir  : " DEFAULT_LOCALE_DIR "\n\
-  output_name : " DEF_OUT_NAME "\n\
-  -c          : no generate c-code for other locale exept C-locale.\n"
-					, argv[0]);
-      return 3;
-  }
-
-  l = strlen(search_dir);
-  if(l == 0) {
-	search_dir = "./";
-	l = 2;
-  } else {
-	if(search_dir[l-1]!='/') {
-
-		t = malloc(l+2);
-		if(t==0) {
-			fprintf (stderr, "Can`t get %d bytes memory\n", l+2);
-			return 4;
-		}
-		search_dir = strcat(strcpy(t, search_dir), "/");
-		l++;
-	}
-  }
-
-  dir = opendir(search_dir);
-  if (!dir) {
-      fprintf (stderr, "Can`t open directory `%s' load all locales\n", search_dir);
-      return 2;
-  }
-
-  while ((next = readdir(dir)) != NULL) {
-
-      struct stat st;
-      if(strcmp(next->d_name, ".")==0)
-	ln = "C";
-      else if(strcmp(next->d_name, "..")==0)
-	continue;
-      else {
-	ln = next->d_name;
-	full_path = realloc(full_path, l+strlen(ln)+1);
-	strcat(strcpy(full_path, search_dir), ln);
-	if (lstat(full_path, &st) < 0)
-		continue;
-	if(S_ISDIR(st.st_mode)==0)
-		continue;
-	}
-      t = setlocale(LC_CTYPE, ln);
-      printf("setlocale(LC_CTYPE, %s) returned %s\n", ln, t);
-      if(t==0)
-		continue;
-      if(mkdir(ln, 0755)!=0 && errno!=EEXIST) {
-		fprintf(stderr, "Can`t create directory `%s'\n", ln);
-		continue;
-      }
-      if(chdir(ln)) {
-		fprintf(stderr, "Can`t change directory to `%s'\n", ln);
-		continue;
-      }
-
-      for (i = 0; i < CURRENT_SUPPORT_MAX; i++) {
-
-	if(isprint(i))
-		x2type[i] |= ISprint;
-	if(isupper(i))
-		x2type[i] |= ISupper;
-	if(islower(i))
-		x2type[i] |= ISlower;
-	if(isspace(i))
-		x2type[i] |= ISspace;
-	if(isalpha(i))
-		x2type[i] |= ISalpha;
-	if(iscntrl(i))
-		x2type[i] |= IScntrl;
-	if(ispunct(i))
-		x2type[i] |= ISpunct;
-	if(isxdigit(i))
-		x2type[i] |= ISxdigit;
-	x2trans[i] = i;
-	if(toupper(x2trans[i]) != x2trans[i])
-		x2trans[i] = toupper(x2trans[i]);
-	else if(tolower(x2trans[i]) != x2trans[i])
-		x2trans[i] = tolower(x2trans[i]);
-      }
-      err += write_out(outname);
-      if(chdir("..")) {
-	fprintf(stderr, "Can`t change directory to `..'\n");
-	return 1;
-      }
-      if(strcmp(ln, "C")==0 || generate_c_code!=0)
-	ctab_out(ln);
-      for (i = 0; i < CURRENT_SUPPORT_MAX; i++)
-	x2type[i] = x2trans[i] = 0;
-  }
-  return err ? 1 : 0;
-}

+ 1254 - 0
extra/locale/gen_locale.c

@@ -0,0 +1,1254 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <locale.h>
+#include <langinfo.h>
+#include <nl_types.h>
+#include <stdint.h>
+
+#define __CTYPE_HAS_8_BIT_LOCALES
+#include "c8tables.h"
+
+
+#define CATEGORIES 6
+
+/* must agree with ordering of gen_mmap! */
+static const unsigned char *lc_names[] = {
+	"LC_CTYPE",
+	"LC_NUMERIC",
+	"LC_MONETARY",
+	"LC_TIME",
+	"LC_COLLATE",
+	"LC_MESSAGES",
+#if CATEGORIES == 12
+	"LC_PAPER",
+	"LC_NAME",
+	"LC_ADDRESS",
+	"LC_TELEPHONE",
+	"LC_MEASUREMENT",
+	"LC_IDENTIFICATION",
+#elif CATEGORIES != 6
+#error unsupported CATEGORIES value!
+#endif
+};
+
+
+
+typedef struct {
+	char *glibc_name;
+	char name[5];
+	char dot_cs;				/* 0 if no codeset specified */
+	char cs;
+	unsigned char idx_name;
+	unsigned char lc_time_row;
+	unsigned char lc_numeric_row;
+	unsigned char lc_monetary_row;
+	unsigned char lc_messages_row;
+#if CATEGORIES != 6
+#error unsupported CATEGORIES value
+#endif
+} locale_entry;
+
+static void read_at_mappings(void);
+static void read_enable_disable(void);
+static void read_locale_list(void);
+
+static int find_codeset_num(const char *cs);
+static int find_at_string_num(const char *as);
+static int le_cmp(const void *, const void *);
+static void dump_table8(const char *name, const char *tbl, int len);
+static void dump_table8c(const char *name, const char *tbl, int len);
+static void dump_table16(const char *name, const int *tbl, int len);
+
+static void do_lc_time(void);
+static void do_lc_numeric(void);
+static void do_lc_monetary(void);
+
+static void do_lc_messages(void);
+
+
+static FILE *fp;
+static FILE *ofp;
+static char line_buf[80];
+static char at_mappings[256];
+static char at_mapto[256];
+static char at_strings[1024];
+static char *at_strings_end;
+static locale_entry locales[700];
+static char glibc_locale_names[60000];
+
+static int num_locales;
+
+static int default_utf8;
+static int default_8bit;
+
+static int total_size;
+static int null_count;
+
+static void do_locale_names(void)
+{
+	/* "C" locale name is handled specially by the setlocale code. */
+	int uniq = 0;
+	int i;
+
+	if (num_locales <= 1) {
+/*  		printf("error - only C locale?\n"); */
+/*  		exit(EXIT_FAILURE); */
+		fprintf(ofp, "static const unsigned char __locales[%d];\n", (3 + CATEGORIES));
+		fprintf(ofp, "static const unsigned char __locale_names5[5];\n");
+	} else {
+		fprintf(ofp, "#define CATEGORIES\t\t\t%d\n", CATEGORIES);
+		fprintf(ofp, "#define WIDTH_LOCALES\t\t\t%d\n", 3+CATEGORIES);
+		fprintf(ofp, "#define NUM_LOCALES\t\t\t%d\n", num_locales);
+		fprintf(ofp, "static const unsigned char __locales[%d] = {\n",
+				(num_locales) * (3 + CATEGORIES));
+		for (i=0 ; i < num_locales ; i++) {
+			if (memcmp(locales[i].name, locales[i-1].name, 5) != 0) {
+				locales[i].idx_name = uniq;
+				++uniq;
+			} else {
+				locales[i].idx_name = uniq - 1;
+			}
+			fprintf(ofp, "\t%#4x, ", (int)((unsigned char) locales[i].idx_name));
+			fprintf(ofp, "\t%#4x, ", (int)((unsigned char) locales[i].dot_cs));
+			fprintf(ofp, "\t%#4x, ", (int)((unsigned char) locales[i].cs));
+			/* lc_ctype would store translit flags and turkish up/low flag. */
+			fprintf(ofp, "%#4x, ", 0); /* place holder for lc_ctype */
+			fprintf(ofp, "%#4x, ", (int)((unsigned char) locales[i].lc_numeric_row));
+			fprintf(ofp, "%#4x, ", (int)((unsigned char) locales[i].lc_monetary_row));
+			fprintf(ofp, "%#4x, ", (int)((unsigned char) locales[i].lc_time_row));
+			fprintf(ofp, "%#4x, ", 0); /* place holder for lc_collate */
+			fprintf(ofp, "%#4x, ", (int)((unsigned char) locales[i].lc_messages_row));
+			fprintf(ofp, "\t/* %s */\n", locales[i].glibc_name);
+		}
+		fprintf(ofp, "};\n\n");
+
+		fprintf(ofp, "#define NUM_LOCALE_NAMES\t\t%d\n", uniq );
+		fprintf(ofp, "static const unsigned char __locale_names5[%d] = \n\t", uniq * 5);
+		uniq = 0;
+		for (i=1 ; i < num_locales ; i++) {
+			if (memcmp(locales[i].name, locales[i-1].name, 5) != 0) {
+				fprintf(ofp, "\"%5.5s\" ", locales[i].name);
+				++uniq;
+				if ((uniq % 8) == 0) {
+					fprintf(ofp, "\n\t");
+				}
+			}
+		}
+		fprintf(ofp,";\n\n");
+
+		if (at_strings_end > at_strings) {
+			int i, j;
+			char *p;
+			i = 0;
+			p = at_strings;
+			while (*p) {
+				++i;
+				p += 1 + (unsigned char) *p;
+			}
+			/* len, char, string\0 */
+			fprintf(ofp, "#define LOCALE_AT_MODIFIERS_LENGTH\t\t%d\n",
+					i + (at_strings_end - at_strings));
+			fprintf(ofp, "static const unsigned char __locale_at_modifiers[%d] = {",
+					i + (at_strings_end - at_strings));
+			i = 0;
+			p = at_strings;
+			while (*p) {
+				fprintf(ofp, "\n\t%4d, '%c',",
+						(unsigned char) *p, /* len of string\0 */
+						at_mapto[i]);
+				for (j=1 ; j < ((unsigned char) *p) ; j++) {
+					fprintf(ofp, " '%c',", p[j]);
+				}
+				fprintf(ofp, " 0,");
+				++i;
+				p += 1 + (unsigned char) *p;
+			}
+			fprintf(ofp, "\n};\n\n");
+		}
+
+		{
+			int pos[CATEGORIES];
+			pos[0] = CATEGORIES;
+			for (i=0 ; i < CATEGORIES ; i++) {
+				fprintf(ofp, "#define __%s\t\t%d\n", lc_names[i], i);
+				if (i + 1 < CATEGORIES) {
+					pos[i+1] = 1 + strlen(lc_names[i]) + pos[i];
+				}
+			}
+			if (pos[CATEGORIES-1] > 255) {
+				printf("error - lc_names is too big (%d)\n", pos[CATEGORIES-1]);
+				exit(EXIT_FAILURE);
+			}
+			fprintf(ofp, "#define __LC_ALL\t\t%d\n\n", i);
+
+			fprintf(ofp, "#define lc_names_LEN\t\t%d\n",
+					pos[CATEGORIES-1] + strlen(lc_names[CATEGORIES-1]) + 1);
+			total_size += pos[CATEGORIES-1] + strlen(lc_names[CATEGORIES-1]) + 1;
+
+			fprintf(ofp, "static unsigned const char lc_names[%d] =\n",
+					pos[CATEGORIES-1] + strlen(lc_names[CATEGORIES-1]) + 1);
+			fprintf(ofp, "\t\"");
+			for (i=0 ; i < CATEGORIES ; i++) {
+				fprintf(ofp, "\\x%02x", (unsigned char) pos[i]);
+			}
+			fprintf(ofp, "\"");
+			for (i=0 ; i < CATEGORIES ; i++) {
+				fprintf(ofp, "\n\t\"%s\\0\"", lc_names[i]);
+			}
+			fprintf(ofp, ";\n\n");
+		}
+
+		printf("locale data = %d  name data = %d for %d uniq\n",
+			   num_locales * (3 + CATEGORIES), uniq * 5, uniq);
+
+		total_size += num_locales * (3 + CATEGORIES) + uniq * 5;
+	}
+
+}
+
+int main(int argc, char **argv)
+{
+	if ((argc != 2) || (!(fp = fopen(*++argv, "r")))) {
+		printf("error: missing filename or file!\n");
+		return EXIT_FAILURE;
+	}
+
+	at_strings_end = at_strings;
+
+	read_at_mappings();
+	read_enable_disable();
+	read_locale_list();
+
+	fclose(fp);
+
+	/* handle C locale specially */
+	qsort(locales+1, num_locales-1, sizeof(locale_entry), le_cmp);
+
+#if 0
+	for (i=0 ; i < num_locales ; i++) {
+		printf("locale: %5.5s %2d %2d %s\n",
+			   locales[i].name,
+			   locales[i].cs,
+			   locales[i].dot_cs,
+			   locales[i].glibc_name
+			   );
+	}
+#endif
+
+	if (!(ofp = fopen("locale_tables.h", "w"))) {
+		printf("error: can not open locale_tables.h for writing!\n");
+		return EXIT_FAILURE;
+	}
+
+	do_lc_time();
+	do_lc_numeric();
+	do_lc_monetary();
+	do_lc_messages();
+
+	do_locale_names();
+
+	fclose(ofp);
+
+	printf("total data size = %d\n", total_size);
+	printf("null count = %d\n", null_count);
+
+	return EXIT_SUCCESS;
+}
+
+static char *idx[10000];
+static char buf[100000];
+static char *last;
+static int uniq;
+
+static int addstring(const char *s)
+{
+	int j;
+	size_t l;
+
+	if (!s) {
+		++null_count;
+		return 0;
+	}
+
+	for (j=0 ; j < uniq ; j++) {
+		if (!strcmp(s, idx[j])) {
+			return idx[j] - buf;
+		}
+	}
+	if (uniq >= sizeof(idx)) {
+		printf("too many uniq strings!\n");
+		exit(EXIT_FAILURE);
+	}
+	l = strlen(s) + 1;
+	if (last + l >= buf + sizeof(buf)) {
+		printf("need to increase size of buf!\n");
+		exit(EXIT_FAILURE);
+	}
+
+	idx[uniq] = last;
+	++uniq;
+	strcpy(last, s);
+	last += l;
+	return idx[uniq - 1] - buf;
+}
+
+static int buf16[50*256];
+
+
+static int lc_time_item[50][256];
+static int lc_time_count[50];
+static unsigned char lc_time_uniq_50[700][50];
+static int lc_time_uniq;
+
+#define DO_NL_S(X)	lc_time_S(X, k++)
+
+static void lc_time_S(int X, int k)
+{
+	int j, m;
+	j = addstring(nl_langinfo(X));
+	for (m=0 ; m < lc_time_count[k] ; m++) {
+		if (lc_time_item[k][m] == j) {
+			break;
+		}
+	}
+	if (m == lc_time_count[k]) { /* new for this nl_item */
+		if (m > 255) {
+			printf("too many nl_item %d entries in lc_time\n", k);
+			exit(EXIT_FAILURE);
+		}
+		lc_time_item[k][m] = j;
+		++lc_time_count[k];
+	}
+/*  	printf("\\x%02x", m); */
+	lc_time_uniq_50[lc_time_uniq][k] = m;
+}
+
+static void do_lc_time(void)
+{
+	int i, k, m;
+
+	last = buf+1;
+	uniq = 1;
+	*buf = 0;
+	*idx = buf;
+
+/*  	printf("processing lc_time..."); */
+	for (i=0 ; i < num_locales ; i++) {
+		k = 0;
+
+/*  		printf(" %d", i); fflush(stdout); */
+		if (!setlocale(LC_ALL, locales[i].glibc_name)) {
+			printf("setlocale(LC_ALL,%s) failed!\n",
+				   locales[i].glibc_name);
+		}
+
+		DO_NL_S(ABDAY_1);
+		DO_NL_S(ABDAY_2);
+		DO_NL_S(ABDAY_3);
+		DO_NL_S(ABDAY_4);
+		DO_NL_S(ABDAY_5);
+		DO_NL_S(ABDAY_6);
+		DO_NL_S(ABDAY_7);
+
+		DO_NL_S(DAY_1);
+		DO_NL_S(DAY_2);
+		DO_NL_S(DAY_3);
+		DO_NL_S(DAY_4);
+		DO_NL_S(DAY_5);
+		DO_NL_S(DAY_6);
+		DO_NL_S(DAY_7);
+
+		DO_NL_S(ABMON_1);
+		DO_NL_S(ABMON_2);
+		DO_NL_S(ABMON_3);
+		DO_NL_S(ABMON_4);
+		DO_NL_S(ABMON_5);
+		DO_NL_S(ABMON_6);
+		DO_NL_S(ABMON_7);
+		DO_NL_S(ABMON_8);
+		DO_NL_S(ABMON_9);
+		DO_NL_S(ABMON_10);
+		DO_NL_S(ABMON_11);
+		DO_NL_S(ABMON_12);
+
+		DO_NL_S(MON_1);
+		DO_NL_S(MON_2);
+		DO_NL_S(MON_3);
+		DO_NL_S(MON_4);
+		DO_NL_S(MON_5);
+		DO_NL_S(MON_6);
+		DO_NL_S(MON_7);
+		DO_NL_S(MON_8);
+		DO_NL_S(MON_9);
+		DO_NL_S(MON_10);
+		DO_NL_S(MON_11);
+		DO_NL_S(MON_12);
+
+		DO_NL_S(AM_STR);
+		DO_NL_S(PM_STR);
+
+		DO_NL_S(D_T_FMT);
+		DO_NL_S(D_FMT);
+		DO_NL_S(T_FMT);
+		DO_NL_S(T_FMT_AMPM);
+		DO_NL_S(ERA);
+
+		DO_NL_S(ERA_YEAR);		/* non SuSv3 */
+		DO_NL_S(ERA_D_FMT);
+		DO_NL_S(ALT_DIGITS);
+		DO_NL_S(ERA_D_T_FMT);
+		DO_NL_S(ERA_T_FMT);
+
+		if (k > 50) {
+			printf("error -- lc_time nl_item count > 50!\n");
+			exit(EXIT_FAILURE);
+		}
+
+		{
+			int r;
+			for (r=0 ; r < lc_time_uniq ; r++) {
+				if (!memcmp(lc_time_uniq_50[lc_time_uniq],
+							lc_time_uniq_50[r], 50)) {
+					break;
+				}
+			}
+			if (r == lc_time_uniq) { /* new locale row */
+				++lc_time_uniq;
+				if (lc_time_uniq > 255) {
+					printf("too many unique lc_time rows!\n");
+					exit(EXIT_FAILURE);
+				}
+			}
+			locales[i].lc_time_row = r;
+		}
+/*  		printf("\n"); */
+	}
+/*  	printf(" done\n"); */
+
+	m = k = 0;
+	for (i=0 ; i < 50 ; i++) {
+		k += lc_time_count[i];
+		if (m < lc_time_count[i]) {
+			m = lc_time_count[i];
+		}
+	}
+	printf("buf-size=%d  uniq=%d  item_offsets=%d  max=%d  rows=%d\n",
+		   (int)(last - buf), uniq, k, m, lc_time_uniq);
+/*  	printf("total = %d * 50 + 2 * (50 + %d) + %d = %d\n", */
+/*  		   num_locales, k, (int)(last - buf), */
+/*  		   num_locales*50 + 2*(50 + k) + (int)(last - buf)); */
+	printf("total = %d + %d * 50 + 2 * (50 + %d) + %d = %d\n",
+		   num_locales, lc_time_uniq, k, (int)(last - buf),
+		   i = num_locales + lc_time_uniq*50 + 2*(50 + k) + (int)(last - buf));
+	total_size += i;
+
+	dump_table8c("__lc_time_data", buf, (int)(last - buf));
+
+	for (i=0 ; i < lc_time_uniq ; i++) {
+		m = locales[i].lc_time_row;
+		for (k=0 ; k < 50 ; k++) {
+			buf[50*i + k] = (char)((unsigned char) lc_time_uniq_50[i][k]);
+		}
+	}
+	dump_table8("__lc_time_rows", buf, lc_time_uniq * 50);
+
+	buf16[0] =0;
+	for (i=0 ; i < 50 - 1 ; i++) {
+		buf16[i+1] = buf16[i] + lc_time_count[i];
+	}
+	dump_table16("__lc_time_item_offsets", buf16, 50);
+
+	m = 0;
+	for (k=0 ; k < 50 ; k++) {
+		for (i=0 ; i < lc_time_count[k] ; i++) {
+			buf16[m] = lc_time_item[k][i];
+			++m;
+		}
+	}
+	dump_table16("__lc_time_item_idx", buf16, m);
+}
+
+static void dump_table8(const char *name, const char *tbl, int len)
+{
+	int i;
+
+	fprintf(ofp, "#define %s_LEN\t\t%d\n", name, len);
+	fprintf(ofp, "static const unsigned char %s[%d] = {", name, len);
+	for (i=0 ; i < len ; i++) {
+		if ((i % 12) == 0) {
+			fprintf(ofp, "\n\t");
+		}
+		fprintf(ofp, "%#4x, ", (int)((unsigned char) tbl[i]));
+	}
+	fprintf(ofp, "\n};\n\n");
+}
+
+#define __C_isdigit(c) \
+	((sizeof(c) == sizeof(char)) \
+	 ? (((unsigned char)((c) - '0')) < 10) \
+	 : (((unsigned int)((c) - '0')) < 10))
+#define __C_isalpha(c) \
+	((sizeof(c) == sizeof(char)) \
+	 ? (((unsigned char)(((c) | 0x20) - 'a')) < 26) \
+	 : (((unsigned int)(((c) | 0x20) - 'a')) < 26))
+#define __C_isalnum(c) (__C_isalpha(c) || __C_isdigit(c))
+
+static void dump_table8c(const char *name, const char *tbl, int len)
+{
+	int i;
+
+	fprintf(ofp, "#define %s_LEN\t\t%d\n", name, len);
+	fprintf(ofp, "static const unsigned char %s[%d] = {", name, len);
+	for (i=0 ; i < len ; i++) {
+		if ((i % 12) == 0) {
+			fprintf(ofp, "\n\t");
+		}
+		if (__C_isalnum(tbl[i]) || (tbl[i] == ' ')) {
+			fprintf(ofp, " '%c', ", (int)((unsigned char) tbl[i]));
+		} else {
+			fprintf(ofp, "%#4x, ", (int)((unsigned char) tbl[i]));
+		}
+	}
+	fprintf(ofp, "\n};\n\n");
+}
+
+static void dump_table16(const char *name, const int *tbl, int len)
+{
+	int i;
+
+	fprintf(ofp, "#define %s_LEN\t\t%d\n", name, len);
+	fprintf(ofp, "static const uint16_t %s[%d] = {", name, len);
+	for (i=0 ; i < len ; i++) {
+		if ((i % 8) == 0) {
+			fprintf(ofp, "\n\t");
+		}
+		if (tbl[i] != (uint16_t) tbl[i]) {
+			printf("error - falls outside uint16 range!\n");
+			exit(EXIT_FAILURE);
+		}
+		fprintf(ofp, "%#6x, ", tbl[i]);
+	}
+	fprintf(ofp, "\n};\n\n");
+}
+
+#undef DO_NL_S
+
+static int lc_numeric_item[3][256];
+static int lc_numeric_count[3];
+static unsigned char lc_numeric_uniq_3[700][3];
+static int lc_numeric_uniq;
+
+#define DO_NL_S(X)	lc_numeric_S(X, k++)
+
+static void lc_numeric_S(int X, int k)
+{
+	int j, m;
+	j = addstring(nl_langinfo(X));
+	for (m=0 ; m < lc_numeric_count[k] ; m++) {
+		if (lc_numeric_item[k][m] == j) {
+			break;
+		}
+	}
+	if (m == lc_numeric_count[k]) { /* new for this nl_item */
+		if (m > 255) {
+			printf("too many nl_item %d entries in lc_numeric\n", k);
+			exit(EXIT_FAILURE);
+		}
+		lc_numeric_item[k][m] = j;
+		++lc_numeric_count[k];
+	}
+/*  	printf("\\x%02x", m); */
+	lc_numeric_uniq_3[lc_numeric_uniq][k] = m;
+}
+
+static void do_lc_numeric(void)
+{
+	int i, k, m;
+
+	last = buf+1;
+	uniq = 1;
+	*buf = 0;
+	*idx = buf;
+
+	for (i=0 ; i < num_locales ; i++) {
+		k = 0;
+
+		if (!setlocale(LC_ALL, locales[i].glibc_name)) {
+			printf("setlocale(LC_ALL,%s) failed!\n",
+				   locales[i].glibc_name);
+		}
+
+		DO_NL_S(RADIXCHAR);		/* DECIMAL_POINT */
+		DO_NL_S(THOUSEP);		/* THOUSANDS_SEP */
+		DO_NL_S(GROUPING);
+
+		if (k > 3) {
+			printf("error -- lc_numeric nl_item count > 3!\n");
+			exit(EXIT_FAILURE);
+		}
+
+		{
+			int r;
+			for (r=0 ; r < lc_numeric_uniq ; r++) {
+				if (!memcmp(lc_numeric_uniq_3[lc_numeric_uniq],
+							lc_numeric_uniq_3[r], 3)) {
+					break;
+				}
+			}
+			if (r == lc_numeric_uniq) { /* new locale row */
+				++lc_numeric_uniq;
+				if (lc_numeric_uniq > 255) {
+					printf("too many unique lc_numeric rows!\n");
+					exit(EXIT_FAILURE);
+				}
+			}
+			locales[i].lc_numeric_row = r;
+		}
+	}
+
+	printf("buf-size=%d  uniq=%d  rows=%d\n",
+		   (int)(last - buf), uniq, lc_numeric_uniq);
+	printf("total = %d + %d * 3 + %d = %d\n",
+		   num_locales, lc_numeric_uniq, (int)(last - buf),
+		   i = num_locales + lc_numeric_uniq*3 + (int)(last - buf));
+	total_size += i;
+
+/*  	printf("buf-size=%d  uniq=%d\n", (int)(last - buf), uniq); */
+
+	dump_table8c("__lc_numeric_data", buf, (int)(last - buf));
+
+
+	for (i=0 ; i < lc_numeric_uniq ; i++) {
+		m = locales[i].lc_numeric_row;
+		for (k=0 ; k < 3 ; k++) {
+			buf[3*i + k] = (char)((unsigned char) lc_numeric_uniq_3[i][k]);
+		}
+	}
+	dump_table8("__lc_numeric_rows", buf, lc_numeric_uniq * 3);
+
+	buf16[0] =0;
+	for (i=0 ; i < 3 - 1 ; i++) {
+		buf16[i+1] = buf16[i] + lc_numeric_count[i];
+	}
+	dump_table16("__lc_numeric_item_offsets", buf16, 3);
+
+	m = 0;
+	for (k=0 ; k < 3 ; k++) {
+		for (i=0 ; i < lc_numeric_count[k] ; i++) {
+			buf16[m] = lc_numeric_item[k][i];
+			++m;
+		}
+	}
+	dump_table16("__lc_numeric_item_idx", buf16, m);
+}
+
+#undef DO_NL_S
+
+/*  #define NUM_NL_MONETARY 7 */
+#define NUM_NL_MONETARY (7+14+1)
+
+static int lc_monetary_item[NUM_NL_MONETARY][256];
+static int lc_monetary_count[NUM_NL_MONETARY];
+static unsigned char lc_monetary_uniq_X[700][NUM_NL_MONETARY];
+static int lc_monetary_uniq;
+
+#define DO_NL_S(X)	lc_monetary_S(X, k++)
+
+/*  #define DO_NL_C(X)		printf("%#02x", (int)(unsigned char)(*nl_langinfo(X))); */
+#define DO_NL_C(X) lc_monetary_C(X, k++)
+
+static void lc_monetary_C(int X, int k)
+{
+	int j, m;
+	char c_buf[2];
+
+#warning fix the char entries for monetary... target signedness of char may be different!
+
+	c_buf[1] = 0;
+	c_buf[0] = *nl_langinfo(X);
+	j = addstring(c_buf);
+	for (m=0 ; m < lc_monetary_count[k] ; m++) {
+		if (lc_monetary_item[k][m] == j) {
+			break;
+		}
+	}
+	if (m == lc_monetary_count[k]) { /* new for this nl_item */
+		if (m > 255) {
+			printf("too many nl_item %d entries in lc_monetary\n", k);
+			exit(EXIT_FAILURE);
+		}
+		lc_monetary_item[k][m] = j;
+		++lc_monetary_count[k];
+	}
+/*  	printf("\\x%02x", m); */
+	lc_monetary_uniq_X[lc_monetary_uniq][k] = m;
+}
+
+
+static void lc_monetary_S(int X, int k)
+{
+	int j, m;
+	j = addstring(nl_langinfo(X));
+	for (m=0 ; m < lc_monetary_count[k] ; m++) {
+		if (lc_monetary_item[k][m] == j) {
+			break;
+		}
+	}
+	if (m == lc_monetary_count[k]) { /* new for this nl_item */
+		if (m > 255) {
+			printf("too many nl_item %d entries in lc_monetary\n", k);
+			exit(EXIT_FAILURE);
+		}
+		lc_monetary_item[k][m] = j;
+		++lc_monetary_count[k];
+	}
+/*  	printf("\\x%02x", m); */
+	lc_monetary_uniq_X[lc_monetary_uniq][k] = m;
+}
+
+static void do_lc_monetary(void)
+{
+	int i, k, m;
+
+	last = buf+1;
+	uniq = 1;
+	*buf = 0;
+	*idx = buf;
+
+	for (i=0 ; i < num_locales ; i++) {
+		k = 0;
+
+		if (!setlocale(LC_ALL, locales[i].glibc_name)) {
+			printf("setlocale(LC_ALL,%s) failed!\n",
+				   locales[i].glibc_name);
+		}
+
+
+		/* non SUSv3 */
+		DO_NL_S(INT_CURR_SYMBOL);
+		DO_NL_S(CURRENCY_SYMBOL);
+		DO_NL_S(MON_DECIMAL_POINT);
+		DO_NL_S(MON_THOUSANDS_SEP);
+		DO_NL_S(MON_GROUPING);
+		DO_NL_S(POSITIVE_SIGN);
+		DO_NL_S(NEGATIVE_SIGN);
+		DO_NL_C(INT_FRAC_DIGITS);
+		DO_NL_C(FRAC_DIGITS);
+		DO_NL_C(P_CS_PRECEDES);
+		DO_NL_C(P_SEP_BY_SPACE);
+		DO_NL_C(N_CS_PRECEDES);
+		DO_NL_C(N_SEP_BY_SPACE);
+		DO_NL_C(P_SIGN_POSN);
+		DO_NL_C(N_SIGN_POSN);
+		DO_NL_C(INT_P_CS_PRECEDES);
+		DO_NL_C(INT_P_SEP_BY_SPACE);
+		DO_NL_C(INT_N_CS_PRECEDES);
+		DO_NL_C(INT_N_SEP_BY_SPACE);
+		DO_NL_C(INT_P_SIGN_POSN);
+		DO_NL_C(INT_N_SIGN_POSN);
+
+		DO_NL_S(CRNCYSTR);		/* CURRENCY_SYMBOL */
+
+/*  		printf("\n"); */
+
+		if (k > NUM_NL_MONETARY) {
+			printf("error -- lc_monetary nl_item count > %d!\n", NUM_NL_MONETARY);
+			exit(EXIT_FAILURE);
+		}
+
+		{
+			int r;
+			for (r=0 ; r < lc_monetary_uniq ; r++) {
+				if (!memcmp(lc_monetary_uniq_X[lc_monetary_uniq],
+							lc_monetary_uniq_X[r], NUM_NL_MONETARY)) {
+					break;
+				}
+			}
+			if (r == lc_monetary_uniq) { /* new locale row */
+				++lc_monetary_uniq;
+				if (lc_monetary_uniq > 255) {
+					printf("too many unique lc_monetary rows!\n");
+					exit(EXIT_FAILURE);
+				}
+			}
+			locales[i].lc_monetary_row = r;
+		}
+	}
+
+	printf("buf-size=%d  uniq=%d  rows=%d\n",
+		   (int)(last - buf), uniq, lc_monetary_uniq);
+	printf("total = %d + %d * %d + %d = %d\n",
+		   num_locales, lc_monetary_uniq, NUM_NL_MONETARY, (int)(last - buf),
+		   i = num_locales + lc_monetary_uniq*NUM_NL_MONETARY + (int)(last - buf));
+	total_size += i;
+
+	dump_table8c("__lc_monetary_data", buf, (int)(last - buf));
+
+	for (i=0 ; i < lc_monetary_uniq ; i++) {
+		m = locales[i].lc_monetary_row;
+		for (k=0 ; k < NUM_NL_MONETARY ; k++) {
+			buf[NUM_NL_MONETARY*i + k] = (char)((unsigned char) lc_monetary_uniq_X[i][k]);
+		}
+	}
+	dump_table8("__lc_monetary_rows", buf, lc_monetary_uniq * NUM_NL_MONETARY);
+
+	buf16[0] =0;
+	for (i=0 ; i < NUM_NL_MONETARY - 1 ; i++) {
+		buf16[i+1] = buf16[i] + lc_monetary_count[i];
+	}
+	dump_table16("__lc_monetary_item_offsets", buf16, NUM_NL_MONETARY);
+
+	m = 0;
+	for (k=0 ; k < NUM_NL_MONETARY ; k++) {
+		for (i=0 ; i < lc_monetary_count[k] ; i++) {
+			buf16[m] = lc_monetary_item[k][i];
+			++m;
+		}
+	}
+	dump_table16("__lc_monetary_item_idx", buf16, m);
+}
+
+
+#undef DO_NL_S
+
+static int lc_messages_item[2][256];
+static int lc_messages_count[2];
+static unsigned char lc_messages_uniq_2[700][2];
+static int lc_messages_uniq;
+
+#define DO_NL_S(X)	lc_messages_S(X, k++)
+
+static void lc_messages_S(int X, int k)
+{
+	int j, m;
+	j = addstring(nl_langinfo(X));
+	for (m=0 ; m < lc_messages_count[k] ; m++) {
+		if (lc_messages_item[k][m] == j) {
+			break;
+		}
+	}
+	if (m == lc_messages_count[k]) { /* new for this nl_item */
+		if (m > 255) {
+			printf("too many nl_item %d entries in lc_messages\n", k);
+			exit(EXIT_FAILURE);
+		}
+		lc_messages_item[k][m] = j;
+		++lc_messages_count[k];
+	}
+/*  	printf("\\x%02x", m); */
+	lc_messages_uniq_2[lc_messages_uniq][k] = m;
+}
+
+static void do_lc_messages(void)
+{
+	int i, k, m;
+
+	last = buf+1;
+	uniq = 1;
+	*buf = 0;
+	*idx = buf;
+
+	for (i=0 ; i < num_locales ; i++) {
+		k = 0;
+
+		if (!setlocale(LC_ALL, locales[i].glibc_name)) {
+			printf("setlocale(LC_ALL,%s) failed!\n",
+				   locales[i].glibc_name);
+		}
+
+		DO_NL_S(YESEXPR);
+		DO_NL_S(NOEXPR);
+
+		if (k > 2) {
+			printf("error -- lc_messages nl_item count > 2!\n");
+			exit(EXIT_FAILURE);
+		}
+
+		{
+			int r;
+			for (r=0 ; r < lc_messages_uniq ; r++) {
+				if (!memcmp(lc_messages_uniq_2[lc_messages_uniq],
+							lc_messages_uniq_2[r], 2)) {
+					break;
+				}
+			}
+			if (r == lc_messages_uniq) { /* new locale row */
+				++lc_messages_uniq;
+				if (lc_messages_uniq > 255) {
+					printf("too many unique lc_messages rows!\n");
+					exit(EXIT_FAILURE);
+				}
+			}
+			locales[i].lc_messages_row = r;
+		}
+	}
+
+	printf("buf-size=%d  uniq=%d  rows=%d\n",
+		   (int)(last - buf), uniq, lc_messages_uniq);
+	printf("total = %d + %d * 2 + %d = %d\n",
+		   num_locales, lc_messages_uniq, (int)(last - buf),
+		   i = num_locales + lc_messages_uniq*2 + (int)(last - buf));
+	total_size += i;
+
+/*  	printf("buf-size=%d  uniq=%d\n", (int)(last - buf), uniq); */
+
+	dump_table8c("__lc_messages_data", buf, (int)(last - buf));
+
+	for (i=0 ; i < lc_messages_uniq ; i++) {
+		m = locales[i].lc_messages_row;
+		for (k=0 ; k < 2 ; k++) {
+			buf[2*i + k] = (char)((unsigned char) lc_messages_uniq_2[i][k]);
+		}
+	}
+	dump_table8("__lc_messages_rows", buf, lc_messages_uniq * 2);
+
+	buf16[0] =0;
+	for (i=0 ; i < 2 - 1 ; i++) {
+		buf16[i+1] = buf16[i] + lc_messages_count[i];
+	}
+	dump_table16("__lc_messages_item_offsets", buf16, 2);
+
+	m = 0;
+	for (k=0 ; k < 2 ; k++) {
+		for (i=0 ; i < lc_messages_count[k] ; i++) {
+			buf16[m] = lc_messages_item[k][i];
+			++m;
+		}
+	}
+	dump_table16("__lc_messages_item_idx", buf16, m);
+}
+
+
+
+
+
+static void read_at_mappings(void)
+{
+	char *p;
+	char *m;
+	int mc = 0;
+
+	do {
+		if (!(p = strtok(line_buf, " \t\n")) || (*p == '#')) {
+			if (!fgets(line_buf, sizeof(line_buf), fp)) {
+				if (ferror(fp)) {
+					printf("error reading file\n");
+					exit(EXIT_FAILURE);
+				}
+				return;			/* EOF */
+			}
+			if ((*line_buf == '#') && (line_buf[1] == '-')) {
+				break;
+			}
+			continue;
+		}
+		if (*p == '@') {
+			if (p[1] == 0) {
+				printf("error: missing @modifier name\n");
+				exit(EXIT_FAILURE);
+			}
+			m = p;				/* save the modifier name */
+			if (!(p = strtok(NULL, " \t\n")) || p[1] || (((unsigned char) *p) > 0x7f)) {
+				printf("error: missing or illegal @modifier mapping char\n");
+				exit(EXIT_FAILURE);
+			}
+			if (at_mappings[(int)((unsigned char) *p)]) {
+				printf("error: reused @modifier mapping char\n");
+				exit(EXIT_FAILURE);
+			}
+			at_mappings[(int)((unsigned char) *p)] = 1;
+			at_mapto[mc] = *p;
+			++mc;
+			*at_strings_end = (char)( (unsigned char) (strlen(m)) );
+			strcpy(++at_strings_end, m+1);
+			at_strings_end += (unsigned char) at_strings_end[-1];
+
+			printf("@mapping: \"%s\" to '%c'\n", m, *p);
+
+			if (((p = strtok(NULL, " \t\n")) != NULL) && (*p != '#')) {
+				printf("ignoring trailing text: %s...\n", p);
+			}
+			*line_buf = 0;
+			continue;
+		}
+		break;
+	} while (1);
+
+#if 0
+	{
+		p = at_strings;
+		
+		if (!*p) {
+			printf("no @ strings\n");
+			return;
+		}
+		
+		do {
+			printf("%s\n", p+1);
+			p += 1 + (unsigned char) *p;
+		} while (*p);
+	}
+#endif
+}
+
+static void read_enable_disable(void)
+{
+	char *p;
+
+	do {
+		if (!(p = strtok(line_buf, " =\t\n")) || (*p == '#')) {
+			if (!fgets(line_buf, sizeof(line_buf), fp)) {
+				if (ferror(fp)) {
+					printf("error reading file\n");
+					exit(EXIT_FAILURE);
+				}
+				return;			/* EOF */
+			}
+			if ((*line_buf == '#') && (line_buf[1] == '-')) {
+				break;
+			}
+			continue;
+		}
+		if (!strcmp(p, "UTF-8")) {
+			if (!(p = strtok(NULL, " =\t\n"))
+				|| ((toupper(*p) != 'Y') && (toupper(*p) != 'N'))) {
+				printf("error: missing or illegal UTF-8 setting\n");
+				exit(EXIT_FAILURE);
+			}
+			default_utf8 = (toupper(*p) == 'Y');
+			printf("UTF-8 locales are %sabled\n", "dis\0en"+ (default_utf8 << 2));
+		} else if (!strcmp(p, "8-BIT")) {
+			if (!(p = strtok(NULL, " =\t\n"))
+				|| ((toupper(*p) != 'Y') && (toupper(*p) != 'N'))) {
+				printf("error: missing or illegal 8-BIT setting\n");
+				exit(EXIT_FAILURE);
+			}
+			default_8bit = (toupper(*p) == 'Y');
+			printf("8-BIT locales are %sabled\n", "dis\0en" + (default_8bit << 2));
+		} else {
+			break;
+		}
+
+		if (((p = strtok(NULL, " \t\n")) != NULL) && (*p != '#')) {
+			printf("ignoring trailing text: %s...\n", p);
+		}
+		*line_buf = 0;
+		continue;
+
+	} while (1);
+}
+
+#ifdef CODESET_LIST
+
+static int find_codeset_num(const char *cs)
+{
+	int r = 2;
+	char *s = CODESET_LIST;
+
+	/* 7-bit is 1, UTF-8 is 2, 8-bits are > 2 */
+
+	if (strcmp(cs, "UTF-8") != 0) {
+		++r;
+		while (*s && strcmp(CODESET_LIST+ ((unsigned char) *s), cs)) {
+/*  			printf("tried %s\n", CODESET_LIST + ((unsigned char) *s)); */
+			++r;
+			++s;
+		}
+		if (!*s) {
+			printf("error: unsupported codeset %s\n", cs);
+			exit(EXIT_FAILURE);
+		}
+	}
+	return r;
+}
+
+#else
+
+static int find_codeset_num(const char *cs)
+{
+	int r = 2;
+
+	/* 7-bit is 1, UTF-8 is 2, 8-bits are > 2 */
+
+	if (strcmp(cs, "UTF-8") != 0) {
+		printf("error: unsupported codeset %s\n", cs);
+		exit(EXIT_FAILURE);
+	}
+	return r;
+}
+
+#endif
+
+static int find_at_string_num(const char *as)
+{
+	int i = 0;
+	char *p = at_strings;
+
+	while (*p) {
+		if (!strcmp(p+1, as)) {
+			return i;
+		}
+		++i;
+		p += 1 + (unsigned char) *p;
+	}
+
+	printf("error: unmapped @string %s\n", as);
+	exit(EXIT_FAILURE);
+}
+
+static void read_locale_list(void)
+{
+	char *p;
+	char *s;
+	char *ln;					/* locale name */
+	char *ls;					/* locale name ll_CC */
+	char *as;					/* at string */
+	char *ds;					/* dot string */
+	char *cs;					/* codeset */
+	int i;
+
+	typedef struct {
+		char *glibc_name;
+		char name[5];
+		char dot_cs;				/* 0 if no codeset specified */
+		char cs;
+	} locale_entry;
+
+	/* First the C locale. */
+	locales[0].glibc_name = locales[0].name;
+	strncpy(locales[0].name,"C",5);
+	locales[0].dot_cs = 0;
+	locales[0].cs = 1;			/* 7-bit encoding */
+	++num_locales;
+
+	do {
+		if (!(p = strtok(line_buf, " \t\n")) || (*p == '#')) {
+			if (!fgets(line_buf, sizeof(line_buf), fp)) {
+				if (ferror(fp)) {
+					printf("error reading file\n");
+					exit(EXIT_FAILURE);
+				}
+				return;			/* EOF */
+			}
+			if ((*line_buf == '#') && (line_buf[1] == '-')) {
+				break;
+			}
+			continue;
+		}
+
+		s = glibc_locale_names;
+		for (i=0 ; i < num_locales ; i++) {
+			if (!strcmp(s+1, p)) {
+				break;
+			}
+			s += 1 + ((unsigned char) *s);
+		}
+		if (i < num_locales) {
+			printf("ignoring dulplicate locale name: %s", p);
+			*line_buf = 0;
+			continue;
+		}
+
+		/* New locale, but don't increment num until codeset verified! */
+		*s = (char)((unsigned char) (strlen(p) + 1));
+		strcpy(s+1, p);
+		locales[num_locales].glibc_name = s+1;
+		ln = p;					/* save locale name */
+
+		if (!(p = strtok(NULL, " \t\n"))) {
+			printf("error: missing codeset for locale %s\n", ln);
+			exit(EXIT_FAILURE);
+		}
+		cs = p;
+		i = find_codeset_num(p);
+		if ((i == 2) && !default_utf8) {
+			printf("ignoring UTF-8 locale %s\n", ln);
+			*line_buf = 0;
+			continue;
+		} else if ((i > 2) && !default_8bit) {	
+			printf("ignoring 8-bit codeset locale %s\n", ln);
+			*line_buf = 0;
+			continue;
+		}
+		locales[num_locales].cs = (char)((unsigned char) i);
+
+		if (((p = strtok(NULL, " \t\n")) != NULL) && (*p != '#')) {
+			printf("ignoring trailing text: %s...\n", p);
+		}
+
+		/* Now go back to locale string for .codeset and @modifier */
+		as = strtok(ln, "@");
+		if (as) {
+			as = strtok(NULL, "@");
+		}
+		ds = strtok(ln, ".");
+		if (ds) {
+			ds = strtok(NULL, ".");
+		}
+		ls = ln;
+
+		if ((strlen(ls) != 5) || (ls[2] != '_')) {
+			printf("error: illegal locale name %s\n", ls);
+			exit(EXIT_FAILURE);
+		}
+
+		i = 0;					/* value for unspecified codeset */
+		if (ds) {
+			i = find_codeset_num(ds);
+			if ((i == 2) && !default_utf8) {
+				printf("ignoring UTF-8 locale %s\n", ln);
+				*line_buf = 0;
+				continue;
+			} else if ((i > 2) && !default_8bit) {	
+				printf("ignoring 8-bit codeset locale %s\n", ln);
+				*line_buf = 0;
+				continue;
+			}
+		}
+		locales[num_locales].dot_cs = (char)((unsigned char) i);
+
+		if (as) {
+			i = find_at_string_num(as);
+			ls[2] = at_mapto[i];
+		}
+		memcpy(locales[num_locales].name, ls, 5);
+/*  		printf("locale: %5.5s %2d %2d %s\n", */
+/*  			   locales[num_locales].name, */
+/*  			   locales[num_locales].cs, */
+/*  			   locales[num_locales].dot_cs, */
+/*  			   locales[num_locales].glibc_name */
+/*  			   ); */
+		++num_locales;
+		*line_buf = 0;
+	} while (1);
+}
+
+static int le_cmp(const void *a, const void *b)
+{
+	const locale_entry *p;
+	const locale_entry *q;
+	int r;
+
+	p = (const locale_entry *) a;
+	q = (const locale_entry *) b;
+
+	if (!(r = p->name[0] - q->name[0])
+		&& !(r = p->name[1] - q->name[1])
+		&& !(r = p->name[3] - q->name[3])
+		&& !(r = p->name[4] - q->name[4])
+		&& !(r = p->name[2] - q->name[2])
+		&& !(r = -(p->cs - q->cs))
+		) {
+		r = -(p->dot_cs - q->dot_cs);
+		/* Reverse the ordering of the codesets so UTF-8 comes last.
+		 * Work-around (hopefully) for glibc bug affecting at least
+		 * the euro currency symbol. */
+	}
+
+	return r;
+}
+

+ 237 - 0
extra/locale/gen_mmap.c

@@ -0,0 +1,237 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdint.h>
+#include <stddef.h>
+
+#define WANT_DATA
+#include "c8tables.h"
+
+/*  #define Cctype_TBL_LEN 328 */
+/*  #define Cuplow_TBL_LEN 400 */
+/*  #define Cc2wc_TBL_LEN 1448 */
+/*  #define Cwc2c_TBL_LEN 3744 */
+
+#define WANT_WCctype_data
+#define WANT_WCuplow_data
+#define WANT_WCuplow_diff_data
+#define WANT_WCcomb_data
+/*  #define WANT_WCwidth_data */
+#include "wctables.h"
+#undef WANT_WCctype_data
+#undef WANT_WCuplow_data
+#undef WANT_WCuplow_diff_data
+#undef WANT_WCcomb_data
+/*  #undef WANT_WCwidth_data */
+
+/*  #define WCctype_TBL_LEN		(WCctype_II_LEN + WCctype_TI_LEN + WCctype_UT_LEN) */
+/*  #define WCuplow_TBL_LEN		(WCuplow_II_LEN + WCuplow_TI_LEN + WCuplow_UT_LEN) */
+/*  #define WCuplow_diff_TBL_LEN (2 * WCuplow_diffs) */
+/*  #define WCcomb_TBL_LEN		(WCcomb_II_LEN + WCcomb_TI_LEN + WCcomb_UT_LEN) */
+
+#include "locale_tables.h"
+
+#include "locale_mmap.h"
+
+/*  #undef __PASTE2 */
+/*  #define __PASTE2(A,B)		A ## B */
+/*  #undef __PASTE3 */
+/*  #define __PASTE3(A,B,C)		A ## B ## C */
+
+
+/*  #define MAGIC_SIZE 64 */
+
+/*  #define COMMON_MMAP(X) \ */
+/*  	unsigned char	__PASTE3(lc_,X,_data)[__PASTE3(__lc_,X,_data_LEN)]; */
+
+/*  #define COMMON_MMIDX(X) \ */
+/*  	unsigned char	__PASTE3(lc_,X,_rows)[__PASTE3(__lc_,X,_rows_LEN)]; \ */
+/*  	uint16_t		__PASTE3(lc_,X,_item_offsets)[__PASTE3(__lc_,X,_item_offsets_LEN)]; \ */
+/*  	uint16_t		__PASTE3(lc_,X,_item_idx)[__PASTE3(__lc_,X,_item_idx_LEN)]; \ */
+
+#define WRITE_COMMON_MMAP(X) \
+	fseek(fp, (long) offsetof(__locale_mmap_t, __PASTE3(lc_,X,_data)), SEEK_SET); \
+	for (i=0 ; i < __PASTE3(__lc_,X,_data_LEN) ; i++) { \
+		putc(__PASTE3(__lc_,X,_data)[i], fp); \
+	}
+
+#define WRITE_COMMON_MMIDX(X) \
+	fseek(fp, (long) offsetof(__locale_mmap_t, __PASTE3(lc_,X,_rows)), SEEK_SET); \
+	for (i=0 ; i < __PASTE3(__lc_,X,_rows_LEN) ; i++) { \
+		putc(__PASTE3(__lc_,X,_rows)[i], fp); \
+	} \
+	fseek(fp, (long) offsetof(__locale_mmap_t, __PASTE3(lc_,X,_item_offsets)), SEEK_SET); \
+	for (i=0 ; i < __PASTE3(__lc_,X,_item_offsets_LEN) ; i++) { \
+		putc( ((unsigned char *) &(__PASTE3(__lc_,X,_item_offsets)[i]))[0], fp); \
+		putc( ((unsigned char *) &(__PASTE3(__lc_,X,_item_offsets)[i]))[1], fp); \
+	} \
+	fseek(fp, (long) offsetof(__locale_mmap_t, __PASTE3(lc_,X,_item_idx)), SEEK_SET); \
+	for (i=0 ; i < __PASTE3(__lc_,X,_item_idx_LEN) ; i++) { \
+		putc( ((unsigned char *) &(__PASTE3(__lc_,X,_item_idx)[i]))[0], fp); \
+		putc( ((unsigned char *) &(__PASTE3(__lc_,X,_item_idx)[i]))[1], fp); \
+	}
+
+#define WRITE_WC_DATA(X) \
+	fseek(fp, (long) offsetof(__locale_mmap_t, __PASTE2(tblw,X)), SEEK_SET); \
+	for (i=0 ; i < __PASTE3(WC,X,_TBL_LEN) ; i++) { \
+		putc(__PASTE3(WC,X,_data)[i], fp); \
+	}
+
+#define WRITE_WC_I16_DATA(X) \
+	fseek(fp, (long) offsetof(__locale_mmap_t, __PASTE2(tblw,X)), SEEK_SET); \
+	for (i=0 ; i < __PASTE3(WC,X,_TBL_LEN) ; i++) { \
+		putc( ((unsigned char *) &(__PASTE3(WC,X,_data)[i]))[0], fp); \
+		putc( ((unsigned char *) &(__PASTE3(WC,X,_data)[i]))[1], fp); \
+	}
+
+#define WRITE_C_DATA(X) \
+	fseek(fp, (long) offsetof(__locale_mmap_t, __PASTE2(tbl8,X)), SEEK_SET); \
+	for (i=0 ; i < __PASTE3(C,X,_TBL_LEN) ; i++) { \
+		putc(__PASTE3(C,X,_data)[i], fp); \
+	}
+
+#define WRITE_C_U16_DATA(X) \
+	fseek(fp, (long) offsetof(__locale_mmap_t, __PASTE2(tbl8,X)), SEEK_SET); \
+	for (i=0 ; i < __PASTE3(C,X,_TBL_LEN) ; i++) { \
+		putc( ((unsigned char *) &(__PASTE3(C,X,_data)[i]))[0], fp); \
+		putc( ((unsigned char *) &(__PASTE3(C,X,_data)[i]))[1], fp); \
+	}
+
+/**********************************************************************/
+
+#define COMMON_OFFSETS(X) \
+	offsetof(__locale_mmap_t, __PASTE3(lc_,X,_rows)), \
+	offsetof(__locale_mmap_t, __PASTE3(lc_,X,_item_offsets)), \
+	offsetof(__locale_mmap_t, __PASTE3(lc_,X,_item_idx)), \
+	offsetof(__locale_mmap_t, __PASTE3(lc_,X,_data)) \
+
+
+static const size_t common_tbl_offsets[CATEGORIES*4] = {
+	0, 0, 0, 0,					/* ctype */
+	COMMON_OFFSETS(numeric),
+	COMMON_OFFSETS(monetary),
+	COMMON_OFFSETS(time),
+	0, 0, 0, 0,					/* collate */
+	COMMON_OFFSETS(messages),
+};
+
+
+
+
+
+int main(void)
+{
+	FILE *fp;
+	size_t i;
+	unsigned char *p;
+
+	if (!(fp = fopen("locale.mmap", "w"))) {
+		printf("error - can't open locale.mmap for writing!");
+		return EXIT_FAILURE;
+	}
+
+	for (i=0 ; i < sizeof(__locale_mmap_t) ; i++) {
+		putc(0, fp);			/* Zero out the file. */
+	}
+
+#ifdef __CTYPE_HAS_8_BIT_LOCALES
+	WRITE_C_DATA(ctype);
+	WRITE_C_DATA(uplow);
+#ifdef __WCHAR_ENABLED
+	WRITE_C_U16_DATA(c2wc);
+	WRITE_C_DATA(wc2c);
+	/* translit  */
+#endif /* __WCHAR_ENABLED */
+#endif /* __CTYPE_HAS_8_BIT_LOCALES */
+
+#ifdef __WCHAR_ENABLED
+	WRITE_WC_DATA(ctype);
+	WRITE_WC_DATA(uplow);
+	WRITE_WC_I16_DATA(uplow_diff);
+	WRITE_WC_DATA(comb);
+	/* width?? */
+#endif /* __WCHAR_ENABLED */
+
+	WRITE_COMMON_MMAP(numeric);
+	WRITE_COMMON_MMAP(monetary);
+	WRITE_COMMON_MMAP(time);
+	/* TODO -- collate*/
+	WRITE_COMMON_MMAP(messages);
+
+#ifdef __CTYPE_HAS_8_BIT_LOCALES
+	fseek(fp, (long) offsetof(__locale_mmap_t, codeset_8_bit), SEEK_SET); \
+	p = (unsigned char *) codeset_8_bit;
+	for (i=0 ; i < sizeof(codeset_8_bit) ; i++) {
+		putc(p[i], fp);
+	}
+#endif /* __CTYPE_HAS_8_BIT_LOCALES */
+
+	WRITE_COMMON_MMIDX(numeric);
+	WRITE_COMMON_MMIDX(monetary);
+	WRITE_COMMON_MMIDX(time);
+	/* TODO -- collate*/
+	WRITE_COMMON_MMIDX(messages);
+
+	fseek(fp, (long) offsetof(__locale_mmap_t, lc_common_item_offsets_LEN), SEEK_SET);
+	putc(1, fp);				/* ctype -- (codeset) handled specially */
+	putc(__lc_numeric_item_offsets_LEN, fp);
+	putc(__lc_monetary_item_offsets_LEN, fp);
+	putc(__lc_time_item_offsets_LEN, fp);
+	putc(0, fp);				/* collate */
+	putc(__lc_messages_item_offsets_LEN, fp);
+
+	fseek(fp, (long) offsetof(__locale_mmap_t, lc_common_tbl_offsets), SEEK_SET);
+	for (i=0 ; i < sizeof(common_tbl_offsets) ; i++) {
+		putc(((unsigned char *)common_tbl_offsets)[i], fp);
+	}
+
+#ifdef NUM_LOCALES
+	fseek(fp, (long) offsetof(__locale_mmap_t, locales), SEEK_SET);
+	for (i=0 ; i < (NUM_LOCALES * WIDTH_LOCALES) ; i++) {
+		putc(__locales[i], fp);
+	}
+
+	fseek(fp, (long) offsetof(__locale_mmap_t, locale_names5), SEEK_SET);
+	for (i=0 ; i < 5 * NUM_LOCALE_NAMES ; i++) {
+		putc(__locale_names5[i], fp);
+	}
+
+#ifdef LOCALE_AT_MODIFIERS_LENGTH
+	fseek(fp, (long) offsetof(__locale_mmap_t, locale_at_modifiers), SEEK_SET);
+	for (i=0 ; i < LOCALE_AT_MODIFIERS_LENGTH ; i++) {
+		putc(__locale_at_modifiers[i], fp);
+	}
+#endif /* LOCALE_AT_MODIFIERS_LENGTH */
+#endif /* NUM_LOCALES */
+
+	fseek(fp, (long) offsetof(__locale_mmap_t, lc_names), SEEK_SET);
+	for (i=0 ; i < lc_names_LEN ; i++) {
+		putc(lc_names[i], fp);
+	}
+
+#ifdef __CTYPE_HAS_8_BIT_LOCALES
+	fseek(fp, (long) offsetof(__locale_mmap_t, codeset_list), SEEK_SET);
+	for (i=0 ; i < sizeof(CODESET_LIST) ; i++) {
+		putc((unsigned char)(CODESET_LIST[i]), fp);
+	}
+#endif /* __CTYPE_HAS_8_BIT_LOCALES */
+
+
+	if (ferror(fp) || (fclose(fp) == EOF)) {
+		printf("error - stream in error state or fclose failed!");
+		return EXIT_FAILURE;
+	}
+
+	printf("sizeof(__locale_mmap_t) = %zd\n", sizeof(__locale_mmap_t));
+
+	return EXIT_SUCCESS;
+}
+
+/* TODO:
+ * collate data (8-bit weighted single char only)
+ * @ mappings!
+ * codeset list? yes, since we'll want to be able to inspect them...
+ * that means putting some header stuff in magic
+ * fix ctype LEN defines in gen_c8tables
+ */

+ 729 - 0
extra/locale/gen_wc8bit.c

@@ -0,0 +1,729 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <stddef.h>
+#include <wctype.h>
+#include <limits.h>
+
+/*  #define CTYPE_PACKED */
+#define UPLOW_IDX_SHIFT		3
+/* best if 2 unpacked or 3 packed */
+#define CTYPE_IDX_SHIFT		3
+/* 3 or 4 are very similar */
+#define C2WC_IDX_SHIFT		3
+
+#define CTYPE_IDX_LEN		(128 >> (CTYPE_IDX_SHIFT))
+#define UPLOW_IDX_LEN		(128 >> (UPLOW_IDX_SHIFT))
+#define C2WC_IDX_LEN		(128 >> (C2WC_IDX_SHIFT))
+
+/*  #ifdef CTYPE_PACKED */
+/*  #define CTYPE_ROW_LEN		(1 << ((CTYPE_IDX_SHIFT)-1)) */
+/*  #else */
+#define CTYPE_ROW_LEN		(1 << (CTYPE_IDX_SHIFT))
+/*  #endif */
+#define UPLOW_ROW_LEN		(1 << (UPLOW_IDX_SHIFT))
+#define C2WC_ROW_LEN		(1 << (C2WC_IDX_SHIFT))
+
+
+
+#define MAX_WCHAR	(0x2600-1)
+
+static unsigned char ctype_tbl[256 * CTYPE_ROW_LEN];
+static unsigned char uplow_tbl[256 * UPLOW_ROW_LEN];
+#ifdef DO_WIDE_CHAR
+static unsigned short c2wc_tbl[256 * C2WC_ROW_LEN];
+#endif
+static unsigned char tt[MAX_WCHAR+1];
+static unsigned char ti[MAX_WCHAR+1];
+static unsigned char xi[MAX_WCHAR+1];
+
+static int n_ctype_rows;
+static int n_uplow_rows;
+#ifdef DO_WIDE_CHAR
+static int n_c2wc_rows;
+#endif
+static int tt_num;
+static int ti_num;
+
+#define RANGE MAX_WCHAR
+
+#define TT_SHIFT 4
+#define TI_SHIFT 4
+
+#define II_LEN		((MAX_WCHAR+1) >> (TT_SHIFT+TI_SHIFT))
+
+typedef struct {
+	unsigned long c2w[256];
+	unsigned char w2c[MAX_WCHAR];
+	unsigned char ii[II_LEN];
+	unsigned char ctype_idx[CTYPE_IDX_LEN];
+	unsigned char uplow_idx[UPLOW_IDX_LEN];
+	unsigned char c2wc_idx[C2WC_IDX_LEN];
+} charset_data;
+
+/* Taking advantage of the C99 mutual-exclusion guarantees for the various
+ * (w)ctype classes, including the descriptions of printing and control
+ * (w)chars, we can place each in one of the following mutually-exlusive
+ * subsets.  Since there are less than 16, we can store the data for
+ * each (w)chars in a nibble. In contrast, glibc uses an unsigned int
+ * per (w)char, with one bit flag for each is* type.  While this allows
+ * a simple '&' operation to determine the type vs. a range test and a
+ * little special handling for the "blank" and "xdigit" types in my
+ * approach, it also uses 8 times the space for the tables on the typical
+ * 32-bit archs we supported.*/
+enum {
+	__CTYPE_unclassified = 0,
+	__CTYPE_alpha_nonupper_nonlower,
+	__CTYPE_alpha_lower,
+	__CTYPE_alpha_upper_lower,
+	__CTYPE_alpha_upper,
+	__CTYPE_digit,
+	__CTYPE_punct,
+	__CTYPE_graph,
+	__CTYPE_print_space_nonblank,
+	__CTYPE_print_space_blank,
+	__CTYPE_space_nonblank_noncntrl,
+	__CTYPE_space_blank_noncntrl,
+	__CTYPE_cntrl_space_nonblank,
+	__CTYPE_cntrl_space_blank,
+	__CTYPE_cntrl_nonspace,
+};
+
+int main(int argc, char **argv)
+{
+	FILE *fp;
+	FILE *out;
+	charset_data csd[20];
+	unsigned long max_wchar;
+	unsigned char *p;
+	int numsets;
+	int i;
+	int j;
+	char buf[80];
+	unsigned char row[256];
+#ifdef DO_WIDE_CHAR
+	unsigned short wrow[256];
+#endif
+	char codeset_list[500];
+	char codeset_index[30];
+	int codeset_list_end = 0;
+	int total_size = 0;
+
+	if (!setlocale(LC_CTYPE, "en_US.UTF-8")) {
+		printf("setlocale(LC_CTYPE,\"en_US.UTF-8\") failed!\n");
+		return EXIT_FAILURE;
+	}
+
+	if (!(out = fopen("c8tables.h","w"))) {
+		printf("error: couldn't open file \"c8tables.h\"\n");
+		return EXIT_FAILURE;
+	}
+
+#if 0
+	if (argc == 1) {
+		/* User requested 8-bit codesets, but didn't list any... */
+		/* Allow to build, just so this feature can be left on in config. */
+		fprintf(out, "#ifdef __CTYPE_HAS_8_BIT_LOCALES\n");
+		fprintf(out, "#warning ignoring 8 bit codesets request"
+				" as no codesets specified.\n");
+		fprintf(out, "#endif\n");
+		fprintf(out, "#undef __CTYPE_HAS_8_BIT_LOCALES\n\n");
+
+		fprintf(out, "#define NUM_CODESETS\t\t0\n");
+		fprintf(out, "#define CODESET_LIST\t\t\"\"\n");
+		fclose(out);
+		return EXIT_SUCCESS;
+	}
+
+/*  	fprintf(out, "#define __CTYPE_HAS_8_BIT_LOCALES\t1\n\n"); */
+	fprintf(out, "#ifdef __CTYPE_HAS_8_BIT_LOCALES\n\n");
+#endif
+
+	if (argc == 1) {
+		fprintf(out, "#undef __CTYPE_HAS_8_BIT_LOCALES\n\n");
+
+		fprintf(out, "#define NUM_CODESETS\t\t0\n");
+		fprintf(out, "#define CODESET_LIST\t\t\"\"\n");
+	} else {
+		fprintf(out, "#define __CTYPE_HAS_8_BIT_LOCALES\t\t1\n\n");
+	}
+
+	fprintf(out, "#define Cctype_IDX_SHIFT\t%d\n", CTYPE_IDX_SHIFT);
+	fprintf(out, "#define Cctype_IDX_LEN\t\t%d\n", CTYPE_IDX_LEN);
+#ifdef CTYPE_PACKED
+	fprintf(out, "#define Cctype_ROW_LEN\t\t%d\n", CTYPE_ROW_LEN >> 1);
+	fprintf(out, "#define Cctype_PACKED\t\t1\n");
+#else
+	fprintf(out, "#define Cctype_ROW_LEN\t\t%d\n", CTYPE_ROW_LEN);
+	fprintf(out, "#undef Cctype_PACKED\n");
+#endif
+
+	fprintf(out, "\n#define Cuplow_IDX_SHIFT\t%d\n", UPLOW_IDX_SHIFT);
+	fprintf(out, "#define Cuplow_IDX_LEN\t\t%d\n", UPLOW_IDX_LEN);
+	fprintf(out, "#define Cuplow_ROW_LEN\t\t%d\n", UPLOW_ROW_LEN);
+
+#ifdef DO_WIDE_CHAR
+	fprintf(out, "\n#define Cc2wc_IDX_LEN\t\t%d\n", C2WC_IDX_LEN);
+	fprintf(out, "#define Cc2wc_IDX_SHIFT\t\t%d\n", C2WC_IDX_SHIFT);
+	fprintf(out, "#define Cc2wc_ROW_LEN\t\t%d\n", C2WC_ROW_LEN);
+#endif
+
+	fprintf(out, "\ntypedef struct {\n");
+	fprintf(out, "\tunsigned char idx8ctype[%d];\n", CTYPE_IDX_LEN);
+	fprintf(out, "\tunsigned char idx8uplow[%d];\n", UPLOW_IDX_LEN);
+#ifdef DO_WIDE_CHAR
+	fprintf(out, "\tunsigned char idx8c2wc[%d];\n", C2WC_IDX_LEN);
+	fprintf(out, "\tunsigned char idx8wc2c[%d];\n", II_LEN);
+#endif
+	fprintf(out, "} codeset_8_bit_t;\n\n");
+
+	fprintf(out, "#ifdef WANT_DATA\n\n");
+	fprintf(out, "static const codeset_8_bit_t codeset_8_bit[%d] = {\n", argc-1);
+
+	max_wchar = 0x7f;
+	numsets = 0;
+	codeset_index[0] = 0;
+	while (--argc) {
+		if (!(fp = fopen(*++argv,"r"))) {
+			printf("error: couldn't open file \"%s\"\n", *argv);
+			return EXIT_FAILURE;
+		}
+		printf("processing %s... ", *argv);
+
+		{
+			char *s0;
+			char *s1;
+			int n;
+			
+			s0 = strrchr(*argv, '/');
+			if (!s0) {
+				s0 = *argv;
+			} else {
+				++s0;
+			}
+			s1 = strchr(s0, '.');
+			if (!s1) {
+				n = strlen(s0);
+			} else {
+				n = s1 - s0;
+			}
+
+/*  			if ((numsets == 0) && strncmp("ASCII", s0, n)) { */
+/*  				printf("error - first codeset isn't ASCII!\n"); */
+/*  				return EXIT_FAILURE; */
+/*  			} */
+
+			if (numsets >= sizeof(codeset_index)) {
+				printf("error - too many codesets!\n");
+				return EXIT_FAILURE;
+			}
+
+			if (codeset_list_end + n + 1 + numsets + 1 + 1 >= 256) {
+				printf("error - codeset list to big!\n");
+				return EXIT_FAILURE;
+			}
+
+			codeset_index[numsets+1] = codeset_index[numsets] + n+1;
+			strncpy(codeset_list + codeset_list_end, s0, n);
+			codeset_list_end += (n+1);
+			codeset_list[codeset_list_end - 1] = 0;
+
+			fprintf(out, "\t{ /* %.*s */", n, s0);
+		}
+
+		memset(&csd[numsets],sizeof(charset_data),0);
+		memset(xi, sizeof(xi), 0);
+		{
+			unsigned long c, wc;
+			int lines;
+			lines = 0;
+			while (fgets(buf,sizeof(buf),fp)) {
+				if ((2 != sscanf(buf, "{ %lx , %lx", &c, &wc))
+					|| (c >= 256) || (wc > MAX_WCHAR)) {
+					printf("error: scanf failure! \"%s\"\n", buf);
+					return EXIT_FAILURE;
+				}
+
+				/* don't put in w2c... dynamicly build tt instead. */
+
+				if (c <= 0x7f) { /* check the 7bit entries but don't store */
+					if (c != wc) {
+						printf("error: c != wc in %s\n", buf);
+						return EXIT_FAILURE;
+					}
+					csd[numsets].c2w[c] = wc;
+					csd[numsets].w2c[wc] = 0; /* ignore */
+					if (wc > max_wchar) {
+						max_wchar = wc;
+					}
+				} else {
+					csd[numsets].c2w[c] = wc;
+					csd[numsets].w2c[wc] = c;
+					if (wc > max_wchar) {
+						max_wchar = wc;
+					}
+				}
+				++lines;
+			}
+			printf("%d lines  ", lines);
+
+			for (i = 0 ; i <= MAX_WCHAR ; i += (1 << TT_SHIFT)) {
+				p = &csd[numsets].w2c[i];
+				for (j = 0 ; j < tt_num ; j++) {
+					if (!memcmp(p, &tt[j << TT_SHIFT], (1 << TT_SHIFT))) {
+						break;
+					}
+				}
+				if (j == tt_num) { /* new entry */
+					memcpy(&tt[j << TT_SHIFT], p, (1 << TT_SHIFT));
+					++tt_num;
+				}
+				xi[i >> TT_SHIFT] = j;
+			}
+
+			for (i = 0 ; i <= (MAX_WCHAR >> TT_SHIFT)  ; i += (1 << TI_SHIFT)) {
+				p = &xi[i];
+				for (j = 0 ; j < ti_num ; j++) {
+					if (!memcmp(p, &ti[j << TI_SHIFT], (1 << TI_SHIFT))) {
+						break;
+					}
+				}
+				if (j == ti_num) { /* new entry */
+					memcpy(&ti[j << TI_SHIFT], p, (1 << TI_SHIFT));
+					++ti_num;
+				}
+				csd[numsets].ii[i >> TI_SHIFT] = j;
+/*  				printf("%d ", i >> TI_SHIFT); */
+			}
+
+#if 1
+			fprintf(out, "\n\t\t/* idx8ctype data */\n\t\t{");
+			for (i = 128 ; i < 256 ; i++) {
+				wchar_t c;
+				unsigned int d;
+
+/*  				if (!(i & 0x7)) { */
+/*  					fprintf(out, "\n"); */
+/*  				} */
+
+				c = csd[numsets].c2w[i];
+
+				if (c == 0) {	/* non-existant char in codeset */
+					d = __CTYPE_unclassified;
+				} else if (iswdigit(c)) {
+					d = __CTYPE_digit;
+				} else if (iswalpha(c)) {
+					d = __CTYPE_alpha_nonupper_nonlower;
+					if (iswlower(c)) {
+						d = __CTYPE_alpha_lower;
+						if (iswupper(c)) {
+							d = __CTYPE_alpha_upper_lower;
+						}
+					} else if (iswupper(c)) {
+						d = __CTYPE_alpha_upper;
+					}
+				} else if (iswpunct(c)) {
+					d = __CTYPE_punct;
+				} else if (iswgraph(c)) {
+					d = __CTYPE_graph;
+				} else if (iswprint(c)) {
+					d = __CTYPE_print_space_nonblank;
+					if (iswblank(c)) {
+						d = __CTYPE_print_space_blank;
+					}
+				} else if (iswspace(c) && !iswcntrl(c)) {
+					d = __CTYPE_space_nonblank_noncntrl;
+					if (iswblank(c)) {
+						d = __CTYPE_space_blank_noncntrl;
+					}
+				} else if (iswcntrl(c)) {
+					d = __CTYPE_cntrl_nonspace;
+					if (iswspace(c)) {
+						d = __CTYPE_cntrl_space_nonblank;
+						if (iswblank(c)) {
+							d = __CTYPE_cntrl_space_blank;
+						}
+					}
+				} else {
+					d = __CTYPE_unclassified;
+				}
+
+#if 1
+				row[i & (CTYPE_ROW_LEN-1)] = d;
+				if ((i & (CTYPE_ROW_LEN-1)) == (CTYPE_ROW_LEN-1)) {
+					p = ctype_tbl;
+					for (j=0 ; j < n_ctype_rows ; j++) {
+						if (!memcmp(p, row, CTYPE_ROW_LEN)) {
+							break;
+						}
+						p += CTYPE_ROW_LEN;
+					}
+					if (j == n_ctype_rows) { /* new entry */
+						if (++n_ctype_rows > 256) {
+							printf("error -- to many ctype rows!\n");
+							return EXIT_FAILURE;
+						}
+						memcpy(p, row, CTYPE_ROW_LEN);
+					}
+					csd[numsets].ctype_idx[i >> CTYPE_IDX_SHIFT] = j;
+					if (!((i >> CTYPE_IDX_SHIFT) & 0x7)
+						&& (i != (127 + CTYPE_ROW_LEN))
+						) {
+						fprintf(out, "\n\t\t ");
+					}
+					fprintf(out, " %#4x,", j);
+				}
+#else
+				fprintf(out, " %#4x,", d);
+#endif
+			}
+#endif
+			fprintf(out, " }");
+
+#if 1
+			fprintf(out, ",\n\t\t/* idx8uplow data */\n\t\t{");
+			for (i = 128 ; i < 256 ; i++) {
+				wchar_t c, u, l;
+/*  				if (!(i & 0x7)) { */
+/*  					fprintf(out, "\n"); */
+/*  				} */
+				c = csd[numsets].c2w[i];
+				if ((c != 0) || 1) {
+					u = towupper(c);
+					l = towlower(c);
+					
+					if (u >= 0x80) u = csd[numsets].w2c[u];
+					if (l >= 0x80) l = csd[numsets].w2c[l];
+
+					if (u == 0) u = i; /* upper is missing, so ignore */
+					if (l == 0) l = i; /* lower is missing, so ignore */
+
+#if 1
+					/* store as unsigned char and let overflow handle it. */
+/*  					if ((((u-i) < CHAR_MIN) || ((u-i) > CHAR_MAX)) */
+/*  						|| (((i-l) < CHAR_MIN) || ((i-l) > CHAR_MAX)) */
+/*  						) { */
+/*  						printf("error - uplow diff out of range! %d %ld %ld\n", */
+/*  							   i, u, l); */
+/*  						return EXIT_FAILURE; */
+/*  					} */
+
+					row[i & (UPLOW_ROW_LEN-1)] = ((l==i) ? (u-i) : (i-l));
+					if ((i & (UPLOW_ROW_LEN-1)) == (UPLOW_ROW_LEN-1)) {
+						p = uplow_tbl;
+						for (j=0 ; j < n_uplow_rows ; j++) {
+							if (!memcmp(p, row, UPLOW_ROW_LEN)) {
+								break;
+							}
+							p += UPLOW_ROW_LEN;
+						}
+						if (j == n_uplow_rows) { /* new entry */
+							if (++n_uplow_rows > 256) {
+								printf("error -- to many uplow rows!\n");
+								return EXIT_FAILURE;
+							}
+							memcpy(p, row, UPLOW_ROW_LEN);
+						}
+						csd[numsets].uplow_idx[i >> UPLOW_IDX_SHIFT] = j;
+						if (!((i >> UPLOW_IDX_SHIFT) & 0x7)
+							&& (i != (127 + UPLOW_ROW_LEN))
+							) {
+							fprintf(out, "\n\t\t ");
+						}
+						fprintf(out, " %#4x,", j);
+					}
+
+#elif 0
+					if (!(i & 0x7) && i) {
+						fprintf(out, "\n");
+					}
+					fprintf(out, " %4ld,", (l==i) ? (u-i) : (i-l));
+/*  					fprintf(out, " %4ld,", (l==i) ? u : l); */
+#else
+					if ((u != i) || (l != i)) {
+#if 0
+						fprintf(out, " %#08lx, %#08lx, %#08lx, %#08lx, %#08lx, %#08lx, \n",
+								(unsigned long) i,
+								(unsigned long) c,
+								(unsigned long) l,
+								(unsigned long) towlower(c),
+								(unsigned long) u,
+								(unsigned long) towupper(c));
+
+#else
+						fprintf(out, " %#08lx, %8ld, %d, %8ld, %d, %#08lx\n",
+								(unsigned long) i,
+								(long) (l - i),
+								iswupper(c),
+								(long) (i - u),
+								iswlower(c),
+								(unsigned long) c);
+#endif
+					}
+#endif
+				}
+			}
+			fprintf(out, " }");
+#endif
+
+#ifndef DO_WIDE_CHAR
+			fprintf(out,"\n");
+#else  /* DO_WIDE_CHAR */
+
+#if 1
+			fprintf(out, ",\n\t\t/* idx8c2wc data */\n\t\t{");
+			for (i = 128 ; i < 256 ; i++) {
+#if 1
+				wrow[i & (C2WC_ROW_LEN-1)] = csd[numsets].c2w[i];
+				if ((i & (C2WC_ROW_LEN-1)) == (C2WC_ROW_LEN-1)) {
+					p = (char *) c2wc_tbl;
+					for (j=0 ; j < n_c2wc_rows ; j++) {
+						if (!memcmp(p, (char *) wrow, 2*C2WC_ROW_LEN)) {
+							break;
+						}
+						p += 2*C2WC_ROW_LEN;
+					}
+					if (j == n_c2wc_rows) { /* new entry */
+						if (++n_c2wc_rows > 256) {
+							printf("error -- to many c2wc rows!\n");
+							return EXIT_FAILURE;
+						}
+						memcpy(p, (char *) wrow, 2*C2WC_ROW_LEN);
+					}
+					csd[numsets].c2wc_idx[i >> C2WC_IDX_SHIFT] = j;
+					if (!((i >> C2WC_IDX_SHIFT) & 0x7)
+						&& (i != (127 + C2WC_ROW_LEN))
+						) {
+						fprintf(out, "\n\t\t ");
+					}
+					fprintf(out, " %#4x,", j);
+				}
+#else
+				if (!(i & 0x7) && i) {
+					fprintf(out, "\n");
+				}
+				fprintf(out, " %#6lx,", csd[numsets].c2w[i]);
+#endif
+			}
+			fprintf(out, " },\n");
+#endif
+
+#if 1
+/*  			fprintf(out, "\nII_LEN = %d\n", II_LEN); */
+			fprintf(out, "\t\t/* idx8wc2c data */\n\t\t{");
+			for (i = 0 ; i < II_LEN ; i++) {
+				if (!(i & 0x7) && i) {
+					fprintf(out, "\n\t\t ");
+				}
+				fprintf(out, " %#4x,", csd[numsets].ii[i]);
+			}
+			fprintf(out, " }\n");
+#endif
+
+#endif /* DO_WIDE_CHAR */
+			fprintf(out, "\t},\n");
+
+		}
+		++numsets;
+		printf("done\n");
+	}
+	fprintf(out, "};\n");
+	fprintf(out, "\n#endif /* WANT_DATA */\n");
+
+#ifdef DO_WIDE_CHAR
+	fprintf(out, "\n");
+	fprintf(out, "#define Cwc2c_DOMAIN_MAX\t%#x\n", RANGE);
+	fprintf(out, "#define Cwc2c_TI_SHIFT\t\t%d\n", TI_SHIFT);
+	fprintf(out, "#define Cwc2c_TT_SHIFT\t\t%d\n", TT_SHIFT);
+	fprintf(out, "#define Cwc2c_II_LEN\t\t%d\n", II_LEN);
+	fprintf(out, "#define Cwc2c_TI_LEN\t\t%d\n", ti_num << TI_SHIFT);
+	fprintf(out, "#define Cwc2c_TT_LEN\t\t%d\n", tt_num << TT_SHIFT);
+	fprintf(out, "\n");
+
+	fprintf(out, "\n#define Cwc2c_TBL_LEN\t\t%d\n",
+			(ti_num << TI_SHIFT) + (tt_num << TT_SHIFT));
+
+	fprintf(out, "#ifdef WANT_DATA\n\n");
+	fprintf(out, "static const unsigned char Cwc2c_data[%d] = {\n",
+			(ti_num << TI_SHIFT) + (tt_num << TT_SHIFT));
+	fprintf(out, "\t/* ti_table */\n\t");
+	for (i=0 ; i < ti_num << TI_SHIFT ; i++) {
+		if (!(i & 7) && i) {
+			fprintf(out, "\n\t");
+		}
+		fprintf(out, " %#4x,", ti[i]);
+	}
+	fprintf(out, "\n");
+	fprintf(out, "\t/* tt_table */\n\t");
+	for (i=0 ; i < tt_num << TT_SHIFT ; i++) {
+		if (!(i & 7) && i) {
+			fprintf(out, "\n\t");
+		}
+		fprintf(out, " %#4x,", tt[i]);
+	}
+	fprintf(out, "\n};\n");
+
+	fprintf(out, "\n#endif /* WANT_DATA */\n");
+#endif /* DO_WIDE_CHAR */
+
+	fprintf(out, "\n#define Cuplow_TBL_LEN\t\t%d\n",
+			n_uplow_rows * UPLOW_ROW_LEN);
+	fprintf(out, "\n#ifdef WANT_DATA\n\n");
+
+	fprintf(out, "\nstatic const unsigned char Cuplow_data[%d] = {\n",
+			n_uplow_rows * UPLOW_ROW_LEN);
+	p = uplow_tbl;
+	for (j=0 ; j < n_uplow_rows ; j++) {
+		fprintf(out, "\t");
+		for (i=0 ; i < UPLOW_ROW_LEN ; i++) {
+			fprintf(out, " %#4x,", (unsigned int)((unsigned char) p[i]));
+		}
+		fprintf(out, "\n");
+		p += UPLOW_ROW_LEN;
+	}
+	fprintf(out, "};\n");
+
+	fprintf(out, "\n#endif /* WANT_DATA */\n");
+	fprintf(out, "\n#define Cctype_TBL_LEN\t\t%d\n",
+#ifdef CTYPE_PACKED
+			n_ctype_rows * CTYPE_ROW_LEN / 2
+#else
+			n_ctype_rows * CTYPE_ROW_LEN
+#endif
+			);
+	fprintf(out, "\n#ifdef WANT_DATA\n\n");
+
+
+	fprintf(out, "\nstatic const unsigned char Cctype_data[%d] = {\n",
+#ifdef CTYPE_PACKED
+			n_ctype_rows * CTYPE_ROW_LEN / 2
+#else
+			n_ctype_rows * CTYPE_ROW_LEN
+#endif
+			);
+	p = ctype_tbl;
+	for (j=0 ; j < n_ctype_rows ; j++) {
+		fprintf(out, "\t");
+		for (i=0 ; i < CTYPE_ROW_LEN ; i++) {
+#ifdef CTYPE_PACKED
+			fprintf(out, " %#4x,", (unsigned int)(p[i] + (p[i+1] << 4)));
+			++i;
+#else
+			fprintf(out, " %#4x,", (unsigned int)p[i]);
+#endif
+		}
+		fprintf(out, "\n");
+		p += CTYPE_ROW_LEN;
+	}
+	fprintf(out, "};\n");
+
+	fprintf(out, "\n#endif /* WANT_DATA */\n");
+
+#ifdef DO_WIDE_CHAR
+
+	fprintf(out, "\n#define Cc2wc_TBL_LEN\t\t%d\n",
+			n_c2wc_rows * C2WC_ROW_LEN);
+	fprintf(out, "\n#ifdef WANT_DATA\n\n");
+
+	fprintf(out, "\nstatic const unsigned short Cc2wc_data[%d] = {\n",
+			n_c2wc_rows * C2WC_ROW_LEN);
+	p = (char *) c2wc_tbl;
+	for (j=0 ; j < n_c2wc_rows ; j++) {
+		fprintf(out, "\t");
+		for (i=0 ; i < C2WC_ROW_LEN ; i++) {
+			fprintf(out, " %#6x,", (unsigned int)(((unsigned short *)p)[i]));
+		}
+		fprintf(out, "\n");
+		p += 2*C2WC_ROW_LEN;
+	}
+	fprintf(out, "};\n");
+	fprintf(out, "\n#endif /* WANT_DATA */\n");
+#endif /* DO_WIDE_CHAR */
+	fprintf(out, "\n\n");
+
+	fprintf(out, "#define NUM_CODESETS\t\t%d\n", numsets);
+	fprintf(out, "#define CODESET_LIST \\\n\t\"");
+	for (i=0 ; i < numsets ; i++) {
+		fprintf(out, "\\x%02x", numsets + 1 + (unsigned char) codeset_index[i]);
+		if (((i & 7) == 7) && (i + 1 < numsets)) {
+			fprintf(out, "\" \\\n\t\"");
+		}
+	}
+	fprintf(out, "\" \\\n\t\"\\0\"");
+	for (i=0 ; i < numsets ; i++) {
+		fprintf(out, " \\\n\t\"%s\\0\"",
+				codeset_list + ((unsigned char)codeset_index[i]));
+	}
+
+	fprintf(out, "\n\n");
+	for (i=0 ; i < numsets ; i++) {
+		char buf[30];
+		char *z;
+		strcpy(buf, codeset_list + ((unsigned char)codeset_index[i]));
+		for (z=buf ; *z ; z++) {
+			if (*z == '-') {
+				*z = '_';
+			}
+		}
+		fprintf(out, "#define __CTYPE_HAS_CODESET_%s\n", buf);
+	}
+#ifdef DO_WIDE_CHAR
+	fprintf(out, "#define __CTYPE_HAS_CODESET_UTF_8\n");
+#endif /* DO_WIDE_CHAR */
+
+#if 0
+	fprintf(out, "\n#endif /* __CTYPE_HAS_8_BIT_LOCALES */\n\n");
+#endif
+
+	fclose(out);
+
+	total_size = 0;
+#ifdef DO_WIDE_CHAR
+	printf("tt_num = %d   ti_num = %d\n", tt_num, ti_num);
+	printf("max_wchar = %#lx\n", max_wchar);
+
+	printf("size is %d * %d  +  %d * %d  + %d * %d  =  %d\n",
+		   tt_num, 1 << TT_SHIFT, ti_num, 1 << TI_SHIFT,
+		   ((MAX_WCHAR >> (TT_SHIFT + TI_SHIFT)) + 1), numsets,
+ 		   j = tt_num * (1 << TT_SHIFT) + ti_num * (1 << TI_SHIFT)
+		   + ((MAX_WCHAR >> (TT_SHIFT + TI_SHIFT)) + 1) * numsets);
+	total_size += j;
+#endif /* DO_WIDE_CHAR */
+
+#ifdef CTYPE_PACKED
+	i = 2;
+#else
+	i = 1;
+#endif
+
+	printf("ctype - CTYPE_IDX_SHIFT = %d -- %d * %d + %d * %d = %d\n",
+		   CTYPE_IDX_SHIFT, numsets, CTYPE_IDX_LEN, n_ctype_rows, CTYPE_ROW_LEN / i,
+		   j = numsets * CTYPE_IDX_LEN +  n_ctype_rows * CTYPE_ROW_LEN / i);
+	total_size += j;
+
+	printf("uplow - UPLOW_IDX_SHIFT = %d -- %d * %d + %d * %d = %d\n",
+		   UPLOW_IDX_SHIFT, numsets, UPLOW_IDX_LEN, n_uplow_rows, UPLOW_ROW_LEN,
+		   j = numsets * UPLOW_IDX_LEN +  n_uplow_rows * UPLOW_ROW_LEN);
+	total_size += j;
+
+#ifdef DO_WIDE_CHAR
+
+	printf("c2wc - C2WC_IDX_SHIFT = %d -- %d * %d + 2 * %d * %d = %d\n",
+		   C2WC_IDX_SHIFT, numsets, C2WC_IDX_LEN, n_c2wc_rows, C2WC_ROW_LEN,
+		   j = numsets * C2WC_IDX_LEN +  2 * n_c2wc_rows * C2WC_ROW_LEN);
+	total_size += j;
+
+#endif /* DO_WIDE_CHAR */
+
+	printf("total size = %d\n", total_size);
+
+/*  	for (i=0 ; i < numsets ; i++) { */
+/*  		printf("codeset_index[i] = %d  codeset_list[ci[i]] = \"%s\"\n", */
+/*  			   (unsigned char) codeset_index[i], */
+/*  			   codeset_list + ((unsigned char)codeset_index[i])); */
+/*  	} */
+
+	return EXIT_SUCCESS;
+}

+ 833 - 0
extra/locale/gen_wctype.c

@@ -0,0 +1,833 @@
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <wctype.h>
+#include <limits.h>
+#include <stdint.h>
+#include <wchar.h>
+#include <ctype.h>
+
+
+/*       0x9 : space  blank */
+/*       0xa : space */
+/*       0xb : space */
+/*       0xc : space */
+/*       0xd : space */
+/*      0x20 : space  blank */
+/*    0x1680 : space  blank */
+/*    0x2000 : space  blank */
+/*    0x2001 : space  blank */
+/*    0x2002 : space  blank */
+/*    0x2003 : space  blank */
+/*    0x2004 : space  blank */
+/*    0x2005 : space  blank */
+/*    0x2006 : space  blank */
+/*    0x2008 : space  blank */
+/*    0x2009 : space  blank */
+/*    0x200a : space  blank */
+/*    0x200b : space  blank */
+/*    0x2028 : space */
+/*    0x2029 : space */
+/*    0x3000 : space  blank */
+
+/*  typecount[ 0] =    88670  C_alpha_nonupper_nonlower */
+/*  typecount[ 1] =      742  C_alpha_lower */
+/*  typecount[ 2] =        4  C_alpha_upper_lower */
+/*  typecount[ 3] =      731  C_alpha_upper */
+/*  typecount[ 4] =       10  C_digit */
+/*  typecount[ 5] =    10270  C_punct */
+/*  typecount[ 6] =        0  C_graph */
+/*  typecount[ 7] =        0  C_print_space_nonblank */
+/*  typecount[ 8] =       14  C_print_space_blank */
+/*  typecount[ 9] =        0  C_space_nonblank_noncntrl */
+/*  typecount[10] =        0  C_space_blank_noncntrl */
+/*  typecount[11] =        6  C_cntrl_space_nonblank */
+/*  typecount[12] =        1  C_cntrl_space_blank */
+/*  typecount[13] =       60  C_cntrl_nonspace */
+/*  typecount[14] =    96100  C_unclassified */
+/*  typecount[15] =        0  empty_slot */
+
+
+
+/* Set to #if 0 to restrict wchars to 16 bits. */
+#if 1
+#define RANGE 0x2ffffUL
+#elif 0
+#define RANGE 0x1ffffUL
+#else
+#define RANGE 0xffffUL			/* Restrict for 16-bit wchar_t... */
+#endif
+
+/* Classification codes. */
+
+static const char *typename[] = {
+	"C_unclassified",
+	"C_alpha_nonupper_nonlower",
+	"C_alpha_lower",
+	"C_alpha_upper_lower",
+	"C_alpha_upper",
+	"C_digit",
+	"C_punct",
+	"C_graph",
+	"C_print_space_nonblank",
+	"C_print_space_blank",
+	"C_space_nonblank_noncntrl",
+	"C_space_blank_noncntrl",
+	"C_cntrl_space_nonblank",
+	"C_cntrl_space_blank",
+	"C_cntrl_nonspace",
+	"empty_slot"
+};
+
+/* Taking advantage of the C99 mutual-exclusion guarantees for the various
+ * (w)ctype classes, including the descriptions of printing and control
+ * (w)chars, we can place each in one of the following mutually-exlusive
+ * subsets.  Since there are less than 16, we can store the data for
+ * each (w)chars in a nibble. In contrast, glibc uses an unsigned int
+ * per (w)char, with one bit flag for each is* type.  While this allows
+ * a simple '&' operation to determine the type vs. a range test and a
+ * little special handling for the "blank" and "xdigit" types in my
+ * approach, it also uses 8 times the space for the tables on the typical
+ * 32-bit archs we supported.*/
+enum {
+	__CTYPE_unclassified = 0,
+	__CTYPE_alpha_nonupper_nonlower,
+	__CTYPE_alpha_lower,
+	__CTYPE_alpha_upper_lower,
+	__CTYPE_alpha_upper,
+	__CTYPE_digit,
+	__CTYPE_punct,
+	__CTYPE_graph,
+	__CTYPE_print_space_nonblank,
+	__CTYPE_print_space_blank,
+	__CTYPE_space_nonblank_noncntrl,
+	__CTYPE_space_blank_noncntrl,
+	__CTYPE_cntrl_space_nonblank,
+	__CTYPE_cntrl_space_blank,
+	__CTYPE_cntrl_nonspace,
+};
+
+/* Some macros that test for various (w)ctype classes when passed one of the
+ * designator values enumerated above. */
+#define __CTYPE_isalnum(D)		((unsigned int)(D-1) <= (__CTYPE_digit-1))
+#define __CTYPE_isalpha(D)		((unsigned int)(D-1) <= (__CTYPE_alpha_upper-1))
+#define __CTYPE_isblank(D) \
+	((((unsigned int)(D - __CTYPE_print_space_nonblank)) <= 5) && (D & 1))
+#define __CTYPE_iscntrl(D)		(((unsigned int)(D - __CTYPE_cntrl_space_nonblank)) <= 2)
+#define __CTYPE_isdigit(D)		(D == __CTYPE_digit)
+#define __CTYPE_isgraph(D)		((unsigned int)(D-1) <= (__CTYPE_graph-1))
+#define __CTYPE_islower(D)		(((unsigned int)(D - __CTYPE_alpha_lower)) <= 1)
+#define __CTYPE_isprint(D)		((unsigned int)(D-1) <= (__CTYPE_print_space_blank-1))
+#define __CTYPE_ispunct(D)		(D == __CTYPE_punct)
+#define __CTYPE_isspace(D)		(((unsigned int)(D - __CTYPE_print_space_nonblank)) <= 5)
+#define __CTYPE_isupper(D)		(((unsigned int)(D - __CTYPE_alpha_upper_lower)) <= 1)
+#define __CTYPE_isxdigit(D,X) \
+	(__CTYPE_isdigit(D) || (((unsigned int)(((X)|0x20) - 'a')) <= 5))
+
+#define mywalnum(x)		__CTYPE_isalnum(d)
+#define mywalpha(x)		__CTYPE_isalpha(d)
+#define mywblank(x) 	__CTYPE_isblank(d)
+#define mywcntrl(x)		__CTYPE_iscntrl(d)
+#define mywdigit(x)		__CTYPE_isdigit(d)
+#define mywgraph(x)		__CTYPE_isgraph(d)
+#define mywlower(x)		__CTYPE_islower(d)
+#define mywprint(x)		__CTYPE_isprint(d)
+#define mywpunct(x)		__CTYPE_ispunct(d)
+#define mywspace(x)		__CTYPE_isspace(d)
+#define mywupper(x)		__CTYPE_isupper(d)
+#define mywxdigit(x)	__CTYPE_isxdigit(d,x)
+
+typedef struct {
+	short l;
+	short u;
+} uldiff_entry;
+
+typedef struct {
+	uint16_t ii_len;
+	uint16_t ti_len;
+	uint16_t ut_len;
+
+	unsigned char ii_shift;
+	unsigned char ti_shift;
+
+	unsigned char *ii;
+	unsigned char *ti;
+	unsigned char *ut;
+} table_data;
+
+
+void output_table(FILE *fp, const char *name, table_data *tbl)
+{
+	size_t i;
+
+	fprintf(fp, "#define WC%s_II_LEN    %7u\n", name, tbl->ii_len);
+	fprintf(fp, "#define WC%s_TI_LEN    %7u\n", name, tbl->ti_len);
+	fprintf(fp, "#define WC%s_UT_LEN    %7u\n", name, tbl->ut_len);
+
+	fprintf(fp, "#define WC%s_II_SHIFT  %7u\n", name, tbl->ii_shift);
+	fprintf(fp, "#define WC%s_TI_SHIFT  %7u\n", name, tbl->ti_shift);
+
+	fprintf(fp, "\n#ifdef WANT_WC%s_data\n", name);
+
+	i = tbl->ii_len + tbl->ti_len + tbl->ut_len;
+	fprintf(fp, "\nstatic const unsigned char WC%s_data[%zu] = {", name, i);
+	for (i=0 ; i < tbl->ii_len ; i++) {
+		if (i % 12 == 0) {
+			fprintf(fp, "\n");
+		}
+		fprintf(fp, " %#04x,", tbl->ii[i]);
+	}
+	for (i=0 ; i < tbl->ti_len ; i++) {
+		if (i % 12 == 0) {
+			fprintf(fp, "\n");
+		}
+		fprintf(fp, " %#04x,", tbl->ti[i]);
+	}
+	for (i=0 ; i < tbl->ut_len ; i++) {
+		if (i % 12 == 0) {
+			fprintf(fp, "\n");
+		}
+		fprintf(fp, " %#04x,", tbl->ut[i]);
+	}
+	fprintf(fp, "\n};\n\n");
+
+	fprintf(fp, "#endif /* WANT_WC%s_data */\n\n", name);
+}
+
+static void dump_table_data(table_data *tbl)
+{
+	printf("ii_shift = %d  ti_shift = %d\n"
+		   "ii_len = %d  ti_len = %d  ut_len = %d\n"
+		   "total = %d\n",
+		   tbl->ii_shift, tbl->ti_shift,
+		   tbl->ii_len, tbl->ti_len, tbl->ut_len,
+		   (int) tbl->ii_len + (int) tbl->ti_len + (int) tbl->ut_len);
+}
+
+/* For sorting the blocks of unsigned chars. */
+static size_t nu_val;
+
+int nu_memcmp(const void *a, const void *b)
+{
+	return memcmp(*(unsigned char**)a, *(unsigned char**)b, nu_val);
+}
+
+static size_t newopt(unsigned char *ut, size_t usize, int shift, table_data *tbl);
+
+#define MAXTO		255			/* Restrict to minimal unsigned char max. */
+
+int main(int argc, char **argv)
+{
+	long int u, l, tt;
+	size_t smallest, t;
+	unsigned int c;
+	unsigned int d;
+	int i, n;
+	int ul_count = 0;
+	uldiff_entry uldiff[MAXTO];
+	table_data cttable;
+	table_data ultable;
+	table_data combtable;
+	table_data widthtable;
+
+	unsigned char wct[(RANGE/2)+1];	/* wctype table (nibble per wchar) */
+	unsigned char ult[RANGE+1];	/* upper/lower table */
+	unsigned char combt[(RANGE/4)+1];	/* combining */
+	unsigned char widtht[(RANGE/4)+1];	/* width */
+	wctrans_t totitle;
+	wctype_t is_comb, is_comb3;
+
+	long int typecount[16];
+	int built = 0;
+
+	setvbuf(stdout, NULL, _IONBF, 0);
+
+	while (--argc) {
+		if (!setlocale(LC_CTYPE, *++argv)) {
+			printf("setlocale(LC_CTYPE,%s) failed!\n", *argv);
+			continue;
+		}
+
+		if (!(totitle = wctrans("totitle"))) {
+			printf("no totitle transformation.\n");
+		}
+		if (!(is_comb = wctype("combining"))) {
+			printf("no combining wctype.\n");
+		}
+		if (!(is_comb3 = wctype("combining_level3"))) {
+			printf("no combining_level3 wctype.\n");
+		}
+
+		if (!built) {
+		built = 1;
+		ul_count = 1;
+		uldiff[0].u = uldiff[0].l = 0;
+
+		memset(wct, 0, sizeof(wct));
+		memset(combt, 0, sizeof(combt));
+		memset(widtht, 0, sizeof(widtht));
+
+		for (i = 0 ; i < 16 ; i++) {
+			typecount[i] = 0;
+		}
+
+		for (c=0 ; c <= RANGE ; c++) {
+			if (iswdigit(c)) {
+				d = __CTYPE_digit;
+			} else if (iswalpha(c)) {
+				d = __CTYPE_alpha_nonupper_nonlower;
+				if (iswlower(c)) {
+					d = __CTYPE_alpha_lower;
+					if (iswupper(c)) {
+						d = __CTYPE_alpha_upper_lower;
+					}
+				} else if (iswupper(c)) {
+					d = __CTYPE_alpha_upper;
+				}
+			} else if (iswpunct(c)) {
+				d = __CTYPE_punct;
+			} else if (iswgraph(c)) {
+				d = __CTYPE_graph;
+			} else if (iswprint(c)) {
+				d = __CTYPE_print_space_nonblank;
+				if (iswblank(c)) {
+					d = __CTYPE_print_space_blank;
+				}
+			} else if (iswspace(c) && !iswcntrl(c)) {
+				d = __CTYPE_space_nonblank_noncntrl;
+				if (iswblank(c)) {
+					d = __CTYPE_space_blank_noncntrl;
+				}
+			} else if (iswcntrl(c)) {
+				d = __CTYPE_cntrl_nonspace;
+				if (iswspace(c)) {
+					d = __CTYPE_cntrl_space_nonblank;
+					if (iswblank(c)) {
+						d = __CTYPE_cntrl_space_blank;
+					}
+				}
+			} else {
+				d = __CTYPE_unclassified;
+			}
+
+			++typecount[d];
+
+#if 0
+			if (iswspace(c)) {
+				if (iswblank(c)) {
+					printf("%#8x : space  blank\n", c);
+				} else {
+					printf("%#8x : space\n", c);
+				}
+			}
+#endif
+
+#if 0
+			if (c < 256) {
+				unsigned int glibc;
+
+				glibc = 0;
+				if (isalnum(c)) ++glibc; glibc <<= 1;
+				if (isalpha(c)) ++glibc; glibc <<= 1;
+				if (isblank(c)) ++glibc; glibc <<= 1;
+				if (iscntrl(c)) ++glibc; glibc <<= 1;
+				if (isdigit(c)) ++glibc; glibc <<= 1;
+				if (isgraph(c)) ++glibc; glibc <<= 1;
+				if (islower(c)) ++glibc; glibc <<= 1;
+				if (isprint(c)) ++glibc; glibc <<= 1;
+				if (ispunct(c)) ++glibc; glibc <<= 1;
+				if (isspace(c)) ++glibc; glibc <<= 1;
+				if (isupper(c)) ++glibc; glibc <<= 1;
+				if (isxdigit(c)) ++glibc;
+				printf("%#8x : ctype %#4x\n", c, glibc);
+			}
+#endif
+
+#if 1
+			/* Paranoid checking... */
+			{
+				unsigned int glibc;
+				unsigned int mine;
+
+				glibc = 0;
+				if (iswalnum(c)) ++glibc; glibc <<= 1;
+				if (iswalpha(c)) ++glibc; glibc <<= 1;
+				if (iswblank(c)) ++glibc; glibc <<= 1;
+				if (iswcntrl(c)) ++glibc; glibc <<= 1;
+				if (iswdigit(c)) ++glibc; glibc <<= 1;
+				if (iswgraph(c)) ++glibc; glibc <<= 1;
+				if (iswlower(c)) ++glibc; glibc <<= 1;
+				if (iswprint(c)) ++glibc; glibc <<= 1;
+				if (iswpunct(c)) ++glibc; glibc <<= 1;
+				if (iswspace(c)) ++glibc; glibc <<= 1;
+				if (iswupper(c)) ++glibc; glibc <<= 1;
+				if (iswxdigit(c)) ++glibc;
+
+				mine = 0;
+				if (mywalnum(c)) ++mine; mine <<= 1;
+				if (mywalpha(c)) ++mine; mine <<= 1;
+				if (mywblank(c)) ++mine; mine <<= 1;
+				if (mywcntrl(c)) ++mine; mine <<= 1;
+				if (mywdigit(c)) ++mine; mine <<= 1;
+				if (mywgraph(c)) ++mine; mine <<= 1;
+				if (mywlower(c)) ++mine; mine <<= 1;
+				if (mywprint(c)) ++mine; mine <<= 1;
+				if (mywpunct(c)) ++mine; mine <<= 1;
+				if (mywspace(c)) ++mine; mine <<= 1;
+				if (mywupper(c)) ++mine; mine <<= 1;
+				if (mywxdigit(c)) ++mine;
+
+				if (glibc != mine) {
+					printf("%#8x : glibc %#4x != %#4x mine  %u\n", c, glibc, mine, d);
+					return EXIT_FAILURE;
+				}
+
+#if 0
+				if (iswctype(c,is_comb) || iswctype(c,is_comb3)) {
+/*  					if (!iswpunct(c)) { */
+						printf("%#8x : %d %d %#4x\n",
+							   c, iswctype(c,is_comb),iswctype(c,is_comb3), glibc);
+/*  					} */
+				}
+#endif
+
+			}
+#endif
+
+			combt[c/4] |= ((((!!iswctype(c,is_comb)) << 1) | !!iswctype(c,is_comb3))
+						   << ((c & 3) << 1));
+/*  			comb3t[c/8] |= ((!!iswctype(c,is_comb3)) << (c & 7)); */
+			widtht[c/4] |= (wcwidth(c) << ((c & 3) << 1));
+
+			if (c & 1) {	/* Use the high nibble for odd numbered wchars. */
+				d <<= 4;
+			}
+			wct[c/2] |= d;
+
+			l = towlower(c) - c;
+			u = towupper(c) - c;
+			ult[c] = 0;
+			if (l || u) {
+				if ((l != (short)l) || (u != (short)u)) {
+					printf("range assumption error!  %x  %ld  %ld\n", c, l, u);
+					return EXIT_FAILURE;
+				}
+				for (i=0 ; i < ul_count ; i++) {
+					if ((l == uldiff[i].l) && (u == uldiff[i].u)) {
+						goto found;
+					}
+				}
+				uldiff[ul_count].l = l;
+				uldiff[ul_count].u = u;
+				++ul_count;
+				if (ul_count > MAXTO) {
+					printf("too many touppers/tolowers!\n");
+					return EXIT_FAILURE;
+				}
+			found:
+				ult[c] = i;
+			}
+		}
+
+		for (i = 0 ; i < 16 ; i++) {
+			printf("typecount[%2d] = %8ld  %s\n", i, typecount[i], typename[i]);
+		}
+
+		printf("optimizing is* table..\n");
+		n = -1;
+		smallest = SIZE_MAX;
+		cttable.ii = NULL;
+		for (i=0 ; i < 14 ; i++) {
+			t = newopt(wct, (RANGE/2)+1, i, &cttable);
+			if (smallest >= t) {
+				n = i;
+				smallest = t;
+/*  			} else { */
+/*  				break; */
+			}
+		}
+		printf("smallest = %zu\n", smallest);
+		if (!(cttable.ii = malloc(smallest))) {
+			printf("couldn't allocate space!\n");
+			return EXIT_FAILURE;
+		}
+		smallest = SIZE_MAX;
+		newopt(wct, (RANGE/2)+1, n, &cttable);
+		++cttable.ti_shift;		/* correct for nibble mode */
+
+
+
+		printf("optimizing u/l-to table..\n");
+		smallest = SIZE_MAX;
+		ultable.ii = NULL;
+		for (i=0 ; i < 14 ; i++) {
+			t = newopt(ult, RANGE+1, i, &ultable);
+			if (smallest >= t) {
+				n = i;
+				smallest = t;
+/*  			} else { */
+/*  				break; */
+			}
+		}
+		printf("%zu (smallest) + %zu (u/l diffs) = %zu\n",
+			   smallest, 4 * ul_count, smallest + 4 * ul_count);
+		printf("smallest = %zu\n", smallest);
+		if (!(ultable.ii = malloc(smallest))) {
+			printf("couldn't allocate space!\n");
+			return EXIT_FAILURE;
+		}
+		smallest = SIZE_MAX;
+		newopt(ult, RANGE+1, n, &ultable);
+
+
+		printf("optimizing comb table..\n");
+		smallest = SIZE_MAX;
+		combtable.ii = NULL;
+		for (i=0 ; i < 14 ; i++) {
+			t = newopt(combt, sizeof(combt), i, &combtable);
+			if (smallest >= t) {
+				n = i;
+				smallest = t;
+/*  			} else { */
+/*  				break; */
+			}
+		}
+		printf("smallest = %zu\n", smallest);
+		if (!(combtable.ii = malloc(smallest))) {
+			printf("couldn't allocate space!\n");
+			return EXIT_FAILURE;
+		}
+		smallest = SIZE_MAX;
+		newopt(combt, sizeof(combt), n, &combtable);
+		combtable.ti_shift += 4; /* correct for 4 entries per */
+
+
+		printf("optimizing width table..\n");
+		smallest = SIZE_MAX;
+		widthtable.ii = NULL;
+		for (i=0 ; i < 14 ; i++) {
+			t = newopt(widtht, sizeof(widtht), i, &widthtable);
+			if (smallest >= t) {
+				n = i;
+				smallest = t;
+/*  			} else { */
+/*  				break; */
+			}
+		}
+		printf("smallest = %zu\n", smallest);
+		if (!(widthtable.ii = malloc(smallest))) {
+			printf("couldn't allocate space!\n");
+			return EXIT_FAILURE;
+		}
+		smallest = SIZE_MAX;
+		newopt(widtht, sizeof(widtht), n, &widthtable);
+		widthtable.ti_shift += 4; /* correct for 4 entries per */
+
+
+#if 0
+		printf("optimizing comb3 table..\n");
+		smallest = SIZE_MAX;
+		comb3table.ii = NULL;
+		for (i=0 ; i < 14 ; i++) {
+			t = newopt(comb3t, sizeof(comb3t), i, &comb3table);
+			if (smallest >= t) {
+				n = i;
+				smallest = t;
+/*  			} else { */
+/*  				break; */
+			}
+		}
+		printf("smallest = %zu\n", smallest);
+		if (!(comb3table.ii = malloc(smallest))) {
+			printf("couldn't allocate space!\n");
+			return EXIT_FAILURE;
+		}
+		smallest = SIZE_MAX;
+		newopt(comb3t, sizeof(comb3t), n, &comb3table);
+		comb3table.ti_shift += 8; /* correct for 4 entries per */
+#endif
+
+		dump_table_data(&cttable);
+		dump_table_data(&ultable);
+		dump_table_data(&combtable);
+		dump_table_data(&widthtable);
+		}
+
+		printf("verifying for %s...\n", *argv);
+#if RANGE == 0xffffU
+		for (c=0 ; c <= 0xffffUL ; c++)
+#else
+		for (c=0 ; c <= 0x10ffffUL ; c++)
+#endif
+			{
+			unsigned int glibc;
+			unsigned int mine;
+			unsigned int upper, lower;
+
+#if 0
+#if RANGE < 0x10000UL
+			if (c == 0x10000UL) {
+				c = 0x30000UL;	/* skip 1st and 2nd sup planes */
+			}
+#elif RANGE < 0x20000UL
+			if (c == 0x20000UL) {
+				c = 0x30000UL;	/* skip 2nd sup planes */
+			}
+#endif
+#endif
+
+			glibc = 0;
+			if (iswalnum(c)) ++glibc; glibc <<= 1;
+			if (iswalpha(c)) ++glibc; glibc <<= 1;
+			if (iswblank(c)) ++glibc; glibc <<= 1;
+			if (iswcntrl(c)) ++glibc; glibc <<= 1;
+			if (iswdigit(c)) ++glibc; glibc <<= 1;
+			if (iswgraph(c)) ++glibc; glibc <<= 1;
+			if (iswlower(c)) ++glibc; glibc <<= 1;
+			if (iswprint(c)) ++glibc; glibc <<= 1;
+			if (iswpunct(c)) ++glibc; glibc <<= 1;
+			if (iswspace(c)) ++glibc; glibc <<= 1;
+			if (iswupper(c)) ++glibc; glibc <<= 1;
+			if (iswxdigit(c)) ++glibc;
+
+			{
+				unsigned int u;
+				int n, sc;
+				int i0, i1;
+
+				u = c;
+				if (u <= RANGE) {
+					sc = u & ((1 << cttable.ti_shift) - 1);
+					u >>= cttable.ti_shift;
+					n = u & ((1 << cttable.ii_shift) - 1);
+					u >>= cttable.ii_shift;
+
+					i0 = cttable.ii[u];
+					i0 <<= cttable.ii_shift;
+					i1 = cttable.ti[i0 + n];
+					i1 <<= (cttable.ti_shift-1);
+					d = cttable.ut[i1 + (sc >> 1)];
+
+					if (sc & 1) {
+						d >>= 4;
+					}
+					d &= 0x0f;
+				} else if ((((unsigned int)(c - 0xe0020UL)) <= 0x5f) || (c == 0xe0001UL)){
+					d = __CTYPE_punct;
+				} else if (((unsigned int)(c - 0xf0000UL)) < 0x20000UL) {
+					if ((c & 0xffffU) <= 0xfffdU) {
+						d = __CTYPE_punct;
+					} else {
+						d = __CTYPE_unclassified;
+					}
+				} else {
+					d = __CTYPE_unclassified;
+				}
+
+			mine = 0;
+			if (mywalnum(c)) ++mine; mine <<= 1;
+			if (mywalpha(c)) ++mine; mine <<= 1;
+			if (mywblank(c)) ++mine; mine <<= 1;
+			if (mywcntrl(c)) ++mine; mine <<= 1;
+			if (mywdigit(c)) ++mine; mine <<= 1;
+			if (mywgraph(c)) ++mine; mine <<= 1;
+			if (mywlower(c)) ++mine; mine <<= 1;
+			if (mywprint(c)) ++mine; mine <<= 1;
+			if (mywpunct(c)) ++mine; mine <<= 1;
+			if (mywspace(c)) ++mine; mine <<= 1;
+			if (mywupper(c)) ++mine; mine <<= 1;
+			if (mywxdigit(c)) ++mine;
+
+			if (glibc != mine) {
+				printf("%#8x : glibc %#4x != %#4x mine %d\n", c, glibc, mine, d);
+				if (c < 0x30000UL) {
+					printf("sc=%#x u=%#x n=%#x i0=%#x i1=%#x\n", sc, u, n, i0, i1);
+				}
+			}
+				upper = lower = u = c;
+				if (u <= RANGE) {
+					sc = u & ((1 << ultable.ti_shift) - 1);
+					u >>= ultable.ti_shift;
+					n = u & ((1 << ultable.ii_shift) - 1);
+					u >>= ultable.ii_shift;
+
+					i0 = ultable.ii[u];
+					i0 <<= ultable.ii_shift;
+					i1 = ultable.ti[i0 + n];
+					i1 <<= (ultable.ti_shift);
+					i1 += sc;
+					i0 = ultable.ut[i1];
+					upper = c + uldiff[i0].u;
+					lower = c + uldiff[i0].l;
+				}
+
+			if (towupper(c) != upper) {
+				printf("%#8x : towupper glibc %#4x != %#4x mine\n",
+					   c, towupper(c), upper);
+			}
+				
+			if (towlower(c) != lower) {
+				printf("%#8x : towlower glibc %#4x != %#4x mine   i0 = %d\n",
+					   c, towlower(c), lower, i0);
+			}
+
+			if (totitle && ((tt = towctrans(c, totitle)) != upper)) {
+				printf("%#8x : totitle glibc %#4lx != %#4x mine   i0 = %d\n",
+					   c, tt, upper, i0);
+			}
+			}
+
+
+			if ((c & 0xfff) == 0xfff) printf(".");
+		}
+		printf("done\n");
+	}
+
+	if (1) {
+		FILE *fp;
+
+		if (!(fp = fopen("wctables.h", "w"))) {
+			printf("couldn't open wctables.h!\n");
+			return EXIT_FAILURE;
+		}
+
+		fprintf(fp, "#define WC_TABLE_DOMAIN_MAX  %#8lx\n\n",
+				(unsigned long) RANGE);
+		output_table(fp, "ctype", &cttable);
+		output_table(fp, "uplow", &ultable);
+	
+
+#warning fix the upper bound on the upper/lower tables... save 200 bytes or so
+		fprintf(fp, "#define WCuplow_diffs  %7u\n", ul_count);
+		fprintf(fp, "\n#ifdef WANT_WCuplow_diff_data\n\n");
+		fprintf(fp, "\nstatic const short WCuplow_diff_data[%zu] = {",
+			   2 * (size_t) ul_count);
+		for (i=0 ; i < ul_count ; i++) {
+			if (i % 4 == 0) {
+				fprintf(fp, "\n");
+			}
+			fprintf(fp, " %6d, %6d,", uldiff[i].u, uldiff[i].l);
+		}
+		fprintf(fp, "\n};\n\n");
+		fprintf(fp, "#endif /* WANT_WCuplow_diff_data */\n\n");
+
+
+		output_table(fp, "comb", &combtable);
+		output_table(fp, "width", &widthtable);
+
+		fclose(fp);
+	}
+
+	return EXIT_SUCCESS;
+}
+
+size_t newopt(unsigned char *ut, size_t usize, int shift, table_data *tbl)
+{
+	static int recurse = 0;
+	unsigned char *ti[RANGE+1];	/* table index */
+	size_t numblocks;
+	size_t blocksize;
+	size_t uniq;
+	size_t i, j;
+	size_t smallest, t;
+	unsigned char *ii_save;
+	int uniqblock[256];
+	unsigned char uit[RANGE+1];
+	int shift2;
+
+	ii_save = NULL;
+	blocksize = 1 << shift;
+	numblocks = usize >> shift;
+
+	/* init table index */
+	for (i=j=0 ; i < numblocks ; i++) {
+		ti[i] = ut + j;
+		j += blocksize;
+	}
+
+	/* sort */
+	nu_val = blocksize;
+	qsort(ti, numblocks, sizeof(unsigned char *), nu_memcmp);
+	
+	uniq = 1;
+	uit[(ti[0]-ut)/blocksize] = 0;
+	for (i=1 ; i < numblocks ; i++) {
+		if (memcmp(ti[i-1], ti[i], blocksize) < 0) {
+			if (++uniq > 255) {
+				break;
+			}
+			uniqblock[uniq - 1] = i;
+		}
+#if 1
+		else if (memcmp(ti[i-1], ti[i], blocksize) > 0) {
+			printf("bad sort %i!\n", i);
+			abort();
+		}
+#endif
+		uit[(ti[i]-ut)/blocksize] = uniq - 1;
+	}
+
+	smallest = SIZE_MAX;
+	shift2 = -1;
+	if (uniq <= 255) {
+		smallest = numblocks + uniq * blocksize;
+		if (!recurse) {
+			++recurse;
+			for (j=1 ; j < 14 ; j++) {
+				if ((numblocks >> j) < 2) break;
+				if (tbl) {
+					ii_save = tbl->ii;
+					tbl->ii = NULL;
+				}
+				if ((t = newopt(uit, numblocks, j, tbl)) < SIZE_MAX) {
+					t += uniq * blocksize;
+				}
+				if (tbl) {
+					tbl->ii = ii_save;
+				}
+				if (smallest >= t) {
+					shift2 = j;
+					smallest = t;
+					if (!tbl->ii) {
+						printf("ishift %zu  tshift %zu  size %zu\n",
+							   shift2, shift, t);
+					}
+/*  				} else { */
+/*  					break; */
+				}
+			}
+			--recurse;
+		}
+	} else {
+		return SIZE_MAX;
+	}
+
+	if (tbl->ii) {
+		if (recurse) {
+			tbl->ii_shift = shift;
+			tbl->ii_len = numblocks;
+			memcpy(tbl->ii, uit, numblocks);
+			tbl->ti = tbl->ii + tbl->ii_len;
+			tbl->ti_len = uniq * blocksize;
+			for (i=0 ; i < uniq ; i++) {
+				memcpy(tbl->ti + i * blocksize, ti[uniqblock[i]], blocksize);
+			}
+		} else {
+			++recurse;
+			printf("setting ishift %zu  tshift %zu\n",
+							   shift2, shift);
+			newopt(uit, numblocks, shift2, tbl);
+			--recurse;
+			tbl->ti_shift = shift;
+			tbl->ut_len = uniq * blocksize;
+			tbl->ut = tbl->ti + tbl->ti_len;
+			for (i=0 ; i < uniq ; i++) {
+				memcpy(tbl->ut + i * blocksize, ti[uniqblock[i]], blocksize);
+			}
+		}
+	}
+	return smallest;
+}

+ 72 - 0
extra/locale/lmmtolso.c

@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+int main(void)
+{
+	FILE *lmm;					/* mmap-able file */
+	FILE *lso;					/* static object */
+	struct stat fd_stat;
+	int c;
+	size_t i;
+
+	if (!(lmm = fopen("locale.mmap", "r"))) {
+		printf("can't open locale.mmap!\n");
+		return EXIT_FAILURE;
+	}
+
+	if (fstat(fileno(lmm), &fd_stat)) {
+		printf("can't stat locale.mmap!\n");
+		fclose(lmm);
+		return EXIT_FAILURE;
+	}
+
+	if (!(lso = fopen("locale_data.c", "w"))) {
+		printf("can't open locale_data.c!\n");
+		fclose(lmm);
+		return EXIT_FAILURE;
+	}
+
+	fprintf(lso,
+			"#include <stddef.h>\n"
+			"#include <stdint.h>\n"
+			"#include \"lt_defines.h\"\n"
+			"#include \"locale_mmap.h\"\n\n"
+			"typedef union {\n"
+			"\tunsigned char buf[%zu];\n"
+			"\t__locale_mmap_t lmm;\n"
+			"} locale_union_t;\n\n"
+			"static const locale_union_t locale_union = { {",
+			(size_t) fd_stat.st_size
+			);
+
+	i = 0;
+	while ((c = getc(lmm)) != EOF) {
+		if (!(i & 0x7)) {
+			fprintf(lso, "\n\t");
+		}
+		fprintf(lso, "%#04x, ", c);
+		++i;
+	}
+	fprintf(lso,
+			"\n} };\n\n"
+			"const __locale_mmap_t *__locale_mmap = &locale_union.lmm;\n\n"
+			);
+
+	if (ferror(lmm)) {
+		printf("error reading!\n");
+		return EXIT_FAILURE;
+	}
+
+	if (ferror(lso) || fclose(lso)) {
+		printf("error writing!\n");
+		return EXIT_FAILURE;
+	}
+
+	fclose(lmm);
+
+	return EXIT_SUCCESS;
+}

+ 89 - 0
extra/locale/locale_mmap.h

@@ -0,0 +1,89 @@
+/* #include "lt_defines.h" */
+
+/* TODO - fix */
+#define MAGIC_SIZE 64
+
+/* TODO - fix */
+#ifdef __WCHAR_ENABLED
+#define WCctype_TBL_LEN		(WCctype_II_LEN + WCctype_TI_LEN + WCctype_UT_LEN)
+#define WCuplow_TBL_LEN		(WCuplow_II_LEN + WCuplow_TI_LEN + WCuplow_UT_LEN)
+#define WCuplow_diff_TBL_LEN (2 * WCuplow_diffs)
+#define WCcomb_TBL_LEN		(WCcomb_II_LEN + WCcomb_TI_LEN + WCcomb_UT_LEN)
+#endif
+
+#undef __PASTE2
+#define __PASTE2(A,B)		A ## B
+#undef __PASTE3
+#define __PASTE3(A,B,C)		A ## B ## C
+
+#define COMMON_MMAP(X) \
+	unsigned char	__PASTE3(lc_,X,_data)[__PASTE3(__lc_,X,_data_LEN)];
+
+#define COMMON_MMIDX(X) \
+	unsigned char	__PASTE3(lc_,X,_rows)[__PASTE3(__lc_,X,_rows_LEN)]; \
+	uint16_t		__PASTE3(lc_,X,_item_offsets)[__PASTE3(__lc_,X,_item_offsets_LEN)]; \
+	uint16_t		__PASTE3(lc_,X,_item_idx)[__PASTE3(__lc_,X,_item_idx_LEN)]; \
+
+
+typedef struct {
+	unsigned char magic[MAGIC_SIZE];
+
+#ifdef __CTYPE_HAS_8_BIT_LOCALES
+	const unsigned char tbl8ctype[Cctype_TBL_LEN];
+    const unsigned char tbl8uplow[Cuplow_TBL_LEN];
+#ifdef __WCHAR_ENABLED
+	const uint16_t tbl8c2wc[Cc2wc_TBL_LEN]; /* char > 0x7f to wide char */
+	const unsigned char tbl8wc2c[Cwc2c_TBL_LEN];
+	/* translit  */
+#endif /* __WCHAR_ENABLED */
+#endif /* __CTYPE_HAS_8_BIT_LOCALES */
+#ifdef __WCHAR_ENABLED
+	const unsigned char tblwctype[WCctype_TBL_LEN];
+	const unsigned char tblwuplow[WCuplow_TBL_LEN];
+	const int16_t tblwuplow_diff[WCuplow_diff_TBL_LEN];
+	const unsigned char tblwcomb[WCcomb_TBL_LEN];
+	/* width?? */
+#endif /* __WCHAR_ENABLED */
+
+	COMMON_MMAP(numeric);
+	COMMON_MMAP(monetary);
+	COMMON_MMAP(time);
+
+	/* TODO -- collate*/
+
+	COMMON_MMAP(messages);
+
+
+#ifdef __CTYPE_HAS_8_BIT_LOCALES
+	const codeset_8_bit_t codeset_8_bit[NUM_CODESETS];
+#endif /* __CTYPE_HAS_8_BIT_LOCALES */
+
+	COMMON_MMIDX(numeric);
+	COMMON_MMIDX(monetary);
+	COMMON_MMIDX(time);
+
+	/* TODO -- collate*/
+
+	COMMON_MMIDX(messages);
+
+
+	unsigned char lc_common_item_offsets_LEN[CATEGORIES];
+    size_t lc_common_tbl_offsets[CATEGORIES * 4];
+	/* offsets from start of locale_mmap_t */
+	/* rows, item_offsets, item_idx, data */
+
+#ifdef NUM_LOCALES
+	unsigned char locales[NUM_LOCALES * WIDTH_LOCALES];
+	unsigned char locale_names5[5*NUM_LOCALE_NAMES];
+	unsigned char locale_at_modifiers[LOCALE_AT_MODIFIERS_LENGTH];
+#endif /* NUM_LOCALES */
+
+	unsigned char lc_names[lc_names_LEN];
+#ifdef __CTYPE_HAS_8_BIT_LOCALES
+	unsigned char codeset_list[sizeof(CODESET_LIST)]; /* TODO - fix */
+#endif /* __CTYPE_HAS_8_BIT_LOCALES */
+
+
+} __locale_mmap_t;
+
+extern const __locale_mmap_t *__locale_mmap;

+ 110 - 66
include/ctype.h

@@ -1,82 +1,126 @@
-/* vi: set sw=4 ts=4: */
-/*
- * ctype.h
- * Character classification and conversion
+/*  Copyright (C) 2002     Manuel Novoa III
  *
- * Copyright (C) 2000 by Lineo, inc.
- * Copyright (C) 2000,2001 Erik Andersen <andersee@debian.org>
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#ifndef __CTYPE_H
-#define __CTYPE_H
+/* NOTE: It is assumed here and throughout the library that the underlying
+ * char encoding for the portable C character set is ASCII (host & target). */
+
+#ifndef _CTYPE_H
+#define _CTYPE_H
 
 #include <features.h>
+#include <bits/uClibc_ctype.h>
 
 __BEGIN_DECLS
 
+extern int isalnum(int c) __THROW;
+extern int isalpha(int c) __THROW;
+#ifdef __USE_ISOC99
+extern int isblank(int c) __THROW;
+#endif
+extern int iscntrl(int c) __THROW;
+extern int isdigit(int c) __THROW;
+extern int isgraph(int c) __THROW;
+extern int islower(int c) __THROW;
+extern int isprint(int c) __THROW;
+extern int ispunct(int c) __THROW;
+extern int isspace(int c) __THROW;
+extern int isupper(int c) __THROW;
+extern int isxdigit(int c) __THROW;
 
-/* function prototpes */ 
-extern int isalnum(int c);
-extern int isalpha(int c);
-extern int isascii(int c);
-extern int isblank(int c);
-extern int iscntrl(int c);
-extern int isdigit(int c);
-extern int isgraph(int c);
-extern int islower(int c);
-extern int isprint(int c);
-extern int ispunct(int c);
-extern int isspace(int c);
-extern int isupper(int c);
-extern int isxdigit(int c);
-extern int isxlower(int c);
-extern int isxupper(int c);
-extern int toascii(int c);
-extern int tolower(int c);
-extern int toupper(int c);
-
-
-/* Locale-compatible macros/inlines have yet to be implemented. */
-#if defined(__USE_CTYPE_MACROS) && !defined __UCLIBC_HAS_LOCALE__
-
-/* macro definitions */
-#define isalnum(c)  (isalpha(c) || isdigit(c))
-#define isalpha(c)  (isupper(c) || islower(c))
-#define isascii(c)  (c > 0 && c <= 0x7f)
-#define isblank(c)  (c == ' ' || c == '\t')
-#define iscntrl(c)  ((c >= 0) && ((c <= 0x1F) || (c == 0x7f)))
-#define isdigit(c)  (c >= '0' && c <= '9')
-#define isgraph(c)  (c != ' ' && isprint(c))
-#define islower(c)  (c >=  'a' && c <= 'z')
-#define isprint(c)  (c >= ' ' && c <= '~')
-#define ispunct(c)  ((c > ' ' && c <= '~') && !isalnum(c))
-#define isspace(c)  (c == ' ' || c == '\f' || c == '\n' || c == '\r' ||\
-			c == '\t' || c == '\v')
-#define isupper(c)  (c >=  'A' && c <= 'Z')
-#define isxdigit(c) (isxupper(c) || isxlower(c))
-#define isxlower(c) (isdigit(c) || (c >= 'a' && c <= 'f'))
-#define isxupper(c) (isdigit(c) || (c >= 'A' && c <= 'F'))
-#define toascii(c)  (c & 0x7f)
-#define tolower(c)  (isupper(c) ? ( c - 'A' + 'a') : (c))
-#define toupper(c)  (islower(c) ? (c - 'a' + 'A') : (c))
+extern int tolower(int c) __THROW;
+extern int toupper(int c) __THROW;
 
+#if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN
+extern int isascii(int c) __THROW;
+extern int toascii(int c) __THROW;
 #endif
 
+/* The following are included for compatibility with older versions of
+ * uClibc; but now they're only visible if MISC funcctionality is requested.
+ * However, as they are locale-independent, the hidden macro versions are
+ * always present. */
+#ifdef __USE_MISC
+extern int isxlower(int c) __THROW;	/* uClibc-specific. */
+extern int isxupper(int c) __THROW;	/* uClibc-specific. */
+#endif
+
+/* Next, some ctype macros which are valid for all supported locales. */
+/* WARNING: isspace and isblank need to be reverified if more 8-bit codesets
+ * are added!!!  But isdigit and isxdigit are always valid. */
+
+#define __isspace(c)	__C_isspace(c)
+#define __isblank(c)	__C_isblank(c)
+
+#define __isdigit(c)	__C_isdigit(c)
+#define __isxdigit(c)	__C_isxdigit(c)
+
+/* Now some non-ansi/iso c99 macros. */
+
+#define __isascii(c) (((unsigned int)(c)) <= 0x7f)
+#define __toascii(c) ((c) & 0x7f)
+
+#define _toupper(c) ((c) | 0x20)
+#define _tolower(c) ((c) ^ 0x20)
+
+/* For compatibility with older versions of uClibc.  Are these ever used? */
+#define __isxlower(c)	__C_isxlower(c)	/* uClibc-specific. */
+#define __isxupper(c)	__C_isxupper(c)	/* uClibc-specific. */
+
+/* Apparently, glibc implements things as macros if __NO_CTYPE isn't defined.
+ * If we don't have locale support, we'll do the same.  Otherwise, we'll
+ * only use macros for the supported-locale-invariant cases. */
+#ifndef __NO_CTYPE
+
+#define isdigit(c)	__isdigit(c)
+#define isxdigit(c)	__isxdigit(c)
+#define isspace(c)	__isspace(c)
+#ifdef __USE_ISOC99
+#define isblank(c)	__isblank(c)
+#endif
+
+#if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN
+#define isascii(c)	__isascii(c)
+#define toascii(c)	__toascii(c)
+#endif
+
+#ifdef __USE_MISC
+#define isxlower(c)	__C_isxlower(c)	/* uClibc-specific. */
+#define isxupper(c)	__C_isxupper(c)	/* uClibc-specific. */
+#endif
+
+/* TODO - Should test for 8-bit codesets instead, but currently impossible. */
+#ifndef __UCLIBC_HAS_LOCALE__
+
+#define isalnum(c)	__C_isalnum(c)
+#define isalpha(c)	__C_isalpha(c)
+#define iscntrl(c)	__C_iscntrl(c)
+#define isgraph(c)	__C_isgraph(c)
+#define islower(c)	__C_islower(c)
+#define isprint(c)	__C_isprint(c)
+#define ispunct(c)	__C_ispunct(c)
+#define isupper(c)	__C_isupper(c)
+
+#define tolower(c)	__C_tolower(c)
+#define toupper(c)	__C_toupper(c)
+
+#endif /*  __UCLIBC_HAS_LOCALE__ */
+
+#endif /* __NO_CTYPE */
+
 __END_DECLS
 
-#endif /* __CTYPE_H */
+#endif /* _CTYPE_H */

+ 2 - 2
include/inttypes.h

@@ -27,7 +27,7 @@
 /* Get the type definitions.  */
 #include <stdint.h>
 
-#if 0
+#if __UCLIBC_HAS_WCHAR__
 /* Get a definition for wchar_t.  But we must not define wchar_t itself.  */
 #ifndef ____gwchar_t_defined
 # ifdef __cplusplus
@@ -311,7 +311,7 @@ extern intmax_t strtoimax (__const char *__restrict __nptr,
 extern uintmax_t strtoumax (__const char *__restrict __nptr,
 			    char ** __restrict __endptr, int __base) __THROW;
 
-#if 0
+#if __UCLIBC_HAS_WCHAR__
 /* Like `wcstol' but convert to `intmax_t'.  */
 extern intmax_t wcstoimax (__const __gwchar_t *__restrict __nptr,
 			   __gwchar_t **__restrict __endptr, int __base)

+ 28 - 8
include/langinfo.h

@@ -23,7 +23,7 @@
 /* Get the type definition.  */
 #include <nl_types.h>
 
-#include <bits/locale.h>	/* Define the __LC_* category names.  */
+#include <bits/uClibc_locale.h>	/* Define the __LC_* category names.  */
 
 
 __BEGIN_DECLS
@@ -32,11 +32,12 @@ __BEGIN_DECLS
    (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))
+#define _NL_ITEM(category, index) \
+	(((category) << __NL_ITEM_CATEGORY_SHIFT) | (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)
+#define _NL_ITEM_CATEGORY(item)		((int) (item) >> __NL_ITEM_CATEGORY_SHIFT)
+#define _NL_ITEM_INDEX(item)		((int) (item) & __NL_ITEM_INDEX_MASK)
 
 
 /* Enumeration of locale items that can be queried with `nl_langinfo'.  */
@@ -157,6 +158,7 @@ enum
   ERA_T_FMT,			/* Time in alternate era format.  */
 #define ERA_T_FMT		ERA_T_FMT
 
+#if 0
   _NL_TIME_ERA_NUM_ENTRIES,	/* Number entries in the era arrays.  */
   _NL_TIME_ERA_ENTRIES,		/* Structure with era entries in usable form.*/
 
@@ -232,12 +234,14 @@ enum
   _NL_W_DATE_FMT,
 
   _NL_TIME_CODESET,
+#endif /* 0 */
 
   _NL_NUM_LC_TIME,	/* Number of indices in LC_TIME category.  */
 
   /* LC_COLLATE category: text sorting.
      This information is accessed by the strcoll and strxfrm functions.
      These `nl_langinfo' names are used only internally.  */
+#if 0
   _NL_COLLATE_NRULES = _NL_ITEM (__LC_COLLATE, 0),
   _NL_COLLATE_RULESETS,
   _NL_COLLATE_TABLEMB,
@@ -258,10 +262,12 @@ enum
   _NL_COLLATE_COLLSEQWC,
   _NL_COLLATE_CODESET,
   _NL_NUM_LC_COLLATE,
+#endif
 
   /* LC_CTYPE category: character classification.
      This information is accessed by the functions in <ctype.h>.
      These `nl_langinfo' names are used only internally.  */
+#if 0
   _NL_CTYPE_CLASS = _NL_ITEM (__LC_CTYPE, 0),
   _NL_CTYPE_TOUPPER,
   _NL_CTYPE_GAP1,
@@ -349,6 +355,11 @@ enum
   _NL_CTYPE_EXTRA_MAP_13,
   _NL_CTYPE_EXTRA_MAP_14,
   _NL_NUM_LC_CTYPE,
+#else  /* 0 */
+  _NL_CTYPE_CODESET_NAME = _NL_ITEM (__LC_CTYPE, 0),
+  CODESET = _NL_CTYPE_CODESET_NAME,
+#define CODESET			CODESET
+#endif /* 0 */
 
   /* LC_MONETARY category: formatting of monetary quantities.
      These items each correspond to a member of `struct lconv',
@@ -413,8 +424,6 @@ enum
 #ifdef __USE_GNU
 # define N_SIGN_POSN		__N_SIGN_POSN
 #endif
-  _NL_MONETARY_CRNCYSTR,
-#define CRNCYSTR		_NL_MONETARY_CRNCYSTR
   __INT_P_CS_PRECEDES,
 #ifdef __USE_GNU
 # define INT_P_CS_PRECEDES	__INT_P_CS_PRECEDES
@@ -439,6 +448,11 @@ enum
 #ifdef __USE_GNU
 # define INT_N_SIGN_POSN	__INT_N_SIGN_POSN
 #endif
+
+  _NL_MONETARY_CRNCYSTR,
+#define CRNCYSTR		_NL_MONETARY_CRNCYSTR
+
+#if 0
   _NL_MONETARY_DUO_INT_CURR_SYMBOL,
   _NL_MONETARY_DUO_CURRENCY_SYMBOL,
   _NL_MONETARY_DUO_INT_FRAC_DIGITS,
@@ -463,6 +477,7 @@ enum
   _NL_MONETARY_DECIMAL_POINT_WC,
   _NL_MONETARY_THOUSANDS_SEP_WC,
   _NL_MONETARY_CODESET,
+#endif /* 0 */
   _NL_NUM_LC_MONETARY,
 
   /* LC_NUMERIC category: formatting of numbers.
@@ -483,15 +498,18 @@ enum
 #ifdef __USE_GNU
 # define GROUPING		__GROUPING
 #endif
+#if 0
   _NL_NUMERIC_DECIMAL_POINT_WC,
   _NL_NUMERIC_THOUSANDS_SEP_WC,
   _NL_NUMERIC_CODESET,
+#endif
   _NL_NUM_LC_NUMERIC,
 
   __YESEXPR = _NL_ITEM (__LC_MESSAGES, 0), /* Regex matching ``yes'' input.  */
 #define YESEXPR			__YESEXPR
   __NOEXPR,			/* Regex matching ``no'' input.  */
 #define NOEXPR			__NOEXPR
+#if 0
   __YESSTR,			/* Output string for ``yes''.  */
 #if defined __USE_GNU || (defined __USE_XOPEN && !defined __USE_XOPEN2K)
 # define YESSTR			__YESSTR
@@ -501,8 +519,10 @@ enum
 # define NOSTR			__NOSTR
 #endif
   _NL_MESSAGES_CODESET,
+#endif
   _NL_NUM_LC_MESSAGES,
 
+#if 0
   _NL_PAPER_HEIGHT = _NL_ITEM (__LC_PAPER, 0),
   _NL_PAPER_WIDTH,
   _NL_PAPER_CODESET,
@@ -560,7 +580,7 @@ enum
   _NL_IDENTIFICATION_CATEGORY,
   _NL_IDENTIFICATION_CODESET,
   _NL_NUM_LC_IDENTIFICATION,
-
+#endif
   /* This marks the highest value used.  */
   _NL_NUM
 };
@@ -585,7 +605,7 @@ extern char *nl_langinfo (nl_item __item) __THROW;
 
 /* Just like nl_langinfo but get the information from the locale object L.  */
 extern char *__nl_langinfo_l (nl_item __item, __locale_t l);
-#endif
+#endif /* 0 */
 
 __END_DECLS
 

+ 0 - 2
include/libgen.h

@@ -26,7 +26,6 @@ __BEGIN_DECLS
 /* Return directory part of PATH or "." if none is available.  */
 extern char *dirname (char *__path) __THROW;
 
-#if 0
 /* Return final component of PATH.
 
    This is the weird XPG version of this function.  It sometimes will
@@ -35,7 +34,6 @@ extern char *dirname (char *__path) __THROW;
    version available under the real name.  */
 extern char *__xpg_basename (char *__path) __THROW;
 #define basename	__xpg_basename
-#endif
 
 __END_DECLS
 

+ 100 - 20
include/locale.h

@@ -1,30 +1,51 @@
-/* locale.h
- * Support international type specific characters.
+/* Copyright (C) 1991,92,1995-1999,2000,2001 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/*
+ *	ISO C99 Standard: 7.11 Localization	<locale.h>
  */
-#ifndef _LOCALE_H
-#define _LOCALE_H       1
+
+#ifndef	_LOCALE_H
+#define	_LOCALE_H	1
 
 #include <features.h>
 
-__BEGIN_DECLS
+#define __need_NULL
+#include <stddef.h>
+#include <bits/uClibc_locale.h>
 
-#ifndef NULL
-#ifdef __cplusplus
-#define NULL    0
-#else
-#define NULL    ((void *) 0)
-#endif
-#endif
+__BEGIN_DECLS
 
 /* These are the possibilities for the first argument to setlocale.
-   The code assumes that LC_ALL is the highest value, and zero the lowest.  */
-#define LC_CTYPE        0
-#define LC_NUMERIC      1
-#define LC_TIME         2
-#define LC_COLLATE      3
-#define LC_MONETARY     4
-#define LC_MESSAGES     5
-#define LC_ALL          6
+   The code assumes that the lowest LC_* symbol has the value zero.  */
+#define LC_CTYPE          __LC_CTYPE
+#define LC_NUMERIC        __LC_NUMERIC
+#define LC_TIME           __LC_TIME
+#define LC_COLLATE        __LC_COLLATE
+#define LC_MONETARY       __LC_MONETARY
+#define LC_MESSAGES       __LC_MESSAGES
+/*  #define LC_PAPER          __LC_PAPER */
+/*  #define LC_NAME           __LC_NAME */
+/*  #define LC_ADDRESS        __LC_ADDRESS */
+/*  #define LC_TELEPHONE	  __LC_TELEPHONE */
+/*  #define LC_MEASUREMENT	  __LC_MEASUREMENT */
+/*  #define LC_IDENTIFICATION __LC_IDENTIFICATION */
+#define	LC_ALL            __LC_ALL
 
 
 /* Structure giving information about numeric and monetary notation.  */
@@ -70,6 +91,31 @@ struct lconv
      4 The sign string immediately follows the currency_symbol.  */
   char p_sign_posn;
   char n_sign_posn;
+#ifdef __USE_ISOC99
+  /* 1 if int_curr_symbol precedes a positive value, 0 if succeeds.  */
+  char int_p_cs_precedes;
+  /* 1 iff a space separates int_curr_symbol from a positive value.  */
+  char int_p_sep_by_space;
+  /* 1 if int_curr_symbol precedes a negative value, 0 if succeeds.  */
+  char int_n_cs_precedes;
+  /* 1 iff a space separates int_curr_symbol from a negative value.  */
+  char int_n_sep_by_space;
+  /* Positive and negative sign positions:
+     0 Parentheses surround the quantity and int_curr_symbol.
+     1 The sign string precedes the quantity and int_curr_symbol.
+     2 The sign string follows the quantity and int_curr_symbol.
+     3 The sign string immediately precedes the int_curr_symbol.
+     4 The sign string immediately follows the int_curr_symbol.  */
+  char int_p_sign_posn;
+  char int_n_sign_posn;
+#else
+  char __int_p_cs_precedes;
+  char __int_p_sep_by_space;
+  char __int_n_cs_precedes;
+  char __int_n_sep_by_space;
+  char __int_p_sign_posn;
+  char __int_n_sign_posn;
+#endif
 };
 
 
@@ -79,6 +125,40 @@ extern char *setlocale (int __category, __const char *__locale) __THROW;
 /* Return the numeric/monetary information for the current locale.  */
 extern struct lconv *localeconv (void) __THROW;
 
+#if 0
+/*  #ifdef	__USE_GNU */
+/* The concept of one static locale per category is not very well
+   thought out.  Many applications will need to process its data using
+   information from several different locales.  Another application is
+   the implementation of the internationalization handling in the
+   upcoming ISO C++ standard library.  To support this another set of
+   the functions using locale data exist which have an additional
+   argument.
+
+   Attention: all these functions are *not* standardized in any form.
+   This is a proof-of-concept implementation.  */
+
+/* Get locale datatype definition.  */
+# include <xlocale.h>
+
+/* Return a reference to a data structure representing a set of locale
+   datasets.  Unlike for the CATEGORY parameter for `setlocale' the
+   CATEGORY_MASK parameter here uses a single bit for each category.
+   I.e., 1 << LC_CTYPE means to load data for this category.  If
+   BASE is non-null the appropriate category information in the BASE
+   record is replaced.  */
+extern __locale_t __newlocale (int __category_mask, __const char *__locale,
+			       __locale_t __base) __THROW;
+
+/* Return a duplicate of the set of locale in DATASET.  All usage
+   counters are increased if necessary.  */
+extern __locale_t __duplocale (__locale_t __dataset) __THROW;
+
+/* Free the data associated with a locale dataset previously returned
+   by a call to `setlocale_r'.  */
+extern void __freelocale (__locale_t __dataset) __THROW;
+#endif
+
 __END_DECLS
 
 #endif /* locale.h  */

+ 5 - 7
include/stdint.h

@@ -24,11 +24,9 @@
 #define _STDINT_H	1
 
 #include <features.h>
-#if 0
-/*#define __need_wchar_t*/
-#include <stddef.h>
-#endif
-/*#include <bits/wchar.h>*/
+#ifdef __UCLIBC_HAS_WCHAR__
+#include <bits/wchar.h>
+#endif /* __UCLIBC_HAS_WCHAR__ */
 #include <bits/wordsize.h>
 
 /* Exact integral types.  */
@@ -280,18 +278,18 @@ typedef unsigned long long int	uintmax_t;
 #  define SIZE_MAX		(4294967295U)
 # endif
 
-#if 0
+#ifdef __UCLIBC_HAS_WCHAR__
 /* Limits of `wchar_t'.  */
 # ifndef WCHAR_MIN
 /* These constants might also be defined in <wchar.h>.  */
 #  define WCHAR_MIN		__WCHAR_MIN
 #  define WCHAR_MAX		__WCHAR_MAX
 # endif
-#endif
 
 /* Limits of `wint_t'.  */
 # define WINT_MIN		(0u)
 # define WINT_MAX		(4294967295u)
+#endif /* __UCLIBC_HAS_WCHAR__ */
 
 #endif	/* C++ && limit macros */
 

+ 6 - 6
include/stdlib.h

@@ -27,7 +27,7 @@
 /* Get size_t, wchar_t and NULL from <stddef.h>.  */
 #define		__need_size_t
 #ifndef __need_malloc_and_calloc
-#if 0
+#ifdef __UCLIBC_HAS_WCHAR__
 # define	__need_wchar_t
 #endif
 # define	__need_NULL
@@ -130,10 +130,10 @@ __extension__ typedef struct
 #define	EXIT_SUCCESS	0	/* Successful exit status.  */
 
 
-#if 0
+#ifdef __UCLIBC_HAS_WCHAR__
 /* Maximum length of a multibyte character in the current locale.  */
-#define	MB_CUR_MAX	(__ctype_get_mb_cur_max ())
-extern size_t __ctype_get_mb_cur_max (void) __THROW;
+#define	MB_CUR_MAX	(_stdlib_mb_cur_max ())
+extern size_t _stdlib_mb_cur_max (void) __THROW;
 #endif
 
 /* Convert a string to a floating-point number.  */
@@ -776,7 +776,7 @@ extern int qfcvt_r (long double __value, int __ndigit,
 # endif	/* misc */
 #endif	/* use MISC || use X/Open Unix */
 
-#if 0
+#ifdef __UCLIBC_HAS_WCHAR__
 /* Return the length of the multibyte character
    in S, which is no longer than N.  */
 extern int mblen (__const char *__s, size_t __n) __THROW;
@@ -796,7 +796,7 @@ extern size_t mbstowcs (wchar_t *__restrict  __pwcs,
 extern size_t wcstombs (char *__restrict __s,
 			__const wchar_t *__restrict __pwcs, size_t __n)
      __THROW;
-#endif
+#endif /* def __UCLIBC_HAS_WCHAR__ */
 
 #ifdef __USE_SVID
 /* Determine whether the string value of RESPONSE matches the affirmation

+ 3 - 0
libc/misc/Makefile

@@ -34,6 +34,9 @@ endif
 ifeq ($(strip $(INCLUDE_THREADS)),true)
 DIRS += pthread
 endif
+ifeq ($(strip $(HAS_WCHAR)),true)
+DIRS += wctype # wchar
+endif
 
 all: libc.a
 

+ 1 - 4
libc/misc/ctype/Makefile

@@ -28,10 +28,7 @@ MSRC=ctype.c
 MOBJ= isalnum.o isalpha.o isascii.o iscntrl.o isdigit.o isgraph.o \
 	islower.o isprint.o ispunct.o isspace.o isupper.o isxdigit.o \
 	isxlower.o isxupper.o toascii.o tolower.o toupper.o isblank.o \
-
-ifeq ($(HAS_LOCALE),true)
-	MOBJ += ctype_C.o
-endif
+	__isctype_loc.o
 
 CSRC=junk.c
 COBJS=$(patsubst %.c,%.o, $(CSRC))

+ 237 - 249
libc/misc/ctype/ctype.c

@@ -1,341 +1,329 @@
-/* ctype.c
- * Character classification and conversion
- * Copyright (C) 2000 Lineo, Inc.
- * Written by Erik Andersen
- * This file is part of the uClibc C library and is distributed
- * under the GNU Library General Public License.
+/*  Copyright (C) 2002     Manuel Novoa III
  *
- * not C-locale only code
- * written by Vladimir Oleynik (c) vodz@usa.net
- * and Manuel Novoa III <mnovoa3@bellsouth.net>
- * used ideas is part of the GNU C Library.
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define __USE_CTYPE_MACROS
+/*  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!
+ *
+ *  Besides uClibc, I'm using this code in my libc for elks, which is
+ *  a 16-bit environment with a fairly limited compiler.  It would make
+ *  things much easier for me if this file isn't modified unnecessarily.
+ *  In particular, please put any new or replacement functions somewhere
+ *  else, and modify the makefile to use your version instead.
+ *  Thanks.  Manuel
+ *
+ *  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION! */
+
+#define _GNU_SOURCE
+#define __NO_CTYPE
+
 #include <ctype.h>
+#include <stdio.h>
+#include <limits.h>
+#include <assert.h>
+#include <locale.h>
 
-#ifdef L_isascii
-#undef isascii
-int
-isascii( int c )
-{
-    return (c > 0 && c <= 0x7f);
-}
-#endif
+/**********************************************************************/
 
-#ifdef L_isdigit
-#undef isdigit
-int
-isdigit( int c )
-{
-    return (c >= '0' && c <= '9');
-}
-#endif
+extern int __isctype_loc(int c, int ct);
 
-#ifdef L_toascii
-#undef toascii
-int
-toascii( int c )
-{
-    return (c & 0x7f);
-}
-#endif
+/* Some macros used throughout the file. */
+#define U		((unsigned char)c)
+/*  #define LCT		(__cur_locale->ctype) */
+#define LCT		(&__global_locale)
 
-#ifdef L_isblank
-#undef isblank
-int
-isblank( int c )
-{
-    return ((c == ' ') || (c == '\t'));
-}
+/**********************************************************************/
+
+#ifndef __PASTE
+#define __PASTE(X,Y)		X ## Y
 #endif
 
-/* locale depended */
-#ifndef __UCLIBC_HAS_LOCALE__
+#define C_MACRO(X)		__PASTE(__C_,X)(c)
 
-#ifdef L_isalpha
-#undef isalpha
-int
-isalpha( int c )
-{
-    return (isupper(c) || islower(c));
-}
-#endif
+#define CT_MACRO(X)		__PASTE(__ctype_,X)(c)
 
-#ifdef L_isalnum
-#undef isalnum
-int
-isalnum( int c )
-{
-    return (isalpha(c) || isdigit(c));
-}
-#endif
+/**********************************************************************/
 
-#ifdef L_iscntrl
-#undef iscntrl
-int
-iscntrl( int c )
-{
-    return ((c >= 0) && ((c <= 0x1f) || (c == 0x7f)));
-}
-#endif
+#ifndef __CTYPE_HAS_8_BIT_LOCALES
 
-#ifdef L_isgraph
-#undef isgraph
-int
-isgraph( int c )
-{
-    return (c > ' ' && isprint(c));
+#define IS_FUNC_BODY(NAME) \
+int NAME (int c) \
+{ \
+	return C_MACRO(NAME); \
 }
-#endif
 
-#ifdef L_islower
-#undef islower
-int
-islower( int c )
-{
-    return (c >=  'a' && c <= 'z');
-}
-#endif
+#else
 
-#ifdef L_isprint
-#undef isprint
-int
-isprint( int c )
-{
-    return (c >= ' ' && c <= '~');
-}
-#endif
+/* It may be worth defining __isctype_loc over the whole range of char. */
+/*  #define IS_FUNC_BODY(NAME) \ */
+/*  int NAME (int c) \ */
+/*  { \ */
+/*  	return __isctype_loc(c, __PASTE(_CTYPE_,NAME)); \ */
+/*  } */
 
-#ifdef L_ispunct
-#undef ispunct
-int
-ispunct( int c )
-{
-    return ((c > ' ' && c <= '~') && !isalnum(c));
+#define IS_FUNC_BODY(NAME) \
+int NAME (int c) \
+{ \
+	if (((unsigned int) c) <= 0x7f) { \
+		return C_MACRO(NAME); \
+	} \
+	return __isctype_loc(c, __PASTE(_CTYPE_,NAME)); \
 }
-#endif
 
-#ifdef L_isspace
-#undef isspace
-int
-isspace( int c )
-{
-    return (c == ' ' || c == '\f' || c == '\n' || c == '\r' ||
-	    c == '\t' || c == '\v');
-}
-#endif
+#endif /* __CTYPE_HAS_8_BIT_LOCALES */
 
-#ifdef L_isupper
-#undef isupper
-int
-isupper( int c )
-{
-    return (c >=  'A' && c <= 'Z');
-}
-#endif
+/**********************************************************************/
+#ifdef L_isalnum
+
+IS_FUNC_BODY(isalnum);
 
-#ifdef L_isxdigit
-#undef isxdigit
-int
-isxdigit( int c )
-{
-    return (isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
-}
 #endif
+/**********************************************************************/
+#ifdef L_isalpha
+
+IS_FUNC_BODY(isalpha);
 
-#ifdef L_isxlower
-#undef isxlower
-int
-isxlower( int c )
-{
-    return (isdigit(c) || (c >= 'a' && c <= 'f'));
-}
 #endif
+/**********************************************************************/
+#ifdef L_isblank
 
-#ifdef L_isxupper
-#undef isxupper
-int
-isxupper( int c )
+/* Warning!!! This is correct for all the currently supported 8-bit locales.
+ * If any are added though, this will need to be verified. */
+
+int isblank(int c)
 {
-    return (isdigit(c) || (c >= 'A' && c <= 'F'));
+	return __isblank(c);
 }
+
 #endif
+/**********************************************************************/
+#ifdef L_iscntrl
+
+IS_FUNC_BODY(iscntrl);
 
-#ifdef L_tolower
-#undef tolower
-int
-tolower( int c )
-{
-    return (isupper(c) ? (c - 'A' + 'a') : (c));
-}
 #endif
+/**********************************************************************/
+#ifdef L_isdigit
 
-#ifdef L_toupper
-#undef toupper
-int
-toupper( int c )
+int isdigit(int c)
 {
-    return (islower(c) ? (c - 'a' + 'A') : (c));
+	return __isdigit(c);
 }
+
 #endif
+/**********************************************************************/
+#ifdef L_isgraph
 
-#else   /* __UCLIBC_HAS_LOCALE__ */
+IS_FUNC_BODY(isgraph);
 
-#include <limits.h>
-#include "../locale/_locale.h"
+#endif
+/**********************************************************************/
+#ifdef L_islower
 
-#define _UC_ISCTYPE(c, type) \
-((c != -1) && ((_uc_ctype_b[(int)((unsigned char)c)] & type) != 0))
+IS_FUNC_BODY(islower);
 
-#define _UC_ISCTYPE2(c, type, type2) \
-((c != -1) && ((_uc_ctype_b[(int)((unsigned char)c)] & type) == type2))
+#endif
+/**********************************************************************/
+#ifdef L_isprint
 
+IS_FUNC_BODY(isprint);
 
-#ifdef L_ctype_C
+#endif
+/**********************************************************************/
+#ifdef L_ispunct
 
-/* startup setlocale(LC_TYPE, "C"); */
-#include "ctype_C.c"
+IS_FUNC_BODY(ispunct);
 
-const unsigned char *_uc_ctype_b     = _uc_ctype_b_C;
-const unsigned char *_uc_ctype_trans = _uc_ctype_b_C+LOCALE_BUF_SIZE/2;
+#endif
+/**********************************************************************/
+#ifdef L_isspace
 
-#endif  /* L_ctype_C */
+/* Warning!!! This is correct for all the currently supported 8-bit locales.
+ * If any are added though, this will need to be verified. */
 
-#ifdef L_isalpha
-#undef isalpha
-int
-isalpha( int c )
+int isspace(int c)
 {
-    return _UC_ISCTYPE(c, ISalpha);
+	return __isspace(c);
 }
-#endif
 
-#ifdef L_isalnum
-#undef isalnum
-int
-isalnum( int c )
-{
-    return _UC_ISCTYPE(c, (ISalpha|ISxdigit));
-}
 #endif
+/**********************************************************************/
+#ifdef L_isupper
+
+IS_FUNC_BODY(isupper);
 
-#ifdef L_iscntrl
-#undef iscntrl
-int
-iscntrl( int c )
-{
-    return _UC_ISCTYPE(c, IScntrl);
-}
 #endif
+/**********************************************************************/
+#ifdef L_isxdigit
 
-#ifdef L_isgraph
-#undef isgraph
-int
-isgraph( int c )
+int isxdigit(int c)
 {
-    return _UC_ISCTYPE2(c, (ISprint|ISspace), ISprint);
+	return __isxdigit(c);
 }
+
 #endif
+/**********************************************************************/
+#ifdef L_tolower
 
-#ifdef L_islower
-#undef islower
-int
-islower( int c )
+#ifdef __CTYPE_HAS_8_BIT_LOCALES
+
+int tolower(int c)
 {
-    return _UC_ISCTYPE(c, ISlower);
+	return ((((unsigned int) c) <= 0x7f)
+			|| (LCT->encoding != __ctype_encoding_8_bit))
+		? __C_tolower(c)
+		: ( __isctype_loc(c, _CTYPE_isupper)
+			? (unsigned char)
+			( U - LCT->tbl8uplow[ ((int)
+								   (LCT->idx8uplow[(U & 0x7f)
+												  >> Cuplow_IDX_SHIFT])
+								   << Cuplow_IDX_SHIFT)
+								+ (U & ((1 << Cuplow_IDX_SHIFT) - 1)) ])
+			: c );
 }
-#endif
 
-#ifdef L_isprint
-#undef isprint
-int
-isprint( int c )
+#else  /* __CTYPE_HAS_8_BIT_LOCALES */
+
+int tolower(int c)
 {
-    return _UC_ISCTYPE(c, ISprint);
+	return __C_tolower(c);
 }
+
+#endif /* __CTYPE_HAS_8_BIT_LOCALES */
+
 #endif
+/**********************************************************************/
+#ifdef L_toupper
 
-#ifdef L_ispunct
-#undef ispunct
-int
-ispunct( int c )
+#ifdef __CTYPE_HAS_8_BIT_LOCALES
+
+int toupper(int c)
 {
-    return _UC_ISCTYPE(c, ISpunct);
+	return ((((unsigned int) c) <= 0x7f)
+			|| (LCT->encoding != __ctype_encoding_8_bit))
+		? __C_toupper(c)
+		: ( __isctype_loc(c, _CTYPE_islower)
+			? (unsigned char)
+			( U + LCT->tbl8uplow[ ((int)
+								   (LCT->idx8uplow[(U & 0x7f)
+												  >> Cuplow_IDX_SHIFT])
+								   << Cuplow_IDX_SHIFT)
+								+ (U & ((1 << Cuplow_IDX_SHIFT) - 1)) ])
+			: c );
 }
-#endif
 
-#ifdef L_isspace
-#undef isspace
-int
-isspace( int c )
+#else  /* __CTYPE_HAS_8_BIT_LOCALES */
+
+int toupper(int c)
 {
-    return _UC_ISCTYPE(c, ISspace);
+	return __C_toupper(c);
 }
+
+#endif /* __CTYPE_HAS_8_BIT_LOCALES */
+
 #endif
+/**********************************************************************/
+#ifdef L_isascii
 
-#ifdef L_isupper
-#undef isupper
-int
-isupper( int c )
+int isascii(int c)
 {
-    return _UC_ISCTYPE(c, ISupper);
+	return __isascii(c);
 }
+
 #endif
+/**********************************************************************/
+#ifdef L_toascii
 
-#ifdef L_isxdigit
-#undef isxdigit
-int
-isxdigit( int c )
+int toascii(int c)
 {
-    return _UC_ISCTYPE(c, ISxdigit);
+	return __toascii(c);
 }
-#endif
 
+#endif
+/**********************************************************************/
 #ifdef L_isxlower
-#undef isxlower
-int
-isxlower( int c )
+
+int isxlower(int c)
 {
-    return _UC_ISCTYPE2(c, (ISxdigit|ISupper), ISxdigit);
+	return __isxlower(c);
 }
-#endif
 
+#endif
+/**********************************************************************/
 #ifdef L_isxupper
-#undef isxupper
-int
-isxupper( int c )
+
+int isxupper(int c)
 {
-    return _UC_ISCTYPE2(c, (ISxdigit|ISlower), ISxdigit);
+	return __isxupper(c);
 }
+
 #endif
+/**********************************************************************/
+#ifdef L___isctype_loc
+#ifdef __CTYPE_HAS_8_BIT_LOCALES
 
-#ifdef L_tolower
-#undef tolower
-int
-tolower( int c )
+/* This internal routine is similar to iswctype(), but it doesn't
+ * work for any non-standard types, itdoesn't work for "xdigit"s,
+ * and it doesn't work for chars between 0 and 0x7f (although that
+ * may change). */
+
+static const char ctype_range[] = {
+	__CTYPE_RANGES
+};
+
+int __isctype_loc(int c, int ct)
 {
-    if((c < CHAR_MIN) || (c > UCHAR_MAX))
-		return c;
-    if(isupper(c))
-		return _uc_ctype_trans[(int)((unsigned char)c)];
-    else
-		return c;
-}
+	unsigned char d;
+
+	assert(((unsigned int)ct) < _CTYPE_isxdigit);
+	assert(((unsigned int)c) > 0x7f);
+
+#if (CHAR_MIN == 0)				/* We don't have signed chars... */
+	if ((LCT->encoding != __ctype_encoding_8_bit)
+		|| (((unsigned int) c) > UCHAR_MAX)
+		) {
+		return 0;
+	}
+#else
+	/* Allow non-EOF negative char values for glibc compatiblity. */
+	if ((LCT->encoding != __ctype_encoding_8_bit) || (c == EOF) 
+		|| ( ((unsigned int)(c - CHAR_MIN)) > (UCHAR_MAX - CHAR_MIN))
+		) {
+		return 0;
+	}
 #endif
 
-#ifdef L_toupper
-#undef toupper
-int
-toupper( int c )
-{
-    if((c < CHAR_MIN) || (c > UCHAR_MAX))
-		return c;
-    if(islower(c))
-		return _uc_ctype_trans[(int)((unsigned char)c)];
-    else
-		return c;
-}
+	/* TODO - test assumptions??? 8-bit chars -- or ensure in generator. */
+
+#define Cctype_TBL_MASK		((1 << Cctype_IDX_SHIFT) - 1)
+#define Cctype_IDX_OFFSET	(128 >> Cctype_IDX_SHIFT)
+
+	c &= 0x7f;
+#ifdef Cctype_PACKED
+	d = LCT->tbl8ctype[ ((int)(LCT->idx8ctype[(U >> Cctype_IDX_SHIFT) ])
+						 << (Cctype_IDX_SHIFT - 1))
+					  + ((U & Cctype_TBL_MASK) >> 1)];
+	d = (U & 1) ? (d >> 4) : (d & 0xf);
+#else
+	d = LCT->tbl8ctype[ ((int)(LCT->idx8ctype[(U >> Cctype_IDX_SHIFT) ])
+						 << Cctype_IDX_SHIFT)
+					  + (U & Cctype_TBL_MASK) ];
 #endif
+	return ( ((unsigned char)(d - ctype_range[2*ct])) <= ctype_range[2*ct+1] );
+}
 
+#endif /* __CTYPE_HAS_8_BIT_LOCALES */
 #endif
+/**********************************************************************/

+ 0 - 517
libc/misc/ctype/ctype_C.c

@@ -1,517 +0,0 @@
-const unsigned char _uc_ctype_b_C[LOCALE_BUF_SIZE] = {
-	/* 0x00, 0, 00 */	IScntrl,
-	/* 0x01, 1, 01 */	IScntrl,
-	/* 0x02, 2, 02 */	IScntrl,
-	/* 0x03, 3, 03 */	IScntrl,
-	/* 0x04, 4, 04 */	IScntrl,
-	/* 0x05, 5, 05 */	IScntrl,
-	/* 0x06, 6, 06 */	IScntrl,
-	/* 0x07, 7, 07 */	IScntrl,
-	/* 0x08, 8, 010 */	IScntrl,
-	/* 0x09, 9, 011 */	IScntrl|ISspace,
-	/* 0x0a, 10, 012 */	IScntrl|ISspace,
-	/* 0x0b, 11, 013 */	IScntrl|ISspace,
-	/* 0x0c, 12, 014 */	IScntrl|ISspace,
-	/* 0x0d, 13, 015 */	IScntrl|ISspace,
-	/* 0x0e, 14, 016 */	IScntrl,
-	/* 0x0f, 15, 017 */	IScntrl,
-	/* 0x10, 16, 020 */	IScntrl,
-	/* 0x11, 17, 021 */	IScntrl,
-	/* 0x12, 18, 022 */	IScntrl,
-	/* 0x13, 19, 023 */	IScntrl,
-	/* 0x14, 20, 024 */	IScntrl,
-	/* 0x15, 21, 025 */	IScntrl,
-	/* 0x16, 22, 026 */	IScntrl,
-	/* 0x17, 23, 027 */	IScntrl,
-	/* 0x18, 24, 030 */	IScntrl,
-	/* 0x19, 25, 031 */	IScntrl,
-	/* 0x1a, 26, 032 */	IScntrl,
-	/* 0x1b, 27, 033 */	IScntrl,
-	/* 0x1c, 28, 034 */	IScntrl,
-	/* 0x1d, 29, 035 */	IScntrl,
-	/* 0x1e, 30, 036 */	IScntrl,
-	/* 0x1f, 31, 037 */	IScntrl,
-	/* 0x20, 32, 040 */	ISprint|ISspace,
-	/* 0x21, 33, 041 */	ISprint|ISpunct,
-	/* 0x22, 34, 042 */	ISprint|ISpunct,
-	/* 0x23, 35, 043 */	ISprint|ISpunct,
-	/* 0x24, 36, 044 */	ISprint|ISpunct,
-	/* 0x25, 37, 045 */	ISprint|ISpunct,
-	/* 0x26, 38, 046 */	ISprint|ISpunct,
-	/* 0x27, 39, 047 */	ISprint|ISpunct,
-	/* 0x28, 40, 050 */	ISprint|ISpunct,
-	/* 0x29, 41, 051 */	ISprint|ISpunct,
-	/* 0x2a, 42, 052 */	ISprint|ISpunct,
-	/* 0x2b, 43, 053 */	ISprint|ISpunct,
-	/* 0x2c, 44, 054 */	ISprint|ISpunct,
-	/* 0x2d, 45, 055 */	ISprint|ISpunct,
-	/* 0x2e, 46, 056 */	ISprint|ISpunct,
-	/* 0x2f, 47, 057 */	ISprint|ISpunct,
-	/* 0x30, 48, 060 */	ISprint|ISxdigit,
-	/* 0x31, 49, 061 */	ISprint|ISxdigit,
-	/* 0x32, 50, 062 */	ISprint|ISxdigit,
-	/* 0x33, 51, 063 */	ISprint|ISxdigit,
-	/* 0x34, 52, 064 */	ISprint|ISxdigit,
-	/* 0x35, 53, 065 */	ISprint|ISxdigit,
-	/* 0x36, 54, 066 */	ISprint|ISxdigit,
-	/* 0x37, 55, 067 */	ISprint|ISxdigit,
-	/* 0x38, 56, 070 */	ISprint|ISxdigit,
-	/* 0x39, 57, 071 */	ISprint|ISxdigit,
-	/* 0x3a, 58, 072 */	ISprint|ISpunct,
-	/* 0x3b, 59, 073 */	ISprint|ISpunct,
-	/* 0x3c, 60, 074 */	ISprint|ISpunct,
-	/* 0x3d, 61, 075 */	ISprint|ISpunct,
-	/* 0x3e, 62, 076 */	ISprint|ISpunct,
-	/* 0x3f, 63, 077 */	ISprint|ISpunct,
-	/* 0x40, 64, 0100 */	ISprint|ISpunct,
-	/* 0x41, 65, 0101 */	ISprint|ISupper|ISalpha|ISxdigit,
-	/* 0x42, 66, 0102 */	ISprint|ISupper|ISalpha|ISxdigit,
-	/* 0x43, 67, 0103 */	ISprint|ISupper|ISalpha|ISxdigit,
-	/* 0x44, 68, 0104 */	ISprint|ISupper|ISalpha|ISxdigit,
-	/* 0x45, 69, 0105 */	ISprint|ISupper|ISalpha|ISxdigit,
-	/* 0x46, 70, 0106 */	ISprint|ISupper|ISalpha|ISxdigit,
-	/* 0x47, 71, 0107 */	ISprint|ISupper|ISalpha,
-	/* 0x48, 72, 0110 */	ISprint|ISupper|ISalpha,
-	/* 0x49, 73, 0111 */	ISprint|ISupper|ISalpha,
-	/* 0x4a, 74, 0112 */	ISprint|ISupper|ISalpha,
-	/* 0x4b, 75, 0113 */	ISprint|ISupper|ISalpha,
-	/* 0x4c, 76, 0114 */	ISprint|ISupper|ISalpha,
-	/* 0x4d, 77, 0115 */	ISprint|ISupper|ISalpha,
-	/* 0x4e, 78, 0116 */	ISprint|ISupper|ISalpha,
-	/* 0x4f, 79, 0117 */	ISprint|ISupper|ISalpha,
-	/* 0x50, 80, 0120 */	ISprint|ISupper|ISalpha,
-	/* 0x51, 81, 0121 */	ISprint|ISupper|ISalpha,
-	/* 0x52, 82, 0122 */	ISprint|ISupper|ISalpha,
-	/* 0x53, 83, 0123 */	ISprint|ISupper|ISalpha,
-	/* 0x54, 84, 0124 */	ISprint|ISupper|ISalpha,
-	/* 0x55, 85, 0125 */	ISprint|ISupper|ISalpha,
-	/* 0x56, 86, 0126 */	ISprint|ISupper|ISalpha,
-	/* 0x57, 87, 0127 */	ISprint|ISupper|ISalpha,
-	/* 0x58, 88, 0130 */	ISprint|ISupper|ISalpha,
-	/* 0x59, 89, 0131 */	ISprint|ISupper|ISalpha,
-	/* 0x5a, 90, 0132 */	ISprint|ISupper|ISalpha,
-	/* 0x5b, 91, 0133 */	ISprint|ISpunct,
-	/* 0x5c, 92, 0134 */	ISprint|ISpunct,
-	/* 0x5d, 93, 0135 */	ISprint|ISpunct,
-	/* 0x5e, 94, 0136 */	ISprint|ISpunct,
-	/* 0x5f, 95, 0137 */	ISprint|ISpunct,
-	/* 0x60, 96, 0140 */	ISprint|ISpunct,
-	/* 0x61, 97, 0141 */	ISprint|ISlower|ISalpha|ISxdigit,
-	/* 0x62, 98, 0142 */	ISprint|ISlower|ISalpha|ISxdigit,
-	/* 0x63, 99, 0143 */	ISprint|ISlower|ISalpha|ISxdigit,
-	/* 0x64, 100, 0144 */	ISprint|ISlower|ISalpha|ISxdigit,
-	/* 0x65, 101, 0145 */	ISprint|ISlower|ISalpha|ISxdigit,
-	/* 0x66, 102, 0146 */	ISprint|ISlower|ISalpha|ISxdigit,
-	/* 0x67, 103, 0147 */	ISprint|ISlower|ISalpha,
-	/* 0x68, 104, 0150 */	ISprint|ISlower|ISalpha,
-	/* 0x69, 105, 0151 */	ISprint|ISlower|ISalpha,
-	/* 0x6a, 106, 0152 */	ISprint|ISlower|ISalpha,
-	/* 0x6b, 107, 0153 */	ISprint|ISlower|ISalpha,
-	/* 0x6c, 108, 0154 */	ISprint|ISlower|ISalpha,
-	/* 0x6d, 109, 0155 */	ISprint|ISlower|ISalpha,
-	/* 0x6e, 110, 0156 */	ISprint|ISlower|ISalpha,
-	/* 0x6f, 111, 0157 */	ISprint|ISlower|ISalpha,
-	/* 0x70, 112, 0160 */	ISprint|ISlower|ISalpha,
-	/* 0x71, 113, 0161 */	ISprint|ISlower|ISalpha,
-	/* 0x72, 114, 0162 */	ISprint|ISlower|ISalpha,
-	/* 0x73, 115, 0163 */	ISprint|ISlower|ISalpha,
-	/* 0x74, 116, 0164 */	ISprint|ISlower|ISalpha,
-	/* 0x75, 117, 0165 */	ISprint|ISlower|ISalpha,
-	/* 0x76, 118, 0166 */	ISprint|ISlower|ISalpha,
-	/* 0x77, 119, 0167 */	ISprint|ISlower|ISalpha,
-	/* 0x78, 120, 0170 */	ISprint|ISlower|ISalpha,
-	/* 0x79, 121, 0171 */	ISprint|ISlower|ISalpha,
-	/* 0x7a, 122, 0172 */	ISprint|ISlower|ISalpha,
-	/* 0x7b, 123, 0173 */	ISprint|ISpunct,
-	/* 0x7c, 124, 0174 */	ISprint|ISpunct,
-	/* 0x7d, 125, 0175 */	ISprint|ISpunct,
-	/* 0x7e, 126, 0176 */	ISprint|ISpunct,
-	/* 0x7f, 127, 0177 */	IScntrl,
-	/* 0x80, 128, 0200 */	0,
-	/* 0x81, 129, 0201 */	0,
-	/* 0x82, 130, 0202 */	0,
-	/* 0x83, 131, 0203 */	0,
-	/* 0x84, 132, 0204 */	0,
-	/* 0x85, 133, 0205 */	0,
-	/* 0x86, 134, 0206 */	0,
-	/* 0x87, 135, 0207 */	0,
-	/* 0x88, 136, 0210 */	0,
-	/* 0x89, 137, 0211 */	0,
-	/* 0x8a, 138, 0212 */	0,
-	/* 0x8b, 139, 0213 */	0,
-	/* 0x8c, 140, 0214 */	0,
-	/* 0x8d, 141, 0215 */	0,
-	/* 0x8e, 142, 0216 */	0,
-	/* 0x8f, 143, 0217 */	0,
-	/* 0x90, 144, 0220 */	0,
-	/* 0x91, 145, 0221 */	0,
-	/* 0x92, 146, 0222 */	0,
-	/* 0x93, 147, 0223 */	0,
-	/* 0x94, 148, 0224 */	0,
-	/* 0x95, 149, 0225 */	0,
-	/* 0x96, 150, 0226 */	0,
-	/* 0x97, 151, 0227 */	0,
-	/* 0x98, 152, 0230 */	0,
-	/* 0x99, 153, 0231 */	0,
-	/* 0x9a, 154, 0232 */	0,
-	/* 0x9b, 155, 0233 */	0,
-	/* 0x9c, 156, 0234 */	0,
-	/* 0x9d, 157, 0235 */	0,
-	/* 0x9e, 158, 0236 */	0,
-	/* 0x9f, 159, 0237 */	0,
-	/* 0xa0, 160, 0240 */	0,
-	/* 0xa1, 161, 0241 */	0,
-	/* 0xa2, 162, 0242 */	0,
-	/* 0xa3, 163, 0243 */	0,
-	/* 0xa4, 164, 0244 */	0,
-	/* 0xa5, 165, 0245 */	0,
-	/* 0xa6, 166, 0246 */	0,
-	/* 0xa7, 167, 0247 */	0,
-	/* 0xa8, 168, 0250 */	0,
-	/* 0xa9, 169, 0251 */	0,
-	/* 0xaa, 170, 0252 */	0,
-	/* 0xab, 171, 0253 */	0,
-	/* 0xac, 172, 0254 */	0,
-	/* 0xad, 173, 0255 */	0,
-	/* 0xae, 174, 0256 */	0,
-	/* 0xaf, 175, 0257 */	0,
-	/* 0xb0, 176, 0260 */	0,
-	/* 0xb1, 177, 0261 */	0,
-	/* 0xb2, 178, 0262 */	0,
-	/* 0xb3, 179, 0263 */	0,
-	/* 0xb4, 180, 0264 */	0,
-	/* 0xb5, 181, 0265 */	0,
-	/* 0xb6, 182, 0266 */	0,
-	/* 0xb7, 183, 0267 */	0,
-	/* 0xb8, 184, 0270 */	0,
-	/* 0xb9, 185, 0271 */	0,
-	/* 0xba, 186, 0272 */	0,
-	/* 0xbb, 187, 0273 */	0,
-	/* 0xbc, 188, 0274 */	0,
-	/* 0xbd, 189, 0275 */	0,
-	/* 0xbe, 190, 0276 */	0,
-	/* 0xbf, 191, 0277 */	0,
-	/* 0xc0, 192, 0300 */	0,
-	/* 0xc1, 193, 0301 */	0,
-	/* 0xc2, 194, 0302 */	0,
-	/* 0xc3, 195, 0303 */	0,
-	/* 0xc4, 196, 0304 */	0,
-	/* 0xc5, 197, 0305 */	0,
-	/* 0xc6, 198, 0306 */	0,
-	/* 0xc7, 199, 0307 */	0,
-	/* 0xc8, 200, 0310 */	0,
-	/* 0xc9, 201, 0311 */	0,
-	/* 0xca, 202, 0312 */	0,
-	/* 0xcb, 203, 0313 */	0,
-	/* 0xcc, 204, 0314 */	0,
-	/* 0xcd, 205, 0315 */	0,
-	/* 0xce, 206, 0316 */	0,
-	/* 0xcf, 207, 0317 */	0,
-	/* 0xd0, 208, 0320 */	0,
-	/* 0xd1, 209, 0321 */	0,
-	/* 0xd2, 210, 0322 */	0,
-	/* 0xd3, 211, 0323 */	0,
-	/* 0xd4, 212, 0324 */	0,
-	/* 0xd5, 213, 0325 */	0,
-	/* 0xd6, 214, 0326 */	0,
-	/* 0xd7, 215, 0327 */	0,
-	/* 0xd8, 216, 0330 */	0,
-	/* 0xd9, 217, 0331 */	0,
-	/* 0xda, 218, 0332 */	0,
-	/* 0xdb, 219, 0333 */	0,
-	/* 0xdc, 220, 0334 */	0,
-	/* 0xdd, 221, 0335 */	0,
-	/* 0xde, 222, 0336 */	0,
-	/* 0xdf, 223, 0337 */	0,
-	/* 0xe0, 224, 0340 */	0,
-	/* 0xe1, 225, 0341 */	0,
-	/* 0xe2, 226, 0342 */	0,
-	/* 0xe3, 227, 0343 */	0,
-	/* 0xe4, 228, 0344 */	0,
-	/* 0xe5, 229, 0345 */	0,
-	/* 0xe6, 230, 0346 */	0,
-	/* 0xe7, 231, 0347 */	0,
-	/* 0xe8, 232, 0350 */	0,
-	/* 0xe9, 233, 0351 */	0,
-	/* 0xea, 234, 0352 */	0,
-	/* 0xeb, 235, 0353 */	0,
-	/* 0xec, 236, 0354 */	0,
-	/* 0xed, 237, 0355 */	0,
-	/* 0xee, 238, 0356 */	0,
-	/* 0xef, 239, 0357 */	0,
-	/* 0xf0, 240, 0360 */	0,
-	/* 0xf1, 241, 0361 */	0,
-	/* 0xf2, 242, 0362 */	0,
-	/* 0xf3, 243, 0363 */	0,
-	/* 0xf4, 244, 0364 */	0,
-	/* 0xf5, 245, 0365 */	0,
-	/* 0xf6, 246, 0366 */	0,
-	/* 0xf7, 247, 0367 */	0,
-	/* 0xf8, 248, 0370 */	0,
-	/* 0xf9, 249, 0371 */	0,
-	/* 0xfa, 250, 0372 */	0,
-	/* 0xfb, 251, 0373 */	0,
-	/* 0xfc, 252, 0374 */	0,
-	/* 0xfd, 253, 0375 */	0,
-	/* 0xfe, 254, 0376 */	0,
-	/* 0xff, 255, 0377 */	0,
-
-/* _uc_ctype_trans_C */
-
-	/* 0x00, 0, 00 */	0x00,
-	/* 0x01, 1, 01 */	0x01,
-	/* 0x02, 2, 02 */	0x02,
-	/* 0x03, 3, 03 */	0x03,
-	/* 0x04, 4, 04 */	0x04,
-	/* 0x05, 5, 05 */	0x05,
-	/* 0x06, 6, 06 */	0x06,
-	/* 0x07, 7, 07 */	0x07,
-	/* 0x08, 8, 010 */	0x08,
-	/* 0x09, 9, 011 */	0x09,
-	/* 0x0a, 10, 012 */	0x0a,
-	/* 0x0b, 11, 013 */	0x0b,
-	/* 0x0c, 12, 014 */	0x0c,
-	/* 0x0d, 13, 015 */	0x0d,
-	/* 0x0e, 14, 016 */	0x0e,
-	/* 0x0f, 15, 017 */	0x0f,
-	/* 0x10, 16, 020 */	0x10,
-	/* 0x11, 17, 021 */	0x11,
-	/* 0x12, 18, 022 */	0x12,
-	/* 0x13, 19, 023 */	0x13,
-	/* 0x14, 20, 024 */	0x14,
-	/* 0x15, 21, 025 */	0x15,
-	/* 0x16, 22, 026 */	0x16,
-	/* 0x17, 23, 027 */	0x17,
-	/* 0x18, 24, 030 */	0x18,
-	/* 0x19, 25, 031 */	0x19,
-	/* 0x1a, 26, 032 */	0x1a,
-	/* 0x1b, 27, 033 */	0x1b,
-	/* 0x1c, 28, 034 */	0x1c,
-	/* 0x1d, 29, 035 */	0x1d,
-	/* 0x1e, 30, 036 */	0x1e,
-	/* 0x1f, 31, 037 */	0x1f,
-	/* 0x20, 32, 040 */	0x20,
-	/* 0x21, 33, 041 */	0x21,
-	/* 0x22, 34, 042 */	0x22,
-	/* 0x23, 35, 043 */	0x23,
-	/* 0x24, 36, 044 */	0x24,
-	/* 0x25, 37, 045 */	0x25,
-	/* 0x26, 38, 046 */	0x26,
-	/* 0x27, 39, 047 */	0x27,
-	/* 0x28, 40, 050 */	0x28,
-	/* 0x29, 41, 051 */	0x29,
-	/* 0x2a, 42, 052 */	0x2a,
-	/* 0x2b, 43, 053 */	0x2b,
-	/* 0x2c, 44, 054 */	0x2c,
-	/* 0x2d, 45, 055 */	0x2d,
-	/* 0x2e, 46, 056 */	0x2e,
-	/* 0x2f, 47, 057 */	0x2f,
-	/* 0x30, 48, 060 */	0x30,
-	/* 0x31, 49, 061 */	0x31,
-	/* 0x32, 50, 062 */	0x32,
-	/* 0x33, 51, 063 */	0x33,
-	/* 0x34, 52, 064 */	0x34,
-	/* 0x35, 53, 065 */	0x35,
-	/* 0x36, 54, 066 */	0x36,
-	/* 0x37, 55, 067 */	0x37,
-	/* 0x38, 56, 070 */	0x38,
-	/* 0x39, 57, 071 */	0x39,
-	/* 0x3a, 58, 072 */	0x3a,
-	/* 0x3b, 59, 073 */	0x3b,
-	/* 0x3c, 60, 074 */	0x3c,
-	/* 0x3d, 61, 075 */	0x3d,
-	/* 0x3e, 62, 076 */	0x3e,
-	/* 0x3f, 63, 077 */	0x3f,
-	/* 0x40, 64, 0100 */	0x40,
-	/* 0x41, 65, 0101 */	0x61,
-	/* 0x42, 66, 0102 */	0x62,
-	/* 0x43, 67, 0103 */	0x63,
-	/* 0x44, 68, 0104 */	0x64,
-	/* 0x45, 69, 0105 */	0x65,
-	/* 0x46, 70, 0106 */	0x66,
-	/* 0x47, 71, 0107 */	0x67,
-	/* 0x48, 72, 0110 */	0x68,
-	/* 0x49, 73, 0111 */	0x69,
-	/* 0x4a, 74, 0112 */	0x6a,
-	/* 0x4b, 75, 0113 */	0x6b,
-	/* 0x4c, 76, 0114 */	0x6c,
-	/* 0x4d, 77, 0115 */	0x6d,
-	/* 0x4e, 78, 0116 */	0x6e,
-	/* 0x4f, 79, 0117 */	0x6f,
-	/* 0x50, 80, 0120 */	0x70,
-	/* 0x51, 81, 0121 */	0x71,
-	/* 0x52, 82, 0122 */	0x72,
-	/* 0x53, 83, 0123 */	0x73,
-	/* 0x54, 84, 0124 */	0x74,
-	/* 0x55, 85, 0125 */	0x75,
-	/* 0x56, 86, 0126 */	0x76,
-	/* 0x57, 87, 0127 */	0x77,
-	/* 0x58, 88, 0130 */	0x78,
-	/* 0x59, 89, 0131 */	0x79,
-	/* 0x5a, 90, 0132 */	0x7a,
-	/* 0x5b, 91, 0133 */	0x5b,
-	/* 0x5c, 92, 0134 */	0x5c,
-	/* 0x5d, 93, 0135 */	0x5d,
-	/* 0x5e, 94, 0136 */	0x5e,
-	/* 0x5f, 95, 0137 */	0x5f,
-	/* 0x60, 96, 0140 */	0x60,
-	/* 0x61, 97, 0141 */	0x41,
-	/* 0x62, 98, 0142 */	0x42,
-	/* 0x63, 99, 0143 */	0x43,
-	/* 0x64, 100, 0144 */	0x44,
-	/* 0x65, 101, 0145 */	0x45,
-	/* 0x66, 102, 0146 */	0x46,
-	/* 0x67, 103, 0147 */	0x47,
-	/* 0x68, 104, 0150 */	0x48,
-	/* 0x69, 105, 0151 */	0x49,
-	/* 0x6a, 106, 0152 */	0x4a,
-	/* 0x6b, 107, 0153 */	0x4b,
-	/* 0x6c, 108, 0154 */	0x4c,
-	/* 0x6d, 109, 0155 */	0x4d,
-	/* 0x6e, 110, 0156 */	0x4e,
-	/* 0x6f, 111, 0157 */	0x4f,
-	/* 0x70, 112, 0160 */	0x50,
-	/* 0x71, 113, 0161 */	0x51,
-	/* 0x72, 114, 0162 */	0x52,
-	/* 0x73, 115, 0163 */	0x53,
-	/* 0x74, 116, 0164 */	0x54,
-	/* 0x75, 117, 0165 */	0x55,
-	/* 0x76, 118, 0166 */	0x56,
-	/* 0x77, 119, 0167 */	0x57,
-	/* 0x78, 120, 0170 */	0x58,
-	/* 0x79, 121, 0171 */	0x59,
-	/* 0x7a, 122, 0172 */	0x5a,
-	/* 0x7b, 123, 0173 */	0x7b,
-	/* 0x7c, 124, 0174 */	0x7c,
-	/* 0x7d, 125, 0175 */	0x7d,
-	/* 0x7e, 126, 0176 */	0x7e,
-	/* 0x7f, 127, 0177 */	0x7f,
-	/* 0x80, 128, 0200 */	0x80,
-	/* 0x81, 129, 0201 */	0x81,
-	/* 0x82, 130, 0202 */	0x82,
-	/* 0x83, 131, 0203 */	0x83,
-	/* 0x84, 132, 0204 */	0x84,
-	/* 0x85, 133, 0205 */	0x85,
-	/* 0x86, 134, 0206 */	0x86,
-	/* 0x87, 135, 0207 */	0x87,
-	/* 0x88, 136, 0210 */	0x88,
-	/* 0x89, 137, 0211 */	0x89,
-	/* 0x8a, 138, 0212 */	0x8a,
-	/* 0x8b, 139, 0213 */	0x8b,
-	/* 0x8c, 140, 0214 */	0x8c,
-	/* 0x8d, 141, 0215 */	0x8d,
-	/* 0x8e, 142, 0216 */	0x8e,
-	/* 0x8f, 143, 0217 */	0x8f,
-	/* 0x90, 144, 0220 */	0x90,
-	/* 0x91, 145, 0221 */	0x91,
-	/* 0x92, 146, 0222 */	0x92,
-	/* 0x93, 147, 0223 */	0x93,
-	/* 0x94, 148, 0224 */	0x94,
-	/* 0x95, 149, 0225 */	0x95,
-	/* 0x96, 150, 0226 */	0x96,
-	/* 0x97, 151, 0227 */	0x97,
-	/* 0x98, 152, 0230 */	0x98,
-	/* 0x99, 153, 0231 */	0x99,
-	/* 0x9a, 154, 0232 */	0x9a,
-	/* 0x9b, 155, 0233 */	0x9b,
-	/* 0x9c, 156, 0234 */	0x9c,
-	/* 0x9d, 157, 0235 */	0x9d,
-	/* 0x9e, 158, 0236 */	0x9e,
-	/* 0x9f, 159, 0237 */	0x9f,
-	/* 0xa0, 160, 0240 */	0xa0,
-	/* 0xa1, 161, 0241 */	0xa1,
-	/* 0xa2, 162, 0242 */	0xa2,
-	/* 0xa3, 163, 0243 */	0xa3,
-	/* 0xa4, 164, 0244 */	0xa4,
-	/* 0xa5, 165, 0245 */	0xa5,
-	/* 0xa6, 166, 0246 */	0xa6,
-	/* 0xa7, 167, 0247 */	0xa7,
-	/* 0xa8, 168, 0250 */	0xa8,
-	/* 0xa9, 169, 0251 */	0xa9,
-	/* 0xaa, 170, 0252 */	0xaa,
-	/* 0xab, 171, 0253 */	0xab,
-	/* 0xac, 172, 0254 */	0xac,
-	/* 0xad, 173, 0255 */	0xad,
-	/* 0xae, 174, 0256 */	0xae,
-	/* 0xaf, 175, 0257 */	0xaf,
-	/* 0xb0, 176, 0260 */	0xb0,
-	/* 0xb1, 177, 0261 */	0xb1,
-	/* 0xb2, 178, 0262 */	0xb2,
-	/* 0xb3, 179, 0263 */	0xb3,
-	/* 0xb4, 180, 0264 */	0xb4,
-	/* 0xb5, 181, 0265 */	0xb5,
-	/* 0xb6, 182, 0266 */	0xb6,
-	/* 0xb7, 183, 0267 */	0xb7,
-	/* 0xb8, 184, 0270 */	0xb8,
-	/* 0xb9, 185, 0271 */	0xb9,
-	/* 0xba, 186, 0272 */	0xba,
-	/* 0xbb, 187, 0273 */	0xbb,
-	/* 0xbc, 188, 0274 */	0xbc,
-	/* 0xbd, 189, 0275 */	0xbd,
-	/* 0xbe, 190, 0276 */	0xbe,
-	/* 0xbf, 191, 0277 */	0xbf,
-	/* 0xc0, 192, 0300 */	0xc0,
-	/* 0xc1, 193, 0301 */	0xc1,
-	/* 0xc2, 194, 0302 */	0xc2,
-	/* 0xc3, 195, 0303 */	0xc3,
-	/* 0xc4, 196, 0304 */	0xc4,
-	/* 0xc5, 197, 0305 */	0xc5,
-	/* 0xc6, 198, 0306 */	0xc6,
-	/* 0xc7, 199, 0307 */	0xc7,
-	/* 0xc8, 200, 0310 */	0xc8,
-	/* 0xc9, 201, 0311 */	0xc9,
-	/* 0xca, 202, 0312 */	0xca,
-	/* 0xcb, 203, 0313 */	0xcb,
-	/* 0xcc, 204, 0314 */	0xcc,
-	/* 0xcd, 205, 0315 */	0xcd,
-	/* 0xce, 206, 0316 */	0xce,
-	/* 0xcf, 207, 0317 */	0xcf,
-	/* 0xd0, 208, 0320 */	0xd0,
-	/* 0xd1, 209, 0321 */	0xd1,
-	/* 0xd2, 210, 0322 */	0xd2,
-	/* 0xd3, 211, 0323 */	0xd3,
-	/* 0xd4, 212, 0324 */	0xd4,
-	/* 0xd5, 213, 0325 */	0xd5,
-	/* 0xd6, 214, 0326 */	0xd6,
-	/* 0xd7, 215, 0327 */	0xd7,
-	/* 0xd8, 216, 0330 */	0xd8,
-	/* 0xd9, 217, 0331 */	0xd9,
-	/* 0xda, 218, 0332 */	0xda,
-	/* 0xdb, 219, 0333 */	0xdb,
-	/* 0xdc, 220, 0334 */	0xdc,
-	/* 0xdd, 221, 0335 */	0xdd,
-	/* 0xde, 222, 0336 */	0xde,
-	/* 0xdf, 223, 0337 */	0xdf,
-	/* 0xe0, 224, 0340 */	0xe0,
-	/* 0xe1, 225, 0341 */	0xe1,
-	/* 0xe2, 226, 0342 */	0xe2,
-	/* 0xe3, 227, 0343 */	0xe3,
-	/* 0xe4, 228, 0344 */	0xe4,
-	/* 0xe5, 229, 0345 */	0xe5,
-	/* 0xe6, 230, 0346 */	0xe6,
-	/* 0xe7, 231, 0347 */	0xe7,
-	/* 0xe8, 232, 0350 */	0xe8,
-	/* 0xe9, 233, 0351 */	0xe9,
-	/* 0xea, 234, 0352 */	0xea,
-	/* 0xeb, 235, 0353 */	0xeb,
-	/* 0xec, 236, 0354 */	0xec,
-	/* 0xed, 237, 0355 */	0xed,
-	/* 0xee, 238, 0356 */	0xee,
-	/* 0xef, 239, 0357 */	0xef,
-	/* 0xf0, 240, 0360 */	0xf0,
-	/* 0xf1, 241, 0361 */	0xf1,
-	/* 0xf2, 242, 0362 */	0xf2,
-	/* 0xf3, 243, 0363 */	0xf3,
-	/* 0xf4, 244, 0364 */	0xf4,
-	/* 0xf5, 245, 0365 */	0xf5,
-	/* 0xf6, 246, 0366 */	0xf6,
-	/* 0xf7, 247, 0367 */	0xf7,
-	/* 0xf8, 248, 0370 */	0xf8,
-	/* 0xf9, 249, 0371 */	0xf9,
-	/* 0xfa, 250, 0372 */	0xfa,
-	/* 0xfb, 251, 0373 */	0xfb,
-	/* 0xfc, 252, 0374 */	0xfc,
-	/* 0xfd, 253, 0375 */	0xfd,
-	/* 0xfe, 254, 0376 */	0xfe,
-	/* 0xff, 255, 0377 */	0xff
-};

+ 12 - 0
libc/misc/internals/__uClibc_main.c

@@ -34,6 +34,9 @@ extern void weak_function _stdio_init(void);
 extern void weak_function _stdio_term(void);
 extern int *weak_const_function __errno_location(void);
 extern int *weak_const_function __h_errno_location(void);
+#ifdef __UCLIBC_HAS_LOCALE__
+extern void weak_function _locale_init(void);
+#endif
 #else
 /*
  * Define an empty function and use it as a weak alias for the stdio
@@ -62,6 +65,9 @@ extern int atexit(void (*function)(void));
 extern int *__errno_location(void);
 //weak_alias(__uClibc_empty_func, __h_errno_location);
 extern int *__h_errno_location(void);
+#ifdef __UCLIBC_HAS_LOCALE__
+extern void _locale_init(void);
+#endif
 #endif
 
 /*
@@ -93,6 +99,12 @@ __uClibc_main(int argc, char **argv, char **envp)
 	if (unlikely (__libc_enable_secure))
 	    __libc_check_standard_fds ();
 #endif
+
+#ifdef __UCLIBC_HAS_LOCALE__
+	/* Initialize the global locale structure. */
+	if (likely(_locale_init)) _locale_init();
+#endif
+
 	/*
 	 * Initialize stdio here.  In the static library case, this will
 	 * be bypassed if not needed because of the weak alias above.

+ 10 - 5
libc/misc/locale/Makefile

@@ -24,9 +24,14 @@
 TOPDIR=../../../
 include $(TOPDIR)Rules.mak
 
-CSRC=locale.c localeconv.c
-COBJS=$(patsubst %.c,%.o, $(CSRC))
-OBJS=$(COBJS)
+MSRC= locale.c
+MOBJ= setlocale.o localeconv.o _locale_init.o nl_langinfo.o
+
+OBJS= $(MOBJ)
+
+ifeq ($(HAS_LOCALE),true)
+	OBJS += locale_data.o
+endif
 
 all: $(OBJS) $(LIBC)
 
@@ -35,8 +40,8 @@ $(LIBC): ar-target
 ar-target: $(OBJS)
 	$(AR) $(ARFLAGS) $(LIBC) $(OBJS)
 
-$(COBJS): %.o : %.c
-	$(CC) $(CFLAGS) -c $< -o $@
+$(MOBJ): $(MSRC)
+	$(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
 	$(STRIPTOOL) -x -R .note -R .comment $*.o
 
 $(OBJS): Makefile

+ 0 - 22
libc/misc/locale/_locale.h

@@ -1,22 +0,0 @@
-extern const unsigned char *_uc_ctype_b;
-extern const unsigned char *_uc_ctype_trans;
-
-extern const unsigned char _uc_ctype_b_C[256+256];
-
-#define LOCALE_BUF_SIZE (sizeof(_uc_ctype_b_C))
-
-#define ISbit(bit)     (1 << bit)
-
-enum
-{
-  ISprint  = ISbit (0),        /* 1   Printable.         */
-  ISupper  = ISbit (1),        /* 2   UPPERCASE.         */
-  ISlower  = ISbit (2),        /* 4   lowercase.         */
-  IScntrl  = ISbit (3),        /* 8   Control character. */
-  ISspace  = ISbit (4),        /* 16  Whitespace.        */
-  ISpunct  = ISbit (5),        /* 32  Punctuation.       */
-  ISalpha  = ISbit (6),        /* 64  Alphabetic.        */
-  ISxdigit = ISbit (7),        /* 128 Hexnumeric.        */
-};
-
-extern const unsigned char *_uc_collate_b;

+ 447 - 272
libc/misc/locale/locale.c

@@ -1,332 +1,507 @@
-/* setlocale.c
- * Load LC_CTYPE and LC_COLLATE locale only special for uclibc
+/*  Copyright (C) 2002     Manuel Novoa III
  *
- * Written by Vladimir Oleynik (c) vodz@usa.net
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
  *
- * This file is part of the uClibc C library and is distributed
- * under the GNU Library General Public License.
- * used ideas is part of the GNU C Library.
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*  TODO:
+ *  Implement the shared mmap code so non-mmu platforms can use this.
+ *  Implement nl_langinfo() for the stub locale support.
+ *  Add some basic collate functionality similar to what the previous
+ *    locale support had (8-bit codesets only).
  */
 
+#define _GNU_SOURCE
 #include <locale.h>
-#include <stdio.h>      /* NULL, fopen */
-#include <stdlib.h>     /* malloc */
 #include <string.h>
-#include <limits.h>     /* PATH_MAX */
-#include <errno.h>      /* EINVAL */
-#include <unistd.h>     /* get(e)[u|g]id */
+#include <stdlib.h>
+#include <stddef.h>
+#include <limits.h>
+#include <stdint.h>
+#include <assert.h>
 
-#include "_locale.h"
+#ifdef __LOCALE_C_ONLY
 
-static char C_LOCALE_NAME    []="C";
-static char POSIX_LOCALE_NAME[]="POSIX";
-static char composite_name_C []=
-"LC_CTYPE=C;LC_NUMERIC=C;LC_TIME=C;LC_COLLATE=C;LC_MONETARY=C;LC_MESSAGES=C";
+#ifdef __WCHAR_ENABLED
+#error wide char support requires full locale support
+#endif
 
-#ifdef __UCLIBC_HAS_LOCALE__
+#else  /* __LOCALE_C_ONLY */
 
-#ifdef TEST_LOCALE
-static const char PATH_LOCALE[]="./";
-#else
-static const char PATH_LOCALE[]=__UCLIBC_LOCALE_DIR;
-#endif
+#define CUR_LOCALE_SPEC			(__global_locale.cur_locale)
+#undef CODESET_LIST
+#define CODESET_LIST			(__locale_mmap->codeset_list)
 
-struct SAV_LOADED_LOCALE {
-	int category;
-	char *locale;
-	const unsigned char *buf;
-	struct SAV_LOADED_LOCALE *next;
-};
+/* TODO: Optional... See below. */
+#define __LOCALE_STRICTER_SETLOCALE
 
-static struct SAV_LOADED_LOCALE sll_C_LC_MESSAGES = {
-  LC_MESSAGES, C_LOCALE_NAME,  0, 0
-};
+#endif /* __LOCALE_C_ONLY */
 
-static struct SAV_LOADED_LOCALE sll_C_LC_MONETARY = {
-  LC_MONETARY, C_LOCALE_NAME, 0, &sll_C_LC_MESSAGES
-};
+/**********************************************************************/
+#ifdef L_setlocale
 
-static struct SAV_LOADED_LOCALE sll_C_LC_COLLATE = {
-  LC_COLLATE,  C_LOCALE_NAME, 0, &sll_C_LC_MONETARY
-};
+#ifdef __LOCALE_C_ONLY
 
-static struct SAV_LOADED_LOCALE sll_C_LC_TIME = {
-  LC_TIME,     C_LOCALE_NAME, 0, &sll_C_LC_COLLATE
-};
+link_warning(setlocale,"the 'setlocale' function supports only C|POSIX locales");
 
-static struct SAV_LOADED_LOCALE sll_C_LC_NUMERIC = {
-  LC_NUMERIC,  C_LOCALE_NAME, 0, &sll_C_LC_TIME
-};
+static const char C_string[] = "C";
 
-static struct SAV_LOADED_LOCALE sll_C_LC_CTYPE = {
-  LC_CTYPE,    C_LOCALE_NAME, _uc_ctype_b_C, &sll_C_LC_NUMERIC
-};
+char *setlocale(int category, register const char *locale)
+{
+	return ( (((unsigned int)(category)) <= LC_ALL)
+			 && ( (!locale)		/* Request for locale category string. */
+				  || (!*locale)	/* Implementation-defined default is C. */
+				  || ((*locale == 'C') && !locale[1])
+				  || (!strcmp(locale, "POSIX"))) )
+		? (char *) C_string		/* Always in C/POSIX locale. */
+		: NULL;
+}
 
-static struct SAV_LOADED_LOCALE *sll = &sll_C_LC_CTYPE;
+#else  /* ---------------------------------------------- __LOCALE_C_ONLY */
 
+#if !defined(NUM_LOCALES) || (NUM_LOCALES <= 1)
+#error locales enabled, but not data other than for C locale!
+#endif
 
-#endif /* __UCLIBC_HAS_LOCALE__ */
+static unsigned char setlocale_buf[LOCALE_STRING_SIZE];
 
 
-static char *nl_current[LC_ALL+1] = {
-	C_LOCALE_NAME, C_LOCALE_NAME, C_LOCALE_NAME,
-	C_LOCALE_NAME, C_LOCALE_NAME, C_LOCALE_NAME,
-	composite_name_C
-};
+#define LOCALE_NAMES			(__locale_mmap->locale_names5)
+#define LOCALES					(__locale_mmap->locales)
+#define LOCALE_AT_MODIFIERS 	(__locale_mmap->locale_at_modifiers)
+#define CATEGORY_NAMES			(__locale_mmap->lc_names)
 
-static const char * const LC_strs[LC_ALL+1] = {
-	"/LC_CTYPE",
-	"/LC_NUMERIC",
-	"/LC_TIME",
-	"/LC_COLLATE",
-	"/LC_MONETARY",
-	"/LC_MESSAGES",
-	"/LC_ALL"
-};
+static const char posix[] = "POSIX";
 
-static char *find_locale(int c, const char **plocale)
+static int find_locale(int category, const char *p, unsigned char *new_locale)
 {
-#ifdef __UCLIBC_HAS_LOCALE__
-	struct SAV_LOADED_LOCALE *cur;
+	int i;
+	const unsigned char *s;
+	uint16_t n;
+	unsigned char lang_cult, codeset;
+
+#if defined(LOCALE_AT_MODIFIERS_LENGTH) && 1
+	/* Support standard locale handling for @-modifiers. */
+	char buf[18];	/* TODO: 7+{max codeset name length} */
+	const char *q;
+
+	if ((q = strchr(p,'@')) != NULL) {
+		if ((((size_t)((q-p)-5)) > (sizeof(buf) - 5)) || (p[2] != '_')) {
+			return 0;
+		}
+		/* locale name at least 5 chars long and 3rd char is '_' */
+		s = LOCALE_AT_MODIFIERS;
+		do {
+			if (!strcmp(s+2, q+1)) {
+				break;
+			}
+			s += 2 + *s;		/* TODO - fix this throughout */
+		} while (*s);
+		if (!*s) {
+			return 0;
+		}
+		memcpy(buf, p, q-p);
+		buf[q-p] = 0;
+		buf[2] = s[1];
+		p = buf;
+	}
 #endif
-	const char *name = *plocale;
-
-	if (name[0] == '\0') {
-	/* The user decides which locale to use by setting environment
-								variables. */
-		name = getenv (&LC_strs[LC_ALL][1]);
-		if (name == NULL || name[0] == '\0')
-			name = getenv (&LC_strs[c][1]);
-		if (name == NULL || name[0] == '\0')
-			name = getenv ("LANG");
-		if (name == NULL || name[0] == '\0')
-			name = C_LOCALE_NAME;
+
+	lang_cult = codeset = 0;	/* Assume C and default codeset.  */
+	if (((*p == 'C') && !p[1]) || !strcmp(p, posix)) {
+		goto FIND_LOCALE;
 	}
 
-	if (strcmp (name, C_LOCALE_NAME) == 0 ||
-				strcmp (name, POSIX_LOCALE_NAME) == 0 ||
-		/* TODO! */     (c!=LC_CTYPE && c!=LC_COLLATE))
-	    name = C_LOCALE_NAME;
+	if (p[5] == '.') {		/* Codeset specified in locale name? */
+		/* TODO: maybe CODESET_LIST + *s ??? */
+		/* 7bit is 1, UTF-8 is 2, 8-bit is >= 3 */
+		codeset = 2;
+		if (strcmp("UTF-8",p+6) != 0) {/* TODO - fix! */
+			s = CODESET_LIST;
+			do {
+				++codeset;		/* Increment codeset first. */
+				if (!strcmp(CODESET_LIST+*s, p+6)) {
+					goto FIND_LANG_CULT;
+				}
+			} while (*++s);
+			return 0;			/* No matching codeset! */
+		}
+	}
 
-	*plocale = name;
+ FIND_LANG_CULT:				/* Find language_culture number. */
+	s = LOCALE_NAMES;
+	do {						/* TODO -- do a binary search? */
+		/* TODO -- fix gen_mmap!*/
+		++lang_cult;			/* Increment first since C/POSIX is 0. */
+		if (!strncmp(s,p,5)) { /* Found a matching locale name; */
+			goto FIND_LOCALE;
+		}
+		s += 5;
+	} while (lang_cult < NUM_LOCALE_NAMES);
+	return 0;					/* No matching language_culture! */
+
+ FIND_LOCALE:					/* Find locale row matching name and codeset */
+	s = LOCALES;
+	n = 1;
+	do {						/* TODO -- do a binary search? */
+		if ((lang_cult == *s) && ((codeset == s[1]) || (codeset == s[2]))) {
+			i = ((category == LC_ALL) ? 0 : category);
+			s = new_locale + 2*i;
+			do {
+				/* Encode current locale row number. */
+				*((unsigned char *) ++s) = (n >> 8) | 0x80;
+				*((unsigned char *) ++s) = n & 0xff;
+			} while (++i < category);
+
+			return i;			/* Return non-zero */
+		}
+		s += WIDTH_LOCALES;
+		++n;
+	} while (n <= NUM_LOCALES);	/* We started at 1!!! */
 
-#ifdef __UCLIBC_HAS_LOCALE__
-	for(cur = sll; cur; cur = cur->next)
-		if(cur->category == c && strcmp(cur->locale, name)==0)
-			return cur->locale;
-#else
-	if(name == C_LOCALE_NAME)
-		return C_LOCALE_NAME;
-#endif
-	return NULL;
+	return 0;					/* Unsupported locale. */
 }
 
-
-#ifdef __UCLIBC_HAS_LOCALE__
-static char *load_locale(int category, const char *locale)
+char *setlocale(int category, const char *locale)
 {
-	FILE * fl;
-	char   full_path[PATH_MAX];
-	char * buf = 0;
-	struct SAV_LOADED_LOCALE *cur;
-	struct SAV_LOADED_LOCALE *bottom;
-	int    bufsize;
-	int    l = strlen(locale);
-
-	if((l+sizeof(PATH_LOCALE)+strlen(LC_strs[category]))>=PATH_MAX)
-		return NULL;
-
-	/* Not allow acces suid/sgid binaries to outside PATH_LOCALE */
-	if((geteuid()!=getuid() || getegid()!=getgid()) &&
-		strchr(locale, '/')!=NULL)
-			return NULL;
-
-	strcpy(full_path, PATH_LOCALE);
-	strcat(full_path, locale);
-	strcat(full_path, LC_strs[category]);
-	fl = fopen(full_path, "r");
-	if(fl==0)
-		return NULL;
+	const unsigned char *p;
+	unsigned char *s;
+	int i;
+	unsigned lc_mask;
+	unsigned char new_locale[LOCALE_STRING_SIZE];
+
+	if (((unsigned int)(category)) > LC_ALL) {
+		/* TODO - set errno?  SUSv3 doesn't say too. */
+		return NULL;			/* Illegal/unsupported category. */
+	}
 
-	switch(category) {
-		case LC_CTYPE:
-			bufsize = LOCALE_BUF_SIZE;
-			break;
-		case LC_COLLATE:
-			bufsize = 256;
-			break;
-		default:        /* TODO */
-			bufsize = 0;
-			break;
+	lc_mask = 1 << category;
+	if (category == LC_ALL) {
+		--lc_mask;
 	}
 
-	cur = malloc(sizeof(struct SAV_LOADED_LOCALE)+bufsize+l+2);
-	if(cur) {
-		buf = (char *)(cur+1);
-		if(bufsize!=0 && fread(buf, 1, bufsize+1, fl)!=(bufsize)) {
-			/* broken locale file */
-			free(cur);
-			buf = 0;
-#ifdef TEST_LOCALE
-			fprintf(stderr, "\nbroken locale file\n");
-#endif
-		}
+	if (!locale) {				/* Request for locale category string... */
+	DONE:
+		strcpy(setlocale_buf, CUR_LOCALE_SPEC);
+#ifdef __LOCALE_STRICTER_SETLOCALE
+		/* The standard says you can only use the string returned to restore
+		 * the category (categories) requested.  This could be optional.
+		 * See below as well. */
+		s = setlocale_buf + 1;
+		lc_mask |= (1 << LC_ALL);
+		do {
+			if (!(lc_mask & 1)) {
+				/* Encode non-selected locale flag. */
+				s[1] = *s = 0xff;
+			}
+			s += 2;
+		} while ((lc_mask >>= 1) > 1);
+#endif /* __LOCALE_STRICTER_SETLOCALE */
+		return (char *) setlocale_buf;
 	}
 
-	fclose(fl);
-	if(cur==0)      /* not enough memory */
+	strcpy(new_locale, CUR_LOCALE_SPEC); /* Start with current. */
+
+	if (!*locale) {				/* locale == "", so check environment. */
+		i = ((category == LC_ALL) ? 0 : category);
+		do {
+			/* Note: SUSv3 doesn't define a fallback mechanism here.  So,
+			 * if LC_ALL is invalid, we do _not_ continue trying the other
+			 * environment vars. */
+			if (!(p = getenv("LC_ALL"))) {
+				if (!(p = getenv(CATEGORY_NAMES + CATEGORY_NAMES[i]))) {
+					if (!(p = getenv("LANG"))) {
+						p = posix;
+					}
+				}
+			}
+
+			/* The user set something... is it valid? */
+			/* Note: Since we don't support user-supplied locales and
+			 * alternate paths, we don't need to worry about special
+			 * handling for suid/sgid apps. */
+			if (!find_locale(i, p, new_locale)) {
+				return NULL;
+			}
+		} while (++i < category);
+	} else if (*locale == '#') { /* Previsouly returned value. */
+		assert(strlen(locale) == LOCALE_STRING_SIZE - 1);
+
+		i = ((category == LC_ALL) ? 0 : category);
+		p = locale + 2*i;
+		s = new_locale + 2*i;
+		do {
+#ifdef __LOCALE_STRICTER_SETLOCALE
+			/* Only set categories that were selected in the previous
+			 * return value.  Could be optional.  See above as well.
+			 * NOTE: This still isn't quite right for non-LC_ALL
+			 * as it only checks the category selected to set. */
+			if ((*p == 0xff) && (p[1] == 0xff)) {
+				return NULL;
+			}
+#endif /* __LOCALE_STRICTER_SETLOCALE */
+			/* Note: Validate settings below. */
+			*++s = *++p;
+			*++s = *++p;
+		} while (++i < category);
+	} else if (!find_locale(category, locale, new_locale)) {
 		return NULL;
-	if(buf==0) {    /* broken locale file, set to "C" */
-		return C_LOCALE_NAME;
 	}
 
-	cur->next     = 0;
-	cur->buf      = buf;
-	cur->category = category;
-	cur->locale   = buf+bufsize;
-	strcpy(cur->locale, locale);
 
-	bottom = sll;
-	while(bottom->next!=0)
-		bottom = bottom->next;
-	bottom->next = cur;
+	/* TODO: Ok, everything checks out, so install the new locale. */
+	_locale_set(new_locale);
 
-	return cur->locale;
+	/* Everything ok, so make a copy in setlocale_buf and return. */
+	goto DONE;
 }
 
-static char *set_composite(int category, char *locale)
+#endif /* __LOCALE_C_ONLY */
+
+#endif
+/**********************************************************************/
+#ifdef L_localeconv
+
+/* Note: We assume here that the compiler does the sane thing regarding
+ * placement of the fields in the struct.  If necessary, we could ensure
+ * this usings an array of offsets but at some size cost. */
+
+#ifdef __LOCALE_C_ONLY
+
+#warning localeconv is hardwired for C/POSIX locale only
+link_warning(localeconv,"the 'localeconv' function is hardwired for C/POSIX locale only");
+
+static struct lconv the_lconv;
+
+static const char decpt[] = ".";
+
+struct lconv *localeconv(void)
 {
-	int i, l;
-	char *old_composite_name = nl_current[LC_ALL];
-	char *new_composite_name;
-	struct SAV_LOADED_LOCALE *cur;
-
-	for(l=i=0; i<LC_ALL; i++) {
-		new_composite_name = i == category ? locale : nl_current[i];
-						/* '=' + ';' or '\0' */
-		l += strlen(&LC_strs[i][1])+strlen(new_composite_name)+2;
-	}
+	register char *p = (char *)(&the_lconv);
 
-	new_composite_name = malloc(l);
-	if(new_composite_name==NULL)
-		return NULL;
-	if(old_composite_name!=composite_name_C)
-		free(old_composite_name);
-	nl_current[category] = locale;  /* change after malloc */
-
-	*new_composite_name = 0;
-	for(i=0; i<LC_ALL; i++) {
-		if(i)
-			strcat(new_composite_name, ";");
-		strcat(new_composite_name, &LC_strs[i][1]);
-		strcat(new_composite_name, "=");
-		strcat(new_composite_name, nl_current[i]);
-	}
-	nl_current[LC_ALL] = new_composite_name;
-
-	/* set locale data for ctype and strcollate functions */
-	for(cur = sll; ; cur = cur->next)
-		if(cur->category == category && cur->locale == locale)
-			break;
-
-	switch(category) {
-		case LC_CTYPE:
-			_uc_ctype_b     = cur->buf;
-			_uc_ctype_trans = cur->buf+LOCALE_BUF_SIZE/2;
-			break;
-		case LC_COLLATE:
-			_uc_collate_b   = cur->buf;
-			break;
-		default:        /* TODO */
-			break;
-	}
-	return locale;
+	*((char **)p) = (char *) decpt;
+	do {
+		p += sizeof(char **);
+		*((char **)p) = (char *) (decpt+1);
+	} while (p < (char *) &the_lconv.negative_sign);
+
+	p = (&the_lconv.int_frac_digits);
+	do {
+		*p = CHAR_MAX;
+		++p;
+	} while (p <= &the_lconv.int_n_sign_posn);
+
+	return &the_lconv;
 }
 
-#endif /* __UCLIBC_HAS_LOCALE__ */
+#else  /* __LOCALE_C_ONLY */
 
-char *setlocale(int category, const char *locale)
+static struct lconv the_lconv;
+
+struct lconv *localeconv(void)
 {
-	char * tl;
-#ifdef __UCLIBC_HAS_LOCALE__
-	int    i;
+	register char *p = (char *) &the_lconv;
+	register char **q = (char **) &__global_locale.decimal_point;
+
+	do {
+		*((char **)p) = *q;
+		p += sizeof(char **);
+		++q;
+	} while (p < &the_lconv.int_frac_digits);
+
+	do {
+		*p = **q;
+		++p;
+		++q;
+	} while (p <= &the_lconv.int_n_sign_posn);
+
+	return &the_lconv;
+}
+
+#endif /* __LOCALE_C_ONLY */
+
 #endif
+/**********************************************************************/
+#ifdef L__locale_init
 
-	if (category < 0 || category > LC_ALL) {
-#ifdef __UCLIBC_HAS_LOCALE__
-einval:
+#ifndef __LOCALE_C_ONLY
+
+#define C_LOCALE_SELECTOR "\x23\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01"
+#define LOCALE_INIT_FAILED "locale init failed!\n"
+
+#define CUR_LOCALE_SPEC			(__global_locale.cur_locale)
+
+__locale_t __global_locale;
+
+void _locale_init(void)
+{
+	/* TODO: mmap the locale file  */
+
+	/* TODO - ??? */
+	memset(CUR_LOCALE_SPEC, 0, LOCALE_STRING_SIZE);
+	CUR_LOCALE_SPEC[0] = '#';
+
+	memcpy(__global_locale.category_item_count,
+		   __locale_mmap->lc_common_item_offsets_LEN,
+		   LC_ALL);
+
+	__global_locale.category_offsets[0] = offsetof(__locale_t, codeset);
+	__global_locale.category_offsets[1] = offsetof(__locale_t, decimal_point);
+	__global_locale.category_offsets[2] = offsetof(__locale_t, int_curr_symbol);
+	__global_locale.category_offsets[3] = offsetof(__locale_t, abday_1);
+/*  	__global_locale.category_offsets[4] = offsetof(__locale_t, collate???); */
+	__global_locale.category_offsets[5] = offsetof(__locale_t, yesexpr);
+
+#ifdef __CTYPE_HAS_8_BIT_LOCALES
+	__global_locale.tbl8ctype
+		= (const unsigned char *) &__locale_mmap->tbl8ctype;
+    __global_locale.tbl8uplow
+		= (const unsigned char *) &__locale_mmap->tbl8uplow;
+#ifdef __WCHAR_ENABLED
+	__global_locale.tbl8c2wc
+		= (const uint16_t *) &__locale_mmap->tbl8c2wc;
+	__global_locale.tbl8wc2c
+		= (const unsigned char *) &__locale_mmap->tbl8wc2c;
+	/* translit  */
+#endif /* __WCHAR_ENABLED */
+#endif /* __CTYPE_HAS_8_BIT_LOCALES */
+#ifdef __WCHAR_ENABLED
+	__global_locale.tblwctype
+		= (const unsigned char *) &__locale_mmap->tblwctype;
+	__global_locale.tblwuplow
+		= (const unsigned char *) &__locale_mmap->tblwuplow;
+	__global_locale.tblwuplow_diff
+		= (const uint16_t *) &__locale_mmap->tblwuplow_diff;
+	__global_locale.tblwcomb
+		= (const unsigned char *) &__locale_mmap->tblwcomb;
+	/* width?? */
+#endif /* __WCHAR_ENABLED */
+
+	_locale_set(C_LOCALE_SELECTOR);
+}
+
+static const char ascii[] = "ASCII";
+static const char utf8[] = "UTF-8";
+
+void _locale_set(const unsigned char *p)
+{
+	const char **x;
+	unsigned char *s = CUR_LOCALE_SPEC + 1;
+	const size_t *stp;
+	const unsigned char *r;
+	const uint16_t *io;
+	const uint16_t *ii;
+	const unsigned char *d;
+	int row;					/* locale row */
+	int crow;					/* category row */
+	int len;
+	int c;
+	int i = 0;
+
+	++p;
+	do {
+		if ((*p != *s) || (p[1] != s[1])) {
+			row  = (((int)(*p & 0x7f)) << 8) + p[1] - 1;
+#ifndef NDEBUG
+			assert(row < NUM_LOCALES);
 #endif
-		errno = EINVAL;
-		return NULL;
-	}
+			*s = *p;
+			s[1] = p[1];
+
+			if (i == LC_CTYPE) {
+				c = __locale_mmap->locales[ WIDTH_LOCALES * row + 2 ]; /* codeset */
+				if (c <= 2) {
+					if (c == 2) {
+						__global_locale.codeset = utf8;
+						__global_locale.encoding = __ctype_encoding_utf8;
+						/* TODO - fix for bcc */
+						__global_locale.mb_cur_max = 6;
+					} else {
+						assert(c==1);
+						__global_locale.codeset = ascii;
+						__global_locale.encoding = __ctype_encoding_7_bit;
+						__global_locale.mb_cur_max = 1;
+					}
+				} else {
+					const codeset_8_bit_t *c8b;
+					r = CODESET_LIST;
+					__global_locale.codeset = r + r[c -= 3];
+					__global_locale.encoding = __ctype_encoding_8_bit;
+#warning REMINDER: update 8 bit mb_cur_max when trasnlit implemented!
+					/* TODO - update when translit implemented! */
+					__global_locale.mb_cur_max = 1;
+					c8b = __locale_mmap->codeset_8_bit + c;
+#ifdef __CTYPE_HAS_8_BIT_LOCALES
+					__global_locale.idx8ctype = c8b->idx8ctype;
+					__global_locale.idx8uplow = c8b->idx8uplow;
+#ifdef __WCHAR_ENABLED
+					__global_locale.idx8c2wc = c8b->idx8c2wc;
+					__global_locale.idx8wc2c = c8b->idx8wc2c;
+					/* translit  */
+#endif /* __WCHAR_ENABLED */
+#endif /* __CTYPE_HAS_8_BIT_LOCALES */
+				}
+
+			} else if ((len = __locale_mmap->lc_common_item_offsets_LEN[i]) != 0) {
+				crow = __locale_mmap->locales[ WIDTH_LOCALES * row + 3 + i ]
+					* len;
+				x = (const char **)(((char *) &__global_locale)
+									+ __global_locale.category_offsets[i]);
+				stp = __locale_mmap->lc_common_tbl_offsets + 4*i;
+				r = (const unsigned char *)( ((char *)__locale_mmap) + *stp );
+				io = (const uint16_t *)( ((char *)__locale_mmap) + *++stp );
+				ii = (const uint16_t *)( ((char *)__locale_mmap) + *++stp );
+				d = (const unsigned char *)( ((char *)__locale_mmap) + *++stp );
+				for (c=0 ; c < len ; c++) {
+					*(x + c) = d + ii[ r[crow + c] + io[c] ];
+				}
+			}
 
-	if(locale==NULL)
-		return nl_current[category];
-
-	if(category!=LC_ALL) {
-		tl = find_locale(category, &locale);
-#ifdef __UCLIBC_HAS_LOCALE__
-		if(tl==NULL)
-			tl = load_locale(category, locale);
-		if(tl) {
-			if(nl_current[category] != tl)
-				tl = set_composite(category, tl);
 		}
+		++i;
+		p += 2;
+		s += 2;
+	} while (i < LC_ALL);
+}
+
+#endif /* __LOCALE_C_ONLY */
+
 #endif
-		return tl;
-	}
-	/* LC_ALL */
-#ifdef __UCLIBC_HAS_LOCALE__
-	/* The user wants to set all categories.  The desired locales
-	 for the individual categories can be selected by using a
-	 composite locale name.  This is a semi-colon separated list
-	 of entries of the form `CATEGORY=VALUE'.  */
-	tl = strchr(locale, ';');
-	if(tl==NULL) {
-	/* This is not a composite name. Load the data for each category. */
-		for(i=0; i<LC_ALL; i++)
-			setlocale(i, locale);   /* recursive */
-	} else {
-	/* This is a composite name.  Make a copy and split it up. */
-	  const char *newnames[LC_ALL];
-	  char *np;
-	  char *cp;
-
-	  i  = strlen(locale);
-	  np = alloca (i);
-	  if(np)
-		strcpy(np, locale);
-	  else
-		return NULL;
-	  for (i = 0; i < LC_ALL; ++i)
-		newnames[i] = 0;
-
-	  while ((cp = strchr (np, '=')) != NULL) {
-	      for (i = 0; i < LC_ALL; ++i)
-		if ((size_t) (cp - np) == strlen(&LC_strs[i][1])
-		    && memcmp (np, &LC_strs[i][1], (cp - np)) == 0)
-		  break;
-
-	      if (i == LC_ALL)
-		/* Bogus category name.  */
-		goto einval;
-
-	      /* Found the category this clause sets.  */
-	      newnames[i] = ++cp;
-	      cp = strchr (cp, ';');
-	      if (cp != NULL) {
-		  /* Examine the next clause.  */
-		  *cp = '\0';
-		  np = cp + 1;
-	      } else
-		/* This was the last clause.  We are done.  */
-		break;
-	  }
-
-	  for (i = 0; i < LC_ALL; ++i)
-		setlocale(i, newnames[i]);   /* recursive */
+/**********************************************************************/
+#ifdef L_nl_langinfo
+
+#ifndef __LOCALE_C_ONLY
+
+#include <langinfo.h>
+#include <nl_types.h>
+
+static const char empty[] = "";
+
+char *nl_langinfo(nl_item item)
+{
+	unsigned int c = _NL_ITEM_CATEGORY(item);
+	unsigned int i = _NL_ITEM_INDEX(item);
+
+	if ((c < LC_ALL) && (i < __global_locale.category_item_count[c])) {
+		return ((char **)(((char *) &__global_locale)
+						  + __global_locale.category_offsets[c]))[i];
+
 	}
+	return (char *) empty;
+}
+
+#endif /* __LOCALE_C_ONLY */
 
 #endif
-	return nl_current[LC_ALL];
-}
+/**********************************************************************/

+ 0 - 52
libc/misc/locale/localeconv.c

@@ -1,52 +0,0 @@
-/* localeconv.c
- *
- * Written by Erik Andersen <andersee@debian.org> 
- *
- * This library is free software; you can redistribute it and/or 
- * modify it under the terms of the GNU Library General Public License as 
- * published by the Free Software Foundation; either version 2 of the 
- * License, or (at your option) any later version.  
- *
- * This 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 this library; see the file COPYING.LIB.  If not, 
- * write to the Free Software Foundation, Inc., 675 Mass Ave, 
- * Cambridge, MA 02139, USA.  */
-
-#include <string.h>
-#include <locale.h>
-
-/* Return monetary and numeric information about the current locale.  */
-struct lconv * localeconv __P ((void))
-{
-  static struct lconv result;
-  static char *blank = "";
-  static char *decimal = ".";
-  char junk = '\177';
-
-  result.decimal_point = decimal;
-  result.thousands_sep = blank;
-  result.grouping = "\177";
-  result.int_curr_symbol = blank;
-  result.currency_symbol = blank;
-  result.mon_decimal_point = blank;
-  result.mon_thousands_sep = blank;
-  result.mon_grouping = blank;
-  result.positive_sign = blank;
-  result.negative_sign = blank;
-  result.int_frac_digits = junk;
-  result.frac_digits = junk;
-  result.p_cs_precedes = junk;
-  result.p_sep_by_space = junk;
-  result.n_cs_precedes = junk;
-  result.n_sep_by_space = junk;
-  result.p_sign_posn = junk;
-  result.n_sign_posn = junk;
-
-  return &result;
-}
-

+ 47 - 0
libc/misc/wctype/Makefile

@@ -0,0 +1,47 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000 by Lineo, inc.
+# Copyright (C) 2000,2001 Erik Andersen <andersen@uclibc.org>
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Library General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Derived in part from the Linux-8086 C library, the GNU C Library, and several
+# other sundry sources.  Files within this library are copyright by their
+# respective copyright holders.
+
+TOPDIR=../../../
+include $(TOPDIR)Rules.mak
+
+MSRC= wctype.c
+MOBJ=  iswalnum.o iswalpha.o iswcntrl.o iswdigit.o iswgraph.o iswlower.o \
+	iswprint.o iswpunct.o iswspace.o iswupper.o iswxdigit.o towlower.o \
+	towupper.o iswblank.o wctype.o iswctype.o wctrans.o towctrans.o
+
+OBJS=$(MOBJ)
+
+all: $(OBJS) $(LIBC)
+
+$(LIBC): ar-target
+
+ar-target: $(OBJS)
+	$(AR) $(ARFLAGS) $(LIBC) $(OBJS)
+
+$(MOBJ): $(MSRC)
+	$(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+	$(STRIPTOOL) -x -R .note -R .comment $*.o
+
+clean:
+	rm -f *.[oa] *~ core
+

+ 480 - 0
libc/misc/wctype/wctype.c

@@ -0,0 +1,480 @@
+/*  Copyright (C) 2002     Manuel Novoa III
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!
+ *
+ *  Besides uClibc, I'm using this code in my libc for elks, which is
+ *  a 16-bit environment with a fairly limited compiler.  It would make
+ *  things much easier for me if this file isn't modified unnecessarily.
+ *  In particular, please put any new or replacement functions somewhere
+ *  else, and modify the makefile to use your version instead.
+ *  Thanks.  Manuel
+ *
+ *  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION! */
+
+#define _GNU_SOURCE
+#define __NO_CTYPE
+
+#include <wctype.h>
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+#include <locale.h>
+
+/* We know wide char support is enabled.  We wouldn't be here otherwise. */
+
+/* Define this if you want to unify the towupper and towlower code in the
+ * towctrans function. */
+/*  #define SMALL_UPLOW */
+
+#define __WCTYPE_WITH_LOCALE
+
+/**********************************************************************/
+
+#ifndef __PASTE
+#define __PASTE(X,Y)		X ## Y
+#endif
+
+#define C_MACRO(X)		__PASTE(__C_,X)(wc)
+
+#define CT_MACRO(X)		__PASTE(__ctype_,X)(wc)
+
+/**********************************************************************/
+
+/* TODO: fix this! */
+#ifdef __WCTYPE_WITH_LOCALE
+
+#define WCctype			(__global_locale.tblwctype)
+#define WCuplow			(__global_locale.tblwuplow)
+#define WCcmob			(__global_locale.tblwcomb)
+#define WCuplow_diff	(__global_locale.tblwuplow_diff)
+
+#define ENCODING		(__global_locale.encoding)
+
+#define ISW_FUNC_BODY(NAME) \
+int NAME (wint_t wc) \
+{ \
+	return iswctype(wc, __PASTE(_CTYPE_,NAME)); \
+}
+
+#else  /* __WCTYPE_WITH_LOCALE */
+
+#define ISW_FUNC_BODY(NAME) \
+int NAME (wint_t wc) \
+{ \
+	return C_MACRO(NAME); \
+}
+
+#endif /* __WCTYPE_WITH_LOCALE */
+
+/**********************************************************************/
+#ifdef L_iswalnum
+
+ISW_FUNC_BODY(iswalnum);
+
+#endif
+/**********************************************************************/
+#ifdef L_iswalpha
+
+ISW_FUNC_BODY(iswalpha);
+
+#endif
+/**********************************************************************/
+#ifdef L_iswblank
+
+ISW_FUNC_BODY(iswblank);
+
+#endif
+/**********************************************************************/
+#ifdef L_iswcntrl
+
+ISW_FUNC_BODY(iswcntrl);
+
+#endif
+/**********************************************************************/
+#ifdef L_iswdigit
+
+int iswdigit(wint_t wc)
+{
+	return __C_iswdigit(wc);
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_iswgraph
+
+ISW_FUNC_BODY(iswgraph);
+
+#endif
+/**********************************************************************/
+#ifdef L_iswlower
+
+ISW_FUNC_BODY(iswlower);
+
+#endif
+/**********************************************************************/
+#ifdef L_iswprint
+
+ISW_FUNC_BODY(iswprint);
+
+#endif
+/**********************************************************************/
+#ifdef L_iswpunct
+
+ISW_FUNC_BODY(iswpunct);
+
+#endif
+/**********************************************************************/
+#ifdef L_iswspace
+
+ISW_FUNC_BODY(iswspace);
+
+#endif
+/**********************************************************************/
+#ifdef L_iswupper
+
+ISW_FUNC_BODY(iswupper);
+
+#endif
+/**********************************************************************/
+#ifdef L_iswxdigit
+
+int iswxdigit(wint_t wc)
+{
+	return __C_iswxdigit(wc);
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_towlower
+
+#ifdef __WCTYPE_WITH_LOCALE
+
+#ifdef SMALL_UPLOW
+
+wint_t towlower(wint_t wc)
+{
+	return towctrans(wc, _CTYPE_tolower);
+}
+
+#else
+
+wint_t towlower(wint_t wc)
+{
+	unsigned int sc, n, i;
+	__uwchar_t u = wc;
+
+	if (ENCODING == __ctype_encoding_7_bit) {
+		/* We're in the C/POSIX locale, so ignore the tables. */
+		return __C_towlower(wc);
+	}
+
+	if (u <= WC_TABLE_DOMAIN_MAX) {
+		sc = u & ((1 << WCuplow_TI_SHIFT) - 1);
+		u >>= WCuplow_TI_SHIFT;
+		n = u & ((1 << WCuplow_II_SHIFT) - 1);
+		u >>= WCuplow_II_SHIFT;
+
+		i = ((unsigned int) WCuplow[u]) << WCuplow_II_SHIFT;
+		i = ((unsigned int) WCuplow[WCuplow_II_LEN + i + n])
+			<< WCuplow_TI_SHIFT;
+		i = ((unsigned int) WCuplow[WCuplow_II_LEN + WCuplow_TI_LEN
+										+ i + sc]) << 1;
+		wc += WCuplow_diff[i + 1];
+	}
+	return wc;
+}
+
+#endif
+
+#else  /* __WCTYPE_WITH_LOCALE */
+
+wint_t towlower(wint_t wc)
+{
+	return __C_towlower(wc);
+}
+
+#endif /* __WCTYPE_WITH_LOCALE */
+
+#endif
+/**********************************************************************/
+#ifdef L_towupper
+
+#ifdef __WCTYPE_WITH_LOCALE
+
+#ifdef SMALL_UPLOW
+
+wint_t towupper(wint_t wc)
+{
+	return towctrans(wc, _CTYPE_toupper);
+}
+
+#else
+
+wint_t towupper(wint_t wc)
+{
+	unsigned int sc, n, i;
+	__uwchar_t u = wc;
+
+	if (ENCODING == __ctype_encoding_7_bit) {
+		/* We're in the C/POSIX locale, so ignore the tables. */
+		return __C_towupper(wc);
+	}
+
+	if (u <= WC_TABLE_DOMAIN_MAX) {
+		sc = u & ((1 << WCuplow_TI_SHIFT) - 1);
+		u >>= WCuplow_TI_SHIFT;
+		n = u & ((1 << WCuplow_II_SHIFT) - 1);
+		u >>= WCuplow_II_SHIFT;
+
+		i = ((unsigned int) WCuplow[u]) << WCuplow_II_SHIFT;
+		i = ((unsigned int) WCuplow[WCuplow_II_LEN + i + n])
+			<< WCuplow_TI_SHIFT;
+		i = ((unsigned int) WCuplow[WCuplow_II_LEN + WCuplow_TI_LEN
+										+ i + sc]) << 1;
+		wc += WCuplow_diff[i];
+	}
+	return wc;
+}
+
+#endif
+
+#else  /* __WCTYPE_WITH_LOCALE */
+
+wint_t towupper(wint_t wc)
+{
+	return __C_towupper(wc);
+}
+
+#endif /* __WCTYPE_WITH_LOCALE */
+
+#endif
+/**********************************************************************/
+#ifdef L_wctype
+
+static const unsigned char typestring[] = __CTYPE_TYPESTRING;
+/*  extern const unsigned char typestring[]; */
+
+wctype_t wctype(const char *property)
+{
+	const unsigned char *p;
+	int i;
+
+	p = typestring;
+	i = 1;
+	do {
+		if (!strcmp(property, ++p)) {
+			return i;
+		}
+		++i;
+		p += p[-1];
+	} while (*p);
+
+	/* TODO - Add locale-specific classifications. */
+	return 0;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_iswctype
+
+#warning TODO: need to fix locale ctype table lookup stuff
+#if 0
+extern const char ctype_range[];
+#else
+static const char ctype_range[] = {
+	__CTYPE_RANGES
+};
+#endif
+
+#warning TODO: need to handle combining class!
+
+#define WCctype_TI_MASK		((1 << WCctype_TI_SHIFT) - 1)
+#define WCctype_II_MASK		((1 << WCctype_II_SHIFT) - 1)
+
+int iswctype(wint_t wc, wctype_t desc)
+{
+	unsigned int sc, n, i0, i1;
+	unsigned char d = __CTYPE_unclassified;
+
+	if ((ENCODING != __ctype_encoding_7_bit) || (((__uwchar_t) wc) <= 0x7f)){
+		if (desc < _CTYPE_iswxdigit) {
+			if (((__uwchar_t) wc) <= WC_TABLE_DOMAIN_MAX) {
+				/* From here on, we know wc > 0. */
+				sc = wc & WCctype_TI_MASK;
+				wc >>= WCctype_TI_SHIFT;
+				n = wc & WCctype_II_MASK;
+				wc >>= WCctype_II_SHIFT;
+
+				i0 = WCctype[wc];
+				i0 <<= WCctype_II_SHIFT;
+				i1 = WCctype[WCctype_II_LEN + i0 + n];
+				i1 <<= (WCctype_TI_SHIFT-1);
+				d = WCctype[WCctype_II_LEN + WCctype_TI_LEN + i1 + (sc >> 1)];
+
+				d = (sc & 1) ? (d >> 4) : (d & 0xf);
+			} else if ( ((((__uwchar_t)(wc - 0xe0020UL)) <= 0x5f)
+						 || (wc == 0xe0001UL))
+						|| ( (((__uwchar_t)(wc - 0xf0000UL)) < 0x20000UL)
+							 && ((wc & 0xffffU) <= 0xfffdU))
+						) {
+				d = __CTYPE_punct;
+			}
+
+			return ( ((unsigned char)(d - ctype_range[2*desc]))
+					 <= ctype_range[2*desc + 1] )
+				&& ((desc != _CTYPE_iswblank) || (d & 1));
+		}
+
+		/* TODO - Add locale-specific classifications. */
+		return (desc == _CTYPE_iswxdigit) ? __C_iswxdigit(wc) : 0;
+	}
+	return 0;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_towctrans
+
+#ifdef __WCTYPE_WITH_LOCALE
+
+#ifdef SMALL_UPLOW
+
+wint_t towctrans(wint_t wc, wctrans_t desc)
+{
+	unsigned int sc, n, i;
+	__uwchar_t u = wc;
+
+	/* TODO - clean up */
+	if (ENCODING == __ctype_encoding_7_bit) {
+		if ((((__uwchar_t) wc) > 0x7f)
+			|| (((unsigned int)(desc - _CTYPE_tolower))
+				> (_CTYPE_toupper - _CTYPE_tolower))
+			){
+			/* We're in the C/POSIX locale, so ignore non-ASCII values
+			 * as well an any mappings other than toupper or tolower. */
+			return wc;
+		}
+	}
+
+	if (((unsigned int)(desc - _CTYPE_tolower))
+		<= (_CTYPE_totitle - _CTYPE_tolower)
+		) {
+		if (u <= WC_TABLE_DOMAIN_MAX) {
+			sc = u & ((1 << WCuplow_TI_SHIFT) - 1);
+			u >>= WCuplow_TI_SHIFT;
+			n = u & ((1 << WCuplow_II_SHIFT) - 1);
+			u >>= WCuplow_II_SHIFT;
+
+			i = ((unsigned int) WCuplow[u]) << WCuplow_II_SHIFT;
+			i = ((unsigned int) WCuplow[WCuplow_II_LEN + i + n])
+				<< WCuplow_TI_SHIFT;
+			i = ((unsigned int) WCuplow[WCuplow_II_LEN + WCuplow_TI_LEN
+											+ i + sc]) << 1;
+			if (desc == _CTYPE_tolower) {
+				++i;
+			}
+			wc += WCuplow_diff[i];
+			if (desc == _CTYPE_totitle) {
+				/* WARNING! These special cases work for glibc 2.2.4.  Changes
+				 * may be needed if the glibc locale tables are updated. */
+				if ( (((__uwchar_t)(wc - 0x1c4)) <= (0x1cc - 0x1c4))
+					 || (wc == 0x1f1)
+					 ) {
+					++wc;
+				}
+			}
+		}
+	} else {
+		/* TODO - Deal with other transliterations. */
+		__set_errno(EINVAL);
+	}
+
+	return wc;
+}
+
+#else
+
+wint_t towctrans(wint_t wc, wctrans_t desc)
+{
+	if (ENCODING == __ctype_encoding_7_bit) {
+		if ((((__uwchar_t) wc) > 0x7f)
+			|| (((unsigned int)(desc - _CTYPE_tolower))
+				> (_CTYPE_toupper - _CTYPE_tolower))
+			){
+			/* We're in the C/POSIX locale, so ignore non-ASCII values
+			 * as well an any mappings other than toupper or tolower. */
+			return wc;
+		}
+	}
+
+	if (desc == _CTYPE_tolower) {
+		return towlower(wc);
+	} else if (((unsigned int)(desc - _CTYPE_toupper))
+		<= (_CTYPE_totitle - _CTYPE_toupper)
+		) {
+		wc = towupper(wc);
+		if (desc == _CTYPE_totitle) {
+			/* WARNING! These special cases work for glibc 2.2.4.  Changes
+			 * may be needed if the glibc locale tables are updated. */
+			if ( (((__uwchar_t)(wc - 0x1c4)) <= (0x1cc - 0x1c4))
+				 || (wc == 0x1f1)
+				 ) {
+				++wc;
+			}
+		}
+	} else {
+		/* TODO - Deal with other transliterations. */
+		__set_errno(EINVAL);
+	}
+	return wc;
+}
+
+#endif
+
+#else
+
+
+#endif
+
+#endif
+/**********************************************************************/
+#ifdef L_wctrans
+
+static const char transstring[] = __CTYPE_TRANSTRING;
+
+wctrans_t wctrans(const char *property)
+{
+	const unsigned char *p;
+	int i;
+
+	p = transstring;
+	i = 1;
+	do {
+		if (!strcmp(property, ++p)) {
+			return i;
+		}
+		++i;
+		p += p[-1];
+	} while (*p);
+
+	/* TODO - Add locale-specific translations. */
+	return 0;
+}
+
+#endif
+/**********************************************************************/

+ 3 - 2
libc/stdlib/Makefile

@@ -28,7 +28,8 @@ DIRS = $(MALLOC)
 ALL_SUBDIRS = malloc malloc-930716 malloc-simple
 
 MSRC = stdlib.c
-MOBJ = abs.o labs.o atoi.o atol.o strtol.o strtoul.o _stdlib_strto_l.o
+MOBJ = abs.o labs.o atoi.o atol.o strtol.o strtoul.o _stdlib_strto_l.o \
+       qsort.o bsearch.o
 
 ifeq ($(HAS_LONG_LONG),true)
 	MOBJ +=  llabs.o atoll.o strtoll.o strtoull.o _stdlib_strto_ll.o
@@ -37,7 +38,7 @@ endif
 MSRC2=atexit.c
 MOBJ2=atexit.o on_exit.o __exit_handler.o exit.o
 
-CSRC =	abort.c getenv.c mktemp.c qsort.c realpath.c bsearch.c \
+CSRC =	abort.c getenv.c mktemp.c realpath.c \
 	mkstemp.c mkstemp64.c putenv.c rand.c random.c random_r.c setenv.c \
 	system.c div.c ldiv.c getpt.c ptsname.c grantpt.c unlockpt.c gcvt.c
 CSRC+=  drand48.c drand48-iter.c drand48_r.c erand48.c erand48_r.c \

+ 169 - 12
libc/stdlib/stdlib.c

@@ -27,30 +27,44 @@
 
 #define _ISOC99_SOURCE			/* for ULLONG primarily... */
 #define _GNU_SOURCE
-#include <stdlib.h>
 #include <limits.h>
 #include <stdint.h>
 #include <inttypes.h>
 #include <ctype.h>
 #include <errno.h>
 #include <assert.h>
+#include <unistd.h>
+
+/* Work around gcc's refusal to create aliases. */
+#define atoi __ignore_atoi
+#define abs __ignore_abs
+#include <stdlib.h>
+#undef atoi
+#undef abs
 
 extern unsigned long
 _stdlib_strto_l(register const char * __restrict str,
 				char ** __restrict endptr, int base, int sflag);
+
+#if defined(ULLONG_MAX)
 extern unsigned long long
 _stdlib_strto_ll(register const char * __restrict str,
 				 char ** __restrict endptr, int base, int sflag);
+#endif
 
-/* TODO: gcc reports an error due to prototype conflicts.  Don't include
- * the header for the problem cases? */
-#define HEADER_ALIAS_PROBLEM
+/**********************************************************************/
+#ifdef L_atof
 
+double atof(const char *nptr)
+{
+	return strtod(nptr, (char **) NULL);
+}
+
+#endif
 /**********************************************************************/
 #ifdef L_abs
 
-#ifdef HEADER_ALIAS_PROBLEM
-/*  #if UINT_MAX < ULONG_MAX */
+#if UINT_MAX < ULONG_MAX
 
 int abs(int j)
 {
@@ -63,8 +77,7 @@ int abs(int j)
 /**********************************************************************/
 #ifdef L_labs
 
-#ifndef HEADER_ALIAS_PROBLEM
-/*  #if UINT_MAX == ULONG_MAX */
+#if UINT_MAX == ULONG_MAX
 strong_alias(labs,abs)
 #endif
 
@@ -102,8 +115,7 @@ long long int llabs(long long int j)
 /**********************************************************************/
 #ifdef L_atoi
 
-#ifdef HEADER_ALIAS_PROBLEM
-/*  #if UINT_MAX < ULONG_MAX  */
+#if UINT_MAX < ULONG_MAX 
 
 int atoi(const char *nptr)
 {
@@ -116,8 +128,7 @@ int atoi(const char *nptr)
 /**********************************************************************/
 #ifdef L_atol
 
-#ifndef HEADER_ALIAS_PROBLEM
-/*  #if UINT_MAX == ULONG_MAX */
+#if UINT_MAX == ULONG_MAX
 strong_alias(atol,atoi)
 #endif
 
@@ -446,3 +457,149 @@ unsigned long long _stdlib_strto_ll(register const char * __restrict str,
 
 #endif
 /**********************************************************************/
+/* Made _Exit() an alias for _exit(), as per C99. */
+/*  #ifdef L__Exit */
+
+/*  void _Exit(int status) */
+/*  { */
+/*  	_exit(status); */
+/*  } */
+
+/*  #endif */
+/**********************************************************************/
+#ifdef L_bsearch
+
+void *bsearch(const void *key, const void *base, size_t /* nmemb */ high,
+			  size_t size, int (*compar)(const void *, const void *))
+{
+	register char *p;
+	size_t low;
+	size_t mid;
+	int r;
+
+	if (size > 0) {				/* TODO: change this to an assert?? */
+		low = 0;
+		while (low < high) {
+			mid = low + ((high - low) >> 1); /* Avoid possible overflow here. */
+			p = ((char *)base) + mid * size; /* Could overflow here... */
+			r = (*compar)(key, p); /* but that's an application problem! */
+			if (r > 0) {
+				low = mid + 1;
+			} else if (r < 0) {
+				high = mid;
+			} else {
+				return p;
+			}
+		}
+	}
+	return NULL;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_qsort
+
+/* This code is derived from a public domain shell sort routine by
+ * Ray Gardner and found in Bob Stout's snippets collection.  The
+ * original code is included below in an #if 0/#endif block.
+ *
+ * I modified it to avoid the possibility of overflow in the wgap
+ * calculation, as well as to reduce the generated code size with
+ * bcc and gcc. */
+
+void qsort (void  *base,
+            size_t nel,
+            size_t width,
+            int (*comp)(const void *, const void *))
+{
+	size_t wgap, i, j, k;
+	char tmp;
+
+	if ((nel > 1) && (width > 0)) {
+		assert( nel <= ((size_t)(-1)) / width ); /* check for overflow */
+		wgap = 0;
+		do {
+			wgap = 3 * wgap + 1;
+		} while (wgap < (nel-1)/3);
+		/* From the above, we know that either wgap == 1 < nel or */
+		/* ((wgap-1)/3 < (int) ((nel-1)/3) <= (nel-1)/3 ==> wgap <  nel. */
+		wgap *= width;			/* So this can not overflow if wnel doesn't. */
+		nel *= width;			/* Convert nel to 'wnel' */
+		do {
+			i = wgap;
+			do {
+				j = i;
+				do {
+					register char *a;
+					register char *b;
+
+					j -= wgap;
+					a = j + ((char *)base);
+					b = a + wgap;
+					if ( (*comp)(a, b) <= 0 ) {
+						break;
+					}
+					k = width;
+					do {
+						tmp = *a;
+						*a++ = *b;
+						*b++ = tmp;
+					} while ( --k );
+				} while (j >= wgap);
+				i += width;
+			} while (i < nel);
+			wgap = (wgap - width)/3;
+		} while (wgap);
+	}
+}
+
+/* ---------- original snippets version below ---------- */
+
+#if 0
+/*
+**  ssort()  --  Fast, small, qsort()-compatible Shell sort
+**
+**  by Ray Gardner,  public domain   5/90
+*/
+
+#include <stddef.h>
+
+void ssort (void  *base,
+            size_t nel,
+            size_t width,
+            int (*comp)(const void *, const void *))
+{
+      size_t wnel, gap, wgap, i, j, k;
+      char *a, *b, tmp;
+
+      wnel = width * nel;
+      for (gap = 0; ++gap < nel;)
+            gap *= 3;
+      while ( gap /= 3 )
+      {
+            wgap = width * gap;
+            for (i = wgap; i < wnel; i += width)
+            {
+                  for (j = i - wgap; ;j -= wgap)
+                  {
+                        a = j + (char *)base;
+                        b = a + wgap;
+                        if ( (*comp)(a, b) <= 0 )
+                              break;
+                        k = width;
+                        do
+                        {
+                              tmp = *a;
+                              *a++ = *b;
+                              *b++ = tmp;
+                        } while ( --k );
+                        if (j < wgap)
+                              break;
+                  }
+            }
+      }
+}
+#endif
+
+#endif
+/**********************************************************************/

+ 42 - 13
libc/string/Makefile

@@ -24,27 +24,48 @@
 TOPDIR=../../
 include $(TOPDIR)Rules.mak
 
+MSRCW= wstring.c
+MOBJW=  basename.o bcopy.o bzero.o dirname.o ffs.o memccpy.o memchr.o memcmp.o \
+	memcpy.o memmove.o mempcpy.o memrchr.o 	memset.o rawmemchr.o stpcpy.o \
+	stpncpy.o strcasecmp.o strcasestr.o strcat.o strchrnul.o strchr.o \
+	strcmp.o strcpy.o strcspn.o strdup.o strlen.o strncasecmp.o strncat.o \
+	strncmp.o strncpy.o strndup.o strnlen.o strpbrk.o strrchr.o strsep.o \
+	strspn.o strstr.o strtok.o strtok_r.o \
+	 __xpg_basename.o # strcoll.o strerror.o strxfrm.o 
+
+MOBJW2= wcscasecmp.o wcscat.o wcschrnul.o wcschr.o wcscmp.o wcscpy.o wcscspn.o \
+	wcsdup.o wcslen.o wcsncasecmp.o wcsncat.o wcsncmp.o wcsncpy.o \
+	wcsnlen.o wcspbrk.o wcsrchr.o wcsspn.o wcsstr.o wcstok.o wmemchr.o \
+	wmemcmp.o wmemcpy.o wmemmove.o wmempcpy.o wmemset.o
+
 MSRC=string.c
-MOBJ=strlen.o strcat.o strcpy.o strchr.o strcmp.o strncat.o strncpy.o \
-	strncmp.o strrchr.o strdup.o strndup.o memcpy.o memccpy.o memset.o \
-	memmove.o memcmp.o memchr.o ffs.o strnlen.o strxfrm.o stpcpy.o \
-	stpncpy.o memrchr.o mempcpy.o
+# MOBJ=strlen.o strcat.o strcpy.o strchr.o strcmp.o strncat.o strncpy.o \
+# 	strncmp.o strrchr.o strdup.o strndup.o memcpy.o memccpy.o memset.o \
+# 	memmove.o memcmp.o memchr.o ffs.o strnlen.o strxfrm.o stpcpy.o \
+# 	stpncpy.o memrchr.o mempcpy.o
+MOBJ=strxfrm.o
 
-ifeq ($(HAS_LOCALE),true)
-	MOBJ += strcoll.o
-endif
+# ifeq ($(HAS_LOCALE),true)
+# 	MOBJ += strcoll.o
+# endif
 
 MSRC1=strsignal.c
 MOBJ1=strsignal.o psignal.o
 
-MSRC2=strstr.c
-MOBJ2=strstr.o strcasestr.o
+MOBJ2=
+#MSRC2=strstr.c
+#MOBJ2=strstr.o strcasestr.o
 
-CSRC=strpbrk.c strsep.c strtok.c strtok_r.c strcspn.c \
-	strspn.c strcasecmp.c strncasecmp.c strerror.c bcopy.c bzero.c \
-	bcmp.c sys_errlist.c dirname.c basename.c
+# CSRC=strpbrk.c strsep.c strtok.c strtok_r.c strcspn.c \
+# 	strspn.c strcasecmp.c strncasecmp.c strerror.c bcopy.c bzero.c \
+# 	bcmp.c sys_errlist.c dirname.c basename.c
+CSRC=strerror.c sys_errlist.c
 COBJS=$(patsubst %.c,%.o, $(CSRC))
-OBJS=$(MOBJ) $(MOBJ1) $(MOBJ2) $(COBJS)
+OBJS=$(MOBJ) $(MOBJ1) $(MOBJ2) $(COBJS) $(MOBJW)
+
+ifeq ($(HAS_WCHAR),true)
+	OBJS += $(MOBJW2)
+endif
 
 all: $(OBJS) $(LIBC)
 
@@ -53,6 +74,14 @@ $(LIBC): ar-target
 ar-target: $(OBJS)
 	$(AR) $(ARFLAGS) $(LIBC) $(OBJS)
 
+$(MOBJW): $(MSRCW)
+	$(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+	$(STRIPTOOL) -x -R .note -R .comment $*.o
+
+$(MOBJW2): $(MSRCW)
+	$(CC) $(CFLAGS) -DWANT_WIDE -DL_$* $< -c -o $*.o
+	$(STRIPTOOL) -x -R .note -R .comment $*.o
+
 $(MOBJ): $(MSRC)
 	$(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
 	$(STRIPTOOL) -x -R .note -R .comment $*.o

+ 1273 - 0
libc/string/wstring.c

@@ -0,0 +1,1273 @@
+/*  Copyright (C) 2002     Manuel Novoa III
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!
+ *
+ *  Besides uClibc, I'm using this code in my libc for elks, which is
+ *  a 16-bit environment with a fairly limited compiler.  It would make
+ *  things much easier for me if this file isn't modified unnecessarily.
+ *  In particular, please put any new or replacement functions somewhere
+ *  else, and modify the makefile to use your version instead.
+ *  Thanks.  Manuel
+ *
+ *  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION! */
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <strings.h>
+#include <limits.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#ifdef WANT_WIDE
+#include <wchar.h>
+#include <wctype.h>
+#include <locale.h>
+
+#define Wvoid			wchar_t
+#define Wchar			wchar_t
+#define Wuchar			__uwchar_t
+#define Wint			wchar_t
+
+#else
+
+#define Wvoid			void
+#define Wchar			char
+typedef unsigned char	__string_uchar_t;
+#define Wuchar			__string_uchar_t
+#define Wint			int
+
+#endif
+
+/**********************************************************************/
+#ifdef L_wmemcpy
+#define L_memcpy
+#define Wmemcpy wmemcpy
+#else
+#define Wmemcpy memcpy
+#endif
+
+#ifdef L_memcpy
+
+Wvoid *Wmemcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n)
+{
+	register Wchar *r1 = s1;
+	register const Wchar *r2 = s2;
+
+#ifdef __BCC__
+	while (n--) {
+		*r1++ = *r2++;
+	}
+#else
+	while (n) {
+		*r1++ = *r2++;
+		--n;
+	}
+#endif
+
+	return s1;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wmemmove
+#define L_memmove
+#define Wmemmove wmemmove
+#else
+#define Wmemmove memmove
+#endif
+
+#ifdef L_memmove
+
+Wvoid *Wmemmove(Wvoid *s1, const Wvoid *s2, size_t n)
+{
+#ifdef __BCC__
+	register Wchar *s = (Wchar *) s1;
+	register const Wchar *p = (const Wchar *) s2;
+
+	if (p >= s) {
+		while (n--) {
+			*s++ = *p++;
+		}
+	} else {
+		s += n;
+		p += n;
+		while (n--) {
+			*--s = *--p;
+		}
+	}
+
+	return s1;
+#else
+	register Wchar *s = (Wchar *) s1;
+	register const Wchar *p = (const Wchar *) s2;
+
+	if (p >= s) {
+		while (n) {
+			*s++ = *p++;
+			--n;
+		}
+	} else {
+		while (n) {
+			--n;
+			s[n] = p[n];
+		}
+	}
+
+	return s1;
+#endif
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcscpy
+#define L_strcpy
+#define Wstrcpy wcscpy
+#else
+#define Wstrcpy strcpy
+#endif
+
+#ifdef L_strcpy
+
+Wchar *Wstrcpy(Wchar * __restrict s1, const Wchar * __restrict s2)
+{
+	register Wchar *s = s1;
+
+#ifdef __BCC__
+	do {
+		*s = *s2++;
+	} while (*s++ != 0);
+#else
+	while ( (*s++ = *s2++) != 0 );
+#endif
+
+	return s1;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcsncpy
+#define L_strncpy
+#define Wstrncpy wcsncpy
+#else
+#define Wstrncpy strncpy
+#endif
+
+#ifdef L_strncpy
+
+Wchar *Wstrncpy(Wchar * __restrict s1, register const Wchar * __restrict s2,
+				size_t n)
+{
+	register Wchar *s = s1;
+
+#ifdef __BCC__
+	while (n--) {
+		if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
+		++s;
+	}
+#else
+	while (n) {
+		if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
+		++s;
+		--n;
+	}
+#endif
+	
+	return s1;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcscat
+#define L_strcat
+#define Wstrcat wcscat
+#else
+#define Wstrcat strcat
+#endif
+
+#ifdef L_strcat
+
+Wchar *Wstrcat(Wchar * __restrict s1, register const Wchar * __restrict s2)
+{
+	register Wchar *s = s1;
+
+	while (*s++);
+	--s;
+	while ((*s++ = *s2++) != 0);
+
+	return s1;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcsncat
+#define L_strncat
+#define Wstrncat wcsncat
+#else
+#define Wstrncat strncat
+#endif
+
+#ifdef L_strncat
+
+Wchar *Wstrncat(Wchar * __restrict s1, register const Wchar * __restrict s2,
+				size_t n)
+{
+	register Wchar *s = s1;
+
+	while (*s++);
+	--s;
+#if __BCC__
+	while (n-- && ((*s = *s2++) != 0)) ++s;
+#else
+	while (n && ((*s = *s2++) != 0)) {
+		--n;
+		++s;
+	}
+#endif
+	*s = 0;
+
+	return s1;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wmemcmp
+#define L_memcmp
+#define Wmemcmp wmemcmp
+#else
+#define Wmemcmp memcmp
+#endif
+
+#ifdef L_memcmp
+
+#ifndef L_wmemcmp
+weak_alias(memcmp,bcmp)
+#endif
+
+int Wmemcmp(const Wvoid *s1, const Wvoid *s2, size_t n)
+{
+	register const Wuchar *r1 = (const Wuchar *) s1;
+	register const Wuchar *r2 = (const Wuchar *) s2;
+
+#ifdef WANT_WIDE
+	while (n && (*r1 == *r2)) {
+		++r1;
+		++r2;
+		--n;
+	}
+
+	return (n == 0) ? 0 : ((*r1 < *r2) ? -1 : 1);
+#else
+	int r = 0;
+
+	while (n-- && ((r = ((int)(*r1++)) - *r2++) == 0));
+
+	return r;
+#endif
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcscmp
+#define L_strcmp
+#define Wstrcmp wcscmp
+#else
+#define Wstrcmp strcmp
+#endif
+
+#ifdef L_strcmp
+
+#ifndef L_wcscmp
+#warning implement strcoll and remove weak alias (or enable for C locale only)
+weak_alias(strcmp, strcoll);
+#endif
+
+int Wstrcmp(register const Wchar *s1, register const Wchar *s2)
+{
+#ifdef WANT_WIDE
+	while (*((Wuchar *)s1) == *((Wuchar *)s2)) {
+		if (!*s1++) {
+			return 0;
+		}
+		++s2;
+	}
+
+	return (*((Wuchar *)s1) < *((Wuchar *)s2)) ? -1 : 1;
+#else
+	int r;
+
+	while (((r = ((int)(*((Wuchar *)s1))) - *((Wuchar *)s2++))
+			== 0) && *s1++);
+	
+	return r;
+#endif
+}
+#endif
+/**********************************************************************/
+#ifdef L_strcoll
+#error implement strcoll and remove weak_alias!!
+/*  extern unsigned char *_ctype_collate; */
+
+/*  int strcoll(register const char *s1, const char *s2) */
+/*  { */
+/*  	int r; */
+
+/*  	while (!(r = (_ctype_collate[(int)(*s1++)]-_ctype_collate[(int)(*s2++)]))); */
+	
+/*  	return r; */
+/*  } */
+#endif
+/**********************************************************************/
+#ifdef L_wcsncmp
+#define L_strncmp
+#define Wstrncmp wcsncmp
+#else
+#define Wstrncmp strncmp
+#endif
+
+#ifdef L_strncmp
+
+int Wstrncmp(register const Wchar *s1, register const Wchar *s2, size_t n)
+{
+#ifdef WANT_WIDE
+	while (n && (*((Wuchar *)s1) == *((Wuchar *)s2))) {
+		if (!*s1++) {
+			return 0;
+		}
+		++s2;
+		--n;
+	}
+
+	return (n == 0) ? 0 : ((*((Wuchar *)s1) < *((Wuchar *)s2)) ? -1 : 1);
+#else
+	int r = 0;
+
+	while (n--
+		   && ((r = ((int)(*((unsigned char *)s1))) - *((unsigned char *)s2++))
+			== 0)
+		   && *s1++);
+
+	return r;
+#endif
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_strxfrm
+#error implement strxfrm
+/*  size_t strxfrm(char * __restrict s1, const char * __restrict s2, size_t n) */
+#endif
+/**********************************************************************/
+#ifdef L_wmemchr
+#define L_memchr
+#define Wmemchr wmemchr
+#else
+#define Wmemchr memchr
+#endif
+
+#ifdef L_memchr
+
+Wvoid *Wmemchr(const Wvoid *s, Wint c, size_t n)
+{
+	register const Wuchar *r = (const Wuchar *) s;
+#ifdef __BCC__
+	/* bcc can optimize the counter if it thinks it is a pointer... */
+	register const char *np = (const char *) n;
+#else
+#define np n
+#endif
+
+	while (np) {
+		if (*r == ((Wuchar)c)) {
+			return (Wvoid *) r;	/* silence the warning */
+		}
+		++r;
+		--np;
+	}
+
+	return NULL;
+}
+#undef np
+
+#endif
+/**********************************************************************/
+#ifdef L_wcschr
+#define L_strchr
+#define Wstrchr wcschr
+#else
+#define Wstrchr strchr
+#endif
+
+#ifdef L_strchr
+
+#ifndef L_wcschr
+weak_alias(strchr,index)
+#endif
+
+Wchar *Wstrchr(register const Wchar *s, Wint c)
+{
+	do {
+		if (*s == ((Wchar)c)) {
+			return (Wchar *) s;	/* silence the warning */
+		}
+	} while (*s++);
+
+	return NULL;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcscspn
+#define L_strcspn
+#define Wstrcspn wcscspn
+#else
+#define Wstrcspn strcspn
+#endif
+
+#ifdef L_strcspn
+
+size_t Wstrcspn(const Wchar *s1, const Wchar *s2)
+{
+	register const Wchar *s;
+	register const Wchar *p;
+
+	for ( s=s1 ; *s ; s++ ) {
+		for ( p=s2 ; *p ; p++ ) {
+			if (*p == *s) goto done;
+		}
+	}
+ done:
+	return s - s1;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcspbrk
+#define L_strpbrk
+#define Wstrpbrk wcspbrk
+#else
+#define Wstrpbrk strpbrk
+#endif
+
+#ifdef L_strpbrk
+
+Wchar *Wstrpbrk(const Wchar *s1, const Wchar *s2)
+{
+	register const Wchar *s;
+	register const Wchar *p;
+
+	for ( s=s1 ; *s ; s++ ) {
+		for ( p=s2 ; *p ; p++ ) {
+			if (*p == *s) return (Wchar *) s; /* silence the warning */
+		}
+	}
+	return NULL;
+}
+#endif
+/**********************************************************************/
+#ifdef L_wcsrchr
+#define L_strrchr
+#define Wstrrchr wcsrchr
+#else
+#define Wstrrchr strrchr
+#endif
+
+#ifdef L_strrchr
+
+#ifndef L_wcsrchr
+weak_alias(strrchr,rindex)
+#endif
+
+Wchar *Wstrrchr(register const  Wchar *s, Wint c)
+{
+	register const Wchar *p;
+
+	p = NULL;
+	do {
+		if (*s == (Wchar) c) {
+			p = s;
+		}
+	} while (*s++);
+
+	return (Wchar *) p;			/* silence the warning */
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcsspn
+#define L_strspn
+#define Wstrspn wcsspn
+#else
+#define Wstrspn strspn
+#endif
+
+#ifdef L_strspn
+
+size_t Wstrspn(const Wchar *s1, const Wchar *s2)
+{
+	register const Wchar *s = s1;
+	register const Wchar *p = s2;
+
+	while (*p) {
+		if (*p++ == *s) {
+			++s;
+			p = s2;
+		}
+	}
+	return s - s1;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcsstr
+#define L_strstr
+#define Wstrstr wcsstr
+#else
+#define Wstrstr strstr
+#endif
+
+#ifdef L_strstr
+
+/* NOTE: This is the simple-minded O(len(s1) * len(s2)) worst-case approach. */
+
+#ifdef L_wcsstr
+weak_alias(wcsstr,wcswcs)
+#endif
+
+Wchar *Wstrstr(const Wchar *s1, const Wchar *s2)
+{
+	register const Wchar *s = s1;
+	register const Wchar *p = s2;
+
+	do {
+		if (!*p) {
+			return (Wchar *) s1;;
+		}
+		if (*p == *s) {
+			++p;
+			++s;
+		} else {
+			p = s2;
+			if (!*s) {
+				return NULL;
+			}
+			s = ++s1;
+		}
+	} while (1);
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcstok
+#define L_strtok_r
+#define Wstrtok_r wcstok
+#define Wstrspn wcsspn
+#define Wstrpbrk wcspbrk
+#else
+#define Wstrtok_r strtok_r
+#define Wstrspn strspn
+#define Wstrpbrk strpbrk
+#endif
+
+#ifdef L_strtok_r
+
+Wchar *Wstrtok_r(Wchar * __restrict s1, const Wchar * __restrict s2,
+				 Wchar ** __restrict next_start)
+{
+	register Wchar *s;
+	register Wchar *p;
+
+#if 1
+	if (((s = s1) != NULL) || ((s = *next_start) != NULL)) {
+		if (*(s += Wstrspn(s, s2))) {
+			if ((p = Wstrpbrk(s, s2)) != NULL) {
+				*p++ = 0;
+			}
+		} else {
+			p = s = NULL;
+		}
+		*next_start = p;
+	}
+	return s;
+#else
+	if (!(s = s1)) {
+		s = *next_start;
+	}
+	if (s && *(s += Wstrspn(s, s2))) {
+		if (*(p = s + Wstrcspn(s, s2))) {
+			*p++ = 0;
+		}
+		*next_start = p;
+		return s;
+	}
+	return NULL;				/* TODO: set *next_start = NULL for safety? */
+#endif
+}
+
+#endif
+/**********************************************************************/
+/*  #ifdef L_wcstok */
+/*  #define L_strtok */
+/*  #define Wstrtok wcstok */
+/*  #define Wstrtok_r wcstok_r */
+/*  #else */
+/*  #define Wstrtok strtok */
+/*  #define Wstrtok_r strtok_r */
+/*  #endif */
+
+#ifdef L_strtok
+#define Wstrtok strtok
+#define Wstrtok_r strtok_r
+
+Wchar *Wstrtok(Wchar * __restrict s1, const Wchar * __restrict s2)
+{
+	static Wchar *next_start;	/* Initialized to 0 since in bss. */
+	return Wstrtok_r(s1, s2, &next_start);
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wmemset
+#define L_memset
+#define Wmemset wmemset
+#else
+#define Wmemset memset
+#endif
+
+#ifdef L_memset
+
+Wvoid *Wmemset(Wvoid *s, Wint c, size_t n)
+{
+	register Wuchar *p = (Wuchar *) s;
+#ifdef __BCC__
+	/* bcc can optimize the counter if it thinks it is a pointer... */
+	register const char *np = (const char *) n;
+#else
+#define np n
+#endif
+
+	while (np) {
+		*p++ = (Wuchar) c;
+		--np;
+	}
+
+	return s;
+}
+#undef np
+
+#endif
+/**********************************************************************/
+#ifdef L_strerror
+#error implement strerror
+/*  char *strerror(int errnum); */
+#endif
+/**********************************************************************/
+#ifdef L_wcslen
+#define L_strlen
+#define Wstrlen wcslen
+#else
+#define Wstrlen strlen
+#endif
+
+#ifdef L_strlen
+
+size_t Wstrlen(const Wchar *s)
+{
+	register const Wchar *p;
+
+	for (p=s ; *p ; p++);
+
+	return p - s;
+}
+
+#endif
+/**********************************************************************/
+/* ANSI/ISO end here */
+/**********************************************************************/
+#ifdef L_ffs
+
+int ffs(int i)
+{
+#if 1
+	/* inlined binary search method */
+	char n = 1;
+#if UINT_MAX == 0xffffU
+	/* nothing to do here -- just trying to avoiding possible problems */
+#elif UINT_MAX == 0xffffffffU
+	if (!(i & 0xffff)) {
+		n += 16;
+		i >>= 16;
+	}
+#else
+#error ffs needs rewriting!
+#endif
+
+	if (!(i & 0xff)) {
+		n += 8;
+		i >>= 8;
+	}
+	if (!(i & 0x0f)) {
+		n += 4;
+		i >>= 4;
+	}
+	if (!(i & 0x03)) {
+		n += 2;
+		i >>= 2;
+	}
+	return (i) ? (n + ((i+1) & 0x01)) : 0;
+
+#else
+	/* linear search -- slow, but small */
+	int n;
+
+	for (n = 0 ; i ; ++n) {
+		i >>= 1;
+	}
+	
+	return n;
+#endif
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcscasecmp
+#define L_strcasecmp
+#define Wstrcasecmp wcscasecmp
+#else
+#define Wstrcasecmp strcasecmp
+#endif
+
+#ifdef L_strcasecmp
+
+int Wstrcasecmp(register const Wchar *s1, register const Wchar *s2)
+{
+#ifdef WANT_WIDE
+	while ((*s1 == *s2) || (towlower(*s1) == towlower(*s2))) {
+		if (!*s1++) {
+			return 0;
+		}
+		++s2;
+	}
+
+	return (((Wuchar)towlower(*s1)) < ((Wuchar)towlower(*s2))) ? -1 : 1;
+	/* TODO -- should wide cmp funcs do wchar or Wuchar compares? */
+#else
+	int r = 0;
+
+	while ( ((s1 == s2) ||
+			 !(r = ((int)( tolower(*((Wuchar *)s1))))
+			   - tolower(*((Wuchar *)s2))))
+			&& (++s2, *s1++));
+
+	return r;
+#endif
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcsncasecmp
+#define L_strncasecmp
+#define Wstrncasecmp wcsncasecmp
+#else
+#define Wstrncasecmp strncasecmp
+#endif
+
+#ifdef L_strncasecmp
+
+int Wstrncasecmp(register const Wchar *s1, register const Wchar *s2, size_t n)
+{
+#ifdef WANT_WIDE
+	while (n && ((*s1 == *s2) || (towlower(*s1) == towlower(*s2)))) {
+		if (!*s1++) {
+			return 0;
+		}
+		++s2;
+		--n;
+	}
+
+	return (n == 0)
+		? 0
+		: ((((Wuchar)towlower(*s1)) < ((Wuchar)towlower(*s2))) ? -1 : 1);
+	/* TODO -- should wide cmp funcs do wchar or Wuchar compares? */
+#else
+	int r = 0;
+
+	while ( n
+			&& ((s1 == s2) ||
+				!(r = ((int)( tolower(*((unsigned char *)s1))))
+				  - tolower(*((unsigned char *)s2))))
+			&& (--n, ++s2, *s1++));
+	return r;
+#endif
+}
+#endif
+/**********************************************************************/
+#ifdef L_wcsnlen
+#define L_strnlen
+#define Wstrnlen wcsnlen
+#else
+#define Wstrnlen strnlen
+#endif
+
+#ifdef L_strnlen
+
+size_t Wstrnlen(const Wchar *s, size_t max)
+{
+	register const Wchar *p = s;
+#ifdef __BCC__
+	/* bcc can optimize the counter if it thinks it is a pointer... */
+	register const char *maxp = (const char *) max;
+#else
+#define maxp max
+#endif
+
+	while (maxp && *p) {
+		++p;
+		--maxp;
+	}
+
+	return p - s;
+}
+#undef maxp
+#endif
+/**********************************************************************/
+/* No wide analog. */
+
+#ifdef L_memccpy
+
+void *memccpy(void * __restrict s1, const void * __restrict s2, int c, size_t n)
+{
+	register char *r1 = s1;
+	register const char *r2 = s2;
+
+	while (n-- && (((unsigned char)(*r1++ = *r2++)) != ((unsigned char) c)));
+
+	return (n == (size_t) -1) ? NULL : r1;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcsdup
+#define L_strdup
+#define Wstrdup wcsdup
+#define Wstrlen wcslen
+#define Wstrcpy wcscpy
+#else
+#define Wstrdup strdup
+#define Wstrlen strlen
+#define Wstrcpy strcpy
+#endif
+
+#ifdef L_strdup
+
+Wchar *Wstrdup(register const Wchar *s1)
+{
+	register Wchar *s;
+
+    if ((s = malloc((Wstrlen(s1) + 1) * sizeof(Wchar))) != NULL) {
+		Wstrcpy(s, s1);
+	}
+
+	return s;
+}
+
+#endif
+/**********************************************************************/
+/* GNU extension functions. */
+/**********************************************************************/
+#ifdef L_wmempcpy
+#define L_mempcpy
+#define Wmempcpy wmempcpy
+#else
+#define Wmempcpy mempcpy
+#endif
+
+#ifdef L_mempcpy
+
+#ifndef L_wmempcpy
+/* uClibc's old string implementation did this to cater to some app. */
+weak_alias(mempcpy,__mempcpy)
+#endif
+
+Wvoid *Wmempcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n)
+{
+	register Wchar *r1 = s1;
+	register const Wchar *r2 = s2;
+
+#ifdef __BCC__
+	while (n--) {
+		*r1++ = *r2++;
+	}
+#else
+	while (n) {
+		*r1++ = *r2++;
+		--n;
+	}
+#endif
+
+	return r1;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_memrchr
+
+void *memrchr(const void *s, int c, size_t n)
+{
+	register const unsigned char *r;
+#ifdef __BCC__
+	/* bcc can optimize the counter if it thinks it is a pointer... */
+	register const char *np = (const char *) n;
+#else
+#define np n
+#endif
+	
+	r = ((unsigned char *)s) + ((size_t) np);
+
+	while (np) {
+		if (*--r == ((unsigned char)c)) {
+			return (void *) r;	/* silence the warning */
+		}
+		--np;
+	}
+
+	return NULL;
+}
+#undef np
+
+#endif
+/**********************************************************************/
+#ifdef L_stpcpy
+
+char *stpcpy(register char * __restrict s1, const char * __restrict s2)
+{
+#ifdef __BCC__
+	do {
+		*s1 = *s2++;
+	} while (*s1++ != 0);
+#else
+	while ( (*s1++ = *s2++) != 0 );
+#endif
+
+	return s1 - 1;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_stpncpy
+
+char *stpncpy(register char * __restrict s1,
+			  register const char * __restrict s2,
+			  size_t n)
+{
+	char *s = s1;
+	const char *p = s2;
+
+#ifdef __BCC__
+	while (n--) {
+		if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
+		++s;
+	}
+	return s1 + (s2 - p);
+#else
+	while (n) {
+		if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
+		++s;
+		--n;
+	}
+	return s1 + (s2 - p);
+#endif
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_bzero
+
+void bzero(void *s, size_t n)
+{
+	register unsigned char *p = s;
+#ifdef __BCC__
+	/* bcc can optimize the counter if it thinks it is a pointer... */
+	register const char *np = (const char *) n;
+#else
+#define np n
+#endif
+
+	while (np) {
+		*p++ = 0;
+		--np;
+	}
+}
+#undef np
+
+#endif
+/**********************************************************************/
+#ifdef L_bcopy
+
+void bcopy(const void *s2, void *s1, size_t n)
+{
+#if 1
+	memmove(s1, s2, n);
+#else
+#ifdef __BCC__
+	register char *s;
+	register const char *p;
+
+	s = s1;
+	p = s2;
+	if (p >= s) {
+		while (n--) {
+			*s++ = *p++;
+		}
+	} else {
+		s += n;
+		p += n;
+		while (n--) {
+			*--s = *--p;
+		}
+	}
+#else
+	register char *s;
+	register const char *p;
+
+	s = s1;
+	p = s2;
+	if (p >= s) {
+		while (n) {
+			*s++ = *p++;
+			--n;
+		}
+	} else {
+		while (n) {
+			--n;
+			s[n] = p[n];
+		}
+	}
+#endif
+#endif
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_strcasestr
+
+char *strcasestr(const char *s1, const char *s2)
+{
+	register const char *s = s1;
+	register const char *p = s2;
+
+#if 1
+	do {
+		if (!*p) {
+			return (char *) s1;;
+		}
+		if ((*p == *s)
+			|| (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s)))
+			) {
+			++p;
+			++s;
+		} else {
+			p = s2;
+			if (!*s) {
+				return NULL;
+			}
+			s = ++s1;
+		}
+	} while (1);
+#else
+	while (*p && *s) {
+		if ((*p == *s)
+			|| (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s)))
+			) {
+			++p;
+			++s;
+		} else {
+			p = s2;
+			s = ++s1;
+		}
+	}
+
+	return (*p) ? NULL : (char *) s1;
+#endif
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_strndup
+
+char *strndup(register const char *s1, size_t n)
+{
+	register char *s;
+
+	n = strnlen(s1,n);			/* Avoid problems if s1 not nul-terminated. */
+
+    if ((s = malloc(n + 1)) != NULL) {
+		memcpy(s, s1, n);
+		s[n] = 0;
+	}
+
+	return s;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_strsep
+
+char *strsep(char ** __restrict s1, const char * __restrict s2)
+{
+	register char *s = *s1;
+	register char *p;
+
+#if 1
+	p = NULL;
+	if (s && *s && (p = strpbrk(s, s2))) {
+		*p++ = 0;
+	}
+#else
+	if (s && *s && *(p = s + strcspn(s, s2))) {
+		*p++ = 0;
+	} else {
+		p = NULL;
+	}
+#endif
+	*s1 = p;
+	return s;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcschrnul
+#define L_strchrnul
+#define Wstrchrnul wcschrnul
+#else
+#define Wstrchrnul strchrnul
+#endif
+
+#ifdef L_strchrnul
+
+Wchar *Wstrchrnul(register const Wchar *s, Wint c)
+{
+	--s;
+	while (*++s && (*s != ((Wchar)c)));
+	return (Wchar *) s;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_rawmemchr
+
+void *rawmemchr(const void *s, int c)
+{
+	register const unsigned char *r = s;
+
+	while (*r != ((unsigned char)c)) ++r;
+
+	return (void *) r;	/* silence the warning */
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_basename
+
+char *basename(const char *path)
+{
+	register const char *s;
+	register const char *p;
+
+	p = s = path;
+
+	while (*s) {
+		if (*s++ == '/') {
+			p = s;
+		}
+	}
+
+	return (char *) p;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L___xpg_basename
+
+char *__xpg_basename(register char *path)
+{
+	static const char null_or_empty[] = ".";
+	char *first;
+	register char *last;
+
+	first = (char *) null_or_empty;
+
+	if (path && *path) {
+		first = path;
+		last = path - 1;
+
+		do {
+			if ((*path != '/') && (path > ++last)) {
+				last = first = path;
+			}
+		} while (*++path);
+
+		if (*first == '/') {
+			last = first;
+		}
+		last[1] = 0;
+	}
+
+	return first;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_dirname
+
+char *dirname(char *path)
+{
+	static const char null_or_empty_or_noslash[] = ".";
+	register char *s;
+	register char *last;
+	char *first;
+
+	last = s = path;
+
+	if (s != NULL) {
+
+	LOOP:
+		while (*s && (*s != '/')) ++s;
+		first = s;
+		while (*s == '/') ++s;
+		if (*s) {
+			last = first;
+			goto LOOP;
+		}
+
+		if (last == path) {
+			if (*last != '/') {
+				goto DOT;
+			}
+			if ((*++last == '/') && (last[1] == 0)) {
+				++last;
+			}
+		}
+		*last = 0;
+		return path;
+	}
+ DOT:
+	return (char *) null_or_empty_or_noslash;
+}
+
+#endif
+/**********************************************************************/

+ 1 - 0
libc/sysdeps/linux/common/bits/.cvsignore

@@ -0,0 +1 @@
+uClibc_locale_data.h

+ 250 - 0
libc/sysdeps/linux/common/bits/uClibc_ctype.h

@@ -0,0 +1,250 @@
+/*  Copyright (C) 2002     Manuel Novoa III
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!
+ *
+ *  Besides uClibc, I'm using this code in my libc for elks, which is
+ *  a 16-bit environment with a fairly limited compiler.  It would make
+ *  things much easier for me if this file isn't modified unnecessarily.
+ *  In particular, please put any new or replacement functions somewhere
+ *  else, and modify the makefile to use your version instead.
+ *  Thanks.  Manuel
+ *
+ *  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION! */
+
+#if !defined(_CTYPE_H) && !defined(_WCTYPE_H)
+#error Always include <{w}ctype.h> rather than <bits/uClibc_ctype.h>
+#endif
+
+#ifndef _BITS_CTYPE_H
+#define _BITS_CTYPE_H
+
+/* Taking advantage of the C99 mutual-exclusion guarantees for the various
+ * (w)ctype classes, including the descriptions of printing and control
+ * (w)chars, we can place each in one of the following mutually-exlusive
+ * subsets.  Since there are less than 16, we can store the data for
+ * each (w)chars in a nibble. In contrast, glibc uses an unsigned int
+ * per (w)char, with one bit flag for each is* type.  While this allows
+ * a simple '&' operation to determine the type vs. a range test and a
+ * little special handling for the "blank" and "xdigit" types in my
+ * approach, it also uses 8 times the space for the tables on the typical
+ * 32-bit archs we supported.*/
+enum {
+	__CTYPE_unclassified = 0,
+	__CTYPE_alpha_nonupper_nonlower,
+	__CTYPE_alpha_lower,
+	__CTYPE_alpha_upper_lower,
+	__CTYPE_alpha_upper,
+	__CTYPE_digit,
+	__CTYPE_punct,
+	__CTYPE_graph,
+	__CTYPE_print_space_nonblank,
+	__CTYPE_print_space_blank,
+	__CTYPE_space_nonblank_noncntrl,
+	__CTYPE_space_blank_noncntrl,
+	__CTYPE_cntrl_space_nonblank,
+	__CTYPE_cntrl_space_blank,
+	__CTYPE_cntrl_nonspace,
+};
+
+/* Some macros that test for various (w)ctype classes when passed one of the
+ * designator values enumerated above. */
+#define __CTYPE_isalnum(D)		((unsigned int)(D-1) <= (__CTYPE_digit-1))
+#define __CTYPE_isalpha(D)		((unsigned int)(D-1) <= (__CTYPE_alpha_upper-1))
+#define __CTYPE_isblank(D) \
+	((((unsigned int)(D - __CTYPE_print_space_nonblank)) <= 5) && (D & 1))
+#define __CTYPE_iscntrl(D)		(((unsigned int)(D - __CTYPE_cntrl_space_nonblank)) <= 2)
+#define __CTYPE_isdigit(D)		(D == __CTYPE_digit)
+#define __CTYPE_isgraph(D)		((unsigned int)(D-1) <= (__CTYPE_graph-1))
+#define __CTYPE_islower(D)		(((unsigned int)(D - __CTYPE_alpha_lower)) <= 1)
+#define __CTYPE_isprint(D)		((unsigned int)(D-1) <= (__CTYPE_print_space_blank-1))
+#define __CTYPE_ispunct(D)		(D == __CTYPE_punct)
+#define __CTYPE_isspace(D)		(((unsigned int)(D - __CTYPE_print_space_nonblank)) <= 5)
+#define __CTYPE_isupper(D)		(((unsigned int)(D - __CTYPE_alpha_upper_lower)) <= 1)
+/*  #define __CTYPE_isxdigit(D) -- isxdigit is untestable this way. 
+ *  But that's ok as isxdigit() (and isdigit() too) are locale-invariant. */
+
+/* The values for wctype_t. */
+enum {
+	_CTYPE_unclassified = 0,
+	_CTYPE_isalnum,
+	_CTYPE_isalpha,
+	_CTYPE_isblank,
+	_CTYPE_iscntrl,
+	_CTYPE_isdigit,
+	_CTYPE_isgraph,
+	_CTYPE_islower,
+	_CTYPE_isprint,
+	_CTYPE_ispunct,
+	_CTYPE_isspace,
+	_CTYPE_isupper,
+	_CTYPE_isxdigit				/* _MUST_ be last of the standard classes! */
+};
+
+
+/* The following is used to implement wctype(), but it is defined
+ * here because the ordering must agree with that of the enumeration
+ * above (ignoring unclassified). */
+#define __CTYPE_TYPESTRING \
+	"\6alnum\0\6alpha\0\6blank\0\6cntrl\0\6digit\0\6graph\0\6lower\0" \
+	"\6print\0\6punct\0\6space\0\6upper\0\7xdigit\0\0"
+
+/* Used in implementing iswctype(), but defined here as it must agree
+ * in ordering with the string above. */
+#define __CTYPE_RANGES \
+	0, -1,								/* unclassified */ \
+	1, __CTYPE_digit - 1,				/* alnum */ \
+	1, __CTYPE_alpha_upper - 1,			/* alpha */ \
+	__CTYPE_print_space_blank, 5,		/* blank -- also must be odd! */ \
+	__CTYPE_cntrl_space_nonblank, 2,	/* cntrl */ \
+	__CTYPE_digit, 0,					/* digit */ \
+	1, __CTYPE_graph - 1,				/* graph */ \
+	__CTYPE_alpha_lower, 1,				/* lower */ \
+	1, __CTYPE_print_space_blank - 1,	/* print */ \
+	__CTYPE_punct, 0,					/* punct */ \
+	__CTYPE_print_space_nonblank, 5, 	/* space */ \
+	__CTYPE_alpha_upper_lower, 1,		/* upper */ \
+	/* No entry for xdigit as it is handled specially. */
+
+#define _CTYPE_iswalnum		_CTYPE_isalnum
+#define _CTYPE_iswalpha		_CTYPE_isalpha
+#define _CTYPE_iswblank		_CTYPE_isblank
+#define _CTYPE_iswcntrl		_CTYPE_iscntrl
+#define _CTYPE_iswdigit		_CTYPE_isdigit
+#define _CTYPE_iswgraph		_CTYPE_isgraph
+#define _CTYPE_iswlower		_CTYPE_islower
+#define _CTYPE_iswprint		_CTYPE_isprint
+#define _CTYPE_iswpunct		_CTYPE_ispunct
+#define _CTYPE_iswspace		_CTYPE_isspace
+#define _CTYPE_iswupper		_CTYPE_isupper
+#define _CTYPE_iswxdigit	_CTYPE_isxdigit
+
+/* The following is used to implement wctrans(). */
+
+enum {
+	_CTYPE_tolower = 1,
+	_CTYPE_toupper,
+	_CTYPE_totitle
+};
+
+#define __CTYPE_TRANSTRING	"\10tolower\0\10toupper\0\10totitle\0\0"
+
+/* Now define some ctype macros valid for the C/POSIX locale. */
+
+/* ASCII ords of \t, \f, \n, \r, and \v are 9, 12, 10, 13, 11 respectively. */
+#define __C_isspace(c) \
+	((sizeof(c) == sizeof(char)) \
+	 ? ((((c) == ' ') || (((unsigned char)((c) - 9)) <= (13 - 9)))) \
+	 : ((((c) == ' ') || (((unsigned int)((c) - 9)) <= (13 - 9)))))
+#define __C_isblank(c) (((c) == ' ') || ((c) == '\t'))
+#define __C_isdigit(c) \
+	((sizeof(c) == sizeof(char)) \
+	 ? (((unsigned char)((c) - '0')) < 10) \
+	 : (((unsigned int)((c) - '0')) < 10))
+#define __C_isxdigit(c) \
+	(__C_isdigit(c) \
+	 || ((sizeof(c) == sizeof(char)) \
+		 ? (((unsigned char)((((c)) | 0x20) - 'a')) < 6) \
+		 : (((unsigned int)((((c)) | 0x20) - 'a')) < 6)))
+#define __C_iscntrl(c) \
+	((sizeof(c) == sizeof(char)) \
+	 ? ((((unsigned char)(c)) < 0x20) || ((c) == 0x7f)) \
+	 : ((((unsigned int)(c)) < 0x20) || ((c) == 0x7f)))
+#define __C_isalpha(c) \
+	((sizeof(c) == sizeof(char)) \
+	 ? (((unsigned char)(((c) | 0x20) - 'a')) < 26) \
+	 : (((unsigned int)(((c) | 0x20) - 'a')) < 26))
+#define __C_isalnum(c) (__C_isalpha(c) || __C_isdigit(c))
+#define __C_isprint(c) \
+	((sizeof(c) == sizeof(char)) \
+	 ? (((unsigned char)((c) - 0x20)) <= (0x7e - 0x20)) \
+	 : (((unsigned int)((c) - 0x20)) <= (0x7e - 0x20)))
+#define __C_islower(c) \
+	((sizeof(c) == sizeof(char)) \
+	 ? (((unsigned char)((c) - 'a')) < 26) \
+	 : (((unsigned int)((c) - 'a')) < 26))
+#define __C_isupper(c) \
+	((sizeof(c) == sizeof(char)) \
+	 ? (((unsigned char)((c) - 'A')) < 26) \
+	 : (((unsigned int)((c) - 'A')) < 26))
+#define __C_ispunct(c) \
+	((!__C_isalnum(c)) \
+	 && ((sizeof(c) == sizeof(char)) \
+		 ? (((unsigned char)((c) - 0x21)) <= (0x7e - 0x21)) \
+		 : (((unsigned int)((c) - 0x21)) <= (0x7e - 0x21))))
+#define __C_isgraph(c) \
+	((sizeof(c) == sizeof(char)) \
+	 ? (((unsigned int)((c) - 0x21)) <= (0x7e - 0x21)) \
+	 : (((unsigned int)((c) - 0x21)) <= (0x7e - 0x21)))
+
+#define __C_tolower(c) (__C_isupper(c) ? ((c) | 0x20) : (c))
+#define __C_toupper(c) (__C_islower(c) ? ((c) ^ 0x20) : (c))
+
+#define __C_isxlower(c) \
+	(__C_isdigit(c) \
+	 || ((sizeof(c) == sizeof(char)) \
+		 ? (((unsigned char)(((c)) - 'a')) < 6) \
+		 : (((unsigned int)(((c)) - 'a')) < 6)))
+#define __C_isxupper(c) \
+	(__C_isdigit(c) \
+	 || ((sizeof(c) == sizeof(char)) \
+		 ? (((unsigned char)(((c)) - 'A')) < 6) \
+		 : (((unsigned int)(((c)) - 'A')) < 6)))
+
+/* TODO: Replace the above with expressions like the following? */
+/*  #define __C_isdigit(c) ((sizeof(c) == sizeof(char)) \ */
+/*  						? (((unsigned char)((c) - '0')) < 10) \ */
+/*  						: (((unsigned int)((c) - '0')) < 10)) */
+
+/* Similarly, define some wctype macros valid for the C/POSIX locale. */
+
+/* First, we need some way to make sure the arg is in range. */
+#define __C_classed(c) \
+	((sizeof(c) <= sizeof(int)) || (c == ((unsigned char)c)))
+
+#define __C_iswspace(c)		(__C_classed(c) && __C_isspace(c))
+#define __C_iswblank(c)		(__C_classed(c) && __C_isblank(c))
+#define __C_iswdigit(c)		(__C_classed(c) && __C_isdigit(c))
+#define __C_iswxdigit(c)	(__C_classed(c) && __C_isxdigit(c))
+#define __C_iswcntrl(c)		(__C_classed(c) && __C_iscntrl(c))
+#define __C_iswalpha(c)		(__C_classed(c) && __C_isalpha(c))
+#define __C_iswalnum(c)		(__C_classed(c) && __C_isalnum(c))
+#define __C_iswprint(c)		(__C_classed(c) && __C_isprint(c))
+#define __C_iswlower(c)		(__C_classed(c) && __C_islower(c))
+#define __C_iswupper(c)		(__C_classed(c) && __C_isupper(c))
+#define __C_iswpunct(c)		(__C_classed(c) && __C_ispunct(c))
+#define __C_iswgraph(c)		(__C_classed(c) && __C_isgraph(c))
+#define __C_towlower(c) \
+	((__C_classed(c) && __C_isupper(c)) ? ((c) | 0x20) : (c))
+#define __C_towupper(c) \
+	((__C_classed(c) && __C_islower(c)) ? ((c) ^ 0x20) : (c))
+
+/* Now define some macros to aviod the extra wrapper-function call. */
+#define __iswalnum(c)		iswctype(c, _CTYPE_iswalnum)
+#define __iswalpha(c)		iswctype(c, _CTYPE_iswalpha)
+#define __iswblank(c)		iswctype(c, _CTYPE_iswblank)
+#define __iswcntrl(c)		iswctype(c, _CTYPE_iswcntrl)
+#define __iswgraph(c)		iswctype(c, _CTYPE_iswgraph)
+#define __iswlower(c)		iswctype(c, _CTYPE_iswlower)
+#define __iswprint(c)		iswctype(c, _CTYPE_iswprint)
+#define __iswpunct(c)		iswctype(c, _CTYPE_iswpunct)
+#define __iswspace(c)		iswctype(c, _CTYPE_iswspace)
+#define __iswupper(c)		iswctype(c, _CTYPE_iswupper)
+#define __iswdigit(c)		__C_iswdigit(c)
+#define __iswxdigit(c)		__C_iswxdigit(c)
+
+#endif /* _BITS_CTYPE_H */

+ 261 - 0
libc/sysdeps/linux/common/bits/uClibc_locale.h

@@ -0,0 +1,261 @@
+/*  Copyright (C) 2002     Manuel Novoa III
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This 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 this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!
+ *
+ *  Besides uClibc, I'm using this code in my libc for elks, which is
+ *  a 16-bit environment with a fairly limited compiler.  It would make
+ *  things much easier for me if this file isn't modified unnecessarily.
+ *  In particular, please put any new or replacement functions somewhere
+ *  else, and modify the makefile to use your version instead.
+ *  Thanks.  Manuel
+ *
+ *  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION! */
+
+#ifndef _UCLIBC_LOCALE_H
+#define _UCLIBC_LOCALE_H
+
+/**********************************************************************/
+/* uClibc compatibilty stuff */
+
+#ifdef __UCLIBC_HAS_WCHAR__
+#define __WCHAR_ENABLED
+#endif
+
+
+#ifdef __UCLIBC_HAS_LOCALE__
+
+#undef __LOCALE_C_ONLY
+
+#else  /* __UCLIBC_HAS_LOCALE__ */
+
+#define __LOCALE_C_ONLY
+
+#endif /* __UCLIBC_HAS_LOCALE__ */
+
+/**********************************************************************/
+
+#define __NL_ITEM_CATEGORY_SHIFT		(8)
+#define __NL_ITEM_INDEX_MASK			(0xff)
+
+/* TODO: Make sure these agree with the locale mmap file gererator! */
+
+#define __LC_CTYPE			0
+#define __LC_NUMERIC		1
+#define __LC_MONETARY		2
+#define __LC_TIME			3
+#define __LC_COLLATE		4
+#define __LC_MESSAGES		5
+#define __LC_ALL			6
+
+/**********************************************************************/
+#if defined(_LIBC) && !defined(__LOCALE_C_ONLY)
+
+#include <stddef.h>
+#include <stdint.h>
+#include <bits/uClibc_locale_data.h>
+
+/* TODO: This really needs to be somewhere else... */
+#include <limits.h>
+#include <stdint.h>
+
+#if WCHAR_MIN == 0
+typedef wchar_t				__uwchar_t;
+#elif WCHAR_MAX <= USHRT_MAX
+typedef unsigned short		__uwchar_t;
+#elif WCHAR_MAX <= UINT_MAX
+typedef unsigned int		__uwchar_t;
+#elif WCHAR_MAX <= ULONG_MAX
+typedef unsigned long		__uwchar_t;
+#elif defined(ULLONG_MAX) && (WCHAR_MAX <= ULLONG_MAX)
+typedef unsigned long long	__uwchar_t;
+#elif WCHAR_MAX <= UINT_MAX
+typedef uintmax_t			__uwchar_t;
+#else
+#error Can not determine an appropriate type for __uwchar_t!
+#endif
+
+
+
+extern void _locale_set(const unsigned char *p);
+extern void _locale_init(void);
+
+/* TODO: assumes 8-bit chars!!! */
+
+enum {
+	__ctype_encoding_7_bit,		/* C/POSIX */
+	__ctype_encoding_utf8,		/* UTF-8 */
+	__ctype_encoding_8_bit		/* for 8-bit codeset locales */
+};
+
+#define LOCALE_STRING_SIZE (2 * __LC_ALL + 2)
+
+ /*
+  * '#' + 2_per_category + '\0'
+  *       {locale row # : 0 = C|POSIX} + 0x8001
+  *       encoded in two chars as (((N+1) >> 8) | 0x80) and ((N+1) & 0xff)
+  *       so decode is  ((((uint16_t)(*s & 0x7f)) << 8) + s[1]) - 1
+  *
+  *       Note: 0s are not used as they are nul-terminators for strings.
+  *       Note: 0xff, 0xff is the encoding for a non-selected locale.
+  *             (see setlocale() below).
+  * In particular, C/POSIX locale is '#' + "\x80\x01"}*LC_ALL + nul.
+  */
+
+
+/*  static unsigned char cur_locale[LOCALE_STRING_SIZE]; */
+
+typedef struct {
+/*  	int tables_loaded; */
+/*  	unsigned char lctypes[LOCALE_STRING_SIZE]; */
+	unsigned char cur_locale[LOCALE_STRING_SIZE];
+
+	/* NL_LANGINFO stuff. BEWARE ORDERING!!! must agree with NL_* constants! */
+	/* Also, numeric must be followed by monetary and the items must be in
+	 * the "struct lconv" order. */
+
+	uint16_t category_offsets[__LC_ALL]; /* TODO -- fix? */
+	unsigned char category_item_count[__LC_ALL]; /* TODO - fix */
+
+	/* ctype */
+	unsigned char encoding;		/* C/POSIX, 8-bit, UTF-8 */
+	unsigned char mb_cur_max;	/* determined by encoding _AND_ translit!!! */
+
+	const char *codeset;
+
+#ifdef __CTYPE_HAS_8_BIT_LOCALES
+	const unsigned char *idx8ctype;
+	const unsigned char *tbl8ctype;
+	const unsigned char *idx8uplow;
+    const unsigned char *tbl8uplow;
+#ifdef __WCHAR_ENABLED
+	const unsigned char *idx8c2wc;
+	const uint16_t *tbl8c2wc;	/* char > 0x7f to wide char */
+	const unsigned char *idx8wc2c;
+	const unsigned char *tbl8wc2c;
+	/* translit  */
+#endif /* __WCHAR_ENABLED */
+#endif /* __CTYPE_HAS_8_BIT_LOCALES */
+#ifdef __WCHAR_ENABLED
+	const unsigned char *tblwctype;
+	const unsigned char *tblwuplow;
+	const unsigned char *tblwcomb;
+	const int16_t *tblwuplow_diff; /* yes... signed */
+	/* width?? */
+#endif /* __WCHAR_ENABLED */
+
+	/* numeric */
+	const char *decimal_point;
+	const char *thousands_sep;
+	const char *grouping;
+
+	/* monetary */
+	const char *int_curr_symbol;
+	const char *currency_symbol;
+	const char *mon_decimal_point;
+	const char *mon_thousands_sep;
+	const char *mon_grouping;
+	const char *positive_sign;
+	const char *negative_sign;
+	const char *int_frac_digits;
+	const char *frac_digits;
+	const char *p_cs_precedes;
+	const char *p_sep_by_space;
+	const char *n_cs_precedes;
+	const char *n_sep_by_space;
+	const char *p_sign_posn;
+	const char *n_sign_posn;
+	const char *int_p_cs_precedes;
+	const char *int_p_sep_by_space;
+	const char *int_n_cs_precedes;
+	const char *int_n_sep_by_space;
+	const char *int_p_sign_posn;
+	const char *int_n_sign_posn;
+
+	const char *crncystr;		/* not returned by localeconv */
+
+	/* time */
+	const char *abday_1;
+	const char *abday_2;
+	const char *abday_3;
+	const char *abday_4;
+	const char *abday_5;
+	const char *abday_6;
+	const char *abday_7;
+
+	const char *day_1;
+	const char *day_2;
+	const char *day_3;
+	const char *day_4;
+	const char *day_5;
+	const char *day_6;
+	const char *day_7;
+
+	const char *abmon_1;
+	const char *abmon_2;
+	const char *abmon_3;
+	const char *abmon_4;
+	const char *abmon_5;
+	const char *abmon_6;
+	const char *abmon_7;
+	const char *abmon_8;
+	const char *abmon_9;
+	const char *abmon_10;
+	const char *abmon_11;
+	const char *abmon_12;
+
+	const char *mon_1;
+	const char *mon_2;
+	const char *mon_3;
+	const char *mon_4;
+	const char *mon_5;
+	const char *mon_6;
+	const char *mon_7;
+	const char *mon_8;
+	const char *mon_9;
+	const char *mon_10;
+	const char *mon_11;
+	const char *mon_12;
+
+	const char *am_str;
+	const char *pm_str;
+
+	const char *d_t_fmt;
+	const char *d_fmt;
+	const char *t_fmt;
+	const char *t_fmt_ampm;
+	const char *era;
+
+	const char *era_year;		/* non SUSv3 */
+	const char *era_d_fmt;
+	const char *alt_digits;
+	const char *era_d_t_fmt;
+	const char *era_t_fmt;
+
+	/* collate */
+
+	/* messages */
+	const char *yesexpr;
+	const char *noexpr;
+
+} __locale_t;
+
+extern __locale_t __global_locale;
+
+#endif /* defined(_LIBC) && !defined(__LOCALE_C_ONLY) */
+
+#endif /* _UCLIBC_LOCALE_H */