Artifact Content

Not logged in

Artifact 97a142a9264ab72a52eb58e890296bce21dc31fc


     1  private import std.string;
     2  private import std.file;
     3  private import win32.ansi.windows;
     4  
     5  char lastChar( char[] s )
     6    { return *CharPrev(s, cast(char*)s+s.length); }
     7  
     8  //----------------------------------------------------------------
     9  // int do_opApply!(E, C)( collection, delegate );
    10  // int do_opApply!(E)   (      array, delegate );
    11  //   forwarding the opApply call to another collection
    12  //----------------------------------------------------------------
    13  
    14  template do_opApply( Elem, Collection )
    15  {
    16  	int do_opApply( Collection c, int delegate(inout Elem) dg )
    17  	{
    18  		int result = 0;
    19  		foreach( Elem x ; c )
    20  			if( 0 != (result=dg(x)) )
    21  				break;
    22  		return result;
    23  	}
    24  }
    25  
    26  template do_opApply( E )
    27  {
    28  	int do_opApply( E[] c, int delegate(inout E) dg )
    29  	{
    30  		return .do_opApply!(E,E[])( c, dg );
    31  	}
    32  }
    33  
    34  //----------------------------------------------------------------
    35  // class set!(T)
    36  //   add    :  T -> void
    37  //   remove :  T -> void
    38  //   has    :  T -> bool
    39  //   elems  : () -> T[]
    40  //   length : () -> int
    41  //----------------------------------------------------------------
    42  
    43  class set(T)
    44  {
    45  	void add   ( T x ) { data[x]; }
    46  	void remove( T x ) { delete data[x]; }
    47  	bool has   ( T x ) { return x in data; }
    48  	T[]  elems ()      { return data.keys; }
    49  	int  opApply( int delegate(inout T) dg )
    50  	                   { return do_opApply!(T)( elems, dg ); }
    51  	int  length()      { return data.length; }
    52  	private void[T] data;
    53  }
    54  
    55  unittest
    56  {
    57  	set!(int) x = new set!(int);
    58  	x.add(1);
    59  	x.add(2);
    60  	x.add(3);
    61  	assert( x.elems[0] + x.elems[1] + x.elems[2] == 6 );
    62  	assert( x.length == 3 );
    63  	x.remove(4);
    64  	x.remove(3);
    65  	x.remove(1);
    66  	assert( x.length == 1 );
    67  	foreach( int t ; x ) assert( t==2 );
    68  }
    69  
    70  //----------------------------------------------------------------
    71  // コマンドライン解析
    72  //----------------------------------------------------------------
    73  
    74  char[][] cmd_parse( char[] str, bool in_resp=false )
    75  {
    76  	char[][] ans;
    77  	char resp_char = '@';
    78  
    79  	for(int i=0; i!=str.length; )
    80  	{
    81  		// 空白スキップ
    82  		while( i!=str.length && 0<=str[i] && str[i]<=' ' )
    83  			++i;
    84  		if( i == str.length )
    85  			break;
    86  
    87  		// ""を考慮して一個パラメタ切り出し
    88  		char[] param;
    89  		if( str[i] == '"' )
    90  		{
    91  			int j = ++i;
    92  			while( j!=str.length )
    93  			{
    94  				if( str[j]=='"' &&
    95  				     (j+1==str.length || 0<=str[j+1] && str[j+1]<=' ') )
    96  					break;
    97  				++j;
    98  			}
    99  			param = str[i .. j];
   100  			i = (j==str.length ? j : j+1);
   101  		}
   102  		else
   103  		{
   104  			int j=i;
   105  			while( j!=str.length && (str[j]<0 || ' '<str[j]) )
   106  				++j;
   107  			param = str[i .. j];
   108  			i = j;
   109  		}
   110  
   111  		// レスポンスファイル関連の処理
   112  		if( !in_resp && param[0]==resp_char )
   113  		{
   114  			try {
   115  				char[] rsp = cast(char[]) std.file.read( param[1 .. param.length] );
   116  				ans ~= cmd_parse(rsp,true);
   117  			} catch( FileException e ) {}
   118  		}
   119  		else if( param.length>=2 && param[0..2]=="--" )
   120  		{
   121  			resp_char = (param.length==2 ? '\0' : param[2]);
   122  		}
   123  		else
   124  		{
   125  			ans ~= param; // 普通にパラメタ追加
   126  		}
   127  	}
   128  	return ans;
   129  }
   130  
   131  //----------------------------------------------------------------
   132  // DOS形式でファイル音更新時刻を書き換え
   133  //----------------------------------------------------------------
   134  
   135  void dosSetFTime( char[] fname, ushort date, ushort time )
   136  {
   137  	FILETIME ft,lc;
   138  	if( DosDateTimeToFileTime( date, time, &lc ) )
   139  		if( LocalFileTimeToFileTime( &lc, &ft ) )
   140  		{
   141  			HANDLE han = CreateFile( toStringz(fname),
   142  									 GENERIC_READ | GENERIC_WRITE,
   143  									 FILE_SHARE_READ,NULL,
   144  									 OPEN_EXISTING,
   145  									 FILE_ATTRIBUTE_NORMAL,
   146  									 NULL );
   147  			if( han==INVALID_HANDLE_VALUE )
   148  				return;
   149  
   150  			SetFileTime( han,&ft,NULL,&ft );
   151  			CloseHandle( han );
   152  		}
   153  }
   154  
   155  //----------------------------------------------------------------
   156  // 指定時刻(DOS形式)より新しいファイルか?
   157  //----------------------------------------------------------------
   158  
   159  bool newer_than( ushort d1, ushort t1, char[] fname )
   160  {
   161  	HANDLE han = CreateFile( toStringz(fname),
   162  							 GENERIC_READ | GENERIC_WRITE,
   163  							 FILE_SHARE_READ,NULL,
   164  							 OPEN_EXISTING,
   165  							 FILE_ATTRIBUTE_NORMAL,
   166  							 NULL );
   167  	if( han==INVALID_HANDLE_VALUE )
   168  		return false;
   169  	FILETIME ft;
   170  	GetFileTime( han, null, null, &ft );
   171  	CloseHandle( han );
   172  
   173  	FILETIME lc;
   174  	FileTimeToLocalFileTime( &ft, &lc );
   175  	ushort d2, t2;
   176  	FileTimeToDosDateTime( &lc, &d2, &t2 );
   177  
   178  	if( d1 < d2 )
   179  		return true;
   180  	if( d1 == d2 )
   181  		return (t1 < t2);
   182  	return false;
   183  }
   184