/********************************************

	Low Lib Func

*********************************************/
#include    "defs.h"

static ushort ank_tbl[]={
        0x8140,0x8149,0x8168,0x8194,0x8190,0x8193,0x8195,0x8166,
        0x8169,0x816A,0x8196,0x817B,0x8143,0x817C,0x8144,0x815E,
        0x824F,0x8250,0x8251,0x8252,0x8253,0x8254,0x8255,0x8256,
        0x8257,0x8258,0x8146,0x8147,0x8183,0x8181,0x8184,0x8148,
        0x8197,0x8260,0x8261,0x8262,0x8263,0x8264,0x8265,0x8266,
	0x8267,0x8268,0x8269,0x826A,0x826B,0x826C,0x826D,0x826E,
        0x826F,0x8270,0x8271,0x8272,0x8273,0x8274,0x8275,0x8276,
        0x8277,0x8278,0x8279,0x816D,0x818F,0x816E,0x814F,0x8151,
        0x8166,0x8281,0x8282,0x8283,0x8284,0x8285,0x8286,0x8287,
        0x8288,0x8289,0x828A,0x828B,0x828C,0x828D,0x828E,0x828F,
        0x8290,0x8291,0x8292,0x8293,0x8294,0x8295,0x8296,0x8297,
        0x8298,0x8299,0x829A,0x816F,0x8162,0x8170,0x8150,0x85A1 };
#ifdef	SJIS
static ushort kana_tbl[]={
        0x8140,0x8142,0x8175,0x8176,0x8141,0x8145,0x8392,0x8340,
        0x8342,0x8344,0x8346,0x8348,0x8383,0x8385,0x8387,0x8362,
        0x815B,0x8341,0x8343,0x8345,0x8347,0x8349,0x834A,0x834C,
        0x834E,0x8350,0x8352,0x8354,0x8356,0x8358,0x835A,0x835C,
        0x835E,0x8360,0x8363,0x8365,0x8367,0x8369,0x836A,0x836B,
        0x836C,0x836D,0x836E,0x8371,0x8374,0x8377,0x837A,0x837D,
        0x837E,0x8380,0x8381,0x8382,0x8384,0x8386,0x8388,0x8389,
        0x838A,0x838B,0x838C,0x838D,0x838F,0x8393,0x814A,0x814B };
#endif	/* SJIS */

