diff --git a/Headers/gnustep/unicode/cyrillic.h b/Headers/gnustep/unicode/cyrillic.h index d5fac1354..9aca9643d 100644 --- a/Headers/gnustep/unicode/cyrillic.h +++ b/Headers/gnustep/unicode/cyrillic.h @@ -138,7 +138,7 @@ unichar Cyrillic_char_to_uni_table[] = const unsigned int Cyrillic_uni_to_char_table_size = 128; -struct _ucc_ Cyrillic_uni_to_char_table[]= +_ucc_ Cyrillic_uni_to_char_table[]= { {0x0080,0x80}, {0x0081,0x81}, diff --git a/Headers/gnustep/unicode/gsm0338.h b/Headers/gnustep/unicode/gsm0338.h index 5cb503137..6d717d97a 100644 --- a/Headers/gnustep/unicode/gsm0338.h +++ b/Headers/gnustep/unicode/gsm0338.h @@ -136,9 +136,7 @@ unichar GSM0338_char_to_uni_table[] = 0x00E0 }; -const unsigned int GSM0338_uni_to_char_table_size = 128; - -struct _ucc_ GSM0338_uni_to_char_table[]= +_ucc_ GSM0338_uni_to_char_table[] = { {0x0080,0x80}, {0x0081,0x81}, @@ -267,6 +265,23 @@ struct _ucc_ GSM0338_uni_to_char_table[]= {0x02D8,0xA2}, {0x02D9,0xFF}, {0x02DB,0xB2}, - {0x02DD,0xBD}, + {0x02DD,0xBD} +}; +#define GSM0338_tsize (sizeof(GSM0338_uni_to_char_table)/sizeof(_ucc_)) + +_ucc_ GSM0338_escapes[] = +{ + {0x000C,0x0A}, + {0x005B,0x3C}, + {0x005C,0x2F}, + {0x005D,0x3E}, + {0x005E,0x14}, + {0x007B,0x28}, + {0x007C,0x40}, + {0x007D,0x29}, + {0x007E,0x3D}, + {0x20AC,0x65} }; +#define GSM0338_esize (sizeof(GSM0338_escapes)/sizeof(_ucc_)) + diff --git a/Headers/gnustep/unicode/latin2.h b/Headers/gnustep/unicode/latin2.h index 60bdd8935..bf76e15aa 100644 --- a/Headers/gnustep/unicode/latin2.h +++ b/Headers/gnustep/unicode/latin2.h @@ -140,7 +140,7 @@ unichar Latin2_char_to_uni_table[] = const unsigned int Latin2_uni_to_char_table_size = 128; -struct _ucc_ Latin2_uni_to_char_table[]= +_ucc_ Latin2_uni_to_char_table[]= { {0x0080,0x80}, {0x0081,0x81}, diff --git a/Headers/gnustep/unicode/nextstep.h b/Headers/gnustep/unicode/nextstep.h index 79baee765..d001492fd 100644 --- a/Headers/gnustep/unicode/nextstep.h +++ b/Headers/gnustep/unicode/nextstep.h @@ -129,7 +129,7 @@ unichar Next_char_to_uni_table[] = const unsigned int Next_uni_to_char_table_size = 128; -struct _ucc_ Next_uni_to_char_table[]= +_ucc_ Next_uni_to_char_table[]= { {0x00A0,0x80}, {0x00A1,0xA1}, diff --git a/Source/Unicode.m b/Source/Unicode.m index 2a1b7ccd6..ad98bc47a 100644 --- a/Source/Unicode.m +++ b/Source/Unicode.m @@ -32,7 +32,7 @@ #include #include -struct _ucc_ {unichar from; char to;}; +typedef struct {unichar from; char to;} _ucc_; #include "unicode/cyrillic.h" #include "unicode/latin2.h" @@ -548,7 +548,7 @@ encode_unitochar(unichar u, NSStringEncoding enc) case NSGSM0338StringEncoding: { while (((res = u - GSM0338_uni_to_char_table[i++].from) > 0) - && (i < GSM0338_uni_to_char_table_size)); + && (i < GSM0338_tsize)); return res ? '*' : GSM0338_uni_to_char_table[--i].to; } #if 0 @@ -642,7 +642,7 @@ encode_unitochar_strict(unichar u, NSStringEncoding enc) case NSGSM0338StringEncoding: { while (((res = u - GSM0338_uni_to_char_table[i++].from) > 0) - && (i < GSM0338_uni_to_char_table_size)); + && (i < GSM0338_tsize)); return res ? 0 : GSM0338_uni_to_char_table[--i].to; } @@ -944,23 +944,49 @@ int encode_ustrtocstr(char *dst, int dl, const unichar *src, int sl, return count; case NSGSM0338StringEncoding: - for (count = 0; count < sl && count < dl; count++) - { - int res; - int i = 0; + { + int dc; - u = src[count]; + for (dc = count = 0; count < sl && dc < dl; count++, dc++) + { + int res; + int i = 0; - while (((res = u - GSM0338_uni_to_char_table[i++].from) > 0) - && (i < GSM0338_uni_to_char_table_size)); - if (!res) - dst[count] = GSM0338_uni_to_char_table[--i].to; - else - return 0; - } - if (count < sl) - return 0; // Not all characters converted. - return count; + u = src[count]; + + while (((res = u - GSM0338_uni_to_char_table[i++].from) > 0) + && (i < GSM0338_tsize)); + if (!res) + { + dst[dc] = GSM0338_uni_to_char_table[--i].to; + } + else if (dc < dl - 1) + { + for (i = 0; i < GSM0338_esize; i++) + { + if (GSM0338_escapes[i].from == u) + { + dst[dc++] = 0x1b; + dst[dc] = GSM0338_escapes[i].to; + break; + } + } + if (i == GSM0338_esize) + { + return 0; + } + } + else + { + return 0; + } + } + if (count < sl) + { + return 0; // Not all characters converted. + } + return dc; + } #if 0 case NSSymbolStringEncoding: @@ -1103,20 +1129,49 @@ int encode_ustrtocstr(char *dst, int dl, const unichar *src, int sl, return count; case NSGSM0338StringEncoding: - for (count = 0; count < sl && count < dl; count++) - { - int res; - int i = 0; + { + int dc; - u = src[count]; + for (dc = count = 0; count < sl && dc < dl; count++, dc++) + { + int res; + int i = 0; - while (((res = u - GSM0338_uni_to_char_table[i++].from) > 0) - && (i < GSM0338_uni_to_char_table_size)); - dst[count] = res ? '*' : GSM0338_uni_to_char_table[--i].to; - } - if (count < sl) - return 0; // Not all characters converted. - return count; + u = src[count]; + + while (((res = u - GSM0338_uni_to_char_table[i++].from) > 0) + && (i < GSM0338_tsize)); + if (!res) + { + dst[dc] = GSM0338_uni_to_char_table[--i].to; + } + else if (dc < dl - 1) + { + for (i = 0; i < GSM0338_esize; i++) + { + if (GSM0338_escapes[i].from == u) + { + dst[dc++] = 0x1b; + dst[dc] = GSM0338_escapes[i].to; + break; + } + } + if (i == GSM0338_esize) + { + dst[dc] = '*'; + } + } + else + { + dst[dc] = '*'; + } + } + if (count < sl) + { + return 0; // Not all characters converted. + } + return dc; + } #if 0 case NSSymbolStringEncoding: @@ -1151,6 +1206,9 @@ int encode_ustrtocstr(char *dst, int dl, const unichar *src, int sl, } } +/** + * Convert to unicode .. return the number of unicode characters produced. + */ int encode_cstrtoustr(unichar *dst, int dl, const char *src, int sl, NSStringEncoding enc) { @@ -1213,15 +1271,34 @@ int encode_cstrtoustr(unichar *dst, int dl, const char *src, int sl, return count; case NSGSM0338StringEncoding: - for (count = 0; count < sl && count < dl; count++) - { - unc c = (unc)src[count]; + { + int dc; - dst[count] = GSM0338_char_to_uni_table[c]; - } - if (count < sl) - return 0; // Not all characters converted. - return count; + for (dc = count = 0; count < sl && dc < dl; count++, dc++) + { + unc c = (unc)src[count]; + + dst[dc] = GSM0338_char_to_uni_table[c]; + if (c == 0x1b && count < sl) + { + unsigned i = 0; + + c = (unc)src[count+1]; + while (i < sizeof(GSM0338_escapes)/sizeof(GSM0338_escapes[0])) + { + if (GSM0338_escapes[i].to == c) + { + dst[dc] = GSM0338_escapes[i].from; + count++; + break; + } + } + } + } + if (count < sl) + return 0; // Not all characters converted. + return dc; + } #if 0 case NSSymbolStringEncoding: