#include "app.h"
/****************************************************************************
 *	グローバル変数
 ****************************************************************************/
Tcl_Interp* iPtr;
/****************************************************************************
 *	ローカル関数宣言
 ****************************************************************************/
static int srandCmd(Tcl_Interp* iPtr);
static int randCmd(Tcl_Interp* iPtr);
/****************************************************************************
 *	main
 ****************************************************************************/
int main(int argc, char* argv[]) {
	FILE* fp = stdin;
	int retCode, i;
//	putenv("GC_LOG_FILE=CON");//ログ出力先を指定
//	GC_set_find_leak(1);//メモリリーク検出を開始
	/* Tclインタプリタを作成する。 */
	iPtr = Tcl_CreateInterp();
//{{必要に応じて、ここでアプリケーション特有のTcl_CreateCommand()を行ってください。
	Tcl_CreateCommand(iPtr, "srand", srandCmd, NULL);
	Tcl_CreateCommand(iPtr, "rand",  randCmd,  NULL);
//}}必要に応じて、ここでアプリケーション特有のTcl_CreateCommand()を行ってください。
	//□tclsh ?fileName arg ...?
	//│argc  argで指定された引数の数(もし引数がなければ0)が入っています。引数にはスクリプトファイル名は含まれません。
	//│argv  argで指定された引数を順に並べたTclのリストが入っています。もしargで引数が指定されなかった時には空文字列になります。
	//│argv0 もしfileName引数が指定されていればそれが入ります。そうでなければtclshが起動された時のコマンド名が入ります。
	/* argv0に、実行ファイル名を設定する。 */
	Tcl_SetVar(iPtr, "argv0", *argv++);		//argvを次へ進める。
	/* 最初の引数が有り、'-'でなければ… */
	if(*argv && strcmp(*argv, "-")) {
		fp = fopen(*argv, "r");			//Tclスクリプトファイルを開く。
		if(!fp) {
			fprintf(stderr, "### %sが開けません｡\n", *argv);
			exit(EXIT_FAILURE);
		}
		/* argv0に、Tclスクリプトファイル名を設定する。 */
		Tcl_SetVar(iPtr, "argv0", *argv);	//Tclスクリプトファイル名を、argv(0)にも設定するので、argvを次へ進めません。
	}
	/* argv()配列を設定する。 */
	for(i = 0; *argv; i++, argv++) {
		Tcl_SetVar(iPtr, strdup_printf("argv(%d)", i), *argv);
	}
	/* argcを設定する。 */
	Tcl_SetVar(iPtr, "argc", strdup_printf("%d", i));
	/* Tclスクリプトを実行する。 */
	retCode = Tcl_EvalStream(iPtr, fp);
	/* 本来はTcl_EvalFile()が適切に処理するが、シェルの場合は非インタラクティブでもエラーを表示したいので、以下の処理を行う。 */
	if(retCode && !isatty(fileno(fp))) {	//エラー発生,かつ,非インタラクティブ(=Tcl_EvalFile()がエラーを表示しない)ならば…
		fprintf(stderr, "Error");
		if(retCode != TCL_ERROR) { fprintf(stderr, " %d", retCode); }
		if(*iPtr->result) { fprintf(stderr, ": %s", iPtr->result); }
		fprintf(stderr, "\n");
#ifdef  _DEBUG
		/* Visual Studio 6.0のIDEでデバッグ実行した場合、プログラム終了後にすぐDOS窓が閉じてしまうので、結果を見るためにキー入力待ちをすることにした。 */
		cputs("何かｷｰを押すと終了します｡");
		getch();
#endif//_DEBUG
	}
	return retCode;
}
/****************************************************************************
 *	
 ****************************************************************************/
//srand seed
static int srandCmd(Tcl_Interp* iPtr) {
	int seed;
	switch(iPtr->argc) {
	case 1:
		seed = time(NULL);
		break;
	case 2:
		seed = atoi(iPtr->argv[1]);
		break;
	default:
		iPtr->result = "wrong # args";
		return TCL_ERROR;
	}
	srand(seed);
	return TCL_OK;
}
/*--------------------------------------------------------------------------*/
//rand
static int randCmd(Tcl_Interp* iPtr) {
	iPtr->result = strdup_printf("%d", rand());
	return TCL_OK;
}