/********************************************

	short & long Byte Swaping

*********************************************/
int	toshort(uchar *p)
{
    int     n;

    n = *(p++) << 8;
    n |= *p;
    return n;
}
long	tolong(uchar *p)
{
    long    l;

    l  = ((long)(*(p++)) << 24);
    l |= ((long)(*(p++)) << 16);
    l |= ((long)(*(p++)) << 8);
    l |= *p;
    return l;
}
int	iszero(uchar *p, int len)
{
    while ( len-- > 0 && *(p++) == '\0' )
	;
    return (len <= 0 ? TRUE:FALSE);
}
int	htoi(char *p)
{
    int     n = 0;
    int     ch;

    while ( (ch = *(p++)) != '\0' ) {
	ch = toupper(ch);
	if ( ch >= '0' && ch <= '9' )
	    n = n * 16 + (ch - '0');
	else if ( ch >= 'A' && ch <= 'F' )
	    n = n * 16 + (ch - 'A') + 10;
	else
	    break;
    }
    return n;
}
/********************************************

	Kanji Code Conv Func

*********************************************/
int	sjistojis(int cd)
{
    int    hi,lo;

    if ( (cd & 0x8000) == 0 )
	return cd;

    hi = (cd >> 8) & 0xff;
    lo = cd & 0xff;
    hi -= (hi <= 0x9f ? 0x71 : 0xb1);
    hi = hi * 2 +1;
    if ( lo > 0x7f )
        lo--;
    if ( lo >= 0x9e ) {
        lo -= 0x7d;
        hi++;
    }
    else
        lo -= 0x1f;
    return (hi << 8 | lo);
}
int     jistosjis(int cd)
{
    int    hi,lo;

    hi = (cd >> 8) & 0xff;
    lo = cd & 0xff;
    if ( (hi & 1) != 0 )
        lo += 0x1F;
    else
        lo += 0x7D;
    if ( lo >= 0x7F )
        lo++;
    hi = (hi - 0x21 >> 1) + 0x81;
    if ( hi > 0x9F )
        hi += 0x40;
    return (hi << 8 | lo);
}
#ifdef	EUC
int	jistoeuc(int ch)
{
    return (ch | 0x8080);
}
#endif
int	hantozen(int code)
{
    if ( 0x20 <= code && code <= 0x7F )
        return ank_tbl[code - 0x20];
#ifdef	SJIS
    else if ( 0xA0 <= code && code <= 0xDF )
	return kana_tbl[code - 0xA0];
#endif	/* SJIS */
    else
        return 0x8140;
}
int	zentohan(int ch)
{
    int     n;
#ifdef	SJIS
    static ushort hira_tab[] = {
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x82F0,0x829F,
	0x82A1,0x82A3,0x82A5,0x82A7,0x82E1,0x82E3,0x82E5,0x82C1,
	0x0000,0x82A0,0x82A2,0x82A4,0x82A6,0x82A8,0x82A9,0x82AB,
	0x82AD,0x82AF,0x82B1,0x82B3,0x82B5,0x82B7,0x82B9,0x82BB,
	0x82BD,0x82BF,0x82C2,0x82C4,0x82C6,0x82C8,0x82C9,0x82CA,
	0x82CB,0x82CC,0x82CD,0x82D0,0x82D3,0x82D6,0x82D9,0x82DC,
	0x82DD,0x82DE,0x82DF,0x82E0,0x82E2,0x82E4,0x82E6,0x82E7,
	0x82E8,0x82E9,0x82EA,0x82EB,0x82ED,0x82F1,0x0000,0x0000
    };
#endif	/* SJIS */
    static struct {
	ushort		kanji, ank;
    } *cp, cnv_tab[] = {
#ifdef	SJIS
	{ 0x82AA, 0xB6DE },	{ 0x82AC, 0xB7DE },	{ 0x82AE, 0xB8DE },
	{ 0x82B0, 0xB9DE },	{ 0x82B2, 0xBADE },	{ 0x82B4, 0xBBDE },
	{ 0x82B6, 0xBCDE },	{ 0x82B8, 0xBDDE },	{ 0x82BA, 0xBEDE },
	{ 0x82BC, 0xBFDE },	{ 0x82BE, 0xC0DE },	{ 0x82C0, 0xC1DE },
	{ 0x82C3, 0xC2DE },	{ 0x82C5, 0xC3DE },	{ 0x82C7, 0xC4DE },
	{ 0x82CE, 0xCADE },	{ 0x82D1, 0xCBDE },	{ 0x82D4, 0xCCDE },
	{ 0x82D7, 0xCCDE },	{ 0x82DA, 0xCEDE },	{ 0x82F2, 0xDDDE },
	{ 0x834B, 0xB6DE },	{ 0x834D, 0xB7DE },	{ 0x834F, 0xB8DE },
	{ 0x8351, 0xB9DE },	{ 0x8353, 0xBADE },	{ 0x8355, 0xBBDE },
	{ 0x8357, 0xBCDE },	{ 0x8359, 0xBDDE },	{ 0x835B, 0xBEDE },
	{ 0x835D, 0xBFDE },	{ 0x835F, 0xC0DE },	{ 0x8361, 0xC1DE },
	{ 0x8364, 0xC2DE },	{ 0x8366, 0xC3DE },	{ 0x8368, 0xC4DE },
	{ 0x836F, 0xCADE },	{ 0x8372, 0xCBDE },	{ 0x8375, 0xCCDE },
	{ 0x8378, 0xCDDE },	{ 0x837B, 0xCEDE },	{ 0x8394, 0xDDDE },
	{ 0x82CF, 0xCADF },	{ 0x82D2, 0xCBDF },	{ 0x82D5, 0xCCDF },
	{ 0x82D8, 0xCDDF },	{ 0x82DB, 0xCEDF },	{ 0x8370, 0xCADF },
	{ 0x8373, 0xCBDF },	{ 0x8376, 0xCCDF },	{ 0x8379, 0xCDDF },
	{ 0x837C, 0xCEDF },
#endif	/* SJIS */
	{ 0x8160, 0x002D },	{ 0x815C, 0x002D },	{ 0x815D, 0x002D },
	{ 0x0000, 0x0000 }
    };

    for ( n = 0x20 ; n <= 0x7F ; n++ ) {
	if ( ank_tbl[n - 0x20] == ch )
	    return n;
    }
#ifdef	SJIS
    for ( n = 0xA0 ; n <= 0xDF ; n++ ) {
	if ( kana_tbl[n - 0xA0] == ch )
	    return n;
    }
    for ( n = 0xA0 ; n <= 0xDF ; n++ ) {
	if ( hira_tab[n - 0xA0] == ch )
	    return n;
    }
#endif	/* SJIS */
    cp = cnv_tab;
    while ( cp->kanji != 0 ) {
	if ( cp->kanji == ch )
	    return cp->ank;
	cp++;
    }

    return ch;
}
void	str_cnv(uchar *buf, uchar *str, int len)
{
    int     ch;

    while ( len > 0 ) {
	ch  = *(str++) << 8;
	ch |= *(str++);
	if ( ch == 0 || ch < 0x2121 || ch > 0x7F7F )
	    break;
#ifdef	SJIS
	ch = jistosjis(ch);
#endif	/* SJIS */

#ifdef	EUC
	ch = jistoeuc(ch);
#endif
	*(buf++) = ch >> 8;
	*(buf++) = ch & 0xff;
	len -= 2;
    }
    *(buf++) = '\0';
    *(buf++) = '\0';
}
void	put_jis(uchar *str, int len)
{
    int     ch;

    while ( len > 0 ) {
	ch = *(str++) << 8;
	ch |= *(str++);
	if ( ch == 0 || ch < 0x2121 || ch > 0x7F7F )
	    break;
#ifdef	SJIS
	ch = jistosjis(ch);
#endif	/* SJIS */

#ifdef	EUC
	ch = jistoeuc(ch);
#endif
	putchar(ch >> 8);
	putchar(ch & 0xff);
	len -= 2;
    }
}
uchar	*str_jis(uchar *buf, uchar *str)
{
    int     ch;
    int     len = 0;

    while ( len < COLS_MAX && (ch = *(str++)) != '\0' ) {
#ifdef	SJIS
	if ( iskanji(ch) && iskanji2(*str) )
	    ch = (ch << 8) | *(str++);
	else
	    ch = hantozen(ch);

	ch = sjistojis(ch);
#endif	/* SJIS */

#ifdef	EUC
	if ( (ch & 0x80) && (*str & 0x80) )
	    ch = ((ch << 8) | *(str++)) & 0x7F7F;
	else
	    ch = sjistojis(hantozen(ch));
#endif	/* EUC */

/****************
	if ( ch == 0x2121 )
	    continue;
*****************/

	buf[len++] = (uchar)(ch >> 8);
	buf[len++] = (uchar)(ch & 0xFF);
    }

    buf[len++] = '\0';
    buf[len++] = '\0';

    return buf;
}
uchar	*str_word(uchar *buf, uchar *str)
{
    int     ch;

    for ( ; ; ) {
	ch = *str << 8;
	ch |= *(str + 1);
	if ( ch != 0x2121 && ch != 0x2161 )	/*  */
	    break;
	str += 2;
    }

    switch(ch) {
    case 0x215C:		/* { */
    case 0x2177:		/* — */
	*(buf++) = *(str++);
	*(buf++) = *(str++);
	break;
    }

    for ( ; ; ) {
	ch = *str << 8;
	ch |= *(str + 1);
	if ( ch == 0x0000 || ch == 0x2121 || ch == 0x2161 ||
	     ch == 0x215C || ch == 0x2177 )
	    break;
	*(buf++) = *(str++);
	*(buf++) = *(str++);
    }

    *(buf++) = '\0';
    *(buf++) = '\0';

    for ( ; ; ) {
	ch = *str << 8;
	ch |= *(str + 1);
	if ( ch != 0x2121 && ch != 0x2161 )
	    break;
	str += 2;
    }

    return str;
}
char	*strlow(char *str)
{
    register char *p;

    for ( p = str ; *p != '\0' ; p++ )
	*p = tolower(*p);
    return str;
}
char	*skipspc(char *str)
{
    while ( isspace((uchar)*str) || *str == ',' )
	str++;
    return str;
}
char	*skipword(char *str)
{
    while ( !isspace((uchar)*str) && 
		*str != ',' && *str != '\n' && *str != '\0' )
	str++;
    return str;
}
int	strcut(int max, char *av[], char *str)
{
    int    ac = 0;

    while ( ac < max && *str != '\0' ) {
	str = skipspc(str);
	if ( *str == '#' )
	    break;
	else if ( *str == '\"' ) {
	    av[ac++] = ++str;
	    while ( *str != '\"' && *str != '\0' )
		str++;
	    if ( *str != '\"' )
		break;
	    *(str++) = '\0';
	} else if ( *str != '\n' && *str != '\0' ) {
	    av[ac++] = str;
	    str = skipword(str);
	    if ( *str != '\0' )
		*(str++) = '\0';
	}
    }
    return ac;
}
#ifdef	LSIC
char	*strdup(char *str)
{
    register char *p;

    if ( (p = (char *)malloc(strlen(str) + 1)) != NULL )
	strcpy(p, str);
    return p;
}
#endif

