/* unicode-jp.c -- JIS X 0208 <=> UCS-2 converter written by N. Tsuchimura */ #include #include #include #include #if defined(KANJI_ICONV) && defined(HAVE_ICONV_H) #include #include /* for atexit() */ #define ICONV_INVALID ((iconv_t)(-1)) #define ICONV_JIS "ISO-2022-JP" #define ICONV_UNI "UCS-2BE" static int inited = FALSE; static iconv_t i_jis2ucs2 = ICONV_INVALID; static iconv_t i_ucs22jis = ICONV_INVALID; #ifdef HAVE_ATEXIT static void close_iconv(void) #else /* HAVE_ATEXIT */ static void close_iconv(int dummy1, void *dummy2) #endif /* HAVE_ATEXIT */ { if (i_jis2ucs2 != ICONV_INVALID) iconv_close(i_jis2ucs2); if (i_ucs22jis != ICONV_INVALID) iconv_close(i_ucs22jis); } static void open_iconv(void) { inited = true; i_jis2ucs2 = iconv_open(ICONV_UNI, ICONV_JIS); i_ucs22jis = iconv_open(ICONV_JIS, ICONV_UNI); #ifdef HAVE_ATEXIT atexit(close_iconv); #endif /* HAVE_ATEXIT */ #ifdef HAVE_ON_EXIT on_exit(close_iconv, NULL); #endif /* HAVE_ON_EXIT */ } /* convert a JIS X 0208 char to UCS-2 */ static int JIStoUCS2native(int jis) { unsigned char jis_seq[8] = { 0x1b, 0x24, 0x42, /* JIS X 0208-1983 */ (unsigned char)HI(jis), (unsigned char)LO(jis), 0x1b, 0x28, 0x42, /* ASCII */ }; unsigned char unicode[2]; size_t from = sizeof jis_seq; size_t to = sizeof unicode; char *from_ptr = (char *)jis_seq; char *to_ptr = (char *)unicode; if (!inited) open_iconv(); if (i_jis2ucs2 == ICONV_INVALID) return 0; if (iconv(i_jis2ucs2, &from_ptr, &from, &to_ptr, &to) == (size_t)(-1)) { return 0; } return HILO(unicode[0], unicode[1]); } /* convert a UCS-2 char to JIS X 0208 */ static int UCS2toJISnative(int ucs2) { unsigned char unicode[2] = { (unsigned char)HI(ucs2), (unsigned char)LO(ucs2), }; unsigned char jis_seq[10] = { 0,0,0,0,0,0,0,0,0,0 }; size_t from = sizeof unicode; size_t to = sizeof jis_seq; char *from_ptr = (char *)unicode; char *to_ptr = (char *)jis_seq; unsigned char *ret = jis_seq; if (!inited) open_iconv(); if (i_ucs22jis == ICONV_INVALID) return 0; if (iconv(i_ucs22jis, &from_ptr, &from, &to_ptr, &to) == (size_t)(-1)) { return 0; } if (ret[0] == 0x1b) ret += 3; return HILO(ret[0], ret[1]); } #else /* KANJI_ICONV && HAVE_ICONV_H */ #include "jisx0208.h" #define MAXJIS 84 /* convert a JIS X 0208 char to UCS-2 */ static int JIStoUCS2native(int jis) { int hi, low; hi = HI(jis) - 0x21; low = LO(jis) - 0x21; if (0 <= hi && hi < MAXJIS && 0 <= low && low < 94) return (int)UnicodeTbl[hi][low]; return 0; } /* convert a UCS-2 char to JIS X 0208 */ static int UCS2toJISnative(int ucs2) { int i, j; for (i=0; i UCS conversion if is_internalUPTEX */ 0x2131 /* 1-17 */, 0xFFE3, 0x203E, 0, 0x213D /* 1-29 */, 0x2015, 0x2014, 0, 0x2141 /* 1-33 */, 0x301C, 0xFF5E, 0, 0x2142 /* 1-34 */, 0x2016, 0x2225, 0, 0x2144 /* 1-36 */, 0x2026, 0x22EF, 0, 0x215D /* 1-61 */, 0x2212, 0xFF0D, 0, 0x216F /* 1-79 */, 0xFFE5, 0x00A5, 0, 0x2171 /* 1-81 */, 0xFFE0, 0x00A2, 0, 0x2172 /* 1-82 */, 0xFFE1, 0x00A3, 0, 0x224C /* 2-44 */, 0xFFE2, 0x00AC, 0, 0 /* end */ }; /* if is_internalUPTEX, force JIS X 0208 -> UCS2 conversion as follows: JIS code (men-ku) -> UCS ( Character Name ) 0x2131 ( 1-17 ) -> U+FFE3 ( FULLWIDTH MACRON ) 0x213D ( 1-29 ) -> U+2015 ( HORIZONTAL BAR ) 0x2141 ( 1-33 ) -> U+301C ( WAVE DASH ) 0x2142 ( 1-34 ) -> U+2016 ( DOUBLE VERTICAL LINE ) 0x2144 ( 1-36 ) -> U+2026 ( HORIZONTAL ELLIPSIS ) 0x215D ( 1-61 ) -> U+2212 ( MINUS SIGN ) 0x216F ( 1-79 ) -> U+FFE5 ( FULLWIDTH YEN SIGN ) 0x2171 ( 1-81 ) -> U+FFE0 ( FULLWIDTH NOT SIGN ) 0x2172 ( 1-82 ) -> U+FFE1 ( FULLWIDTH POUND SIGN ) 0x224C ( 2-44 ) -> U+FFE2 ( FULLWIDTH NOT SIGN ) */ /* voiced sound of kana http://developer.apple.com/technotes/tn/tn1150table.html */ static unsigned short int voiced_sounds[] = { /* from, to */ 0x3046, 0x3094, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F, 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, 0x3059, 0x305A, 0x305B, 0x305C, 0x305D, 0x305E, 0x305F, 0x3060, 0x3061, 0x3062, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, 0x3069, 0x306F, 0x3070, 0x3072, 0x3073, 0x3075, 0x3076, 0x3078, 0x3079, 0x307B, 0x307C, 0x309D, 0x309E, 0x30A6, 0x30F4, 0x30AB, 0x30AC, 0x30AD, 0x30AE, 0x30AF, 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4, 0x30B5, 0x30B6, 0x30B7, 0x30B8, 0x30B9, 0x30BA, 0x30BB, 0x30BC, 0x30BD, 0x30BE, 0x30BF, 0x30C0, 0x30C1, 0x30C2, 0x30C4, 0x30C5, 0x30C6, 0x30C7, 0x30C8, 0x30C9, 0x30CF, 0x30D0, 0x30D2, 0x30D3, 0x30D5, 0x30D6, 0x30D8, 0x30D9, 0x30DB, 0x30DC, 0x30EF, 0x30F7, 0x30F0, 0x30F8, 0x30F1, 0x30F9, 0x30F2, 0x30FA, 0x30FD, 0x30FE, 0 /* end mark */ }; /* semi voiced sound of kana */ static unsigned short int semi_voiced_sounds[] = { /* from, to */ 0x306F, 0x3071, 0x3072, 0x3074, 0x3075, 0x3077, 0x3078, 0x307A, 0x307B, 0x307D, 0x30CF, 0x30D1, 0x30D2, 0x30D4, 0x30D5, 0x30D7, 0x30D8, 0x30DA, 0x30DB, 0x30DD, 0 /* end mark */ }; /* convert a JIS X 0208 char to UCS-2 */ int JIStoUCS2(int jis) { int i, j; /* first: variation table */ if (is_internalUPTEX()) { for (i=0; variation[i]!=0; i=j+1) { if (variation[i] == jis) return variation[i+1]; for (j=i+3; variation[j]!=0; j++) ; } } /* second: UnicodeTbl[][] */ return JIStoUCS2native(jis); } /* convert a UCS-2 char to JIS X 0208 */ int UCS2toJIS(int ucs2) { int i, j; /* first: variation table */ for (i=0; variation[i]!=0; i=j+1) { for (j=i+1; variation[j]!=0; j++) { if (variation[j] == ucs2) return variation[i]; } } /* second: UnicodeTbl[][] */ return UCS2toJISnative(ucs2); } /* for U+3099 or U+309A */ int get_voiced_sound(int ucs2, boolean semi) { int i; unsigned short int *table; if (semi) table = semi_voiced_sounds; else table = voiced_sounds; for (i=0; table[i]!=0; i+=2) { if (ucs2 == table[i]) return table[i+1]; } return 0; } #ifdef TEST #include int main(int argc, char **argv) { int hi, low; for (hi=0; hi