Browse Source

Part of the ctype locale support.

Manuel Novoa III 24 years ago
parent
commit
a12156f0c4

+ 27 - 0
extra/locale/README

@@ -0,0 +1,27 @@
+
+The program gen_ctype_from_glibc.c will generate data files which can be
+used by uClibc ctype functions to support locales.  From the comments:
+
+/*
+ * 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>
+ *
+ */
+
+
+Sample usage to dump all the data files in a tmp directory:
+
+gcc gen_ctype_from_glibc.c -o gen_ctype_from_glibc
+
+mkdir tmp
+cd tmp
+../gen_ctype_from_glibc
+
+Then just move the directory or directories you need (not the .c files)
+to the uClibc locale file directory you set in Config.

+ 276 - 0
extra/locale/gen_ctype_from_glibc.c

@@ -0,0 +1,276 @@
+/*
+ * 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 "../../misc/ctype/ctype.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)) {
+		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;
+}

+ 9 - 3
include/ctype.h

@@ -4,11 +4,17 @@
 #ifndef __CTYPE_H
 #define __CTYPE_H
 
+#include <features.h>
+
 /* For now, just always use the functions instead of the macros...*/
-#define USE_CTYPE_C_FUNCTIONS
+#define __USE_CTYPE_C_FUNCTIONS
 
+/* Locale-compatible macros/inlines have yet to be implemented. */
+#if __UCLIBC_HAS_LOCALE__ && !defined(__USE_CTYPE_C_FUNCTIONS)
+#define __USE_CTYPE_C_FUNCTIONS
+#endif
 
-#ifdef USE_CTYPE_C_FUNCTIONS
+#ifdef __USE_CTYPE_C_FUNCTIONS
 /* function prototpes */ 
 extern int isalnum(int c);
 extern int isalpha(int c);
@@ -34,7 +40,7 @@ extern int toupper(int c);
 #define isalnum(c)  (isalpha(c) || isdigit(c))
 #define isalpha(c)  (isupper(c) || islower(c))
 #define isascii(c)  (c > 0 && c <= 0x7f)
-#define iscntrl(c)  ((c > 0) && ((c <= 0x1F) || (c == 0x7f)))
+#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')

+ 29 - 0
include/locale.h

@@ -0,0 +1,29 @@
+/* locale.h
+ * Support international type specific characters.
+ */
+#ifndef _LOCALE_H
+#define _LOCALE_H       1
+
+#include <features.h>
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL    0
+#else
+#define NULL    ((void *) 0)
+#endif
+#endif
+
+/* 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
+
+extern char *setlocale(int __category, __const char *__locale);
+
+#endif /* locale.h  */

+ 1 - 1
libc/misc/Makefile

@@ -26,7 +26,7 @@ LIBC=$(TOPDIR)libc.a
 
 
 DIRS = assert crypt ctype fnmatch glob internals lsearch mntent syslog shm \
-	time utmp tsearch
+	time utmp tsearch locale
 
 # regex bombs out with an internal compiler error using m68k-pic-coff-gcc.
 ifneq ($(TARGET_ARCH),m68k)

+ 7 - 1
libc/misc/ctype/Makefile

@@ -27,7 +27,13 @@ LIBC=$(TOPDIR)libc.a
 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 
+	isxlower.o isxupper.o toascii.o tolower.o toupper.o
+
+ifeq ($(HAS_LOCALE),true)
+	MOBJ += ctype_C.o
+endif
+
+
 OBJS=$(MOBJ)
 all: $(MOBJ) $(LIBC)
 

+ 178 - 24
libc/misc/ctype/ctype.c

@@ -1,51 +1,67 @@
-/* ctype.c	
+/* 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.
+ *
+ * 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.
  */
 
-#define USE_CTYPE_C_FUNCTIONS
 #include <ctype.h>
 
-#ifdef L_isalnum
+#ifdef L_isascii
 int