static	struct	{
	char	len;
	char	*base;
	char	*conv[4];
	} gobi_tab[] = {
	    {	3,  "ies",	"ie",	"i",	"y",	NULL	},
	    {	2,  "es",	"e",	"",	NULL,	NULL	},
	    {	1,  "s",	"",	NULL,	NULL,	NULL	},
	    {	3,  "ied",	"ie",	"i",	"y",	NULL	},
	    {	2,  "ed",	"e",	"",	NULL,	NULL	},
	    {	4,  "iest",	"ie",	"i",	"y",	NULL	},
	    {	2,  "st",	"",	NULL,	NULL,	NULL	},
	    {	3,  "ier",	"ie",	"i",	"y",	NULL	},
	    {	2,  "er",	"e",	"",	NULL,	NULL	},
	    {	1,  "r",	"",	NULL,	NULL,	NULL	},
	    {	3,  "ing",	"",	"e",	NULL,	NULL	},
	    {	2,  "ly",	"",	"le",	NULL,	NULL	},
	    {	0,  NULL,	NULL,	NULL,	NULL,	NULL	}
	};
static	char	gobi_tmp[COLS_MAX + 2];
static	char	gobi_buf[COLS_MAX + 2];
static	char	*gobi_base = NULL;
static	char	**gobi_pos = NULL;

