/*
 */

/*
WNN7 CLIENT LIBRARY--SOFTWARE LICENSE TERMS AND CONDITIONS


Wnn7 Client Library :
(C) Copyright OMRON Corporation.       1995,1998,2000,2001 all rights reserved.
(C) Copyright OMRON Software Co., Ltd. 1995,1998,2000,2001 all rights reserved.

Wnn Software :
(C) Copyright Kyoto University Research Institute for Mathematical Sciences
     1987, 1988, 1989, 1990, 1991, 1992, 1993
(C) Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1993
(C) Copyright ASCTEC, Inc.  1987, 1988, 1989, 1990, 1991, 1992, 1993

Preamble

These Wnn7 Client Library--Software License Terms and Conditions
 (the "License Agreement") shall state the conditions under which you are
 permitted to copy, distribute or modify the software which can be used
 to create Wnn7 Client Library (the "Wnn7 Client Library").  The License
 Agreement can be freely copied and distributed verbatim, however, you
 shall NOT add, delete or change anything on the License Agreement.

OMRON Corporation and OMRON Software Co., Ltd. (collectively referred to
 as "OMRON") jointly developed the Wnn7 Software (development code name
 is FI-Wnn), based on the Wnn Software.  Starting from November, 1st, 1998,
 OMRON publishes the source code of the Wnn7 Client Library, and OMRON
 permits anyone to copy, distribute or change the Wnn7 Client Library under
 the License Agreement.

Wnn7 Client Library is based on the original version of Wnn developed by
 Kyoto University Research Institute for Mathematical Sciences (KURIMS),
 OMRON Corporation and ASTEC Inc.

Article 1.  Definition.

"Source Code" means the embodiment of the computer code, readable and
 understandable by a programmer of ordinary skills.  It includes related
 source code level system documentation, comments and procedural code.

"Object File" means a file, in substantially binary form, which is directly
 executable by a computer after linking applicable files.

"Library" means a file, composed of several Object Files, which is directly
 executable by a computer after linking applicable files.

"Software" means a set of Source Code including information on its use.

"Wnn7 Client Library" the computer program, originally supplied by OMRON,
 which can be used to create Wnn7 Client Library.

"Executable Module" means a file, created after linking Object Files or
 Library, which is directly executable by a computer.

"User" means anyone who uses the Wnn7 Client Library under the License
 Agreement.

Article 2.  Copyright

2.1  OMRON Corporation and OMRON Software Co., Ltd. jointly own the Wnn7
 Client Library, including, without limitation, its copyright.

2.2  Following words followed by the above copyright notices appear
 in all supporting documentation of software based on Wnn7 Client Library:

  This software is based on the original version of Wnn7 Client Library
  developed by OMRON Corporation and OMRON Software Co., Ltd. and also based on
  the original version of Wnn developed by Kyoto University Research Institute
  for Mathematical Sciences (KURIMS), OMRON Corporation and ASTEC Inc.

Article 3.  Grant

3.1  A User is permitted to make and distribute verbatim copies of
 the Wnn7 Client Library, including verbatim of copies of the License
 Agreement, under the License Agreement.

3.2  A User is permitted to modify the Wnn7 Client Library to create
 Software ("Modified Software") under the License Agreement.  A User
 is also permitted to make or distribute copies of Modified Software,
 including verbatim copies of the License Agreement with the following
 information.  Upon modifying the Wnn7 Client Library, a User MUST insert
 comments--stating the name of the User, the reason for the modifications,
 the date of the modifications, additional terms and conditions on the
 part of the modifications if there is any, and potential risks of using
 the Modified Software if they are known--right after the end of the
 License Agreement (or the last comment, if comments are inserted already).

3.3  A User is permitted to create Library or Executable Modules by
 modifying the Wnn7 Client Library in whole or in part under the License
 Agreement.  A User is also permitted to make or distribute copies of
 Library or Executable Modules with verbatim copies of the License
 Agreement under the License Agreement.  Upon modifying the Wnn7 Client
 Library for creating Library or Executable Modules, except for porting
 a computer, a User MUST add a text file to a package of the Wnn7 Client
 Library, providing information on the name of the User, the reason for
 the modifications, the date of the modifications, additional terms and
 conditions on the part of the modifications if there is any, and potential
 risks associated with using the modified Wnn7 Client Library, Library or
 Executable Modules if they are known.

3.4  A User is permitted to incorporate the Wnn7 Client Library in whole
 or in part into another Software, although its license terms and
 conditions may be different from the License Agreement, if such
 incorporation or use associated with the incorporation does NOT violate
 the License Agreement.

Article 4. Warranty

THE WNN7 CLIENT LIBRARY IS PROVIDED BY OMRON ON AN "AS IS" BAISIS.
  OMRON EXPRESSLY DISLCIAMS ANY AND ALL WRRANTIES, EXPRESS OR IMPLIED,
 INCLUDING, WITHOUT LIMITATION, WARRANTIES OF MERCHANTABILITY AND FITNESS
 FOR A PARTICULAR PURPOSE, IN CONNECTION WITH THE WNN7 CLIENT LIBRARY
 OR THE USE OR OTHER DEALING IN THE WNN7 CLIENT LIBRARY.  IN NO EVENT
 SHALL OMRON BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, PUNITIVE
 OR CONSEQUENTIAL DAMAGES OF ANY KIND WHATSOEVER IN CONNECTION WITH THE
 WNN7 CLIENT LIBRARY OR THE USE OR OTHER DEALING IN THE WNN7 CLIENT
LIBRARY.

***************************************************************************
Wnn7 Client Library :
(C) Copyright OMRON Corporation.       1995,1998,2000,2001 all rights reserved.
(C) Copyright OMRON Software Co., Ltd. 1995,1998,2000,2001 all rights reserved.

Wnn Software :
(C) Copyright Kyoto University Research Institute for Mathematical Sciences
     1987, 1988, 1989, 1990, 1991, 1992, 1993
(C) Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1993
(C) Copyright ASCTEC, Inc.  1987, 1988, 1989, 1990, 1991, 1992, 1993
***************************************************************************

Comments on Modifications:
*/

