From a12156f0c4d93e521429a72d3eb0a109655fb219 Mon Sep 17 00:00:00 2001 From: Manuel Novoa III Date: Sun, 18 Mar 2001 22:19:32 +0000 Subject: Part of the ctype locale support. --- extra/locale/README | 27 ++ extra/locale/gen_ctype_from_glibc.c | 276 +++++++++++++++++++ include/ctype.h | 12 +- include/locale.h | 29 ++ libc/misc/Makefile | 2 +- libc/misc/ctype/Makefile | 8 +- libc/misc/ctype/ctype.c | 202 ++++++++++++-- libc/misc/ctype/ctype.h | 21 ++ libc/misc/ctype/ctype_C.c | 517 ++++++++++++++++++++++++++++++++++++ libc/misc/locale/Makefile | 46 ++++ libc/misc/locale/locale.c | 164 ++++++++++++ 11 files changed, 1275 insertions(+), 29 deletions(-) create mode 100644 extra/locale/README create mode 100644 extra/locale/gen_ctype_from_glibc.c create mode 100644 include/locale.h create mode 100644 libc/misc/ctype/ctype.h create mode 100644 libc/misc/ctype/ctype_C.c create mode 100644 libc/misc/locale/Makefile create mode 100644 libc/misc/locale/locale.c diff --git a/extra/locale/README b/extra/locale/README new file mode 100644 index 000000000..c555943ac --- /dev/null +++ b/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 2001 + * Base on ideas Nickolay Saukh + * + */ + + +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. diff --git a/extra/locale/gen_ctype_from_glibc.c b/extra/locale/gen_ctype_from_glibc.c new file mode 100644 index 000000000..5cbceb052 --- /dev/null +++ b/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 2001 + * Base on ideas Nickolay Saukh + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/include/ctype.h b/include/ctype.h index a4fab9bca..cf6c7fb85 100644 --- a/include/ctype.h +++ b/include/ctype.h @@ -4,11 +4,17 @@ #ifndef __CTYPE_H #define __CTYPE_H +#include + /* 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') diff --git a/include/locale.h b/include/locale.h new file mode 100644 index 000000000..f0c6f2e63 --- /dev/null +++ b/include/locale.h @@ -0,0 +1,29 @@ +/* locale.h + * Support international type specific characters. + */ +#ifndef _LOCALE_H +#define _LOCALE_H 1 + +#include + +#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 */ diff --git a/libc/misc/Makefile b/libc/misc/Makefile index fcaf6b473..3bae40b43 100644 --- a/libc/misc/Makefile +++ b/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) diff --git a/libc/misc/ctype/Makefile b/libc/misc/ctype/Makefile index 4ccfec415..a9d5837e5 100644 --- a/libc/misc/ctype/Makefile +++ b/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) diff --git a/libc/misc/ctype/ctype.c b/libc/misc/ctype/ctype.c index fb465838f..38da17f26 100644 --- a/libc/misc/ctype/ctype.c +++ b/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 + * used ideas is part of the GNU C Library. */ -#define USE_CTYPE_C_FUNCTIONS #include -#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 +#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 diff --git a/libc/misc/ctype/ctype.h b/libc/misc/ctype/ctype.h new file mode 100644 index 000000000..f9a34cb18 --- /dev/null +++ b/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. */ +}; + diff --git a/libc/misc/ctype/ctype_C.c b/libc/misc/ctype/ctype_C.c new file mode 100644 index 000000000..2aa2690b6 --- /dev/null +++ b/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 +}; diff --git a/libc/misc/locale/Makefile b/libc/misc/locale/Makefile new file mode 100644 index 000000000..c4b62a661 --- /dev/null +++ b/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 + diff --git a/libc/misc/locale/locale.c b/libc/misc/locale/locale.c new file mode 100644 index 000000000..109573871 --- /dev/null +++ b/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 +#include /* NULL, fopen */ +#include /* malloc */ +#include +#include /* 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 */ -- cgit v1.2.3