Mercurial > freewnn
diff Wnn/jserver/fzk.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/jserver/fzk.c Thu Dec 13 04:30:14 2007 +0900 @@ -0,0 +1,829 @@ +/* + * $Id: fzk.c,v 1.7 2003/05/11 19:01:06 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, 2003 + * + * 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 + */ + +static char rcs_id[] = "$Id: fzk.c,v 1.7 2003/05/11 19:01:06 hiroo Exp $"; + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#if STDC_HEADERS +# include <stdlib.h> +# include <string.h> +#else +# if HAVE_MALLOC_H +# include <malloc.h> +# endif +#endif /* STDC_HEADERS */ + +#include "commonhd.h" +#include "de_header.h" +#include "fzk.h" +#include "kaiseki.h" + +#define vgetc(pt) ((pt)? getc((pt)):xgetc_cur()) +#define vungetc(k, pt) {if(pt) {ungetc((k),(pt));}else{xungetc_cur(k);}} + +#ifndef NO_FZK +static void link_job (int, struct FT *); +static int fzk_ken (w_char *, w_char *, word_vector *, struct fzkken *); +static int setfzk (struct fzkentry *, struct fzkken **, word_vector *, int); +static struct fzkentry *bsrch (w_char *); +#endif +static int kng_ckvt (word_vector *, int); +static int fzk_ck_vector (word_vector *); +static void fzk_orvt (int *, int *); +static int bittest (int *, int); +static int error_fzk (void); +static int error_eof (void); +static int get_decimal (FILE *); +static int get_hexsa (FILE *); +static int get_string (FILE *, unsigned char *); +static int check_eof (FILE *); + +#ifndef NO_FZK +static int fzkvect_kosuu; /* 付属語ベクタ数 */ +#endif /* NO_FZK */ +static int kango_vect_kosuu; /* 幹語ベクタの数 */ +static int kango_length; /* 幹語数 */ + +/* + * 付属語ファイルのフォーマット + + 付属語の個数 (ft->fzklength) + 接続ベクタの長さ (fzkvect_l) + 付属語ベクタの個数 (fzkvect_kosuu) + 幹語ベクタの長さ (kango_vect_l) V4.0 + 幹語の品詞数 (kango_length) V4.0 + 幹語ベクタの数 (kango_vect_kosuu) V4.0 + + 付属語読み文字列 付属語ベクタ数 + No. 接続ベクタ + … … + 付属語読み文字列 付属語ベクタ数 + No. 接続ベクタ + … … + … … + … + … … + 〜 + + 終端ベクタ + … + … + 〜 + + 幹語接続ベクタNo. 幹語接続ベクタ V4.0 + 幹語接続ベクタ kango_vect_l 付属語接続ベクタ fzk_vect_l + [31,30,...,1][63,62,....32]... + … … + … … + 〜 + + 幹語No. 幹語接続ベクタNo. V4.0 + … … + … … + 〜 + + 疑似品詞No. 幹語接続ベクタNo. 疑似品詞ベクタ (JKTVECT_KOSUU) V4.0 + */ + + +struct FT * +fzk_read (FILE *fp) +{ + struct FT *fzk_tbl; + + fzk_tbl = fzk_ld (fp); + if (fzk_tbl != NULL) + { +#ifndef NO_FZK + link_job (fzk_tbl->fzklength, fzk_tbl); +#endif + } + return (fzk_tbl); +} + +struct FT * +fzk_ld (FILE *fp) +{ + struct FT *fzk_tbl; + int k, l, m; + int vect_count = 0; +#ifndef NO_FZK + struct fzkentry *ptr; + unsigned char charyomi[(YOMI_L + 1) * 2]; + int fzklength; +#endif /* NO_FZK */ + int fzkvect_l; + int kango_vect_l; + +#ifndef NO_FZK + fzklength = get_decimal (fp); /* 付属語の個数 */ +#endif /* NO_FZK */ + fzkvect_l = get_decimal (fp); /* 付属語ベクタの長さ */ +#ifndef NO_FZK + fzkvect_kosuu = get_decimal (fp); /* 付属語ベクタの個数 */ +#endif /* NO_FZK */ + kango_vect_l = get_decimal (fp); /* 幹語ベクタの長さ */ + kango_vect_kosuu = get_decimal (fp); /* 幹語ベクタの個数 */ + kango_length = get_decimal (fp); /* 幹語の品詞数 */ + + if (fzkvect_l > VECT_L) + { + wnn_errorno = WNN_FZK_TOO_DEF; + log_err ("Sorry, your fuzokugo bit data has too many id."); + log_err ("Please change define VECT_L %d and compile again.", fzkvect_l); + return (NULL); + } + + if (kango_vect_l > KANGO_VECT_L) + { + wnn_errorno = WNN_FZK_TOO_DEF; + log_err ("Sorry, your kango bit data has too many id."); + log_err ("Please change define KANGO_VECT_L %d and compile again.", kango_vect_l); + return (NULL); + } + + if (kango_length > KANGO_HINSI_MX) + { + wnn_errorno = WNN_FZK_TOO_DEF; + log_err ("Sorry, your kango bit data has too many id."); + log_err ("Please change define KANGO_MX %d and compile again.", kango_length); + return (NULL); + } + if (kango_vect_kosuu > kango_length) + { + wnn_errorno = WNN_FZK_TOO_DEF; + log_err ("KANGO vector kosuu is more than the number of KANGO hinsi."); + return (NULL); + } + if ((fzk_tbl = (struct FT *) malloc (sizeof (struct FT))) == NULL) + { + wnn_errorno = WNN_MALLOC_ERR; + log_err ("fzk_ld: malloc error."); + return (NULL); + } + /* clear struct */ + bzero (fzk_tbl, sizeof (struct FT)); + + fzk_tbl->kango_hinsi_area = NULL; + fzk_tbl->kango_vect_area = NULL; + fzk_tbl->fzkvect_l = fzkvect_l; + fzk_tbl->kango_vect_l = kango_vect_l; +#ifndef NO_FZK + fzk_tbl->vect_area = NULL; + fzk_tbl->tablefuzokugo = NULL; + fzk_tbl->fzklength = fzklength; + + if ((fzk_tbl->vect_area = (fzkvect *) calloc (fzkvect_kosuu, sizeof (fzkvect))) == NULL) + { + wnn_errorno = WNN_MALLOC_ERR; + log_err ("fzk_ld: malloc error."); + fzk_discard (fzk_tbl); + return (NULL); + } +#endif /* NO_FZK */ + + if ((fzk_tbl->kango_hinsi_area = (int *) calloc (kango_length, sizeof (int))) == NULL) + { + wnn_errorno = WNN_MALLOC_ERR; + error1 ("malloc error in fzk\n"); + fzk_discard (fzk_tbl); + return (NULL); + } + if ((fzk_tbl->kango_vect_area = (word_vector *) calloc ((kango_vect_kosuu + SV_KOSUU), sizeof (word_vector))) == NULL) + { + wnn_errorno = WNN_MALLOC_ERR; + log_err ("fzk_ld: malloc error."); + fzk_discard (fzk_tbl); + return (NULL); + } + +#ifndef NO_FZK + if ((fzk_tbl->tablefuzokugo = (struct fzkentry *) calloc (fzk_tbl->fzklength, sizeof (struct fzkentry))) == NULL) + { + wnn_errorno = WNN_MALLOC_ERR; + log_err ("fzk_ld: malloc error."); + fzk_discard (fzk_tbl); + return (NULL); + } + ptr = fzk_tbl->tablefuzokugo; + + for (m = 0; m < fzk_tbl->fzklength; m++, ptr++) + { + get_string (fp, charyomi); + (void) Sstrcpy (ptr->yomi, charyomi); + ptr->yomi_su = Strlen (ptr->yomi); + ptr->kosu = get_decimal (fp); + ptr->pter = &fzk_tbl->vect_area[vect_count]; + ptr->link = NULL; + for (l = 0; l < ptr->kosu; l++, vect_count++) + { + fzk_tbl->vect_area[vect_count].no = get_decimal (fp); + for (k = 0; k < fzkvect_l; k++) + { + fzk_tbl->vect_area[vect_count].vector[k] = get_hexsa (fp); + } + } + } +#endif /* !NO_FZK */ +/* 終端 vector を SV_KOSUU 個読み取る */ + + for (l = 0; l < SV_KOSUU; l++) + { + for (k = 0; k < fzkvect_l; k++) + { + fzk_tbl->kango_vect_area[l].vector[k] = get_hexsa (fp); + } + } +/* 幹語接続ベクタを読み取る */ + /* 幹語前端接続ベクタNo. - 幹語前端接続ベクタ */ + for (m = 0; m < kango_vect_kosuu; m++) + { + vect_count = get_decimal (fp); + for (k = 0; k < fzkvect_l; k++) + { + fzk_tbl->kango_vect_area[SV_KOSUU + vect_count].vector[k] = get_hexsa (fp); + } + } + /* 幹語品詞No. - 幹語前端接続ベクタNo. */ + for (m = 0; m < kango_length; m++) + { + vect_count = get_decimal (fp); + if ((k = get_decimal (fp)) != -1) + { + fzk_tbl->kango_hinsi_area[vect_count] = SV_KOSUU + k; + } + else + { + fzk_tbl->kango_hinsi_area[vect_count] = -1; + } + } + + if (check_eof (fp) < 0) + { + wnn_errorno = WNN_BAD_FZK_FILE; + return (NULL); + } + + /* 疑似品詞番号を調べる */ +#ifdef nodef + if ((sentou_no = wnn_find_hinsi_by_name (WNN_SENTOU_MEI)) == -1) + { + giji_hinsi_err (WNN_SENTOU_MEI); + return (NULL); + } + if ((suuji_no = wnn_find_hinsi_by_name (WNN_SUUJI_MEI)) == -1) + { + giji_hinsi_err ("SENTOU"); + return (NULL); + } + if ((katakanago_no = wnn_find_hinsi_by_name (WNN_KANA_MEI)) == -1) + { + giji_hinsi_err ("KANA"); + return (NULL); + } + if ((eisuu_no = wnn_find_hinsi_by_name (WNN_EISUU_MEI)) == -1) + { + giji_hinsi_err ("EISUU"); + return (NULL); + } + if ((kigou_no = wnn_find_hinsi_by_name (WNN_KIGOU_MEI)) == -1) + { + giji_hinsi_err ("KIGOU"); + return (NULL); + } + if ((toji_kakko_no = wnn_find_hinsi_by_name (WNN_TOJIKAKKO_MEI)) == -1) + { + giji_hinsi_err ("TOJI_KKAKO"); + return (NULL); + } + if ((fuzokugo_no = wnn_find_hinsi_by_name (WNN_FUZOKUGO_MEI)) == -1) + { + giji_hinsi_err ("FUZOKUGO"); + return (NULL); + } + if ((kai_kakko_no = wnn_find_hinsi_by_name (WNN_KAIKKAKO_MEI)) == -1) + { + giji_hinsi_err ("KAIKAKKO"); + return (NULL); + } + if ((giji_no = wnn_find_hinsi_by_name (WNN_GIJI_MEI)) == -1) + { + giji_hinsi_err ("GIJI"); + return (NULL); + } +#endif /* nodef */ + return (fzk_tbl); +} + +#ifdef nodef +void +giji_hinsi_err (char *str) +{ + wnn_errorno = WNN_GIJI_HINSI_ERR; + log_err ("GIJI hinsi (%s) is not defined in hinsi data file.", str); +} +#endif /* nodef */ + +void +fzk_discard (struct FT *fzk_tbl) +{ + if (fzk_tbl->kango_hinsi_area != NULL) + free (fzk_tbl->kango_hinsi_area); + if (fzk_tbl->kango_vect_area != NULL) + free (fzk_tbl->kango_vect_area); +#ifndef NO_FZK + if (fzk_tbl->vect_area != NULL) + free (fzk_tbl->vect_area); + if (fzk_tbl->tablefuzokugo != NULL) + free (fzk_tbl->tablefuzokugo); +#endif + free (fzk_tbl); +} + +#ifndef NO_FZK +static void +link_job (int x, struct FT *fzk_tbl) +{ + int n; + struct fzkentry *pter_a, *pter_b; + + for (pter_a = fzk_tbl->tablefuzokugo, x--, n = 0; n < x; n++, pter_a++) + { + for (pter_b = pter_a + 1; pter_b <= fzk_tbl->tablefuzokugo + x && Strncmp (pter_a->yomi, pter_b->yomi, pter_a->yomi_su) == 0; pter_b++) + pter_b->link = pter_a; + } +} +#endif + + +/* + * fzk_kai : fuzokugo kaiseki + */ + +int +fzk_kai (w_char *start, /* string start pointer */ + w_char *end, /* string end pointer */ + int syuutan_vect, /* 文節終端 vector */ + int syuutan_vect1, /* 文節終端 vector 1 */ + struct ICHBNP **ichbnp_p) /* ich-bunpou area 付属語候補 set pointer pointer */ +{ +#ifndef NO_FZK + static word_vector fzkwk[STRK_L + 1]; /* 付属語解析 work area */ + static word_vector fzkwk1[STRK_L + 1]; /* 付属語解析 work area */ + static int maxpoint = STRK_L; + + struct fzkken fzkinf[YOMI_L + 1]; /* 検索 work area */ + struct fzkken fzkinf1[YOMI_L + 1]; /* 検索 work area */ + struct fzkken *fzkinfp; + struct ICHBNP *ichbnptr = NULL; + struct ICHBNP *wkptr = NULL; + + int point; /* index */ + int i, j; /* work index */ + int cnt, n; /* counter */ + word_vector *endvect; /* 文節終端 vector pointer */ + word_vector *endvect1; /* 文節終端 vector 1 */ + + int fzkvect_l = ft->fzkvect_l; + int kango_vect_l = ft->kango_vect_l; + + endvect = (word_vector *) ft->kango_vect_area + syuutan_vect; + if (syuutan_vect1 != WNN_VECT_NO) + endvect1 = (word_vector *) ft->kango_vect_area + syuutan_vect1; + else + endvect1 = NULL; + + /* + * initialize + */ + for (i = maxpoint; i >= 0; i--) + { + for (j = VECT_L - 1; j >= 0; j--) + { + fzkwk[i].vector[j] = 0; + fzkwk1[i].vector[j] = 0; + } + } + maxpoint = 0; + for (j = 0; j < fzkvect_l; j++) + { + fzkwk[0].vector[j] = endvect->vector[j]; + if (endvect1 != 0) + fzkwk1[0].vector[j] = endvect1->vector[j]; + } + /* + * 付属語解析 + */ + + for (point = 0; point <= maxpoint; point++) + { + if (point > STRK_L) + { + wnn_errorno = WNN_WKAREA_FULL; + log_err ("fzk_kai: fuzokugo-kaiseki area is full."); + return (-1); + } + if (fzk_ck_vector (&fzkwk[point])) + { + /* 付属語検索 vector */ + fzk_ken (start + point, end, &fzkwk[point], &fzkinf[0]); + for (fzkinfp = &fzkinf[0]; fzkinfp->ent_ptr; fzkinfp++) + { + n = (fzkinfp->ent_ptr)->yomi_su; + fzk_orvt (fzkwk[point + n].vector, fzkinfp->vector); + maxpoint = (maxpoint < point + n) ? point + n : maxpoint; + } + } + if (fzk_ck_vector (&fzkwk1[point])) + { + /* 付属語検索 vector 1 */ + fzk_ken (start + point, end, &fzkwk1[point], &fzkinf1[0]); + for (fzkinfp = &fzkinf1[0]; fzkinfp->ent_ptr; fzkinfp++) + { + n = (fzkinfp->ent_ptr)->yomi_su; + fzk_orvt (fzkwk1[point + n].vector, fzkinfp->vector); + maxpoint = (maxpoint < point + n) ? point + n : maxpoint; + } + } + } + + + /* + * 付属語候補 set + */ + for (point = cnt = 0, *ichbnp_p = NULL; point <= maxpoint; point++) + { + if (kng_ckvt (&fzkwk[point], kango_vect_l) || + kng_ckvt (&fzkwk1[point], kango_vect_l)) + { + if (!(n = cnt % FZKIBNO)) + { + if ((wkptr = getibsp ()) == NULL) + { + if (*ichbnp_p != NULL) + (void) freeibsp (*ichbnp_p); + *ichbnp_p = NULL; + log_err ("fzk_kai: error."); + return (-1); + } + else + { + if (*ichbnp_p == NULL) + *ichbnp_p = wkptr; + else + ichbnptr->next_p = wkptr; + ichbnptr = wkptr; + } + } + ichbnptr->fzkib[n].offset = point; + for (i = 0; i < kango_vect_l; i++) + { + ichbnptr->fzkib[n].vector[i] = fzkwk[point].vector[i]; + ichbnptr->fzkib1[n].vector[i] = fzkwk1[point].vector[i]; + } + cnt++; + } + } + return (cnt); +#else /* NO_FZK */ + struct ICHBNP *wkptr; + + int i; /* work index */ + word_vector *endvect; /* 文節終端 vector pointer */ + word_vector *endvect1; /* 文節終端 vector 1 */ + + int kango_vect_l = ft->kango_vect_l; + + endvect = (word_vector *) ft->kango_vect_area + syuutan_vect; + if (syuutan_vect1 != WNN_VECT_NO) + endvect1 = (word_vector *) ft->kango_vect_area + syuutan_vect1; + else + endvect1 = NULL; + + *ichbnp_p = NULL; + if (kng_ckvt (endvect, kango_vect_l) || kng_ckvt (endvect1, kango_vect_l)) + { + if ((wkptr = getibsp ()) == NULL) + { + log_err ("fzk_kai: error."); + return (-1); + } + else + { + *ichbnp_p = wkptr; + } + wkptr->fzkib[0].offset = 0; + for (i = 0; i < kango_vect_l; i++) + { + wkptr->fzkib[0].vector[i] = endvect->vector[i]; + if (endvect1 != NULL) + wkptr->fzkib1[0].vector[i] = endvect1->vector[i]; + } + } + return (1); +#endif /* NO_FZK */ +} + + +/* + * kng_ckvt 幹語ベクタのチェック V4.0 + */ + +static int +kng_ckvt (word_vector *wv, int kango_vect_l) +{ + int i, rts; + int *v = wv->vector; + + for (rts = 0, i = kango_vect_l; i > 0; i--) + rts |= *v++; /* OR cheak */ + return (rts); +} + + +/* + * fzk_ckvt + */ +int +fzk_ckvt (int vector) +{ + return vector >= 0 && + fzk_ck_vector (&ft->kango_vect_area[vector]); +} + + +static int +fzk_ck_vector (word_vector *wv) +{ + int i, rts; + int *v = wv->vector; + + rts = *v++ & ~0x01; /* 「先頭可」のビットを除く */ + for (i = ft->fzkvect_l - 1; i > 0; i--) + rts |= *v++; /* OR cheak */ + return (rts); +} + + +/* + * fzk_orvt + */ + +static void +fzk_orvt (int *vector1, int *vector2) +{ + int i; + + for (i = ft->fzkvect_l; i > 0; i--) + *vector1++ |= *vector2++; /* OR set */ +} + +#ifndef NO_FZK +static int +fzk_ken (w_char *start, w_char *end, word_vector *wv, struct fzkken *fzkptr) +{ + int yomicnt; + int setno; + struct fzkken *ansptr; + struct fzkentry *search_ptr; + w_char key[YOMI_L + 1]; + int fzkvect_l = ft->fzkvect_l; + + ansptr = fzkptr; + for (yomicnt = end - start; yomicnt < YOMI_L; key[yomicnt++] = 0) + ; + for (yomicnt = 0; (yomicnt < YOMI_L) && (start < end); key[yomicnt++] = *start++) + ; + key[yomicnt] = 0; + for (; yomicnt > 0; key[--yomicnt] = NULL) + { + search_ptr = (struct fzkentry *) bsrch (key); + if (search_ptr != NULL) + { + setno = setfzk (search_ptr, &ansptr, wv, fzkvect_l); + ansptr->ent_ptr = NULL; + return (setno); + } + } + fzkptr->ent_ptr = NULL; + return (NO); +} + +/******************************************/ +static int +setfzk (struct fzkentry *entry_ptr, + struct fzkken **answer_ptr, + word_vector *wv, + int fzkvect_l) +{ + int setno; + int vectroop; + int wcnt, setflg; + fzkvect *vect_ptr; + + if (entry_ptr != NULL) + { + setno = setfzk (entry_ptr->link, answer_ptr, wv, fzkvect_l); + for (wcnt = 0; wcnt < fzkvect_l; (*answer_ptr)->vector[wcnt++] = 0); + setflg = 0; + for (vectroop = entry_ptr->kosu, vect_ptr = entry_ptr->pter; vectroop > 0; vectroop--, vect_ptr++) + { + if (bittest (wv->vector, vect_ptr->no) > 0) + { + setflg = 1; + for (wcnt = 0; wcnt < fzkvect_l; wcnt++) + (*answer_ptr)->vector[wcnt] |= vect_ptr->vector[wcnt]; + } + } + if (setflg != 0) + { + (*answer_ptr)->ent_ptr = entry_ptr; + (*answer_ptr)++; + return (setno + 1); + } + else + return (setno); + } + else + return (0); +} +#endif /* NO_FZK */ + +/***************************************************/ +static int +bittest (int vector[], int no) +{ + int wvect; + + wvect = vector[no / (sizeof (int) * 8)]; + wvect >>= (int) (no % (sizeof (int) * 8)); + if ((wvect & 0x00000001) == 1) + return (1); + else + return (-1); +} + +/* +int Strncmp(w_char *s1, w_char *s2, int n) +{ + if(n == 0)return(0); + for (;n > 0 && *s1++ == *s2++;n--); + return (int)(*--s1 - *--s2); +} +*/ + +#ifndef NO_FZK +static struct fzkentry * +bsrch (w_char *key_yomi) +{ + int low, high, j, flg; + + for (low = 0, high = ft->fzklength; low < high;) + { + j = (high + low) >> 1; + /* + flg = Strncmp(key_yomi, (ft->tablefuzokugo + j)->yomi, YOMI_L); + */ + { + int n; + w_char *s1, *s2; + s1 = key_yomi; + s2 = (ft->tablefuzokugo + j)->yomi; + for (n = YOMI_L; n > 0 && *s1++ == *s2++; n--); + flg = (int) (*--s1 - *--s2); + } + if (flg > 0) + low = j + 1; + else if (flg < 0) + high = j; + else + return (ft->tablefuzokugo + j); + } + return (0); +} +#endif + +static int +error_fzk (void) +{ + wnn_errorno = WNN_NOT_FZK_FILE; + log_err ("Bad format in fzk_file."); + return (-1); +} + +static int +error_eof (void) +{ + wnn_errorno = WNN_NOT_FZK_FILE; + log_err ("Unecpected EOF in reading fzk_file."); + return (-1); +} + +static int +get_decimal (FILE *fp) +{ + unsigned char buf[24]; + int k; + if (get_string (fp, buf) == EOF) + { + return (error_eof ()); + } + if (sscanf ((char *) buf, "%d", &k) != 1) + { + return (error_fzk ()); + } + return (k); +} + +static int +get_hexsa (FILE *fp) +{ + unsigned char buf[24]; + int k; + if (get_string (fp, buf) == EOF) + { + return (error_eof ()); + } + if (sscanf ((char *) buf, "%x", &k) != 1) + { + return (error_fzk ()); + } + return (k); +} + +static int +get_string (FILE *fp, unsigned char *buf) +{ + unsigned char *c = buf; + int k; + for (; (k = vgetc (fp)) == ';' || k == '\n' || k == '\t' || k == ' ';) + { + if (k == ';') + { + for (; (k = vgetc (fp)) != '\n';) + { + if (k == EOF) + { + return (EOF); + } + } + } + } + if (k == EOF) + { + return (EOF); + } + vungetc (k, fp); + for (; (k = vgetc (fp)) != ';' && k != '\n' && k != '\t' && k != ' ' && k != EOF;) + { + *c++ = k; + } + *c = '\0'; + return (0); /* not EOF */ +} + +static int +check_eof (FILE *fp) +{ + unsigned char buf[24]; + if (get_string (fp, buf) != EOF) + { + wnn_errorno = WNN_NOT_FZK_FILE; + log_err ("Not at the end of fzk_file."); + return (-1); + } + return (0); +} +