-isalnum( int c )
+isascii( int c )
 {
-    return (isalpha(c) || isdigit(c));
+    return (c > 0 && c <= 0x7f);
 }
 #endif
 
-#ifdef L_isalpha
+#ifdef L_isdigit
 int
-isalpha( int c )
+isdigit( int c )
 {
-    return (isupper(c) || islower(c));
+    return (c >= '0' && c <= '9');
 }
 #endif
 
-#ifdef L_isascii
+#ifdef L_toascii
 int
-isascii( int c )
+toascii( int c )
 {
-    return (c > 0 && c <= 0x7f);
+    return (c & 0x7f);
 }
 #endif
 
-#ifdef L_iscntrl
+
+/* locale depended */
+#if !__UCLIBC_HAS_LOCALE__
+
+#ifdef L_isalpha
 int
-iscntrl( int c )
+isalpha( int c )
 {
-    return ((c > 0) && ((c <= 0x1f) || (c == 0x7f)));
+    return (isupper(c) || islower(c));
 }
 #endif
 
-#ifdef L_isdigit
+#ifdef L_isalnum
 int
-isdigit( int c )
+isalnum( int c )
 {
-    return (c >= '0' && c <= '9');
+    return (isalpha(c) || isdigit(c));
+}
+#endif
+
+#ifdef L_iscntrl
+int
+iscntrl( int c )
+{
+    return ((c >= 0) && ((c <= 0x1f) || (c == 0x7f)));
 }
 #endif
 
@@ -53,7 +69,7 @@ isdigit( int c )
 int
 isgraph( int c )
 {
-    return (c != ' ' && isprint(c));
+    return (c > ' ' && isprint(c));
 }
 #endif
 
@@ -102,7 +118,7 @@ isupper( int c )
 int
 isxdigit( int c )
 {
-    return (isxupper(c) || isxlower(c));
+    return (isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
 }
 #endif
 
@@ -122,11 +138,137 @@ isxupper( int c )
 }
 #endif
 
-#ifdef L_toascii
+#ifdef L_tolower
 int
-toascii( int c )
+tolower( int c )
 {
-    return (c & 0x7f);
+    return (isupper(c) ? (c - 'A' + 'a') : (c));
+}
+#endif
+
+#ifdef L_toupper
+int
+toupper( int c )
+{
+    return (islower(c) ? (c - 'a' + 'A') : (c));
+}
+#endif
+
+#else   /* __UCLIBC_HAS_LOCALE__ == 1 */
+
+#include <limits.h>
+#include "./ctype.h"
+
+#define _UC_ISCTYPE(c, type) \
+((c != -1) && ((_uc_ctype_b[(int)((unsigned char)c)] & type) != 0))
+
+#define _UC_ISCTYPE2(c, type, type2) \
+((c != -1) && ((_uc_ctype_b[(int)((unsigned char)c)] & type) == type2))
+
+
+#ifdef L_ctype_C
+
+/* startup setlocale(LC_TYPE, "C"); */
+#include "ctype_C.c"
+
+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  /* L_ctype_C */
+
+#ifdef L_isalpha
+int
+isalpha( int c )
+{
+    return _UC_ISCTYPE(c, ISalpha);
+}
+#endif
+
+#ifdef L_isalnum
+int
+isalnum( int c )
+{
+    return _UC_ISCTYPE(c, (ISalpha|ISxdigit));
+}
+#endif
+
+#ifdef L_iscntrl
+int
+iscntrl( int c )
+{
+    return _UC_ISCTYPE(c, IScntrl);
+}
+#endif
+
+#ifdef L_isgraph
+int
+isgraph( int c )
+{
+    return _UC_ISCTYPE2(c, (ISprint|ISspace), ISprint);
+}
+#endif
+
+#ifdef L_islower
+int
+islower( int c )
+{
+    return _UC_ISCTYPE(c, ISlower);
+}
+#endif
+
+#ifdef L_isprint
+int
+isprint( int c )
+{
+    return _UC_ISCTYPE(c, ISprint);
+}
+#endif
+
+#ifdef L_ispunct
+int
+ispunct( int c )
+{
+    return _UC_ISCTYPE(c, ISpunct);
+}
+#endif
+
+#ifdef L_isspace
+int
+isspace( int c )
+{
+    return _UC_ISCTYPE(c, ISspace);
+}
+#endif
+
+#ifdef L_isupper
+int
+isupper( int c )
+{
+    return _UC_ISCTYPE(c, ISupper);
+}
+#endif
+
+#ifdef L_isxdigit
+int
+isxdigit( int c )
+{
+    return _UC_ISCTYPE(c, ISxdigit);
+}
+#endif
+
+#ifdef L_isxlower
+int
+isxlower( int c )
+{
+    return _UC_ISCTYPE2(c, (ISxdigit|ISupper), ISxdigit);
+}
+#endif
+
+#ifdef L_isxupper
+int
+isxupper( int c )
+{
+    return _UC_ISCTYPE2(c, (ISxdigit|ISlower), ISxdigit);
 }
 #endif
 
