/*
 *	app.c
 *
 *	dpmucc - ミュージック・データ・コンバーター
 *	Copyright (C) 2015-2016 Naoyuki Sawa
 *
 *	* Thu Jan 22 00:43:59 JST 2015 Naoyuki Sawa
 *	- 1st リリース。
 *	* Sat Jan 24 05:36:54 JST 2015 Naoyuki Sawa
 *	- mmlEnd()のループ処理が間違っていたのを修正しました。
 *	  元のmucc.exeのソース(\usr\PIECE\tools\mucc\mmlcv.c)は正しくて、自分で再実装した際のエンバグです。
 *	* Tue Feb 03 20:30:54 JST 2015 Naoyuki Sawa
 *	- コマンドラインオプション'-p'を追加しました。
 *	* Sun Feb 21 21:02:01 JST 2016 Naoyuki Sawa
 *	- 「Boehm GC」をマルチスレッド対応にした事,及び,それに伴ってclipbpe.cモジュールを修正した事に伴い、当ツールもプロジェクト設定の変更を行ってリビルドしました。
 *	  詳細は、/clip/tool/gc/README.TXT と /clip/clipbpe.c の2015/11/03のコメントを参照して下さい。
 *	- libclipのライブラリ化の伴い、以下の変更を行いました。
 *	  ・extclip.hとextclip.cを削除しました。extclip.hとextclip.cはlibclipに含まれるようになったからです。
 *	  ・"CLiP Files"を削除しました。CLiPライブラリの各モジュールはlibclipに含まれるようになったからです。
 *	  当ツールの動作には変更有りません。
 */
#include "app.h"
/****************************************************************************
 *	グローバル変数
 ****************************************************************************/
char	outName[_MAX_PATH];	//出力ファイル名
char	srcName[_MAX_PATH];	//現在の入力ファイル名
int	srcLine;		//現在の入力ファイルの処理中の行番号
FILE*	fp;			//現在の入力ストリーム,又は,出力ストリーム
/****************************************************************************
 *	usage
 ****************************************************************************/
static void usage() {
	fprintf(stderr, "dpmucc - ミュージック・データ・コンバーター (%s)\n", VERSION);
	fprintf(stderr, "Copyright (C) 2015-2016 Naoyuki Sawa All Rights Reserved.\n");
	fprintf(stderr, "Usage:\n");
	fprintf(stderr, "    dpmucc [-o outName[.pmd]] [srcName[.mml] ...]\n");
	fprintf(stderr, "Arguments:\n");
	fprintf(stderr, "    srcName[.mml]    入力ファイル名を指定します。\n");
	fprintf(stderr, "                     入力ファイル名を複数指定すると、連結した内容として読み込みます。\n");
	fprintf(stderr, "                     入力ファイル名を一つも指定しなければ、標準入力から読み込みます。\n");
	fprintf(stderr, "Options:\n");
	fprintf(stderr, "    -h               使い方を表示します。\n");
	fprintf(stderr, "    -o outName[.pmd] 出力ファイル名を指定します。\n");
	fprintf(stderr, "                     出力ファイル名を指定しなければ、先頭の入力ファイル名の拡張子を'.pmd'に変更したファイル名を、出力ファイル名とします。\n");
	fprintf(stderr, "                     出力ファイル名が指定されず、入力ファイル名も指定されていない場合(標準入力から読み込む場合)、出力ファイル名は'aaa'とします。\n");
	fprintf(stderr, "    -p               出力ファイルを生成した後、出力ファイルを引数としてpm.exeを実行します。\n");
	fprintf(stderr, "                     MMLの修正/試聴を事を繰り返す時に、このオプションを利用すると便利です。\n");
	fprintf(stderr, "Example:\n");
	fprintf(stderr, "    dpmucc.exe -p -o sample1.pmd sample1a.mml sample1b.mml sample1c.mml\n");
	fprintf(stderr, "    sample1a.mml,sample1b.mml,sample1c.mmlを連結した内容として読み込み、sample1.pmdを出力します。\n");
	fprintf(stderr, "    sample1.pmdを出力した後、自動的にpm.exeを実行してsample1.pmdを再生します。\n");
	exit(EXIT_FAILURE);
}
/****************************************************************************
 *	main
 ****************************************************************************/
