Artifact Content

Not logged in

Artifact 97a142a9264ab72a52eb58e890296bce21dc31fc


private import std.string;
private import std.file;
private import win32.ansi.windows;

char lastChar( char[] s )
  { return *CharPrev(s, cast(char*)s+s.length); }

//----------------------------------------------------------------
// int do_opApply!(E, C)( collection, delegate );
// int do_opApply!(E)   (      array, delegate );
//   forwarding the opApply call to another collection
//----------------------------------------------------------------

template do_opApply( Elem, Collection )
{
	int do_opApply( Collection c, int delegate(inout Elem) dg )
	{
		int result = 0;
		foreach( Elem x ; c )
			if( 0 != (result=dg(x)) )
				break;
		return result;
	}
}

template do_opApply( E )
{
	int do_opApply( E[] c, int delegate(inout E) dg )
	{
		return .do_opApply!(E,E[])( c, dg );
	}
}

//----------------------------------------------------------------
// class set!(T)
//   add    :  T -> void
//   remove :  T -> void
//   has    :  T -> bool
//   elems  : () -> T[]
//   length : () -> int
//----------------------------------------------------------------

class set(T)
{
	void add   ( T x ) { data[x]; }
	void remove( T x ) { delete data[x]; }
	bool has   ( T x ) { return x in data; }
	T[]  elems ()      { return data.keys; }
	int  opApply( int delegate(inout T) dg )
	                   { return do_opApply!(T)( elems, dg ); }
	int  length()      { return data.length; }
	private void[T] data;
}

unittest
{
	set!(int) x = new set!(int);
	x.add(1);
	x.add(2);
	x.add(3);
	assert( x.elems[0] + x.elems[1] + x.elems[2] == 6 );
	assert( x.length == 3 );
	x.remove(4);
	x.remove(3);
	x.remove(1);
	assert( x.length == 1 );
	foreach( int t ; x ) assert( t==2 );
}

//----------------------------------------------------------------
// コマンドライン解析
//----------------------------------------------------------------

char[][] cmd_parse( char[] str, bool in_resp=false )
{
	char[][] ans;
	char resp_char = '@';

	for(int i=0; i!=str.length; )
	{
		// 空白スキップ
		while( i!=str.length && 0<=str[i] && str[i]<=' ' )
			++i;
		if( i == str.length )
			break;

		// ""を考慮して一個パラメタ切り出し
		char[] param;
		if( str[i] == '"' )
		{
			int j = ++i;
			while( j!=str.length )
			{
				if( str[j]=='"' &&
				     (j+1==str.length || 0<=str[j+1] && str[j+1]<=' ') )
					break;
				++j;
			}
			param = str[i .. j];
			i = (j==str.length ? j : j+1);
		}
		else
		{
			int j=i;
			while( j!=str.length && (str[j]<0 || ' '<str[j]) )
				++j;
			param = str[i .. j];
			i = j;
		}

		// レスポンスファイル関連の処理
		if( !in_resp && param[0]==resp_char )
		{
			try {
				char[] rsp = cast(char[]) std.file.read( param[1 .. param.length] );
				ans ~= cmd_parse(rsp,true);
			} catch( FileException e ) {}
		}
		else if( param.length>=2 && param[0..2]=="--" )
		{
			resp_char = (param.length==2 ? '\0' : param[2]);
		}
		else
		{
			ans ~= param; // 普通にパラメタ追加
		}
	}
	return ans;
}

//----------------------------------------------------------------
// DOS形式でファイル音更新時刻を書き換え
//----------------------------------------------------------------

void dosSetFTime( char[] fname, ushort date, ushort time )
{
	FILETIME ft,lc;
	if( DosDateTimeToFileTime( date, time, &lc ) )
		if( LocalFileTimeToFileTime( &lc, &ft ) )
		{
			HANDLE han = CreateFile( toStringz(fname),
									 GENERIC_READ | GENERIC_WRITE,
									 FILE_SHARE_READ,NULL,
									 OPEN_EXISTING,
									 FILE_ATTRIBUTE_NORMAL,
									 NULL );
			if( han==INVALID_HANDLE_VALUE )
				return;

			SetFileTime( han,&ft,NULL,&ft );
			CloseHandle( han );
		}
}

//----------------------------------------------------------------
// 指定時刻(DOS形式)より新しいファイルか?
//----------------------------------------------------------------

bool newer_than( ushort d1, ushort t1, char[] fname )
{
	HANDLE han = CreateFile( toStringz(fname),
							 GENERIC_READ | GENERIC_WRITE,
							 FILE_SHARE_READ,NULL,
							 OPEN_EXISTING,
							 FILE_ATTRIBUTE_NORMAL,
							 NULL );
	if( han==INVALID_HANDLE_VALUE )
		return false;
	FILETIME ft;
	GetFileTime( han, null, null, &ft );
	CloseHandle( han );

	FILETIME lc;
	FileTimeToLocalFileTime( &ft, &lc );
	ushort d2, t2;
	FileTimeToDosDateTime( &lc, &d2, &t2 );

	if( d1 < d2 )
		return true;
	if( d1 == d2 )
		return (t1 < t2);
	return false;
}