@@ -134,7 +276,12 @@ toascii( int c )
 int
 tolower( int c )
 {
-    return (isupper(c) ? ( c - 'A' + 'a') : (c));
+    if((c < CHAR_MIN) || (c > UCHAR_MAX))
+		return c;
+    if(isupper(c))
+		return _uc_ctype_trans[(int)((unsigned char)c)];
+    else
+		return c;
 }
 #endif
 
@@ -142,6 +289,13 @@ tolower( int c )
 int
 toupper( int c )
 {
-    return (islower(c) ? (c - 'a' + 'A') : (c));
+    if((c < CHAR_MIN) || (c > UCHAR_MAX))
+		return c;
+    if(islower(c))
+		return _uc_ctype_trans[(int)((unsigned char)c)];
+    else
+		return c;
 }
 #endif
+
+#endif

+ 21 - 0
libc/misc/ctype/ctype.h

@@ -0,0 +1,21 @@
+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.        */
+};
+

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

@@ -0,0 +1,517 @@
+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
+};

+ 46 - 0
libc/misc/locale/Makefile

@@ -0,0 +1,46 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000 by Lineo, inc.
+#
+# 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
+LIBC=$(TOPDIR)libc.a
+
+MSRC=locale.c
+MOBJ= setlocale.o
+
+OBJS=$(MOBJ)
+all: $(MOBJ) $(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
+
+$(OBJS): Makefile
+
+clean:
+	rm -f *.[oa] *~ core
+

+ 164 - 0
libc/misc/locale/locale.c

@@ -0,0 +1,164 @@
+/* setlocale.c
+ * Load LC_CTYPE locale only special for uclibc
+ *
+ * Written by Vladimir Oleynik (c) vodz@usa.net
+ *
+ * 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.
+ */
+
+/*
+ * No-locale-support setlocale() added.
+ */
+
+#include <locale.h>
+#include <stdio.h>      /* NULL, fopen */
+#include <stdlib.h>     /* malloc */
+#include <string.h>
+#include <limits.h>     /* PATH_MAX */
+
+#include "../ctype/ctype.h"
+
+#undef TEST_LOCALE
+
+
+#ifdef L_setlocale
+
+#if __UCLIBC_HAS_LOCALE__
+
+static char C_LOCALE_NAME[]="C";
+
+#ifdef TEST_LOCALE
+static const char PATH_LOCALE[]="./";
+#else
+static const char PATH_LOCALE[]=__UCLIBC_LOCALE_DIR;
+#endif
+
+static const char LC_CTYPE_STR[]="/LC_CTYPE";
+
+struct SAV_LOADED_LOCALE {
+	char *locale;
+	const unsigned char *buf;
+	struct SAV_LOADED_LOCALE *next;
+};
+
+
+static struct SAV_LOADED_LOCALE sav_loaded_locale [1] = {
+	{ C_LOCALE_NAME, _uc_ctype_b_C, 0 }
+};
+
+static struct SAV_LOADED_LOCALE * old_locale = sav_loaded_locale;
+
+static char *set_new_locale(struct SAV_LOADED_LOCALE * s_locale)
+{
+	_uc_ctype_b     = s_locale->buf;
+	_uc_ctype_trans = s_locale->buf+LOCALE_BUF_SIZE/2;
+	old_locale      = s_locale;
+	return            s_locale->locale;
+}
+
+/* Current support only LC_CTYPE or LC_ALL category */
+
+char *setlocale(int category, const char *locale)
+{
+	FILE * fl;
+	struct SAV_LOADED_LOCALE *cur;
+	struct SAV_LOADED_LOCALE *bottom;
+	char   full_path[PATH_MAX];
+	char * buf = 0;
+	int    l;
+
+	if(category!=LC_CTYPE && category!=LC_ALL)
+		return NULL;
+
+	if(locale==0)
+		return set_new_locale(old_locale);
+
+	if(strcmp(locale, "POSIX")==0)
+		return set_new_locale(sav_loaded_locale);
+	 else if(*locale == '\0') {
+
+		locale = getenv(LC_CTYPE_STR+1);
+		if(locale == 0 || *locale == 0)
+			locale = getenv("LANG");
+		if(locale == 0 || *locale == '\0')
+			return set_new_locale(old_locale);
+		if(strcmp(locale, "POSIX")==0)
+			return set_new_locale(sav_loaded_locale);
+	}
+
+	for(cur = sav_loaded_locale; cur; cur = cur->next)
+		if(strcmp(cur->locale, locale)==0)
+			return set_new_locale(cur);
+
+	l = strlen(locale);
+	if((l+sizeof(PATH_LOCALE)+sizeof(LC_CTYPE_STR))>=PATH_MAX)
+		return NULL;
+
+	strcpy(full_path, PATH_LOCALE);
+	strcat(full_path, locale);
+	strcat(full_path, LC_CTYPE_STR);
+	fl = fopen(full_path, "r");
+	if(fl==0)
+		return NULL;
+
+	cur = malloc(sizeof(struct SAV_LOADED_LOCALE)+LOCALE_BUF_SIZE+l);
+	if(cur) {
+		buf = (char *)(cur+1);
+		if(fread(buf, 1, LOCALE_BUF_SIZE+1, fl)!=(LOCALE_BUF_SIZE)) {
+			/* broken locale file */
+			free(cur);
+			buf = 0;
+#ifdef TEST_LOCALE
+			fprintf(stderr, "\nbroken locale file\n");
+#endif
+		}
+	}
+
+	fclose(fl);
+	if(cur==0)      /* not enough memory */
+		return NULL;
+	if(buf==0)      /* broken locale file, set to "C" */
+		return set_new_locale(sav_loaded_locale);
+
+	cur->next = 0;
+	strcpy(buf+LOCALE_BUF_SIZE, locale);
+
+	bottom = sav_loaded_locale;
+	while(bottom->next!=0)
+		bottom = bottom->next;
+	bottom->next = cur;
+
+	/* next two line only pedantic */
+	cur->buf    = buf;
+	cur->locale = buf+LOCALE_BUF_SIZE;
+
+	return set_new_locale(cur);
+}
+
+#else /* no locale support */
+
+char *setlocale(int category, const char *locale)
+{
+	/* Allow locales "C" and "" (native).  Both are "C" for our purposes. */
+	if (locale) {
+		if (*locale == 'C') {
+			++locale;
+		}
+		if (*locale) {				/* locale wasn't "C" or ""!! */
+			return NULL;
+		}
+	}
+
+	/* Allow any legal category for "C" or "" (native) locale. */
+	if((category < LC_CTYPE) || (category > LC_ALL)) { /* Illegal category! */
+		return NULL;
+	}
+
+	return "C";
+}
+
+#endif
+
+#endif /* L_setlocale */