/*****************************************************************************/
/* 変数管理システム */
/*****************************************************************************/

#include "defines.h"
#include "amacro.h"
#include "abuff.h"
#include "vsiki.h"

/*****************************************************************************/
/* 変数の格納仕方
	len type num name[00]
	1   1    4   len+1		size
	0   1    2   6        6+len+1	offset

	lenは1byte。従って、文字列長は最大255byteまで。
	00は予約で、1〜255までが有効。

	typeは変数モード。現在定義済みは次の状態。
		VKAKU	0=確定,1=未確定
		VDAI	0=普通,1=再代入不可
		VLABEL	0=数値,1=ラベル
		VTYPE	0〜31
			0=数値

	num:数値は32bit(long)数値のみ。
	それを数値とみなすかポインターとみなすかは利用システムによる。

	エリアサイズはlongサイズ。
	ハッシュは変数エリアの1/16の大きさで、longサイズ。
	ただし、その要素数はmin 1024,max unsint=64Kで、各要素はlong。
*/
/*****************************************************************************/

int var_open(long vsize,long vlmax,int mode,VARSYS *var)
/* 変数管理ルーチン初期化 */
/* vsize=変数格納エリアサイズ , vlmax=１変数名最大長 */
{
int i;
long VWMIN;
	/* 変数エリアサイズ計算 */
	if (vlmax>255||vlmax<1) return(2);
	var->vlmax=vlmax;
	VWMIN=(VTOP+1+1+LLONG+vlmax+1); /* 変数格納エリア最小サイズ */
	if (vsize<VWMIN) vsize=VWMIN;
	if (vsize&1) vsize++; // サイズは偶数にする（ハッシュはワードアクセスするため）
	
	/* ハッシュエリアサイズ計算 */
	if (vsize>=16*65536) vsize=65535*16; // max 65535にするため
	var->vhsize=vsize/16; /* サイズは変数格納エリアの1/16 */
	if (var->vhsize<1024)  var->vhsize=1024;  /* ある程度以下にはしない */
	
	/* エリア確保（変数/ハッシュ同時）*/
	var->vwork=newmalloc(vsize+var->vhsize*LLONG);
	if (var->vwork==NULL) return(1); /* error */
	
	var->vhash=(long *)&var->vwork[vsize];
	
	/* 変数格納エリア初期化 */
	var->vwsize=vsize;
	var->vpoint=VTOP;	/* ハッシュの関係で先頭は使えない */
	var->vwork[0]=0;
	var->vlots=0;		/* 変数は１つも登録されていない */
	var->mode=mode;
	/* ハッシュテーブル初期化 */
	for (i=0;i<var->vhsize;i++) var->vhash[i]=0;
	return(0);
}

/*****************************************************************************/