char	*gobi_conv()
{
    if ( gobi_pos == NULL || *gobi_pos == NULL )
	return NULL;
    strcpy(gobi_base, *(gobi_pos++));
    return str_jis(gobi_buf, gobi_tmp);
}
int	gobi_init(uchar *str)
{
    int ch, len, n;
    char *p;

    for ( len = 0 ; *str != '\0' && len < COLS_MAX ; ) {
	ch = (*(str++) << 8);
	ch |= *(str++);

	if ( ch >= 0x2341 && ch <= 0x235A )
	    gobi_tmp[len++] = ch - 0x2341 + 'a';
	else if ( ch >= 0x2361 && ch <= 0x237A )
	    gobi_tmp[len++] = ch - 0x2361 + 'a';
	else {
	    gobi_tmp[len++] = ch >> 8;
	    gobi_tmp[len++] = (char)ch;
	}
    }
    gobi_tmp[len] = '\0';
    p = &(gobi_tmp[len]);

    for ( n = 0 ; gobi_tab[n].len > 0 ; n++ ) {
	if ( len > gobi_tab[n].len &&
		strcmp(gobi_tab[n].base, p - gobi_tab[n].len) == 0 ) {
	    gobi_pos = gobi_tab[n].conv;
	    gobi_base = p - gobi_tab[n].len;
	    return TRUE;
	}
    }

    return FALSE;
}