/*	Version 4.0
*/
/*      品詞ファイルの構造に関する定義
*/

#include <stdio.h>
#include "commonhd.h"
#include "config.h"
#include "wnnerror.h"
#include "jslib.h"
#include "wnn_os.h"
#include "wnn_string.h"
#include "hinsi_file.h"


/*
      wnn_loadhinsi(NULL)			 品詞の情報を読み込む 
      
      wnn_find_hinsi_by_name(c)		 名前を与えて、品詞番号を取る 
      char *c;
      
      char *wnn_get_hinsi_name(k)	 品詞番号から名前を取る 
      int k;
      
      int
      wnn_get_fukugou_component(k,str, )  複合品詞に対して 構成要素を求める 
      int k;			      構成要素の個数が返値として返され、
      unsigned short **str;	      構成要素は str 以降に返される。
      
      */

/*    extern int wnn_errorno;   */

/*
 *here start the real program 
 */

#define SIZE 1024

int wnnerror_hinsi;
static int hinsi_loaded = 0;
static int line_no = 0;

static int find_hinsi_by_name(w_char *c);
static w_char * get_hinsi_name(int k);

static w_char heap[HEAP_LEN];
static w_char *hp = heap;
static unsigned short wheap[WHEAP_LEN];
static unsigned short *whp = wheap;
static w_char *hinsi[MAXHINSI];
static struct wnn_fukugou fukugou[MAXFUKUGOU];
static struct wnn_hinsi_node node[MAXNODE];

int mhinsi = 0;
int mfukugou = 0;
int mnode = 0;

#if !defined(DSERVER) && defined(JSERVER)
extern char hinsi_file_name[];
#endif /* !DSERVER && JSERVER */

static void
error_long()
{
	wnnerror_hinsi = WNN_TOO_LONG_HINSI_FILE_LINE;
}

static void
error_no_heap()
{
	wnnerror_hinsi = WNN_TOO_BIG_HINSI_FILE;
}

static int
get_char0(fp)
FILE *fp;
{
	int c,d;

	for(;(c = getc(fp)) == COMMENT_CHAR || c == CONTINUE_CHAR ||
	    c == IGNORE_CHAR1 || c == IGNORE_CHAR2;){
		if(c == CONTINUE_CHAR){
			if((d = getc(fp))== EOF){
				break;
			}
			if(d == '\n'){
				line_no += 1;
				continue;
			} else{
				ungetc(d,fp);
				break;
			}
		} else if(c == COMMENT_CHAR){
			for(;;){
				if((c = getc(fp))== EOF){
					return(EOF);
				}
				if(c == '\n'){
					ungetc(c,fp);
					line_no += 1;
					break;
				}
			}
		}
	}
	if(c == '\n')line_no += 1;
	return(c);
}

static int
get_char(fp) /* remove null lines */
FILE *fp;
{
	int d;
	static int cucucu = -1;
	static int fufufu = 0;

	if (cucucu != -1){
		d = cucucu;
		cucucu = -1;
		return(d);
	}
	if (fufufu == 0) {  /* remove all new lines in the head of the file */
		for(;(d = get_char0(fp)) == '\n';);
		fufufu = 1;
	} else {
		d = get_char0(fp);
	}
	if (d == '\n') {
		while((cucucu = get_char0(fp)) == '\n');
	}
	return(d);
}

