Mercurial > freewnn
diff Wnn/etc/xutoj.c @ 0:bbc77ca4def5
initial import
author | Yoshiki Yazawa <yaz@cc.rim.or.jp> |
---|---|
date | Thu, 13 Dec 2007 04:30:14 +0900 |
parents | |
children | 790205f476c0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Wnn/etc/xutoj.c Thu Dec 13 04:30:14 2007 +0900 @@ -0,0 +1,2402 @@ +/* + * $Id: xutoj.c,v 1.7 2002/03/24 01:25:13 hiroo Exp $ + */ + +/* + * FreeWnn is a network-extensible Kana-to-Kanji conversion system. + * This file is part of FreeWnn. + * + * Copyright Kyoto University Research Institute for Mathematical Sciences + * 1987, 1988, 1989, 1990, 1991, 1992 + * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999 + * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992 + * Copyright FreeWnn Project 1999, 2000, 2002 + * + * Maintainer: FreeWnn Project <freewnn@tomo.gr.jp> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU 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 + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#define NEED_CR + +#if STDC_HEADERS +# include <stdlib.h> +# include <string.h> +#elif HAVE_STRINGS_H +# include <strings.h> +#endif /* STDC_HEADERS */ + +#include "commonhd.h" +#include "wnn_config.h" +#include "wnn_os.h" + +#define ECNS_IS_UCNS 1 /* The trust CNS is CNS11643 based on ISO2022, + but the CNS is binded on EUC */ + +#define NON_LIMIT 0x7FFFFFFF + +#define G0 0 +#define G1 1 +#define G2 2 +#define G3 3 +#define SS 4 +#define GL 1 +#define GR 2 +#define LS0 0x0f +#define LS1 0x0e +#define LS1R 0x7e +#define LS2 0x6e +#define LS2R 0x7d +#define LS3 0x6f +#define LS3R 0x7c +#define SS2 0x8e +#define SS3 0x8f + + +#define CS_MASK 0x8080 +#define CS0_MASK 0x0000 +#define CS1_MASK 0x8080 +#define CS2_MASK 0x0080 +#define CS3_MASK 0x8000 + +#define CS1 0 +#define CS2 1 +#define CS3 2 + +#define UJIS_CSWIDTH "2,1,2" +#define UGB_CSWIDTH "2,1,2" +#define UKSC_CSWIDTH "2,1,2" + +typedef struct _CSWidthTable +{ + int cs1, cs2, cs3; +} +CSWidthTable; + +typedef struct _cswidth_name_struct +{ + char *lang; + char *name; + char *def_name; +} +cswidth_name_struct; + +typedef struct _DesignateTable +{ + unsigned char *code; + unsigned int mask; +} +DesignateTable; + +static int _etc_cs[3] = { 2, 1, 2 }; +static int _etc_cs_len[3] = { 2, 1, 2 }; +static int cs_mask[3] = { 0x8080, 0x0080, 0x8000 }; + +static int default_glr_mode[3] = { 0, G0, G1 }; +static int save_glr_mode[2]; +static int default_gn_len[4] = { 1, 1, 1, 2 }; +static unsigned int default_gn_mask[4] = { 0x00, 0x80, 0x80, 0x8000 }; +static DesignateTable default_designate[4] = { + {(unsigned char *) "(B", 0x0}, + {(unsigned char *) NULL, 0x0} +}; + +static int *glr_mode = default_glr_mode; +static int *gn_len = default_gn_len; +static unsigned int *gn_mask = default_gn_mask; + +static unsigned char save_seq[6] = { '\0' }; +static int save_seq_len = 0; +static int pending_esc = 0; +static unsigned char pending = '\0'; +static w_char pending_mask = (w_char) 0; + +static DesignateTable *designate = default_designate; + +#ifdef JAPANESE +static DesignateTable JIS_designate[] = { + {(unsigned char *) "(B", 0x0}, + {(unsigned char *) "(J", 0x0}, + {(unsigned char *) "(I", 0x80}, + {(unsigned char *) "$B", 0x8080}, + {(unsigned char *) "$(B", 0x8080}, + {(unsigned char *) ")I", 0x80}, + {(unsigned char *) "$)B", 0x8080}, + {(unsigned char *) "$)D", 0x8000}, + {(unsigned char *) "$(D", 0x8000}, + {(unsigned char *) NULL, 0x0} +}; +#endif /* JAPANESE */ + +#ifdef CHINESE +#ifndef ECNS_IS_UCNS +static DesignateTable CNS_designate[] = { + {(unsigned char *) "(B", 0x0}, + {(unsigned char *) "$)0", 0x8080}, + {(unsigned char *) "$*1", 0x8000}, + {NULL, 0x0} +}; +#endif /* ECNS_IS_UCNS */ +#endif /* CHINESE */ + +#ifdef KOREAN +static DesignateTable KSC_designate[] = { + {(unsigned char *) "(B", 0x0}, + {(unsigned char *) "$(C", 0x8080}, + {(unsigned char *) "$)C", 0x8080}, + {(unsigned char *) NULL, 0x0} +}; +#endif /* KOREAN */ + +#if defined(JAPANESE) || defined(CHINESE) || defined(KOREAN) +static w_char tmp_w_buf[1000]; +#endif + +static void +set_gn (dg) + DesignateTable *dg; +{ + register char *p = (char *) dg->code; + register int len = 1, gn = 0; + + if (!strcmp (p, "$B")) + { /* JIS */ + gn_len[0] = 2; + gn_mask[0] = dg->mask; + return; + } + if (*p == '$') + { + len = 2; + p++; + } + if (*p >= '(' && *p <= '+') + gn = *p - '('; + else if (*p >= '-' && *p <= '/') + gn = *p - '+'; + else + return; + gn_len[gn] = len; + gn_mask[gn] = dg->mask; +} + +static int +check_designate (ec, eend, ret_buf) + unsigned char *ec, *eend, **ret_buf; +{ + register unsigned char *c = ec; + register int i, j, ok = 0; + + *ret_buf = NULL; + for (i = save_seq_len; c < eend; c++) + { + ok = 0; + save_seq[i++] = *c; + save_seq[i] = '\0'; + for (j = 0; designate[j].code; j++) + { + if (!strncmp ((char *) save_seq, (char *) designate[j].code, i)) + { + if (i == strlen ((char *) designate[j].code)) + { + set_gn (&designate[j]); + save_seq_len = 0; + return (c - ec); + } + ok = 1; + break; + } + } + if (ok == 0) + { + *ret_buf = save_seq; + save_seq_len = 0; + return (c - ec); + } + } + save_seq_len = i; + return (c - ec - 1); +} + +int +flush_designate (buf) + w_char *buf; +{ + register w_char *c = buf; + register int i; + + if (pending_esc) + { + *c++ = ESC; + pending_esc = 0; + return (1); + } + if (save_seq_len == 0) + return (0); + *c++ = ESC; + for (i = 0; i < save_seq_len; i++) + { + *c++ = save_seq[i]; + } + save_seq_len = 0; + return ((char *) c - (char *) buf); +} + +int +extc_to_intc (intc, extc, esiz) + w_char *intc; + unsigned char *extc; + int esiz; +{ + unsigned char *eend = extc + esiz; + register unsigned char *ec = extc; + register w_char *ic = intc; + register int LorR = 0, i; + w_char tmp; + int ret, len; + unsigned char *ret_buf; + register unsigned char *p; + + for (; ec < eend; ec++) + { + if (pending_esc) + { + pending_esc = 0; + goto ESC_SWITCH; + } + if (pending) + { + *ic++ = ((pending << 8 | *ec) & 0x7f7f) | pending_mask; + pending = '\0'; + continue; + } + switch (*ec) + { +#ifdef JIS7 + case LS0: + glr_mode[GL] = G0; + break; + case LS1: + glr_mode[GL] = G1; + break; +#endif /* JIS7 */ + case SS2: + save_glr_mode[GL] = glr_mode[GL]; + glr_mode[GL] = (G2 | SS); + break; + case SS3: + save_glr_mode[GL] = glr_mode[GL]; + glr_mode[GL] = (G3 | SS); + break; + case ESC: + if (++ec == eend) + { + pending_esc = 1; + break; + } + ESC_SWITCH: + switch (*ec) + { + case LS1R: + glr_mode[GR] = G1; + break; + case LS2: + glr_mode[GL] = G2; + break; + case LS2R: + glr_mode[GR] = G2; + break; + case LS3: + glr_mode[GL] = G3; + break; + case LS3R: + glr_mode[GR] = G3; + break; + default: + ret = check_designate (ec, eend, &ret_buf); + ec += ret; + if (ret_buf) + { + *ic++ = ESC; + for (p = ret_buf; *p; p++) + *ic++ = *p; + } + break; + } + break; + default: + LorR = 0; + if (*ec >= 0x20 && *ec <= 0x7f) + { /* GL */ + LorR = GL; + } + else if (*ec >= 0xa0 && *ec <= 0xff) + { /* GR */ + LorR = GR; + } + if (LorR) + { + len = gn_len[(glr_mode[LorR] & 0x3)]; + if ((ec + len) > eend) + { + pending = *ec; + pending_mask = gn_mask[(glr_mode[LorR] & 0x3)]; + } + else + { + for (tmp = (w_char) 0, i = 0; i < len; i++) + { + tmp = ((tmp << 8 | *ec++) & 0x7f7f) | gn_mask[(glr_mode[LorR] & 0x3)]; + } + if (len) + ec -= 1; + *ic++ = tmp; + if (glr_mode[LorR] & SS) + glr_mode[LorR] = save_glr_mode[LorR]; + } + } + else + { + *ic++ = *ec; + } + } + } + return ((char *) ic - (char *) intc); +} + +int +through (x, y, z) + char *x, *y; + int z; +{ + bcopy (y, x, z); + return z; +} + +int +ibit8_to_ebit8 (ebit8, ibit8, ibsiz) + unsigned char *ebit8; + w_char *ibit8; + int ibsiz; +{ + register unsigned char *eb = ebit8; + register w_char *ib = ibit8; + + for (; ibsiz > 0; ibsiz -= sizeof (w_char)) + { + *eb++ = *ib++ & 0xff; + } + return ((char *) eb - (char *) ebit8); +} + +/** cswidth functions **/ +unsigned int +create_cswidth (s) + char *s; +{ + char tmp[2]; + int cs = 0, css = 0, i; + + if (!s || !*s) + return (0); + + tmp[0] = tmp[1] = '\0'; + for (i = 2; i >= 0; i--) + { + tmp[0] = *s; + cs = atoi (tmp); + if (cs > 0 && cs < 3) + css = (cs << (i * 8 + 4)) | css; + if (!*++s) + { + if (cs > 0 && cs < 3) + css = (cs << (i * 8)) | css; + break; + } + if (*s == ':') + { + if (!*++s) + { + if (cs > 0 && cs < 3) + css = (cs << (i * 8)) | css; + break; + } + tmp[0] = *s; + cs = atoi (tmp); + s++; + } + if (cs > 0 && cs < 3) + css = (cs << (i * 8)) | css; + if (!*s || *s != ',' || !*++s) + break; + } + return (css); +} + +void +set_cswidth (id) + register unsigned int id; +{ + _etc_cs[CS1] = (id >> 20) & 0xf; + _etc_cs[CS2] = (id >> 12) & 0xf; + _etc_cs[CS3] = (id >> 4) & 0xf; + _etc_cs_len[CS1] = (id >> 16) & 0xf; + _etc_cs_len[CS2] = (id >> 8) & 0xf; + _etc_cs_len[CS3] = id & 0xf; + return; +} + +static cswidth_name_struct cs_width_name[] = { + {WNN_J_LANG, "JCSWIDTH", "2,1,2"}, + {WNN_C_LANG, "CCSWIDTH", "2,1,2"}, + {WNN_K_LANG, "KCSWIDTH", "2"}, + {WNN_T_LANG, "TCSWIDTH", "2,1,2"}, + {NULL, NULL} +}; + +char * +get_cswidth_name (lang) + register char *lang; +{ + register cswidth_name_struct *p; + register char *name; + extern char *getenv (); + + if (!lang || !*lang) + { + return (getenv ("CSWIDTH")); + } + + for (p = cs_width_name; p->lang; p++) + { + if (!strncmp (lang, p->lang, strlen (lang))) + { + if ((name = getenv (p->name)) != NULL) + { + return (name); + } + else if ((name = getenv ("CSWIDTH")) != NULL) + { + return (name); + } + else + { + return (p->def_name); + } + } + } + return (NULL); +} + +int +get_cswidth (cs) + int cs; +{ + return (_etc_cs[cs]); +} + +int +get_cswidth_by_char (c) + register unsigned char c; +{ + if (c < SS2 || (c < 0xa0 && c > SS3)) + return (1); + if (c == SS2) + return (_etc_cs[CS2] + 1); + if (c == SS3) + return (_etc_cs[CS3] + 1); + return (_etc_cs[CS1]); +} + +int +get_cs_mask (cs) + int cs; +{ + return (cs_mask[cs]); +} + +int +columnlen (eeuc) + unsigned char *eeuc; +{ + register int n = 0; + register unsigned char *c, x; + register int cs_id; + + for (c = eeuc; *c;) + { + x = *c; + if (x & 0x80) + { + cs_id = ((x == SS2) ? CS2 : ((x == SS3) ? CS3 : CS1)); + if (cs_id == CS2 || cs_id == CS3) + c++; + n += _etc_cs_len[cs_id]; + c += _etc_cs[cs_id]; + } + else + { + n++; + c++; + } + } + return (n); +} + +int +columnlen_w (ieuc) + w_char *ieuc; +{ + register int n = 0; + register w_char *c, x; + register int cs_id, mask; + + for (c = ieuc; *c; c++) + { + x = *c; + mask = x & CS_MASK; + if (mask == CS0_MASK) + { + n++; + } + else + { + cs_id = (mask == cs_mask[CS3]) ? CS3 : ((mask == cs_mask[CS2]) ? CS2 : CS1); + n += _etc_cs_len[cs_id]; + } + } + return (n); +} + +int +ieuc_to_eeuc (eeuc, ieuc, iesiz) + unsigned char *eeuc; + w_char *ieuc; + int iesiz; +{ + register int x; + register w_char *ie; + register unsigned char *ee; + register int cs_id, mask, non_limit = 0; + ie = ieuc; + ee = eeuc; + + if (iesiz == -1) + non_limit = 1; + for (; (non_limit ? (*ie) : (iesiz > 0)); iesiz -= sizeof (w_char)) + { + x = *ie++; + mask = x & CS_MASK; + if (mask == CS0_MASK || x == 0xffff) + { + *ee++ = x; + } + else + { + cs_id = (mask == cs_mask[CS3]) ? CS3 : ((mask == cs_mask[CS2]) ? CS2 : CS1); + if (_etc_cs[cs_id] <= 0) + continue; + if (cs_id == CS2) + *ee++ = SS2; + else if (cs_id == CS3) + *ee++ = SS3; + if (_etc_cs[cs_id] > 1) + *ee++ = (x >> 8) | 0x80; + if (_etc_cs[cs_id] > 0) + *ee++ = (x & 0xff) | 0x80; + } + } + return ((char *) ee - (char *) eeuc); +} + + +int +eeuc_to_ieuc (ieuc, eeuc, eesiz) + w_char *ieuc; + unsigned char *eeuc; + register int eesiz; +{ + register unsigned char x; + register w_char *ie; + register unsigned char *ee; + register int cs_id, non_limit = 0; + ie = ieuc; + ee = eeuc; + + if (eesiz == -1) + non_limit = 1; + for (; (non_limit ? (*ee) : (eesiz > 0));) + { + x = *ee++; + if (x > 0x9f || x == SS2 || x == SS3) + { + cs_id = ((x == SS2) ? CS2 : ((x == SS3) ? CS3 : CS1)); + if (cs_id == CS2 || cs_id == CS3) + x = *ee++; + if (_etc_cs[cs_id] <= 0) + continue; + if (_etc_cs[cs_id] > 1) + { + *ie = (w_char) (x & 0x7f) << 8; + x = *ee++; + } + else + { + *ie = (w_char) 0; + } + *ie |= (x & 0x7f); + *ie++ |= cs_mask[cs_id]; + eesiz -= _etc_cs[cs_id] + 1; + } + else + { + *ie++ = x; + eesiz--; + } + } + return ((char *) ie - (char *) ieuc); +} + +#ifdef nodef +void +wnn_delete_ss2 (s, n) + register unsigned int *s; + register int n; +{ + register unsigned int x; + + for (; n != 0 && (x = *s); n--, s++) + { + if ((x & 0xff00) == 0x8e00) + *s &= ~0xff00; + if (x == 0xffffffff) + break; + } +} +#endif + +void +wnn_delete_w_ss2 (s, n) + register w_char *s; + register int n; +{ + register w_char x; + + for (; n != 0 && (x = *s); n--, s++) + { + if ((x & 0xff00) == 0x8e00) + *s &= ~0xff00; + } +} + +#ifdef nodef +int +wnn_byte_count (in) + register int in; +{ + return (((in < 0xa0 && in != 0x00 && in != 0x8e) || in == 0xff) ? 1 : 2); +} +#endif + +#define ASCII 0 + +#ifdef JAPANESE +#define HANKAKU_JIS_IN '\016' +#define HANKAKU_JIS_OUT '\017' + +#define HANKAKU_JIS 2 +#define ZENKAKU_JIS 1 +#define ZENKAKU_JIS_HOJYO 3 + +static unsigned char *j; +static w_char *iu; +static unsigned char *eu; +static unsigned char *sj; +static unsigned char tmp_buf[2000]; + +static void +putj (x) + int x; +{ + *j++ = x; +} + +static void +puteu (x) + int x; +{ + *eu++ = x; +} + +static void +putsj (x) + int x; +{ + *sj++ = x; +} + +static void +putsjw (x) + int x; +{ + *sj++ = x >> 8; + *sj++ = x; +} + +static int oj_mode = ASCII; /* 出力時のjisコードのモード */ +static int jtosj (); +extern int eujis_to_iujis (); + +/* convert JIS code to shift-JIS code */ +static int +jtosj (high, low) + unsigned high, low; +{ + if (high & 1) + low += 0x1f; + else + low += 0x7d; + if (low >= 0x7f) + low++; + high = ((high - 0x21) >> 1) + 0x81; + if (high > 0x9f) + high += 0x40; + return ((high << 8) | low); +} + +/* convert shift-JIS to JIS code */ +static int +sjtoj (high, low) + register unsigned high, low; +{ + high -= (high <= 0x9f) ? 0x71 : 0xb1; + high = high * 2; + if (low > 0x7f) + low--; + if (low >= 0x9e) + { + high += 2; + low -= 0x7d; + } + else + { + high++; + low -= 0x1f; + } + return ((high << 8) | low); +} + +static void +jis_change_mode (mode, new_mode) + int *mode; + int new_mode; +{ + if (*mode == new_mode) + return; + switch (*mode) + { + case ZENKAKU_JIS: + case ZENKAKU_JIS_HOJYO: + /* designate ISO-8859-1 rather than JIS X 0201 */ + /* putj('\033'); putj('('); putj('J');break; */ + putj ('\033'); + putj ('('); + putj ('B'); + break; +#ifdef JIS7 + case HANKAKU_JIS: + putj (HANKAKU_JIS_OUT); + break; +#endif /* JIS7 */ + default:; + } + *mode = new_mode; + switch (new_mode) + { + case ZENKAKU_JIS: + putj ('\033'); + putj ('$'); + putj ('B'); + break; + case ZENKAKU_JIS_HOJYO: + putj ('\033'); + putj ('$'); + putj ('('); + putj ('D'); + break; +#ifdef JIS7 + case HANKAKU_JIS: + putj (HANKAKU_JIS_IN); + break; +#endif /* JIS7 */ + default:; + } +} + +#ifdef JIS7 +/* 内部 U-jis を 7bit jis コードに変換します + 文字列の長さを返します */ +extern int +iujis_to_jis (jis, iujis, iusiz) + unsigned char *jis; /* jisコードになったものをおくbuf */ + w_char *iujis; /* iujisコードのものをおいてくるbuf */ + int iusiz; /* iujis の大きさ */ +{ + int x; + j = jis; + iu = iujis; + for (; iusiz > 0; iusiz -= sizeof (w_char)) + { + x = *iu++; + if (((x & 0xFF00) == 0x8E00) || ((x & 0xFF80) == 0x80)) + { + jis_change_mode (&oj_mode, HANKAKU_JIS); + putj (x & 0x7f); + } + else if ((x & 0x8080) == 0x8080) + { + jis_change_mode (&oj_mode, ZENKAKU_JIS); + putj ((x >> 8) & 0x7f); + putj (x & 0x7f); + } + else if (x & 0x8000) + { + jis_change_mode (&oj_mode, ZENKAKU_JIS_HOJYO); + putj ((x >> 8) & 0x7f); + putj (x & 0x7f); + } + else + { + jis_change_mode (&oj_mode, ASCII); + putj (x); + } + } + jis_change_mode (&oj_mode, ASCII); + return (j - jis); +} +#endif /* JIS7 */ + +/* 内部 U-jis を 8bit jis コードに変換します + 文字列の長さを返します */ +extern int +iujis_to_jis8 (jis, iujis, iusiz) + unsigned char *jis; /* jisコードになったものをおくbuf */ + w_char *iujis; /* iujisコードのものをおいてくるbuf */ + int iusiz; /* iujis の大きさ */ +{ + int x; + j = jis; + iu = iujis; + for (; iusiz > 0; iusiz -= sizeof (w_char)) + { + x = *iu++; + if (((x & 0xFF00) == 0x8E00) || ((x & 0xFF80) == 0x80)) + { + jis_change_mode (&oj_mode, ASCII); + putj (x & 0xff); + } + else if ((x & 0x8080) == 0x8080) + { + jis_change_mode (&oj_mode, ZENKAKU_JIS); + putj ((x >> 8) & 0x7f); + putj (x & 0x7f); + } + else if (x & 0x8000) + { + jis_change_mode (&oj_mode, ZENKAKU_JIS_HOJYO); + putj ((x >> 8) & 0x7f); + putj (x & 0x7f); + } + else + { + jis_change_mode (&oj_mode, ASCII); + putj (x); + } + } + jis_change_mode (&oj_mode, ASCII); + return (j - jis); +} + + +#ifdef JIS7 +/* 外部 U-jis を 7bit jis コードに変換します */ +extern int +eujis_to_jis (jis, eujis, eusiz) + unsigned char *jis, *eujis; + int eusiz; +{ + static int kanji1 = 0; + static char kanji1_code = 0; + /* 0: normal + 1: get SS2 + 2: get kanji 1 byte */ + /* + int oj_mode; + */ + int x; + j = jis; + eu = eujis; + /* ADD KURI */ + if (kanji1 != 0) + { + if (kanji1 == 2) + { + putj (kanji1_code & 0x7f); + } + putj (*eu & 0x7f); + eusiz -= sizeof (char); + kanji1 = 0; + } + /* ADD KURI end */ + /* + for(oj_mode=ASCII;eusiz>0;eusiz-=sizeof(char)){ + */ + for (; eusiz > 0; eusiz -= sizeof (char)) + { + x = *eu++; + if ((x & 0xFF) == 0x8E) + { + jis_change_mode (&oj_mode, HANKAKU_JIS); + if (eusiz > 1) + { + putj (*eu++ & 0x7f); + eusiz -= sizeof (char); + } + else + { + kanji1 = 1; + } + } + else if (x & 0x80) + { + jis_change_mode (&oj_mode, ZENKAKU_JIS); + if (eusiz > 1) + { + putj (x & 0x7f); + putj (*eu++ & 0x7f); + eusiz -= sizeof (char); + } + else + { + kanji1 = 2; + kanji1_code = x & 0x7f; + } + } + else + { + jis_change_mode (&oj_mode, ASCII); + putj (x); + } + } + if (kanji1 == 0) + jis_change_mode (&oj_mode, ASCII); + return (j - jis); +} +#endif /* JIS7 */ + +/* 外部 U-jis を 8bit jis コードに変換します */ +extern int +eujis_to_jis8 (jis, eujis, eusiz) + unsigned char *jis, *eujis; + int eusiz; +{ + static int kanji1 = 0; + static unsigned char kanji1_code = 0; + /* 0: normal + 1: get SS2 + 2: get kanji 1 byte */ + /* + int oj_mode; + */ + int x; + j = jis; + eu = eujis; + /* ADD KURI */ + if (kanji1 != 0) + { + if (kanji1 == 2) + { + putj (kanji1_code & 0x7f); + putj (*eu & 0x7f); + } + else + { + putj (*eu); + } + eusiz -= sizeof (char); + kanji1 = 0; + eu++; + } + /* ADD KURI end */ + /* + for(oj_mode=ASCII;eusiz>0;eusiz-=sizeof(char)){ + */ + for (; eusiz > 0; eusiz -= sizeof (char)) + { + x = *eu++; + if ((x & 0xFF) == 0x8E) + { + jis_change_mode (&oj_mode, ASCII); + if (eusiz > 1) + { + putj (*eu++); + eusiz -= sizeof (char); + } + else + { + kanji1 = 1; + } + } + else if (x & 0x80) + { + jis_change_mode (&oj_mode, ZENKAKU_JIS); + if (eusiz > 1) + { + putj (x & 0x7f); + putj (*eu++ & 0x7f); + eusiz -= sizeof (char); + } + else + { + kanji1 = 2; + kanji1_code = x; + } + } + else + { + jis_change_mode (&oj_mode, ASCII); + putj (x); + } + } + if (kanji1 == 0) + jis_change_mode (&oj_mode, ASCII); + return (j - jis); +} + +/* 内部 U-jis を 外部 U-jis コードに変換します */ +extern int +iujis_to_eujis (eujis, iujis, iusiz) + unsigned char *eujis; + w_char *iujis; + int iusiz; +{ + static int first = 0; + static unsigned int cswidth_id; + + if (first == 0) + { + cswidth_id = create_cswidth (UJIS_CSWIDTH); + first++; + } + set_cswidth (cswidth_id); + return (ieuc_to_eeuc (eujis, iujis, iusiz)); +} + +int +jis_to_eujis (eujis, jis, jsiz) + unsigned char *eujis, *jis; + int jsiz; +{ + int len; + + designate = JIS_designate; + len = extc_to_intc (tmp_w_buf, jis, jsiz); + return (iujis_to_eujis (eujis, tmp_w_buf, len)); +} + +/* + * Shifted JIS + */ + +/* 外部 U-jis を S-jis コードに変換します + 文字列の長さを返します */ +extern int +eujis_to_sjis (sjis, eujis, eusiz) + unsigned char *sjis; /* sjisコードになったものをおくbuf */ + unsigned char *eujis; /* eujisコードのものをおいてくるbuf */ + int eusiz; /* eujis の大きさ */ +{ + register int x; + int save = 0; + sj = sjis; + eu = eujis; + if (save && eusiz > 0) + { + if (save == 0x8e) + { + putsj (*eu++ | 0x80); + } + else + { + putsjw (jtosj (save & 0x7F, *eu++ & 0x7F)); + } + eusiz--; + } + for (; eusiz > 0;) + { + x = *eu++; + eusiz--; + if (x & 0x80) + { + if (eusiz <= 0) + { + save = x; + break; + } + if (x == 0x8e) + { + putsj (*eu++ | 0x80); + } + else + { + putsjw (jtosj (x & 0x7F, *eu++ & 0x7F)); + } + eusiz--; + } + else + { + putsj (x); + } + } + return (sj - sjis); +} + +/* 内部 U-jis を S-jis コードに変換します + 文字列の長さを返します */ +extern int +iujis_to_sjis (sjis, iujis, iusiz) + unsigned char *sjis; /* sjisコードになったものをおくbuf */ + w_char *iujis; /* iujisコードのものをおいてくるbuf */ + int iusiz; /* iujis の大きさ */ +{ + register int x; + sj = sjis; + iu = iujis; + for (; iusiz > 0; iusiz -= sizeof (w_char)) + { + if ((x = *iu++) & 0xff00) + { + if ((x & 0xff00) == 0x8e00) + { + putsj ((x & 0xff) | 0x80); + } + else + { + putsjw (jtosj ((x >> 8) & 0x7f, x & 0x7f)); + } + } + else + { + putsj (x); + } + } + return (sj - sjis); +} + +int +sjis_to_iujis (iujis, sjis, ssiz) + w_char *iujis; /* iujisコードになったものをおくbuf */ + unsigned char *sjis; /* sjisコードのものをおいてくるbuf */ + int ssiz; /* sjis の大き */ +{ + register int x; + int save = 0; + sj = sjis; + iu = iujis; + if (save && ssiz > 0) + { + *iu++ = (sjtoj (save, *sj++) | 0x8080); + ssiz--; + save = 0; + } + for (; ssiz > 0;) + { + x = *sj++; + ssiz--; + if (x & 0x80) + { + if (ssiz <= 0) + { + save = x; + break; + } + *iu++ = ((sjtoj (x, *sj++)) | 0x8080); + ssiz--; + } + else + { + *iu++ = (x); + } + } + return ((char *) iu - (char *) iujis); +} + +int +sjis_to_eujis (eujis, sjis, ssiz) + unsigned char *eujis; /* eujisコードになったものをおくbuf */ + unsigned char *sjis; /* sjisコードのものをおいてくるbuf */ + int ssiz; /* sjis の大きさ */ +{ + register int x; + unsigned char *sj; + int save = 0; + sj = sjis; + eu = eujis; + if (save && ssiz > 0) + { + x = (sjtoj (save, *sj++) | 0x8080); + puteu (x >> 8); + puteu (x); + ssiz--; + save = 0; + } + for (; ssiz > 0;) + { + x = *sj++; + ssiz--; + if (x & 0x80) + { + if (ssiz <= 0) + { + save = x; + break; + } + x = (sjtoj (x, *sj++) | 0x8080); /* 変えました KUWA */ + puteu (x >> 8); + puteu (x); + ssiz--; + } + else + { + puteu (x); + } + } + return (eu - eujis); +} + +#ifdef JIS7 +int +sjis_to_jis (jis, sjis, siz) + unsigned char *jis, *sjis; + int siz; +{ + int len; + len = sjis_to_eujis (tmp_buf, sjis, siz); + return (eujis_to_jis (jis, tmp_buf, len)); +} +#endif /* JIS7 */ + +int +sjis_to_jis8 (jis, sjis, siz) + unsigned char *jis, *sjis; + int siz; +{ + int len; + len = sjis_to_eujis (tmp_buf, sjis, siz); + return (eujis_to_jis8 (jis, tmp_buf, len)); +} + +int +jis_to_iujis (iujis, jis, jsiz) + w_char *iujis; + unsigned char *jis; + int jsiz; +{ + designate = JIS_designate; + return (extc_to_intc (iujis, jis, jsiz)); +} + +int +jis_to_sjis (sjis, jis, siz) + unsigned char *sjis, *jis; + int siz; +{ + int len; + len = jis_to_iujis (tmp_w_buf, jis, siz); + return (iujis_to_sjis (sjis, tmp_w_buf, len)); +} + +int +eujis_to_iujis (iujis, eujis, eusiz) + w_char *iujis; + unsigned char *eujis; + int eusiz; +{ + static int first = 0; + static unsigned int cswidth_id; + + if (first == 0) + { + cswidth_id = create_cswidth (UJIS_CSWIDTH); + first++; + } + set_cswidth (cswidth_id); + return (eeuc_to_ieuc (iujis, eujis, eusiz)); +} + +#endif /* JAPANESE */ + +#ifdef CHINESE + +#define CNS11643_1 2 +#define CNS11643_2 1 + +/* The following facts are helpful for understanding: + * _W, means Wei in Pinyin + * _Q, means Wei in Pinyin. + * 0x5e = 94, num of wchar in one _Q at 1xxxxxxx 1xxxxxxx hand + * 0x3f = 63, Num of Wchar in one _Q at 1xxxxxxx 0xxxxxxx hand + * Almost all the numbers in HEX are given for showing the _Q or _W +*/ + +#define CNS_NUM_Q 0x5e /* num of wchar in one _Q at hand */ +#define BIG5_NUM_11_Q 0x5e /* num of wchar in one _Q at 1xxxxxxx 1xxxxxxx hand */ +#define BIG5_NUM_10_Q 0x3f /* num of wchar in one _Q at 1xxxxxxx 0xxxxxxx hand */ + +#define CNS_HANZI_11_START_Q 0x24 /* At 1xxxxxxx 1xxxxxxx hand */ +#define CNS_HANZI_11_START_W 0x01 /* At 1xxxxxxx 1xxxxxxx hand */ +#define CNS_HANZI_11_END_Q 0x5D /* At 1xxxxxxx 1xxxxxxx hand */ +#define CNS_HANZI_11_END_W 0x2B /* At 1xxxxxxx 1xxxxxxx hand */ +#define CNS_HANZI_11_START_QM 0x01 /* At 1xxxxxxx 1xxxxxxx hand */ +#define CNS_HANZI_11_END_QM 0x05 /* At 1xxxxxxx 1xxxxxxx hand */ + +#define CNS_HANZI_10_START_Q 0x01 /* At 1xxxxxxx 0xxxxxxx hand */ +#define CNS_HANZI_10_START_W 0x01 /* At 1xxxxxxx 0xxxxxxx hand */ +#define CNS_HANZI_10_END_Q 0x52 /* At 1xxxxxxx 0xxxxxxx hand */ +#define CNS_HANZI_10_END_W 0x24 /* At 1xxxxxxx 0xxxxxxx hand */ + +#define BIG5_HANZI_11_START_Q 0x04 /* At 1xxxxxxx 1xxxxxxx hand */ +#define BIG5_HANZI_11_START_W 0x01 /* At 1xxxxxxx 1xxxxxxx hand */ +#define BIG5_HANZI_11_END_Q 0x25 /* At 1xxxxxxx 1xxxxxxx hand */ +#define BIG5_HANZI_11_END_W 0x5e /* At 1xxxxxxx 1xxxxxxx hand */ +#define BIG5_HANZI_11_START_QM 0x01 /* At 1xxxxxxx 1xxxxxxx hand */ +#define BIG5_HANZI_11_END_QM 0x03 /* At 1xxxxxxx 1xxxxxxx hand */ + +#define BIG5_HANZI_10_START_Q 0x04 /* At 1xxxxxxx 0xxxxxxx hand */ +#define BIG5_HANZI_10_START_W 0x20 /* At 1xxxxxxx 0xxxxxxx hand */ +#define BIG5_HANZI_10_END_Q 0x26 /* At 1xxxxxxx 0xxxxxxx hand */ +#define BIG5_HANZI_10_END_W 0x5e /* At 1xxxxxxx 0xxxxxxx hand */ + +#define BIG5_HANZI_11_START_Q2 0x29 /* At 1xxxxxxx 1xxxxxxx hand */ +#define BIG5_HANZI_11_START_W2 0x01 /* At 1xxxxxxx 1xxxxxxx hand */ +#define BIG5_HANZI_11_END_Q2 0x59 /* At 1xxxxxxx 1xxxxxxx hand */ +#define BIG5_HANZI_11_END_W2 0x35 /* At 1xxxxxxx 1xxxxxxx hand */ + +#define BIG5_HANZI_10_START_Q2 0x29 /* At 1xxxxxxx 0xxxxxxx hand */ +#define BIG5_HANZI_10_START_W2 0x20 /* At 1xxxxxxx 0xxxxxxx hand */ +#define BIG5_HANZI_10_END_Q2 0x59 /* At 1xxxxxxx 0xxxxxxx hand */ +#define BIG5_HANZI_10_END_W2 0x5e /* At 1xxxxxxx 0xxxxxxx hand */ + +#define CNS_SYMBOL_11_START 0 +#define CNS_SYMBOL_11_END 0 +#define BIG5_SYMBOL_10_START 0 +#define BIG5_SYMBOL_10_END 0 +#define BIG5_SYMBOL_11_START 0 +#define BIG5_SYMBOL_11_END 0 + +#define BIG5_TO_CNS 0x0000 /* Flag for convert from BIG5 to CNS */ +#define CNS_TO_BIG5 0x0001 /* Flag for convert from CNS to BIG5 */ + +#define BIG5_1NUMS ((BIG5_NUM_10_Q*0x23)+(BIG5_NUM_11_Q*0x22)) + /* Numbers of level 1 */ +#define BIG5_1TO2_SKIP (0x25*(BIG5_NUM_10_Q+BIG5_NUM_11_Q)) + /*Location of starting level 2 */ + +#define CNS_SPACE 0x256D /* for unconvert character code */ + +/* not sequential character code on CNS level 2 */ +#define CNS_XK 0xa121 /* XK on Tsang Jye */ +#define CNS_ONLN 0xa14c /* ONLN on Tsang Jye */ +#define CNS_MSOK 0xa24d /* MSOK on Tsang Jye */ +#define CNS_TNKM 0xbf6a /* TNKM on Tsang Jye */ +#define CNS_CYIB 0xd54b /* CYIB on Tsang Jye */ +#define CNS_YIHXO 0xda28 /* YIHXO on Tsang Jye */ +#define CNS_MDMR 0xdd74 /* MDMR on Tsang Jye */ +#define CNS_COLH 0xe42f /* COLH on Tsang Jye */ +#define CNS_ODC 0xe761 /* ODC on Tsang Jye */ +#define CNS_OKHAE 0xe934 /* OKHAE on Tsang Jye */ +#define CNS_HBBM 0xe64d /* HBBM on Tsang Jye */ +#define CNS_CJTC 0xea4b /* CJTC on Tsang Jye */ +#define CNS_LNNXU 0xf166 /* LNNXU on Tsang Jye */ +#define CNS_YPYBP 0xf244 /* YPYBP on Tsang Jye */ +#define CNS_FDDH 0xf240 /* FDDH on Tsang Jye */ +#define CNS_HOOMA 0xd722 /* HOOMA on Tsang Jye */ + +/* not sequential character code on BIG5 level 2 */ +#define BIG5_XK 0xc940 /* XK on Tsang Jye */ +#define BIG5_ONLN 0xc9be /* ONLN on Tsang Jye */ +#define BIG5_MSOK 0xcaf7 /* MSOK on Tsang Jye */ +#define BIG5_TNKM 0xd77a /* TNKM on Tsang Jye */ +#define BIG5_CYIB 0xebf1 /* CYIB on Tsang Jye */ +#define BIG5_YIHXO 0xf0cb /* YIHXO on Tsang Jye */ +#define BIG5_MDMR 0xf056 /* MDMR on Tsang Jye */ +#define BIG5_COLH 0xeeeb /* COLH on Tsang Jye */ +#define BIG5_ODC 0xf16b /* ODC on Tsang Jye */ +#define BIG5_OKHAE 0xf268 /* OKHAE on Tsang Jye */ +#define BIG5_HBBM 0xf4b5 /* HBBM on Tsang Jye */ +#define BIG5_CJTC 0xf663 /* CJTC on Tsang Jye */ +#define BIG5_LNNXU 0xf9c4 /* LNNXU on Tsang Jye */ +#define BIG5_YPYBP 0xf9d5 /* YPYBP on Tsang Jye */ +#define BIG5_FDDH 0xf9c6 /* FDDH on Tsang Jye */ +#define BIG5_HOOMA 0xecde /* HOOMA on Tsang Jye */ +#define BIG5_MU 0xc94a /* MU on Tsang Jye */ +#define BIG5_GRHNE 0xddfc /* GRHNE on Tsang Jye */ + +/* This function checks if the given code is really a Hanzi in the original +code definition determined by "which". If so, it returns 1. And otherwise +it returns 0) +*/ +static int +_is_hanzi (code, which) + w_char code; + int which; +{ + register unsigned char high, low; + + if (which == CNS_TO_BIG5) + { + if ((code & 0x8080) == 0x8080) + { /* 1xxxxxxx 1xxxxxxx Case */ + high = (code >> 8) - 0xa0; + low = (code & 0xff) - 0xa0; + if (((high >= CNS_HANZI_11_START_Q && high < CNS_HANZI_11_END_Q) && + (low >= CNS_HANZI_11_START_W && low <= CNS_NUM_Q)) || + ((high == CNS_HANZI_11_END_Q) && + (low >= CNS_HANZI_11_START_W && low <= CNS_HANZI_11_END_W)) || ((high >= CNS_HANZI_11_START_QM && high < CNS_HANZI_11_END_QM) && (low >= CNS_HANZI_11_START_W && low <= CNS_NUM_Q))) + { + return (1); + } + else + { + return (0); + } + } + else if ((code & 0x8080) == 0x8000) + { /* 1xxxxxxx 0xxxxxxx Case */ + high = (code >> 8) - 0xa0; + low = (code & 0xff) - 0x20; + if (((high >= CNS_HANZI_10_START_Q && high < CNS_HANZI_10_END_Q) && + (low >= CNS_HANZI_10_START_W && low <= CNS_NUM_Q)) || ((high == CNS_HANZI_10_END_Q) && (low >= CNS_HANZI_10_START_W && low <= CNS_HANZI_10_END_W))) + { + return (1); + } + else + { + return (0); + } + } + else + { + return (0); + } + } + else if (which == BIG5_TO_CNS) + { + if ((code & 0x8080) == 0x8080) + { /* 1xxxxxxx 1xxxxxxx Case */ + high = (code >> 8) - 0xa0; + low = (code & 0xff) - 0xa0; + if (((high >= BIG5_HANZI_11_START_Q && high <= BIG5_HANZI_11_END_Q) && + (low >= BIG5_HANZI_11_START_W && low <= BIG5_HANZI_11_END_W)) || + ((high >= BIG5_HANZI_11_START_QM && high <= BIG5_HANZI_11_END_QM) && (low >= BIG5_HANZI_11_START_W && low <= BIG5_HANZI_11_END_W))) + { + return (1); + } + else if (((high >= BIG5_HANZI_11_START_Q2 && high < BIG5_HANZI_11_END_Q2) && + (low >= BIG5_HANZI_11_START_W2 && low <= BIG5_HANZI_11_END_W)) || ((high == BIG5_HANZI_11_END_Q2) && (low >= BIG5_HANZI_11_START_W2 && low <= BIG5_HANZI_11_END_W2))) + { + return (1); + } + else + { + return (0); + } + } + else if ((code & 0x8080) == 0x8000) + { /* 1xxxxxxx 0xxxxxxx Case */ + high = (code >> 8) - 0xa0; + low = (code & 0xff) - 0x20; + if ((high >= BIG5_HANZI_10_START_Q && high <= BIG5_HANZI_10_END_Q) && (low >= BIG5_HANZI_10_START_W && low <= BIG5_HANZI_10_END_W)) + { + return (1); + } + else if ((high >= BIG5_HANZI_10_START_Q2 && high <= BIG5_HANZI_10_END_Q2) && (low >= BIG5_HANZI_10_START_W2 && low <= BIG5_HANZI_10_END_W2)) + { + return (1); + } + else + { + return (0); + } + } + else + { + return (0); + } + } + return (0); +} + +/* convert one Hanzi from BIG5 (or CNS) to CNS (or BIG5) depend on the + parameter "which". This function works under the asumpsion that the + give code is really a Hanzi under the original code definition. Given + code value can be checked by function "_is_hanzi()" in the same file. + The result Hanzi code is always returned. +*/ +static unsigned int +_convert (code, which) + register w_char code; + int which; +{ + unsigned int qu, wei; /* counting from 1 ------ */ + register unsigned int location; /* counting from 0 ---- */ + unsigned int loc_wei; /* counting from 0 ---- */ + int plant; + + if (which == CNS_TO_BIG5) + { + if ((code & 0x8080) == 0x8080) + { /* 1xxxxxxx 1xxxxxxx Case */ + if (code <= 0xa5fe && code >= 0xa1a1) + { + wei = (code & 0x7f); + switch (((code & 0xff00) >> 8) - 0xa0) + { + case (1): + if (wei > 0x5f) + { + return (0xa1a1 + (wei - 0x60)); + } + else + { + return (0xa140 + (wei - 0x21)); + } + case (2): + if (wei > 0x5f) + { + return (0xa2a1 + (wei - 0x60)); + } + else + { + return (0xa240 + (wei - 0x21)); + } + case (3): + if (wei > 0x40) + { + return (0xa2a1 + (wei - 0x41)); + } + else + { + return (0xa25f + (wei - 0x21)); + } + case (4): + if (wei > 0x70) + { + return (0xa340 + (wei - 0x71)); + } + else + { + return (0xa2af + (wei - 0x21)); + } + case (5): + if (wei > 0x51) + { + return (0xa3a1 + (wei - 0x52)); + } + else + { + return (0xa34e + (wei - 0x21)); + } + } + } + location = ((code >> 8) - 0xa0 - CNS_HANZI_11_START_Q) * CNS_NUM_Q + (code & 0xff) - 0xa0 - 1; + if ((code > 0xebd0 && code <= 0xefdb) || (code > 0xf5c5 && code <= 0xf7c6) || (code > 0xf8ad && code <= 0xf9e1)) + location--; + else if (code == 0xebd0) + return (0xbe52); + else if (code == 0xf5b5) + return (0xc2cb); + else if (code == 0xf8ad) + return (0xc456); + } + else + { /* 1xxxxxxx 0xxxxxxx Case */ + location = ((code >> 8) - 0xa0 - CNS_HANZI_10_START_Q) * CNS_NUM_Q + (code & 0xff) - 0x20 - 1; + location += BIG5_1TO2_SKIP; + if (code > CNS_YIHXO && code <= 0xdb3e) + location--; + else if ((code >= 0xa12b && code < CNS_ONLN) || + (code >= 0xa17d && code < CNS_MSOK) || + (code >= 0xa439 && code <= 0xb87d) || + (code > CNS_TNKM && code <= 0xc423) || + (code > CNS_CYIB && code < CNS_HOOMA) || + (code >= 0xdc6a && code < CNS_MDMR) || + (code >= 0xe039 && code <= 0xe242) || (code > CNS_OKHAE && code <= 0xe961) || (code > CNS_CJTC && code <= 0xec51) || (code > CNS_LNNXU && code <= 0xf233)) + location++; + else if ((code >= 0xb87e && code < CNS_TNKM) || + (code >= 0xc424 && code < CNS_CYIB) || + (code >= 0xe243 && code <= 0xe336) || + (code > CNS_COLH && code <= 0xe437) || + (code > CNS_ODC && code < CNS_OKHAE) || (code >= 0xe962 && code < CNS_CJTC) || (code >= 0xec52 && code < CNS_LNNXU) || (code == 0xf234) || (code > CNS_FDDH && code <= CNS_YPYBP)) + location += 2; + else if ((code >= 0xe337 && code < CNS_COLH) || (code >= 0xe438 && code <= 0xe572) || (code > CNS_HBBM && code < CNS_ODC) || (code >= 0xf235 && code < CNS_FDDH)) + location += 3; + else if (code >= 0xe573 && code < CNS_HBBM) + location += 4; + else if (code == CNS_ONLN) + return (BIG5_ONLN); + else if (code == CNS_MSOK) + return (BIG5_MSOK); + else if (code == CNS_TNKM) + return (BIG5_TNKM); + else if (code == CNS_CYIB) + return (BIG5_CYIB); + else if (code == CNS_YIHXO) + return (BIG5_YIHXO); + else if (code == CNS_MDMR) + return (BIG5_MDMR); + else if (code == CNS_COLH) + return (BIG5_COLH); + else if (code == CNS_ODC) + return (BIG5_ODC); + else if (code == CNS_OKHAE) + return (BIG5_OKHAE); + else if (code == CNS_HBBM) + return (BIG5_HBBM); + else if (code == CNS_CJTC) + return (BIG5_CJTC); + else if (code == CNS_LNNXU) + return (BIG5_LNNXU); + else if (code == CNS_YPYBP) + return (BIG5_YPYBP); + else if (code == CNS_HOOMA) + return (BIG5_HOOMA); + else if (code == CNS_FDDH) + return (BIG5_FDDH); + } + qu = location / (BIG5_NUM_10_Q + BIG5_NUM_11_Q) + BIG5_HANZI_11_START_Q; + loc_wei = location % (BIG5_NUM_10_Q + BIG5_NUM_11_Q); + + if (loc_wei < BIG5_NUM_10_Q) + { /* 1xxxxxxx 0xxxxxxx Case */ + plant = 0xa020; + wei = loc_wei + BIG5_HANZI_10_START_W; + } + else + { + plant = 0xa0a0; + wei = loc_wei - BIG5_NUM_10_Q + 1; /* 1xxxxxxx 1xxxxxxx Case */ + } + return ((qu << 8) + wei + plant); + } + else if (which == BIG5_TO_CNS) + { + if (code >= 0xa3cd && code <= 0xa140) + { + if (code <= 0xa1bf) + { + if (code & 0x80) + { + return (0xa1e0 + (code - 0xa1a1)); + } + else + { + return (0xa1a1 + (code - 0xa140)); + } + } + else if (code <= 0xa25e) + { + if (code & 0x80) + { + return (0xa2a1 + (code - 0xa1c0)); + } + else + { + return (0xa2e0 + (code - 0xa240)); + } + } + else if (code <= 0xa2ae) + { + if (code & 0x80) + { + return (0xa3c1 + (code - 0xa2a1)); + } + else + { + return (0xa3a1 + (code - 0xa25f)); + } + } + else if (code <= 0xa34e) + { + if (code & 0x80) + { + return (0xa4a1 + (code - 0xa2af)); + } + else + { + return (0xa4f1 + (code - 0xa340)); + } + } + else + { + if (code & 0x80) + { + return (0xa5d2 + (code - 0xa3a1)); + } + else + { + return (0xa5a1 + (code - 0xa34e)); + } + } + } + if ((code & 0x8080) == 0x8080) + { /* 1xxxxxxx 1xxxxxxx Case */ + location = (((code >> 8) - 0xa0 - BIG5_HANZI_11_START_Q) * (BIG5_NUM_10_Q + BIG5_NUM_11_Q) + (code & 0xff) - 0xa0 + BIG5_NUM_10_Q - 1); + + } + else + { /* 1xxxxxxx 0xxxxxxx Case */ + location = (((code >> 8) - 0xa0 - BIG5_HANZI_10_START_Q) * (BIG5_NUM_10_Q + BIG5_NUM_11_Q) + (code & 0xff) - 0x20 - BIG5_HANZI_10_START_W); + } + if (location < BIG5_1NUMS) + { /* 1xxxxxxx 0xxxxxxx Case */ + plant = 0xa0a0; + qu = location / BIG5_NUM_11_Q + CNS_HANZI_11_START_Q; + wei = location % BIG5_NUM_11_Q + CNS_HANZI_11_START_W; + if ((code >= 0xbbc8 && code < 0xbe52) || (code >= 0xc1ab && code < 0xc2cb) || (code >= 0xc361 && code < 0xc456)) + location++; + else if (code == 0xbe52) + return (0xebd0); + else if (code == 0xc2cb) + return (0xf5b5); + else if (code == 0xc456) + return (0xf8ad); + } + else + { /* 1xxxxxxx 1xxxxxxx Case */ + location -= BIG5_1TO2_SKIP; /* For level two */ + if (code >= 0xeb5b && code < BIG5_CYIB) + location++; + else if ((code > BIG5_MU && code <= 0xc96b) || + (code > BIG5_ONLN && code <= 0xc9ec) || + (code > BIG5_MSOK && code < BIG5_TNKM) || + (code >= 0xdba7 && code < BIG5_GRHNE) || + (code >= 0xe8a3 && code <= 0xe975) || + (code > BIG5_HOOMA && code <= 0xeda9) || + (code > BIG5_COLH && code < BIG5_MDMR) || (code >= 0xf466 && code < BIG5_HBBM) || (code >= 0xf4fd && code < BIG5_CJTC) || (code >= 0xf977 && code < BIG5_LNNXU)) + location--; + else if ((code > BIG5_TNKM && code <= 0xdba6) || + (code > BIG5_GRHNE && code <= 0xe8a2) || + (code > BIG5_MDMR && code < BIG5_YIHXO) || + (code >= 0xf163 && code < BIG5_ODC) || + (code >= 0xf375 && code <= 0xf465) || (code > BIG5_HBBM && code <= 0xf4fc) || (code > BIG5_CJTC && code <= 0xf976) || (code == 0xf9c5) || (code >= 0xf9d2 && code <= BIG5_YPYBP)) + location -= 2; + else if ((code > BIG5_YIHXO && code <= 0xf162) || (code > BIG5_ODC && code < BIG5_OKHAE) || (code >= 0xf2c3 && code <= 0xf374) || (code > BIG5_FDDH && code <= 0xf9d1)) + location -= 3; + else if (code > BIG5_OKHAE && code <= 0xf2c2) + location -= 4; + else if (code == BIG5_ONLN) + return (CNS_ONLN); + else if (code == BIG5_MSOK) + return (CNS_MSOK); + else if (code == BIG5_TNKM) + return (CNS_TNKM); + else if (code == BIG5_CYIB) + return (CNS_CYIB); + else if (code == BIG5_YIHXO) + return (CNS_YIHXO); + else if (code == BIG5_MDMR) + return (CNS_MDMR); + else if (code == BIG5_COLH) + return (CNS_COLH); + else if (code == BIG5_ODC) + return (CNS_ODC); + else if (code == BIG5_OKHAE) + return (CNS_OKHAE); + else if (code == BIG5_HBBM) + return (CNS_HBBM); + else if (code == BIG5_CJTC) + return (CNS_CJTC); + else if (code == BIG5_LNNXU) + return (CNS_LNNXU); + else if (code == BIG5_FDDH) + return (CNS_FDDH); + else if (code == BIG5_YPYBP) + return (CNS_YPYBP); + else if (code == BIG5_HOOMA) + return (CNS_HOOMA); + else if (code == BIG5_MU) + return (CNS_SPACE); + else if (code == BIG5_GRHNE) + return (CNS_SPACE); + + plant = 0xa020; + qu = location / BIG5_NUM_11_Q + CNS_HANZI_10_START_Q; + wei = location % BIG5_NUM_11_Q + CNS_HANZI_10_START_W; + } + return ((qu << 8) + wei + plant); + } + return (0); +} + +#ifdef ECNS_IS_UCNS +int +ecns_to_icns (icns, ucns, siz) + w_char *icns; + unsigned char *ucns; + int siz; +{ + register w_char *i = icns; + register unsigned char *u = ucns, *uend = ucns + siz, x; + static w_char local_pending = (w_char) 0; + static unsigned char shift_mode = '\0'; + + if (siz <= 0) + return (0); + if (local_pending) + { + *i = local_pending | (*u++ & 0x7f); + if (shift_mode == SS3) + { + *i++ |= 0x8000; + shift_mode = '\0'; + } + else + { + *i++ |= 0x8080; + } + local_pending = (w_char) 0; + } + if (shift_mode == SS2) + { + *i++ = *u++; + shift_mode = '\0'; + } + for (; u < uend;) + { + x = *u++; + if (x == SS2) + { + if (u == uend) + { + shift_mode = SS2; + break; + } + *i++ = *u++; + break; + } + else if (x == SS3) + { + if (u == uend) + { + shift_mode = SS3; + break; + } + *i = ((*u++ & 0x7f) << 8); + if (u == uend) + { + local_pending = *i; + break; + } + *i |= (*u++ & 0x7f); + *i++ |= 0x8000; + } + else if (x > 0x7f) + { + *i = ((x & 0x7f) << 8); + if (u == uend) + { + local_pending = *i; + break; + } + *i |= (*u++ & 0x7f); + *i++ |= 0x8080; + } + else + { + *i++ = x; + } + } + return ((char *) i - (char *) icns); +} + +int +icns_to_ecns (ucns, icns, siz) + unsigned char *ucns; + w_char *icns; + int siz; +{ + register unsigned char *u = ucns; + register w_char *i = icns, w; + + for (; siz > 0; siz -= sizeof (w_char)) + { + w = *i++; + if (!(w & 0xff80)) + { /* CS0 */ + *u++ = (unsigned char) w; + } + else if (!(w & 0xff00)) + { /* CS2 */ + *u++ = SS2; + *u++ = (unsigned char) w; + } + else if (w & 0x80) + { /* CS1 */ + *u++ = (unsigned char) ((w & 0xff00) >> 8); + *u++ = (unsigned char) (w & 0xff); + } + else + { /* CS3 */ + *u++ = SS3; + *u++ = (unsigned char) ((w & 0xff00) >> 8); + *u++ = (unsigned char) ((w & 0xff) | 0x80); + } + } + return (u - ucns); +} +#else /* ECNS_IS_UCNS */ + +static int oc_mode = ASCII; +static unsigned char *cns; + +static void +putcns (x) + unsigned char x; +{ + *cns++ = x; +} + +static void +cns_change_mode (mode, new_mode) + int *mode; + int new_mode; +{ + if (*mode == new_mode) + return; + switch (*mode = new_mode) + { + case CNS11643_1: + putcns ('\033'); + putcns ('$'); + putcns (')'); + putcns ('0'); + break; + case CNS11643_2: + putcns ('\033'); + putcns ('$'); + putcns ('*'); + putcns ('1'); + break; + case ASCII: + /* designate ISO-8859-1 rather than JIS X 0201 */ + /* putcns('\033'); putcns('('); putcns('J'); break; */ + putcns ('\033'); + putcns ('('); + putcns ('B'); + break; + } +} + +int +ecns_to_icns (icns, ecns, siz) + w_char *icns; + unsigned char *ecns; + int siz; +{ + designate = CNS_designate; + return (extc_to_intc (icns, ecns, siz)); +} + +int +icns_to_ecns (ecns, icns, siz) + unsigned char *ecns; + w_char *icns; + int siz; +{ + register int i = siz; + register w_char *ic, x; + cns = ecns; + + for (; i > 0; i -= sizeof (w_char)) + { + x = *ic++; + if ((x & 0x8080) == 0x8080) + { + cns_change_mode (&oc_mode, CNS11643_1); + putcns ((x >> 8) & 0xff); + putcns (x & 0xff); + } + else if ((x & 0x8000) == 0x8000) + { + cns_change_mode (&oc_mode, CNS11643_2); + putcns (((x >> 8) & 0x7f) | 0x80); + putcns ((x & 0x7f) | 0x80); + } + else + { + cns_change_mode (&oc_mode, ASCII); + putcns (x & 0x7f); + } + } + cns_change_mode (&oc_mode, ASCII); + return (cns - ecns); +} +#endif /* ECNS_IS_UCNS */ + +int +icns_to_big5 (big5, icns, siz) + unsigned char *big5; + w_char *icns; + int siz; +{ + register unsigned char *d = big5; + register w_char *s = icns; + register int i = siz; + short code_out; /* Buffering one two-byte code */ + + if (d == NULL || s == NULL) + return (-1); + + for (; i > 0; i -= sizeof (w_char)) + { + if (!(*s & 0xff00)) + { /* Ascii */ + if (!(*s & 0x80)) + { + *d++ = (unsigned char) (*s++ & 0x7f); + } + else + { /* Single Shift */ + *d++ = SS2; + *d++ = (unsigned char) (*s++ & 0xff); + } + } + else if (_is_hanzi (*s, CNS_TO_BIG5)) + { + code_out = _convert (*s++, CNS_TO_BIG5); + *d++ = (code_out >> 8); + *d++ = code_out & 0x00ff; + } + else + { /* Strainge codes */ + *d++ = (unsigned char) ((*s & 0xff00) >> 8); + *d++ = (unsigned char) (*s++ & 0xff); + } + } + *d = '\0'; + return (d - big5); +} + +int +ecns_to_big5 (big5, ecns, siz) + unsigned char *big5, *ecns; + int siz; +{ + int len; + len = ecns_to_icns (tmp_w_buf, ecns, siz); + return (icns_to_big5 (big5, tmp_w_buf, len)); +} + +int +big5_to_icns (icns, big5, siz) + w_char *icns; + unsigned char *big5; + int siz; +{ + register w_char *d = icns; + register unsigned char *s = big5; + unsigned char *send = s + siz; + unsigned short code_in; /* Buffering one two-byte code */ + + if (d == NULL || s == NULL) + return (-1); + + for (; s < send; s++) + { + if (!(*s & 0x80)) + { /* Ascii */ + *d++ = (w_char) * s; + } + else if (*s == 0x8e) + { /* Single Shift */ + *d++ = (w_char) * (++s); + } + else + { + code_in = ((*s++) << 8); + code_in |= *s; + if (_is_hanzi (code_in, BIG5_TO_CNS)) + { + *d++ = _convert (code_in, BIG5_TO_CNS); + } + else + { /* Strainge codes */ + *d++ = code_in; + } + } + } + *d = (w_char) 0; + return ((char *) d - (char *) icns); +} + +int +big5_to_ecns (ecns, big5, siz) + unsigned char *ecns, *big5; + int siz; +{ + int len; + len = big5_to_icns (tmp_w_buf, big5, siz); + return (icns_to_ecns (ecns, tmp_w_buf, len)); +} + +int +iugb_to_eugb (eugb, iugb, siz) + unsigned char *eugb; + w_char *iugb; + int siz; +{ + static int first = 0; + static unsigned int cswidth_id; + + if (first == 0) + { + cswidth_id = create_cswidth (UGB_CSWIDTH); + first++; + } + set_cswidth (cswidth_id); + return (ieuc_to_eeuc (eugb, iugb, siz)); +} + +int +eugb_to_iugb (iugb, eugb, siz) + w_char *iugb; + unsigned char *eugb; + int siz; +{ + static int first = 0; + static unsigned int cswidth_id; + + if (first == 0) + { + cswidth_id = create_cswidth (UGB_CSWIDTH); + first++; + } + set_cswidth (cswidth_id); + return (eeuc_to_ieuc (iugb, eugb, siz)); +} +#endif /* CHINESE */ + + +#ifdef KOREAN + +#define ZENKAKU_KSC 1 + +static unsigned char *ks; +static w_char *iuk; +static unsigned char *euk; + +static void +putks (x) + int x; +{ + *ks++ = x; +} + +static int oks_mode = ASCII; /* 出力時のKSCコードのモード */ +extern int euksc_to_iuksc (); + +static void +ksc_change_mode (mode, new_mode) + int *mode; + int new_mode; +{ + if (*mode == new_mode) + return; + switch (*mode) + { + case ZENKAKU_KSC: + putks ('\033'); + putks ('('); + putks ('B'); + break; + default:; + } + *mode = new_mode; + switch (new_mode) + { + case ZENKAKU_KSC: + putks ('\033'); + putks ('$'); + putks ('('); + putks ('C'); + break; + default:; + } +} + +/* 内部 U-ksc を ksc コードに変換します + 文字列の長さを返します */ +extern int +iuksc_to_ksc (ksc, iuksc, iusiz) + unsigned char *ksc; /* kscコードになったものをおくbuf */ + w_char *iuksc; /* iukscコードのものをおいてくるbuf */ + int iusiz; /* iuksc の大きさ */ +{ + int x; + ks = ksc; + iuk = iuksc; + for (; iusiz > 0; iusiz -= sizeof (w_char)) + { + x = *iuk++; + if ((x & 0x8080) == 0x8080) + { + ksc_change_mode (&oks_mode, ZENKAKU_KSC); + putks ((x >> 8) & 0x7f); + putks (x & 0x7f); + } + else + { + ksc_change_mode (&oks_mode, ASCII); + putks (x); + } + } + ksc_change_mode (&oks_mode, ASCII); + return (ks - ksc); +} + + +/* 外部 U-ksc を ksc コードに変換します */ +extern int +euksc_to_ksc (ksc, euksc, eusiz) + unsigned char *ksc, *euksc; + int eusiz; +{ + static int kanji1 = 0; + static unsigned char kanji1_code = 0; + /* 0: normal + 1: get SS2 + 2: get kanji 1 byte */ + int x; + ks = ksc; + euk = euksc; + if (kanji1 != 0) + { + if (kanji1 == 2) + { + putks (kanji1_code & 0x7f); + putks (*euk & 0x7f); + } + else + { + putks (*euk); + } + eusiz -= sizeof (char); + kanji1 = 0; + euk++; + } + for (; eusiz > 0; eusiz -= sizeof (char)) + { + x = *euk++; + if (x & 0x80) + { + ksc_change_mode (&oks_mode, ZENKAKU_KSC); + if (eusiz > 1) + { + putks (x & 0x7f); + putks (*euk++ & 0x7f); + eusiz -= sizeof (char); + } + else + { + kanji1 = 2; + kanji1_code = x; + } + } + else + { + ksc_change_mode (&oks_mode, ASCII); + putks (x); + } + } + if (kanji1 == 0) + ksc_change_mode (&oks_mode, ASCII); + return (ks - ksc); +} + +/* 内部 U-ksc を 外部 U-ksc コードに変換します */ +extern int +iuksc_to_euksc (euksc, iuksc, iusiz) + unsigned char *euksc; + w_char *iuksc; + int iusiz; +{ + static int first = 0; + static unsigned int cswidth_id; + + if (first == 0) + { + cswidth_id = create_cswidth (UKSC_CSWIDTH); + first++; + } + set_cswidth (cswidth_id); + return (ieuc_to_eeuc (euksc, iuksc, iusiz)); +} + +int +ksc_to_euksc (euksc, ksc, jsiz) + unsigned char *euksc, *ksc; + int jsiz; +{ + int len; + + designate = KSC_designate; + len = extc_to_intc (tmp_w_buf, ksc, jsiz); + return (iuksc_to_euksc (euksc, tmp_w_buf, len)); +} + +int +ksc_to_iuksc (iuksc, ksc, jsiz) + w_char *iuksc; + unsigned char *ksc; + int jsiz; +{ + designate = KSC_designate; + return (extc_to_intc (iuksc, ksc, jsiz)); +} + +int +euksc_to_iuksc (iuksc, euksc, eusiz) + w_char *iuksc; + unsigned char *euksc; + int eusiz; +{ + static int first = 0; + static unsigned int cswidth_id; + + if (first == 0) + { + cswidth_id = create_cswidth (UKSC_CSWIDTH); + first++; + } + set_cswidth (cswidth_id); + return (eeuc_to_ieuc (iuksc, euksc, eusiz)); +} + +#endif /* KOREAN */