int main(int argc, char* argv[]) {
	char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
	int opt, opt_p = 0;
	//---------- コマンドライン解析 ----------
	//コマンドラインを解析する。
	opterr = 0;	//getopt()のエラーメッセージを抑制する。オプションのエラーメッセージは、本プログラムが表示する。
	while((opt = getopt(argc, argv, "o:ph")) != -1) {
		switch(opt) {
		case 'o':
			if(*outName) { usage(); }	//エラー:出力ファイル名が二回指定された。
			strcpy(outName, optarg);	//出力ファイル名を格納する。
			break;
		case 'p':
			if(opt_p) { usage(); }		//エラー:コマンドラインオプション'-p'が二回指定された。
			opt_p = 1;			//コマンドラインオプション'-p'が指定された事を記憶する。
			break;
	//	case 'h':
		default:
			usage();
			break;
		}
	}
	//出力ファイル名が指定されていたら…
	if(*outName) {
		//出力ファイル名の拡張子が省略されていたら、'.pmd'とする。
		_splitpath(outName, drive, dir, fname, ext);
		if(!*ext) { _makepath(outName, drive, dir, fname, ".pmd"); }
	//出力ファイル名が指定されていなければ…
	} else {
		//入力ファイル名が指定されていたら…
		if(argv[optind]) {
			//先頭の入力ファイル名の拡張子を'.pmd'に変更したファイル名を、出力ファイル名とする。
			_splitpath(argv[optind], drive, dir, fname, NULL);
			_makepath(outName, drive, dir, fname, ".pmd");
		//入力ファイル名が指定されていなければ…
		} else {
			//出力ファイル名を'aaa'とする。
			strcpy(outName, "aaa");
		}
	}
	//---------- 変換処理 ----------
	//変換処理の準備を行う。
	mmlSetup();
	//入力ファイル名が指定されていたら…
	if(argv[optind]) {
		do {
			//入力ファイル名を取得する。
			strcpy(srcName, argv[optind]);
			//入力ファイル名の拡張子が省略されていたら、'.mml'とする。
			_splitpath(srcName, drive, dir, fname, ext);
			if(!*ext) { _makepath(srcName, drive, dir, fname, ".mml"); }
			//入力ファイルを開く。
			fp = fopen(srcName, "r");
			if(!fp) { die("%s: ファイルが開けません。\n", srcName); }
			//現在の入力ファイルの行番号をリセットする。
			srcLine = 0;
			//入力ストリームを処理する。
			mmlParse();
			//入力ファイルを閉じる。
			fclose(fp);
		} while(argv[++optind]);
	//入力ファイル名が指定されていなければ…
	} else {
		//入力ストリームを、標準入力とする。
		strcpy(srcName, "-");	//エラーメッセージはファイル名を'-'で表す。
		fp = stdin;
		//現在の入力ファイルの行番号をリセットする。
		srcLine = 0;
		//入力ストリームを処理する。
		mmlParse();
	}
	//出力ファイルを作成する。
	fp = fopen(outName, "wb");
	if(!fp) { die("%s: ファイルが作成できません。\n", outName); }
	//変換結果を出力する。
	mmlEnd();
	//出力ファイルを閉じる。
	fclose(fp);
	//---------- pm.exe実行 ----------
	//コマンドラインオプション'-p'が指定されていたら…
	if(opt_p) {
		//出力ファイルを引数としてpm.exeを実行する。
	#if 0
		_execlp("pm.exe", "pm.exe", outName, NULL);	//_execlp()が成功すると、_execlp()は呼び出し側のプロセスに戻らない。
		die("pm.exeが実行できません。\n");
	#else	//↓_execlp()ではダメです。cmd.exeがdpmucc.exeが終了したと判断してpm.exeが実行中のままコマンドプロンプトに戻ってしまいます。pm.exeがキー入力を受け付けずpm.exeを終了できなくなります。_spawnlp()を使ってpm.exeの終了を待つのが正しいです。
		if(_spawnlp(_P_WAIT, "pm.exe", "pm.exe", outName, NULL)) {
			die("pm.exeが実行できません。\n");
		}
	#endif
	}
	return EXIT_SUCCESS;
}