/* get one phrase and return the separater */
static int
get_phrase(s0,size,fp)
UCHAR *s0;
int size;
FILE *fp;
{
	UCHAR *s = s0;
	int c;
	static int eof = 0;

	if(eof){
		*s0 = 0;
		return(EOF);
	}

#if defined(JSERVER) && !defined(DSERVER)
	if(fp) {
#endif /* JSERVER && !DSERVER */
		while(((c = get_char(fp)) != '\n') &&
			(c != DEVIDE_CHAR) &&
			(c != NODE_CHAR) &&
			(c != HINSI_SEPARATE_CHAR) &&
			(c != EOF)
			){
			if(s - s0 >= size){
				error_long();
				return(HINSI_ERR);
			}
			*s++ = c;
		}
#if defined(JSERVER) && !defined(DSERVER)
	} else {
		while(((c = get4com()) != '\n') &&
			(c != DEVIDE_CHAR) &&
			(c != NODE_CHAR) &&
			(c != HINSI_SEPARATE_CHAR) &&
			(c != EOF)
			){
			if(s - s0 >= size){
				error_long();
				return(HINSI_ERR);
			}
			*s++ = c;
		}
	}
#endif /* JSERVER && !DSERVER */

	if(c == EOF) eof = 1;
	if(s - s0 >= size - 1){
		error_long();
		return(HINSI_ERR);
	}
	*s++ = '\0';
	return(c);
}

static int
stradd(cp,str)
w_char **cp;
char *str;
{
	int len = strlen(str);

	if(hp + len + 1 >= heap + HEAP_LEN){
		error_no_heap();
		return(-1);
	}
	*cp = hp;
	wnn_Sstrcpy(hp,str);
	hp += wnn_Strlen(hp) + 1;
	return(0);
}

static int
w_stradd(cp, str)
unsigned short **cp;
unsigned short *str;
{

	*cp = whp;
	for(;*str != TERMINATE; str++,whp++){
		if(whp >= wheap + WHEAP_LEN){
			error_no_heap();
			return(-1);
		}
		*whp = *str;
	}
	*whp++ = TERMINATE;
	return(0);
}

int
wnn_loadhinsi(fname)
char *fname;
{
	FILE *fp;
	UCHAR buf[SIZE];
	unsigned short fukugou_str[MAXHINSI];
	int sep;
	int h;
	int len;
	unsigned short *c;
	char hinsi_file_name[MAXPATHLEN];
	extern int wnn_find_hinsi_by_name(char *name);


	if((fname == NULL) || (*fname == 0)){
		memset(hinsi_file_name, 0, sizeof(hinsi_file_name));
		strncpy(hinsi_file_name, LIBDIR, sizeof(hinsi_file_name) - 1);
		strncat(hinsi_file_name, HINSIDATA_FILE, sizeof(hinsi_file_name) - strlen(hinsi_file_name) - 1);
		fname = &hinsi_file_name[0];
	}


	if((fp = fopen((char *)fname, "r")) == NULL){
		wnnerror_hinsi = WNN_NO_HINSI_DATA_FILE;
		goto err_1;
	}

	hinsi_loaded = 1;
	while((sep = get_phrase(buf,SIZE,fp)) != EOF){
		if(sep == HINSI_ERR){
			goto err;		/* wnnerror_hinsi set in get_phrase */
		}
		if(buf[0] == YOYAKU_CHAR){	/* yoyaku */
			if(sep != '\n'){
				wnnerror_hinsi = WNN_BAD_HINSI_FILE;
				goto err;
			}
			hinsi[mhinsi++] = NULL;
		} else if(sep == '\n'){	/* hinsi */
			if(stradd(&hinsi[mhinsi++],buf))goto err;
		} else if(sep == DEVIDE_CHAR){	/* fukugou */
			if(stradd(&fukugou[mfukugou].name,buf))goto err;
			c = fukugou_str;
			len = sizeof(fukugou_str) / sizeof(unsigned short);
			while((sep = get_phrase(buf,SIZE,fp)) != EOF){
				if(sep == -1){
					goto err;		/* wnnerror_hinsi set in get_phrase */
				}
				if(sep != EOF && sep != HINSI_SEPARATE_CHAR && sep != '\n'){
					wnnerror_hinsi = WNN_BAD_HINSI_FILE;
					goto err;
				}
				if((h = wnn_find_hinsi_by_name(buf)) == -1 ||
				    h >= mhinsi){
					wnnerror_hinsi = WNN_BAD_HINSI_FILE;
					goto err;
				}
				if (len-- <= 1) {
					wnnerror_hinsi = WNN_BAD_HINSI_FILE;
					goto err;
				}
				*c++ = h;
				if(sep == '\n' || sep == EOF)
					break;
			}
			*c = TERMINATE;
			if(w_stradd(&fukugou[mfukugou++].component,fukugou_str))goto err;
		} else if(sep == NODE_CHAR){
			int first = 1;
			w_char *dummy;

			node[mnode].kosuu = 0;
			if(stradd(&node[mnode].name,buf))goto err;
			while((sep = get_phrase(buf,SIZE,fp)) != EOF){
				if(sep == -1){
					goto err;		/* wnnerror_hinsi set in get_phrase */
				}
				if(sep != EOF && sep != HINSI_SEPARATE_CHAR && sep != '\n'){
					wnnerror_hinsi = WNN_BAD_HINSI_FILE;
					goto err;
				}
				node[mnode].kosuu++;
				if(first){
					if(stradd(&node[mnode].son,buf))goto err;
					first = 0;
				} else{
					if(stradd(&dummy,buf))goto err;
				}
				if(sep == '\n' || sep == EOF)
					break;
			}
			mnode++;
		}
	}
	fclose(fp);
	return(0);
err:
	fclose(fp);
err_1:
	return(HINSI_ERR);
}

