// * Fri Dec 05 22:14:14 JST 2014 Naoyuki Sawa
// - 1st リリース。
// - 「/clip/tclwin/」は、非標準のコマンドとして、srand,randを追加しています。
//   本物のtclsh.exeには、srand,randが無いため、両者で同じスクリプトをテストしようとすると、本物のtclsh.exeでエラーになる問題があります。
//   そこで、本物のtclsh.exeでsrand,randを使用するための、DLLを作成しました。
// - 本物のtclsh.exeと「/clip/tclwin/」のどちらでも動作するスクリプトの例です:
//   │catch {load tclrnd}	…「/clip/tclwin/」はloadコマンドに対応していないのでエラーになるが、catchして無視する。
//   │srand			…引数無しで呼び出すと時刻をシードとして乱数を初期化する。引数を指定することも可能です。
//   │set rndVal [rand]	…乱数値を取得する。
//   │puts $rndVal
//------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
//------------------------------------------------------------------------------
#include <tcl.h>
#pragma comment(lib, "tcl86.lib")
//------------------------------------------------------------------------------
//srand seed
static int srandCmd(ClientData cData, Tcl_Interp* iPtr, int argc, const char* argv[]) {
	int seed;
	switch(argc) {
	case 1:
		seed = time(NULL);
		break;
	case 2:
		seed = atoi(argv[1]);
		break;
	default:
		Tcl_SetResult(iPtr, "wrong # args", TCL_VOLATILE);
		return TCL_ERROR;
	}
	srand(seed);
	return TCL_OK;
}
//------------------------------------------------------------------------------
//rand
static int randCmd(ClientData cData, Tcl_Interp* iPtr, int argc, const char* argv[]) {
	char buf[32];
	sprintf(buf, "%d", rand());
	Tcl_SetResult(iPtr, buf, TCL_VOLATILE);
	return TCL_OK;
}
//------------------------------------------------------------------------------
__declspec(dllexport) int Tclrnd_Init(Tcl_Interp* iPtr) {
	Tcl_CreateCommand(iPtr, "srand", srandCmd, NULL, NULL);
	Tcl_CreateCommand(iPtr, "rand",  randCmd,  NULL, NULL);
	return TCL_OK;
}
