home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Phoenix Heaven Sunny 2
/
APPARE2.BIN
/
oh_towns
/
dic
/
src
/
dic.c
< prev
next >
Wrap
Text File
|
1995-06-20
|
19KB
|
762 lines
/********************************************
CD Dic Search Func
*********************************************/
#include "defs.h"
#include "dic.h"
MULTI *multi_top = NULL;
int index_tab_base = 0;
int index_tab_max = 0;
INDEX *index_ptr = NULL;
int index_max = 0;
int index_total = 0;
INDEX index_buf[INDEX_MAX];
INDTAB index_tab[] = {
{ MK_KANA , NULL }, /* かな検索用INDEX */
{ MK_ALPHA , NULL }, /* 英字検索用INDEX */
{ MK_KANJI , NULL }, /* 漢字検索用INDEX */
{ MK_HYOKI , NULL }, /* 表記形検索用INDEX */
{ MK_KKANA , NULL }, /* 後方一致かな検索用INDEX */
{ MK_KHYOKI, NULL }, /* 後方一致表記形検索用INDEX */
{ MK_KALPHA, NULL }, /* 後方一致英字検索用INDEX */
{ MK_TANGO , NULL }, /* 単語検索用INDEX */
{ MK_CROSS , NULL }, /* 見出し条件CROSS検索用INDEX */
{ MK_ZKANA , NULL }, /* 前方一致かな検索用INDEX */
{ MK_ZHYOKI, NULL }, /* 前方一致表記形検索用INDEX */
{ MK_ZALPHA, NULL }, /* 前方一致英字検索用INDEX */
{ MK_NUMBER, NULL }, /* 項目番号(数字)INDEX */
{ MK_MENU , NULL }, /* メニュ-表示用DATA */
{ MK_COPR , NULL } /* 著作権表示用DATA */
};
#define SER_READ 0
#define SER_INIT 1
#define SER_KOTEI 2
#define SER_KAHEN 3
#define SER_KIHON 4
#define SER_CROSS 5
#define SER_NONTREE 6
#define SER_ERROR 7
static int key_stat = SER_READ;
static ulong key_block = 0L;
static int key_id, key_ent, key_len;
static int key_size, key_flg;
static uchar *key_ptr;
static uchar key_org[COLS_MAX + 2];
static uchar key_buf[COLS_MAX + 2];
POINT title;
POINT honbun;
/********************************************
Makeing Keyword Func
*********************************************/
#define KATA2HIRA(ix) (((ix)->type[0] & 0xC0) == 0x00)
#define LOW2UP(ix) (((ix)->type[0] & 0x30) == 0x00)
#define NO2DEL(ix) (((ix)->type[0] & 0x0C) == 0x00)
#define CYO2BON(ix) (((ix)->type[0] & 0x03) == 0x00)
#define CYO2DEL(ix) (((ix)->type[0] & 0x03) == 0x02)
#define STU2TU(ix) (((ix)->type[1] & 0xC0) == 0x00)
#define SYA2YA(ix) (((ix)->type[1] & 0x30) == 0x00)
#define SAI2AI(ix) (((ix)->type[1] & 0x0C) == 0x00)
#define DAK2SEI(ix) (((ix)->type[1] & 0x03) == 0x00)
#define HDA2SEI(ix) (((ix)->type[2] & 0xC0) == 0x00)
static uchar *make_key(uchar *buf, uchar *str)
{
int n, ch;
int old = 0;
int len = 0;
static struct {
ushort old;
ushort cod;
} daku_tab[] = {
{ 0x002c, 0x002b }, /* が */
{ 0x002e, 0x002d }, /* ぎ */
{ 0x0030, 0x002f }, /* ぐ */
{ 0x0032, 0x0031 }, /* げ */
{ 0x0034, 0x0033 }, /* ご */
{ 0x0036, 0x0035 }, /* ざ */
{ 0x0038, 0x0037 }, /* じ */
{ 0x003a, 0x0039 }, /* ず */
{ 0x003c, 0x003b }, /* ぜ */
{ 0x003e, 0x003d }, /* ぞ */
{ 0x0040, 0x003f }, /* だ */
{ 0x0042, 0x0041 }, /* じ */
{ 0x0045, 0x0044 }, /* ず */
{ 0x0047, 0x0046 }, /* ぜ */
{ 0x0049, 0x0048 }, /* ぞ */
{ 0x0050, 0x004f }, /* ば */
{ 0x0053, 0x0052 }, /* び */
{ 0x0056, 0x0055 }, /* ぶ */
{ 0x0059, 0x0058 }, /* べ */
{ 0x005c, 0x005b }, /* ぼ */
{ 0x0000, 0x0000 }
}, hdaku_tab[] = {
{ 0x0051, 0x004f }, /* ぱ */
{ 0x0054, 0x0052 }, /* ぴ */
{ 0x0057, 0x0055 }, /* ぷ */
{ 0x005a, 0x0058 }, /* ぺ */
{ 0x005d, 0x005b }, /* ぽ */
{ 0x0000, 0x0000 }
};
while ( len < COLS_MAX ) {
ch = *(str++) << 8;
ch |= *(str++);
if ( ch == 0 )
break;
if ( LOW2UP(index_ptr) && ch >= 0x2361 && ch <= 0x237a )/* a-z */
ch -= 0x20;
if ( KATA2HIRA(index_ptr) && ch >= 0x2521 && ch <= 0x2576 )/* ァ-ヶ */
ch = 0x2400 | (ch & 0x00FF);
if ( NO2DEL(index_ptr) &&
(ch == 0x2147 || ch == 0x215D || ch == 0x2126) )
continue; /* ’- ・ */
if ( (ch >= 0x2421 && ch <= 0x2476) ||
(ch >= 0x2521 && ch <= 0x2576) ) {
if ( STU2TU(index_ptr) && (ch == 0x2443 || ch == 0x2543) )
ch++;
if ( SYA2YA(index_ptr) ) {
switch(ch & 0x00FF) {
case 0x0063: /* ゃ */
case 0x0065: /* ゅ */
case 0x0067: /* ょ */
ch++;
break;
}
}
if ( SAI2AI(index_ptr) ) {
switch(ch & 0x00FF) {
case 0x0021: /* ぁ */
case 0x0023: /* ぃ */
case 0x0025: /* ぅ */
case 0x0027: /* ぇ */
case 0x0029: /* ぉ */
ch++;
break;
}
}
if ( DAK2SEI(index_ptr) ) {
for ( n = 0 ; daku_tab[n].old != 0 ; n++ ) {
if ( daku_tab[n].old == (ch & 0x00FF) ) {
ch = (ch & 0xFF00) | daku_tab[n].cod;
break;
}
}
}
if ( HDA2SEI(index_ptr) ) {
for ( n = 0 ; hdaku_tab[n].old != 0 ; n++ ) {
if ( hdaku_tab[n].old == (ch & 0x00FF) ) {
ch = (ch & 0xFF00) | hdaku_tab[n].cod;
break;
}
}
}
}
if ( ch == 0x213c ) { /* ー */
if ( CYO2DEL(index_ptr) )
continue;
else if ( CYO2BON(index_ptr) &&
((old >= 0x2421 && old <= 0x2476) ||
(old >= 0x2521 && old <= 0x2576)) ) {
switch(old & 0x00FF) {
case 0x0022: case 0x002b: case 0x0035: case 0x003f:
case 0x004a: case 0x004f: case 0x005e: case 0x0064:
case 0x0069: case 0x006f:
ch = (old & 0xFF00) | 0x0022; /* あ */
break;
case 0x0024: case 0x002d: case 0x0037: case 0x0041:
case 0x004b: case 0x0052: case 0x005f: case 0x006a:
case 0x0070:
ch = (old & 0xFF00) | 0x0024; /* い */
break;
case 0x0026: case 0x002f: case 0x0039: case 0x0044:
case 0x004c: case 0x0055: case 0x0060: case 0x0066:
case 0x006b:
ch = (old & 0xFF00) | 0x0026; /* う */
break;
case 0x0028: case 0x0031: case 0x003b: case 0x0046:
case 0x004d: case 0x0058: case 0x0061: case 0x006c:
case 0x0071:
ch = (old & 0xFF00) | 0x0028; /* え */
break;
case 0x002a: case 0x0033: case 0x003d: case 0x0048:
case 0x004e: case 0x005b: case 0x0062: case 0x0068:
case 0x006d: case 0x0072:
ch = (old & 0xFF00) | 0x002a; /* お */
break;
case 0x0073:
ch = (old & 0xFF00) | 0x0073; /* ん */
break;
}
}
}
buf[len++] = (uchar)(ch >> 8);
buf[len++] = (uchar)(ch & 0xFF);
old = ch;
}
buf[len++] = '\0';
buf[len++] = '\0';
return buf;
}
static INDEX *key_index(uchar *str)
{
int ch, n;
int now = KEY_NULL;
int zenko = 0;
INDEX *ix;
uchar *top;
uchar *s, *p;
top = str;
zenkou_flag = FALSE;
while ( now != KEY_HYOKI ) {
ch = *(str++) << 8;
ch |= *(str++);
if ( ch == 0 ) {
break;
} else if ( ch == 0x2121 || ch == 0x2147 ||
ch == 0x215D || ch == 0x2126 ) {
continue;
} else if ( now == KEY_NULL && (ch == 0x2177 || ch == 0x215C) ) {
p = str;
for ( n = 0 ; *p != '\0' ; n += 2 )
p += 2;
memcpy(str - 2, str, n);
str -= 2;
str[n] = str[n + 1] = '\0';
if ( ch == 0x2177 && IDX_CROSS != NULL ) /* @ */
return IDX_CROSS;
if ( ch == 0x215C && IDX_TANGO != NULL ) /* + */
return IDX_TANGO;
continue;
} else if ( ch == 0x2176 || ch == 0x2141 ) { /* *~ */
if ( now == KEY_NULL && zenko == 0 ) {
p = str;
for ( n = 0 ; *p != '\0' ; n += 2 )
p += 2;
memcpy(str - 2, str, n);
str -= 2;
str[n] = str[n + 1] = '\0';
zenko = 2;
zenkou_flag = TRUE;
continue;
} else if ( *str == 0 && *(str+1) == 0 ) {
*(str - 2) = *(str - 1) = '\0';
zenko = 1;
zenkou_flag = TRUE;
break;
} else
n = KEY_HYOKI; /* is Hyoki */
} else if ( (ch >= 0x2341 && ch <= 0x235A) || /* A-Z */
(ch >= 0x2361 && ch <= 0x237A) || /* a-z */
(ch >= 0x2621 && ch <= 0x2638) || /* Α-Ω */
(ch >= 0x2641 && ch <= 0x2658) || /* α-ω */
(ch >= 0x2721 && ch <= 0x2741) || /* А-Я */
(ch >= 0x2751 && ch <= 0x2771) || /* а-я */
(ch == 0x2147) ) { /* ’ */
n = KEY_ALPHA; /* is Alpha */
} else if ( (ch >= 0x2421 && ch <= 0x2476) || /* ぁ- */
(ch >= 0x2521 && ch <= 0x2576) || /* ァ-ヶ */
ch == 0x213C || /* ー */
ch == 0x212B || /* ゛ */
ch == 0x212C ) { /* ゜ */
n = KEY_KANA; /* is Kana */
} else if ( ch >= 0x2330 && ch <= 0x2339 ) { /* 0-9 */
n = KEY_NUMBER; /* is Number */
} else if ( ch >= 0x3021 ) { /* 亜 */
n = KEY_KANJI; /* is Kanji */
} else {
n = KEY_HYOKI; /* is Hyoki */
}
switch(now) {
case KEY_NULL: /* Fast */
now = n;
break;
case KEY_NUMBER: /* Kanji */
if ( n != KEY_NUMBER && n != KEY_ALPHA )
now = KEY_HYOKI;
break;
case KEY_ALPHA: /* Alpha */
case KEY_KANA: /* Kana */
case KEY_KANJI: /* Kanji */
if ( now != n )
now = KEY_HYOKI;
break;
case KEY_HYOKI: /* Hyoki */
break;
}
}
switch(now) {
case KEY_ALPHA:
if ( zenko != 0 ) {
if ( zenko == 1 )
ix = IDX_ZALPHA;
else
ix = IDX_KALPHA;
if ( ix == NULL )
ix = IDX_ALPHA;
} else
ix = IDX_ALPHA;
if ( ix == NULL ) {
if ( IDX_ZALPHA != NULL )
ix = IDX_ZALPHA;
else
goto NOINDEX;
}
break;
case KEY_KANA:
if ( zenko != 0 ) {
if ( zenko == 1 )
ix = IDX_ZKANA;
else
ix = IDX_KKANA;
if ( ix == NULL )
ix = IDX_KANA;
} else
ix = IDX_KANA;
if ( ix == NULL ) {
if ( IDX_ZKANA != NULL )
ix = IDX_ZKANA;
else
goto NOINDEX;
}
break;
case KEY_KANJI:
if ( (ix = IDX_KANJI) == NULL )
goto NOINDEX;
break;
case KEY_NUMBER:
if ( (ix = IDX_NUMBER) == NULL )
goto NOINDEX;
break;
NOINDEX:
case KEY_HYOKI:
case KEY_NULL:
if ( zenko != 0 ) {
if ( zenko == 1 )
ix = IDX_ZHYOKI;
else
ix = IDX_KHYOKI;
if ( ix == NULL )
ix = IDX_HYOKI;
} else
ix = IDX_HYOKI;
if ( ix == NULL ) {
if ( IDX_ZHYOKI != NULL )
ix = IDX_ZHYOKI;
else
ix = NULL;
}
break;
}
if ( ix != NULL &&
(ix->id == MK_KALPHA || ix->id == MK_KKANA ||
ix->id == MK_KHYOKI) ) {
s = p = top;
while ( *p != 0 )
p += 2;
p -= 2;
while ( s < p ) {
ch = *s;
*s = *p;
*p = ch;
ch = *(s + 1);
*(s + 1) = *(p + 1);
*(p + 1) = ch;
s += 2;
p -= 2;
}
}
if ( ix != NULL && zenkou_flag != FALSE ) {
switch(ix->id) {
case MK_KKANA: case MK_KHYOKI: case MK_KALPHA:
case MK_ZKANA: case MK_ZHYOKI: case MK_ZALPHA:
break;
default:
zenkou_flag = FALSE;
break;
}
}
return ix;
}
static int reg_exp(register uchar *key, register uchar *idx, int len)
{
int cd;
#ifdef DEBUG
put_jis(key, 256);
printf(" ? ");
put_jis(idx, len);
printf(" %d\n", len);
#endif
for ( ; ; ) {
if ( len == 0 && *key == '\0' )
return 0;
if ( len == 0 )
return 1;
if ( *key == '\0' )
return (zenkou_flag != FALSE ? 0:(-1));
if ( (cd = *key - *idx) != 0 )
return cd;
key++;
idx++;
len--;
}
}
static ulong key_to_number(uchar *str)
{
int ch;
ulong no = 0L;
for ( ; ; ) {
ch = *(str++) << 8;
ch |= *(str++);
if ( ch == 0 || ch < 0x2330 || ch > 0x2339 ) /* 0-9 */
break;
no = no * 10 + (ch - 0x2330);
}
return no;
}
int init_serch(char *str)
{
int n, ch;
int bs, mx;
uchar *p;
bs = index_tab_base;
mx = index_tab_max;
p = str;
n = 0;
for ( ; ; ) {
ch = *(p++) << 8;
ch |= *(p++);
if ( ch < 0x2330 || ch > 0x2339 ) /* 0-9 */
break;
n = n * 10 + (ch - 0x2330);
}
if ( ch == 0x2127 ) { /* : */
if ( multi_select(n) )
return ERR;
str = p;
}
str_word(key_org, str);
if ( (index_ptr = key_index(key_org)) == NULL )
return ERR;
make_key(key_buf, key_org);
if ( ch == 0x2127 )
index_tab_init(bs, mx);
#ifdef DEBUG
put_jis(key_org, 256); putchar('\n');
put_jis(key_buf, 256); putchar('\n');
#endif
key_block = index_ptr->start_block;
if ( (index_ptr->id & 0xF0) >= 0xB0 &&
(index_ptr->id & 0xF0) <= 0xC0 ) {
key_stat = SER_NONTREE;
return FALSE;
}
for ( ; ; ) {
if ( IO_block_read(key_block++) )
return ERR;
key_id = dic_buf[0];
if ( (key_id & 0x80) != 0 ) /* 最下位レベルなら */
break;
key_len = dic_buf[1];
key_ent = toshort(dic_buf + 2);
key_ptr = dic_buf + 4;
if ( key_len == 0 ) /* キ-長固定形式のはず! */
return ERR;
for ( n = 0 ; n < key_ent ; n++ ) {
if ( reg_exp(key_buf, key_ptr, key_len) <= 0 ) {
key_block = tolong(key_ptr + key_len);
break;
}
key_ptr += (key_len + 4);
}
if ( n >= key_ent && (key_id & 0x20) != 0 ) /* 最右端 */
return ERR;
}
key_flg = 1;
key_stat = SER_INIT;
return FALSE;
}
int dic_serch()
{
int mk, cd;
ulong no;
for ( ; ; ) {
LOOP:
#ifdef DEBUG
printf("stat %d\n", key_stat);
#endif
switch(key_stat) {
case SER_READ:
if ( (key_id & 0x20) != 0 || IO_block_read(key_block++) )
return ERR;
key_stat = SER_INIT;
break;
case SER_INIT:
key_id = dic_buf[0];
if ( (key_id & 0x80) == 0 ) /* 最下位レベルでない */
return ERR;
key_len = dic_buf[1];
key_ent = toshort(dic_buf + 2);
key_ptr = dic_buf + 4;
if ( key_len != 0 ) { /* キ-長固定形式 */
key_stat = SER_KOTEI;
} else if ( (key_id & 0x10) == 0 ) { /* キ-長可変 */
key_size = (index_ptr->id == MK_ZHYOKI ||
index_ptr->id == MK_KHYOKI ||
index_ptr->id == MK_ZALPHA ||
index_ptr->id == MK_KALPHA ||
index_ptr->id == MK_NUMBER ) ? 12:6;
key_stat = SER_KAHEN;
} else { /* キ-長可変で基本/集合 */
key_size = (index_ptr->id == MK_ZKANA ||
index_ptr->id == MK_KKANA ) ? 12:6;
key_stat = (index_ptr->id == MK_CROSS ||
index_ptr->id == MK_TANGO ) ? SER_CROSS:SER_KIHON;
}
break;
case SER_KOTEI:
while ( key_ent-- > 0 ) {
if ( (cd = reg_exp(key_buf, key_ptr, key_len)) <= 0 ) {
title.block = 0L;
honbun.block = tolong(key_ptr + key_len);
honbun.offset = toshort(key_ptr + key_len + 4);
key_ptr += (key_len + 6);
return (cd < 0 ? TRUE:FALSE);
}
key_ptr += (key_len + 6);
}
key_stat = SER_READ;
break;
case SER_KAHEN:
while ( key_ent-- > 0 ) {
key_len = *(key_ptr++);
if ( (cd = reg_exp(key_buf, key_ptr, key_len)) <= 0 ) {
if ( key_size == 12 ) {
title.block = tolong(key_ptr + key_len + 6);
title.offset = toshort(key_ptr + key_len + 10);
} else
title.block = 0L;
honbun.block = tolong(key_ptr + key_len);
honbun.offset = toshort(key_ptr + key_len + 4);
key_ptr += (key_len + key_size);
return (cd < 0 ? TRUE:FALSE);
}
key_ptr += (key_len + key_size);
}
key_stat = SER_READ;
break;
case SER_KIHON:
while ( key_ent-- > 0 ) {
mk = *(key_ptr++);
key_len = *(key_ptr++);
if ( mk == 0x00 && key_len == 0x00 ) { /* Null */
if ( IO_block_read(key_block++) )
return ERR;
key_ptr = dic_buf + 4;
key_ent++;
} else if ( mk == 0x00 ) { /* 基本エントリ */
if ( (cd = reg_exp(key_buf, key_ptr, key_len)) <= 0 ) {
if ( key_size == 12 ) {
title.block = tolong(key_ptr + key_len + 6);
title.offset = toshort(key_ptr + key_len + 10);
} else
title.block = 0L;
honbun.block = tolong(key_ptr + key_len);
honbun.offset = toshort(key_ptr + key_len + 4);
key_ptr += (key_len + key_size);
return (cd < 0 ? TRUE:FALSE);
}
key_flg = 1;
key_ptr += (key_len + key_size);
} else if ( mk == 0x80 ) { /* キ-項目 */
/* key_sub = toshort(key_ptr); */
key_ptr += 2;
key_flg = reg_exp(key_buf, key_ptr, key_len);
key_ptr += key_len;
} else if ( mk == 0xC0 ) { /* メンバ項目 */
if ( (key_flg < 0 &&
(cd = reg_exp(key_org, key_ptr, key_len)) <= 0) ||
(key_flg == 0 &&
(cd = reg_exp(key_org, key_ptr, key_len)) == 0) ) {
if ( key_size == 12 ) {
title.block = tolong(key_ptr + key_len + 6);
title.offset = toshort(key_ptr + key_len + 10);
} else
title.block = 0L;
honbun.block = tolong(key_ptr + key_len);
honbun.offset = toshort(key_ptr + key_len + 4);
key_ptr += (key_len + key_size);
return (cd < 0 ? TRUE:FALSE);
}
key_ptr += (key_len + key_size);
} else {
return ERR;
}
}
key_stat = SER_READ;
break;
case SER_CROSS: /* 単語クロス見出し用 */
while ( key_ent-- > 0 ) {
mk = *(key_ptr++);
if ( mk == 0x00 ) { /* 基本エントリ */
if ( (key_len = *(key_ptr++)) == 0 ) {
if ( IO_block_read(key_block++) )
return ERR;
key_ptr = dic_buf + 4;
key_ent++;
continue;
}
if ( (cd = reg_exp(key_buf, key_ptr, key_len)) <= 0 ) {
honbun.block = tolong(key_ptr + key_len);
honbun.offset = toshort(key_ptr + key_len + 4);
title.block = tolong(key_ptr + key_len + 6);
title.offset = toshort(key_ptr + key_len + 10);
key_ptr += (key_len + 12);
return (cd < 0 ? TRUE:FALSE);
}
key_flg = 1;
key_ptr += (key_len + 12);
} else if ( mk == 0x80 ) { /* キ-項目 */
key_len = *(key_ptr++);
/* key_sub = tolong(key_ptr); */
key_ptr += 4;
key_flg = reg_exp(key_buf, key_ptr, key_len);
title.block = tolong(key_ptr + key_len);
title.offset = toshort(key_ptr + key_len + 4);
key_ptr += (key_len + 6);
} else if ( mk == 0xC0 ) { /* メンバ項目 */
if ( key_flg <= 0 ) {
honbun.block = tolong(key_ptr);
honbun.offset = toshort(key_ptr + 4);
key_ptr += 6;
return (key_flg < 0 ? TRUE:FALSE);
}
key_ptr += 6;
} else {
return ERR;
}
}
key_stat = SER_READ;
break;
case SER_NONTREE:
no = key_to_number(key_buf);
if ( IO_block_read(key_block + no / 341L) )
return ERR;
key_ptr = dic_buf + ((no % 341) * 6);
honbun.block = tolong(key_ptr);
honbun.offset = toshort(key_ptr + 4);
title.block = 0L;
key_stat = SER_ERROR;
return FALSE;
case SER_ERROR:
return ERR;
}
}
}