static int
find_hinsi_by_name(c)
register w_char *c;
{
	register int k;
	char *hfname = NULL;

#if !defined(DSERVER) && defined(JSERVER)
	hfname = &hinsi_file_name[0];
#endif /* !DSERVER && JSERVER */
	if(!hinsi_loaded){
		if(wnn_loadhinsi(hfname) != 0){
			return(-1);
		}
	}
	for(k = 0 ; k < mhinsi; k++){
		if(hinsi[k] && wnn_Strcmp(hinsi[k],c) == 0){
			return(k);
		}
	}
	for(k = 0 ; k < mfukugou; k++){
		if(fukugou[k].name && wnn_Strcmp(fukugou[k].name,c) == 0){
			return(FUKUGOU_START - k);
		}
	}
	return(-1);
}


int
wnn_find_hinsi_by_name(name)
register char *name;
{
	w_char hin[WNN_HINSI_NAME_LEN];

	wnn_Sstrncpy(hin, (sizeof(hin) / sizeof(w_char)) - 1, name, -1);
	return(find_hinsi_by_name(hin));
}


static w_char *
get_hinsi_name(k)
int k;
{
	char *hfname = NULL;

#if !defined(DSERVER) && defined(JSERVER)
	hfname = &hinsi_file_name[0];
#endif /* !DSERVER && JSERVER */
	if(!hinsi_loaded){
		if(wnn_loadhinsi(hfname) != 0){
			return(NULL);
		}
	}
	if(k < mhinsi && k >= 0){
		return(hinsi[k]);
	} else if(k > FUKUGOU_START - mfukugou){
		return(fukugou[FUKUGOU_START - k].name);
	}
	return(NULL);
}

char *
wnn_get_hinsi_name(k)
int k;
{
	w_char *s;
	static char hin[WNN_HINSI_NAME_LEN * 2];

	if((s = get_hinsi_name(k)) == NULL)return(NULL);
	wnn_sStrncpy(hin, sizeof(hin) - 1, s, -1);
	return(hin);
}

static
int
wnn_get_fukugou_component_body(k, shp)
register int k;
register unsigned short **shp;
{
	static unsigned short tmp;
	register unsigned short *s;
	int n;

	if(k < mhinsi && k >= 0){
		tmp = k;
		*shp = &tmp;
		return(1);
	}
	if(k > FUKUGOU_START - mfukugou && k <= FUKUGOU_START){
		n = FUKUGOU_START - k;
		for(*shp = s = fukugou[n].component;*s != TERMINATE;s++)
			;
		return(s - *shp);
	}
	return(-1);
}

int
wnn_get_fukugou_component(k, shp)
register int k;
register unsigned short **shp;
{
	char *hfname = NULL;

#if !defined(DSERVER) && defined(JSERVER)
	hfname = &hinsi_file_name[0];
#endif /* !DSERVER && JSERVER */
	if(!hinsi_loaded){
		if(wnn_loadhinsi(hfname) != 0){
			return(-1);
		}
	}
	return(wnn_get_fukugou_component_body(k, shp));
}




/* ?? need doc. */
int
wnn_get_hinsi_i4_boundary_free(hinsi_pter)
register unsigned char *hinsi_pter;
{
	register int ret;

	ret = *hinsi_pter; 
	ret = (ret<<8) | *(hinsi_pter+1);
	return(ret);
}


syntax highlighted by Code2HTML, v. 0.9.1