static  char    sccsid[]="%Z% %M% %I% %E% %U%";
/********************************************************************/
/* <clprimport.c>                                                   */
/********************************************************************/
#include "colmn.h"

extern condList  CLcList;      /* 情報リスト */
extern CLNCB     CLSTCB;  /* タグの構文解析を行うための領域 */
extern CLPRTBL   *pGLprocTable;
extern GlobalCt  *pGlobTable;
extern CLCOMMON  CLcommon;
extern int giOptions[];
extern tdtLruScrHead *tpLruScrHeadImp;
extern tdtLruScrHead *tpLruScrHead;

int cl_pr_ex_import();
static int _imp_cmp_name();
static int _imp_cmp_leaf();

/************************************/
/* cl_process_import					*/
/************************************/
int cl_process_import(scrct,leafTop)
ScrPrCT  *scrct;
Leaf     *leafTop;
{
	Leaf *leaf;
	int rc,cno;

	if (scrct == NULL) return ECL_SYSTEM_ERROR;

	rc = 0;
	if (leafTop) leaf = leafTop;
	else if (!(leaf = scrct->TreeTop)) return ECL_SYSTEM_ERROR;

	if (((cno=leaf->cmd.cid)==C_NODE_SCRIPT || cno==C_NODE_IMPORT) &&
		    leaf->leftleaf) leaf = leaf->leftleaf;
#if 1
	while (leaf && rc==NormalEnd) {
		cno = leaf->cmd.cid;
		if (cno==C_PROC || cno==C_FUNCTION ||  cno == C_CLASS) break;
		else if (cno == C_NODE_DEFINE) leaf = leaf->leftleaf;
		else {
#else
	while (leaf->cmd.cid != C_PROC && leaf->cmd.cid != C_FUNCTION &&
	       leaf->rightleaf != NULL && rc == NormalEnd) {
#endif
			if (leaf->cmd.cid == C_IMPORT) {
DEBUGOUTL1(100,"[ %s ]",cl_get_pcmd_line(leaf));
				if (CLcommon.dbgopt[0]) {
					cl_debug_mode(leaf,NULL,0);
				}
				rc = cl_pr_ex_import(leaf,pGLprocTable->CurScr);
				if (rc) clerrdisp(rc,leaf);
			}
			leaf = leaf->rightleaf;
		}
	}
	return rc;
}

/************************************/
/* _mk_scr_const						*/
/************************************/
ScrConstCt *_mk_scr_const(scrct)
ScrPrCT *scrct;
{
	ScrConstCt *scrconst;

	if (scrconst = (ScrConstCt *)Malloc(sizeof(ScrConstCt))) {
		scrconst->pId = Strdup(scrct->pId);
		scrconst->ConstCt = scrct->ConstCt;
		scrconst->LeafConstCt = scrct->LeafConstCt;
		scrconst->NodeLeaf = NULL;
	}
	return scrconst;
}

/************************************/
/* cl_pr_ex_import						*/
/************************************/
int cl_pr_ex_import(leaf, scrct)
Leaf    *leaf;
ScrPrCT *scrct;
{
	static char *fmt="***** Import Name ( %s ) Skipped *****";
	static char *_fn_="cl_pr_ex_import";
	int rc,parmnum,namelen,iUSE_MAIN,len,iIMPORTCACHE,iIMPORTTOP,i;
	char *name,*scrname,*skipped,*p;
	tdtInfoParm InfoParm;
	Leaf     *leafw,*leafTop,*leafimp;
	ScrPrCT  Scrprct,*scrprctlru,*scrimp;
	ScrConstCt *scrconst;
	ConstantCt *pConstCt;
	ParList sc_nam;

	if (!leaf || !scrct) return ECL_SYSTEM_ERROR;

	/* Importファイル名の取り込みとチェック */
#if 1	/* 2020.5.13 */
	rc = cl_ex_get_proc_name(leaf->cmd.prmp[0],NULL,&sc_nam);
#else
	rc = cl_ex_get_proc_name(0,leaf->cmd.prmp[0],NULL,&name,&namelen);
#endif
	if (rc) {
		ERROROUT("cl_pr_ex_import: file name get procedure error.");
		return rc;
	}
#if 1	/* 2020.5.13 */
	if (rc = cl_exe_scr_name_check(&sc_nam,NULL)) return rc;
	name =    sc_nam.par;
	namelen = sc_nam.parlen;
#else
	if (rc = cl_exe_scr_name_check(name,namelen)) return rc;
#endif
	if (!(scrname = cl_set_script_name_extension(name,namelen)))
		return ECL_EX_IMPORT;
	/* 自分自身は、Importしない */
	if (!strcmp(scrname,scrct->pId)) {
	/*	PRINTOUT1(fmt,scrname);
		DEBUGOUTL1(1,fmt,scrname);	*/
		PRDBGOUTL1(1,fmt,scrname);
		return 0;
	}
	/* オプションの取り込みとチェック */
	iIMPORTTOP = pGlobTable->options[5] & 0x01;
	iUSE_MAIN = 0;
	parmnum = leaf->cmd.prmnum;
	for (i=1;i<parmnum;i++) {
		if (rc=cl_arg_to_char(leaf->cmd.prmp[i],NULL,&InfoParm,"オプション")) {
			ERROROUT("cl_pr_ex_import: option get procedure error.");
			return rc;
		}
		p = InfoParm.pi_data;
		if (*p == '-') p++;
		if (!stricmp(p,"HEAD")) iIMPORTTOP = 1;
		else if (!stricmp(p,"TAIL")) iIMPORTTOP = 0;
		else if (!stricmp(p,"USE_MAIN")) iUSE_MAIN = 1;
		else {
				/* cl_pr_ex_import: 不正なオプション[%s]です。 */
			ERROROUT2(FORMAT(561),_fn_,InfoParm.pi_data);
			return ECL_EX_IMPORT;
		}
	}
	if (iUSE_MAIN) iIMPORTTOP = 1;
#if 1
	/* scrct->ConstCtがNULLだと、エラーリターン時に_pr_ret()でmallocされても
	   cl_scr_const_malloc()の実行で元に戻り、メモリ・リークとなるのでここで設定しておく */
	if (!scrct->ConstCt) scrct->ConstCt = cl_const_ct_new();
#endif
#if 1
	/* キャッシュされているtreeは、キャッシュされているConstCt内にあるので
	   これを使う */
	if (scrprctlru=cl_lru_scr_src_opt(tpLruScrHeadImp,scrct->pId,0))
		pConstCt = scrprctlru->ConstCt;
	else
		pConstCt = scrct->ConstCt;
#endif
#if 0	/* 2010.11.16 pConstCt = scrct->ConstCtのときに、scrct->ConstCtがNULLだと
		   pConstCtがNULLになるのでその前に移動 */
	/* scrct->ConstCtがNULLだと、エラーリターン時に_pr_ret()でmallocされても
	   cl_scr_const_malloc()の実行で元に戻り、メモリ・リークとなるのでここで設定しておく */
	if (!scrct->ConstCt) scrct->ConstCt = cl_const_ct_new();
#endif
	/* Import済みかのチェック */
	if (!scrct->pListImport) {
		if (!(scrct->pListImport=akxs_list_new(0,0))) {
			ERROROUT("cl_pr_ex_import: pListImport malloc error.");
			return ECL_EX_IMPORT;
		}
#if 1
		leafw = cl_make_node_leaf(pConstCt,C_NODE_SCRIPT,scrct->pId);
		leafTop  = scrct->TreeTop;
		scrct->TreeTop = leafw;
		scrct->pFlag |= D_LEAF_IMPORTMODE;
		leafw->leftleaf = leafTop;
		leafw->pFlag = scrct->pFlag;
#endif
		/* 呼び出し先から復帰したときに、自分のConstCTを戻せるように
		   自分自身も登録しておく。自分をImportできないようにもできる。 */
		if (!(scrconst=_mk_scr_const(scrct))) return ECL_SYSTEM_ERROR;
#if 0
		scrconst->NodeLeaf = scrct->TreeTop;
#else
		scrconst->NodeLeaf = leafw;
/*
printf("cl_pr_ex_import:1 leafw=%08x\n",leafw);
*/
#endif
		akxs_list_set(scrct->pListImport, scrconst);
	}
	if (akxs_list_srch(scrct->pListImport, scrname, _imp_cmp_name, 0)) {
		skipped = "Skipped ";
	}
	else {
		skipped = "";
	}
	PRDBGOUTL2(1,"***** Import Name ( %s ) %s*****",scrname,skipped);
	if (*skipped) return 0;
	if (scrprctlru=cl_lru_scr_src(tpLruScrHeadImp,scrname)) {	/* キャッシュにあるか調べる */
DEBUGOUTL1(0,"cl_pr_ex_import: %s is found in cache",scrname);
		scrimp = &Scrprct;
		scrimp->ConstCt = NULL;
		scrimp->TreeTop = scrprctlru->TreeTop;
		scrimp->LeafConstCt = scrprctlru->LeafConstCt;
		scrimp->pId = scrprctlru->pId;
		iIMPORTCACHE = D_LEAF_CACHED;
	}
	else {
		scrimp = cl_mk_scr_and_reg(tpLruScrHeadImp,&Scrprct,scrname);
		if (!scrimp) return ECL_SYSTEM_ERROR;
#if 0
		iIMPORTCACHE = scrimp->TreeTop->pFlag & D_LEAF_CACHED;
#else
		iIMPORTCACHE = scrimp->pFlag & D_LEAF_CACHED;
#endif
	}
	if (!(scrconst=_mk_scr_const(scrimp))) return ECL_SYSTEM_ERROR;
	akxs_list_set(scrct->pListImport, scrconst);
	leafimp = scrimp->TreeTop;
#if 0
	/* キャッシュされているtreeは、キャッシュされているConstCt内にあるので
	   これを使う */
	if (scrprctlru=cl_lru_scr_src_opt(tpLruScrHeadImp,scrct->pId,0))
		pConstCt = scrprctlru->ConstCt;
	else
		pConstCt = scrct->ConstCt;
#endif
	/* ImportしたスクリプトのNodeLeafは、Importしたスクリプトで使用しているので
	   自分用のNodeLeafを作成する */
	leafw = cl_make_node_leaf(pConstCt,C_NODE_IMPORT,scrname);
#if 0
	leafw->leftleaf = leafimp->leftleaf;
#else
	leafw->leftleaf = leafimp;
#endif
	leafw->pFlag = iIMPORTCACHE;
	scrconst->NodeLeaf = leafw;
/*
printf("cl_pr_ex_import:2 leafw=%08x\n",leafw);
*/
	if (cl_search_proc(leafw,"main")) {
				/* %s: Importファイル[%s]内にmainがあります。 */
		ERROROUT2(FORMAT(562),_fn_,scrname);
		if (!iUSE_MAIN) {
					/* %s: mainを無効にしました。 */;
			ERROROUT1(FORMAT(563),_fn_);
			leafw->pFlag |= D_LEAF_INEFFECTIVE;
		}
	}
	if (iIMPORTTOP) {
		/* ImportしたスクリプトのTreeは先頭に挿入する */
		leafTop  = scrct->TreeTop;
		scrct->TreeTop = leafw;
		leafw->rightleaf = leafTop;
		leafTop  = NULL;
	}
	else {
		/* ImportしたスクリプトのTreeは最後に追加する */
		leafTop = leafw;
		leafw = scrct->TreeTop;
		while (leafw->rightleaf) {
			leafw = leafw->rightleaf;
		}
		leafw->rightleaf = leafTop;
	}
/**********
	ImportしたtreeにあるONとDEFINEは、後でまとめて実行する。
	Import文は、treeの先頭から、PROCまたはFUNCTIONの前にあるもののみ実行する。
	これは、Importしているスクリプトがキャッシュされているときは、Importを実行
	しなくても良いようにするためである。
	if (rc = cl_process_on(&Scrprct)) {
		ERROROUT("Error occured ON condition Process");
	}
	else if (rc = cl_process_define(&Scrprct)) {
		ERROROUT("Error occured Define Process");
	}
	else
************/
	if (rc = cl_process_import(scrct,leafTop)) {
		ERROROUT1("Error occured Import Process rc=%d",rc);
	}

	return rc;
}

/************************************/
/* _imp_cmp_name					*/
/************************************/
static int _imp_cmp_name(scrname,scrconst)
ScrConstCt *scrconst;
char       *scrname;
{
	return strcmp(scrconst->pId,scrname);
}

/************************************/
/* _imp_cmp_leaf					*/
/************************************/
static int _imp_cmp_leaf(nodeleaf,scrconst)
ScrConstCt *scrconst;
Leaf       *nodeleaf;
{
	return (scrconst->NodeLeaf == nodeleaf) ? 0 : -1;
}

/************************************/
/* cl_get_scr_const_ct				*/
/************************************/
ScrConstCt *cl_get_scr_const_ct(scrct,nodeleaf)
ScrPrCT *scrct;
Leaf    *nodeleaf;
{
	tdtRbCtl *pCt;
	ScrConstCt *scrconst;

DEBUGOUTL2(120,"cl_get_scr_const_ct: called scrct=%08x,nodeleaf=%08x",scrct,nodeleaf);
/*
if (nodeleaf) printf("cl_get_scr_const_ct: called scrct=%08x,nodeleaf=%08x\n",scrct,nodeleaf);
*/
	scrconst = NULL;
	if (scrct && nodeleaf) {
		if (pCt=scrct->pListImport) {
			if (akxs_list_srch(pCt,nodeleaf,_imp_cmp_leaf,0)) {
				akxs_list_read(pCt,-1,&scrconst);

DEBUGOUTL1(0,"cl_get_scr_const_ct: found scrconst=%08x",scrconst);
/*
printf("cl_get_scr_const_ct: found scrconst=%08x\n",scrconst);
*/
			}
		}
	}
	return scrconst;
}

/************************************/
/* cl_set_scr_const_ct				*/
/************************************/
int cl_set_scr_const_ct(scrct,nodeleaf,impscrct)
ScrPrCT *scrct,*impscrct;
Leaf    *nodeleaf;
{
	tdtRbCtl *pCt;
	ScrConstCt *scrconst;
	int rc;

DEBUGOUTL3(120,"cl_set_scr_const_ct: called scrct=%08x,nodeleaf=%08x impscrct=%08x",scrct,nodeleaf,impscrct);
/*
if (nodeleaf) printf("cl_set_scr_const_ct: called scrct=%08x,nodeleaf=%08x impscrct=%08x\n",scrct,nodeleaf,impscrct);
*/
	rc = 0;
	if (scrct && nodeleaf) {
#if 1	/* 2021.8.18 */
		if (!impscrct) impscrct = scrct;
		if (scrconst = cl_get_scr_const_ct(impscrct,nodeleaf)) {
#else
		if (pCt=impscrct->pListImport) {
			if (akxs_list_srch(pCt,nodeleaf,_imp_cmp_leaf,0)) {
				akxs_list_read(pCt,-1,&scrconst);
#endif
				scrct->ConstCt     = scrconst->ConstCt;
				scrct->LeafConstCt = scrconst->LeafConstCt;

DEBUGOUTL1(0,"cl_set_scr_const_ct: LeafConstCt=%08x",scrconst->LeafConstCt);
/*
printf("cl_set_scr_const_ct: LeafConstCt=%08x\n",scrconst->LeafConstCt);
*/
				rc = 1;
#if 0	/* 2021.8.18 */
			}
#endif
		}
	}
	return rc;
}
