//---------------------------------------
// CARG Class - Argc, Argvユーティリティ
// Copyright (c) 2002, K. Yoshida
//---------------------------------------

class CARG
{
public:
	int		m_Argc;					//コマンドライン引数の数
	CSTR	m_Argv[MAX_PATH];		//コマンドライン引数
	CSTR	m_Drive;				//第１引数のドライブ
	CSTR	m_Path;					//第１引数のパス
	CSTR	m_FileName;				//第１引数のファイル名
	CSTR	m_Ext;					//第１引数の拡張子

	CARG();						//コマンドラインを分解
	CARG(char*);				//引数を分解（ドライブ名、パス、ファイル名分析用）
	int c() {return m_Argc;}
	char* v(int i) {return m_Argv[i].ToChar();}
	char* Drive()  {return m_Drive.ToChar();}
	char* Path()  {return m_Path.ToChar();}
	char* FileName()  {return m_FileName.ToChar();}
	char* Ext() {return m_Ext.ToChar();}
	char* GetLongName(char*);	//引数にスペースがあればダブルコーテーションをつける
	char* GetQuatoOff(char*);	//引数にダブルコーテーションがあればこれをとる
	CARG& operator = (char*);
};

//コマンドラインを分解
CARG::CARG() {

	//コマンドラインをBuffにコピーする
	CSTR Buff(GetCommandLine());
	//スペース文字で区切られた文字列（""で囲まれたものを含む）を切り出す
	for(m_Argc = 0; Buff.Next(m_Argv[m_Argc]); m_Argc++);
	//第１引数を分解する
	Buff = m_Argv[0].ToChar();
	//文字列の先頭（sp）と末尾(ep）のポインターを設定する
	unsigned char* sp = (unsigned char*)Buff.ToChar();
	unsigned char* ep = (unsigned char*)Buff.ToChar() + lstrlen(Buff.ToChar()) - 1;
	char* last = 0;				//最後の'\'を指すポインター
	if(*sp == '\"' && *ep == '\"')
		*ep = NULL;	//「""」で囲まれていれば外す（NULLを指す）
	//文字列の'\'を探す
	while(sp < ep) {
		if(*sp == '\\')
		last = (char*)sp;		//spを進めるのでlastに記録
		//Shift-JISの第1バイト（0x81-0x9Fまたは0xE0-0xEF）なら2バイト進める
		if((*sp >= 0x81 && *sp <= 0x9F) || (*sp >= 0xE0 && *sp <= 0xEF))
			sp += 2;
		else
			sp++;				//spを進める
	}
	if(!last) {					//'\\'が無かった場合、lastは0である為
		MessageBox(NULL, "文字列の構文が違法です", "エラー", MB_OK | MB_ICONERROR);
		return;
	}
	*last = NULL;				//パスとファイル名を切り離す
	//第１引数のファイル名を取り出す
	m_FileName = (last + 1);
	//第１引数の拡張子を取り出す
	char* p = strstr(m_FileName.ToChar(), ".");
	p ? (m_Ext = (p + 1)) : (m_Ext = "");
	//第１引数のパス名を取り出す
	m_Path = Buff;
	for(p =  Buff.ToChar(); *p && *p != ':'; p++);
	if(*p == ':') {
		*(p + 1) = NULL;
		//第１引数のドライブ名を取り出す
		m_Drive = Buff;
	}
	else
		m_Drive = "";
}

//引数を分解（ドライブ名、パス、ファイル名分析用）
CARG::CARG(char* str) {

	//strをBuffにコピーする
	CSTR Buff(str);
	//スペース文字で区切られた文字列（""で囲まれたものを含む）を切り出す
	for(m_Argc = 0; Buff.Next(m_Argv[m_Argc]); m_Argc++);
	//第１引数を分解する
	Buff = m_Argv[0].ToChar();
	//文字列の先頭（sp）と末尾(ep）のポインターを設定する
	unsigned char* sp = (unsigned char*)Buff.ToChar();
	unsigned char* ep = (unsigned char*)Buff.ToChar() + lstrlen(Buff.ToChar()) - 1;
	char* last = 0;				//最後の'\'を指すポインター
	if(*sp == '\"' && *ep == '\"')
		*ep = NULL;	//「""」で囲まれていれば外す（NULLを指す）
	//文字列の'\'を探す
	while(sp < ep) {
		if(*sp == '\\')
		last = (char*)sp;		//spを進めるのでlastに記録
		//Shift-JISの第1バイト（0x81-0x9Fまたは0xE0-0xEF）なら2バイト進める
		if((*sp >= 0x81 && *sp <= 0x9F) || (*sp >= 0xE0 && *sp <= 0xEF))
			sp += 2;
		else
			sp++;				//spを進める
	}
	if(!last) {					//'\\'が無かった場合、lastは0である為
		MessageBox(NULL, "文字列の構文が違法です", "エラー", MB_OK | MB_ICONERROR);
		return;
	}
	*last = NULL;				//パスとファイル名を切り離す
	//第１引数のファイル名を取り出す
	m_FileName = (last + 1);
	//第１引数の拡張子を取り出す
	char* p = strstr(m_FileName.ToChar(), ".");
	p ? (m_Ext = (p + 1)) : (m_Ext = "");
	//第１引数のパス名を取り出す
	m_Path = Buff;
	for(p =  Buff.ToChar(); *p && *p != ':'; p++);
	if(*p == ':') {
		*(p + 1) = NULL;
		//第１引数のドライブ名を取り出す
		m_Drive = Buff;
	}
	else
		m_Drive = "";
}

//引数にスペースがあればダブルコーテーションをつける
char* CARG::GetLongName(char* str) {

	static char Buff[MAX_PATH];
	bool IsSpace = FALSE;
	for(int i = lstrlen(str) - 1; i > 0; i--)
		if(isspace(str[i])) {
			IsSpace = TRUE;
			break;
		}
	if(IsSpace) {
		lstrcpy(Buff, "\"");
		lstrcat(Buff, str);
		lstrcat(Buff, "\"");
		return Buff;
	}
	else
		return str;
}

//引数にダブルコーテーションがあればこれをとる
char* CARG::GetQuatoOff(char* str) {

	if(*str == '\"') {
		lstrcpy(str, str + 1);
		for(int i = lstrlen(str) - 1; i >= 0; i--)
			if(str[i] == '\"') {
				str[i]= NULL;
				break;
			}
	}
	return str;
}

//文字列の代入
CARG& CARG::operator = (char* cp) {

	CARG arg(cp);
	m_Argc = arg.m_Argc;			//コマンドライン引数の数
	for(int i = 0; i < m_Argc; i++)
		m_Argv[i] = arg.m_Argv[i];	//コマンドライン引数
	m_Drive = arg.m_Drive;			//第１引数のドライブ
	m_Path = arg.m_Path;			//第１引数のパス
	m_FileName = arg.m_FileName;	//打１引数のファイル名
	m_Ext = arg.m_Ext;			//打１引数の拡張子
	return *this;
}
