[Mono-list] System.Text.StringBuilder
Norman Lorrain
normanlorrainmailinglists@telus.net
Wed, 29 Jan 2003 17:45:45 -0700
This is a multi-part message in MIME format.
------=_NextPart_000_0001_01C2C7BE.41120990
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
After changing mcs/class/corlib/Test/run_test.sh, (see attached; this is
based on correspondence with Nick Drochak), I noticed two unit tests
failing for StringBuilder
- the constructor with null string
- the constructor for a given capacity
Based on MSDN doc's I made some changes. Attached is the new
StringBuilder.cs
I also updated the unit tests to Nunit v2, (see attached).
These files were tested with release 0.19. I'm having trouble building
from CVS and so can't get a proper patch.
Norman
------=_NextPart_000_0001_01C2C7BE.41120990
Content-Type: application/octet-stream;
name="StringBuilder.cs"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="StringBuilder.cs"
// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
//
// System.Text.StringBuilder
//
// Author: Marcin Szczepanski (marcins@zipworld.com.au)
//
// TODO: Make sure the coding complies to the ECMA draft, there's some
// variable names that probably don't (like sString)
//
using System.Runtime.CompilerServices;
namespace System.Text {
=09
[Serializable]
public sealed class StringBuilder {
private const int defaultCapacity =3D 16;
private int sCapacity;
private int sLength;
private char[] sString;
private int sMaxCapacity =3D Int32.MaxValue;
public StringBuilder(string value, int startIndex, int length, int =
capacity) {
if(value =3D=3D null) {
value =3D String.Empty;
}
// make sure startIndex is zero or positive
if(startIndex < 0) {
throw new System.ArgumentOutOfRangeException("startIndex", =
startIndex, "StartIndex cannot be less than zero.");
}
// make sure length is zero or positive
if(length < 0) {
throw new System.ArgumentOutOfRangeException("length", length, =
"Length cannot be less than zero.");
}
// make sure startIndex and length give a valid substring of value
if(startIndex + (length -1) > (value.Length - 1) ) {
throw new System.ArgumentOutOfRangeException("startIndex", =
startIndex, "StartIndex and length must refer to a location within the =
string.");
}
=09
if(capacity > sMaxCapacity) {
throw new System.ArgumentOutOfRangeException("capacity", "Capacity =
exceeds maximum capacity.");
}
sCapacity =3D capacity;
// LAMESPEC: what to do if capacity is too small to hold the =
substring?
// Like the MS implementation, double the capacity until it is large =
enough
while (sCapacity < length) {
// However, take care not to double if that would make the number
// larger than what an int can hold
if (sCapacity <=3D Int32.MaxValue / 2) {
sCapacity *=3D 2;
}
else{
sCapacity =3D Int32.MaxValue;
}
}
sString =3D new char[sCapacity];
sLength =3D length;
// if the length is not zero, then we have to copy some characters
if (sLength > 0) {
// Copy the correct number of characters into the internal array
value.CopyTo (startIndex, sString, 0, sLength);
}
}
public StringBuilder () : this(String.Empty, 0, 0, defaultCapacity ) =
{}
public StringBuilder( int capacity ) : this(String.Empty, 0, 0, =
capacity) {}
public StringBuilder( int capacity, int maxCapacity ) : =
this(String.Empty, 0, 0, capacity) {
if(capacity > maxCapacity) {
throw new System.ArgumentOutOfRangeException("capacity", "Capacity =
exceeds maximum capacity.");
}
sMaxCapacity =3D maxCapacity;
}
public StringBuilder( string value ) : this(value, 0, value =3D=3D =
null ? 0 : value.Length, value =3D=3D null? 0 : value.Length) {
}
=09
public StringBuilder( string value, int capacity) : this(value, 0, =
value.Length, capacity) {}
=09
public int MaxCapacity {
get {
// MS runtime always returns Int32.MaxValue.
return sMaxCapacity;
}
}
public int Capacity {
get {
return sCapacity;
}
set {
if( value < sLength ) {
throw new ArgumentException( "Capacity must be > length" );
} else {
char[] tString =3D new char[value]; =20
Array.Copy( sString, tString, sLength );
sString =3D tString;
sCapacity =3D sString.Length;
}
}
}
public int Length {
get {
return sLength;
}
set {
if( value < 0 || value > MaxCapacity) {
throw new ArgumentOutOfRangeException();
} else {
if( value < sLength ) {
// Truncate current string at value
// LAMESPEC: The spec is unclear as to what to do
// with the capacity when truncating the string.
//
// Don't change the capacity, as this is what
// the MS implementation does.
sLength =3D value;
} else {
// Expand the capacity to the new length and
// pad the string with spaces.
=09
// LAMESPEC: The spec says to put the spaces on the
// left of the string however the MS implementation
// puts them on the right. We'll do that for=20
// compatibility (!)
char[] tString =3D new char[ value ];
int padLength =3D value - sLength;
=09
string padding =3D new String( ' ', padLength );
Array.Copy( sString, tString, sLength );
padding.CopyTo (0, sString, sLength, padLength);
sString =3D tString;
sLength =3D sString.Length;
sCapacity =3D value;
}
}
}
}
[IndexerName("Chars")]
public char this[ int index ] {
get {
if( index >=3D sLength || index < 0 ) {
throw new IndexOutOfRangeException();
}
return sString[ index ];
}=20
set {
if( index >=3D sLength || index < 0 ) {
throw new IndexOutOfRangeException();
}
sString[ index ] =3D value;
}
}
public override string ToString() {
return ToString(0, sLength);
}
public string ToString( int startIndex, int length ) {
if( startIndex < 0 || length < 0 || startIndex + length > sLength ) {
throw new ArgumentOutOfRangeException();
}
=09
return new String( sString, startIndex, length );
}
public int EnsureCapacity( int capacity ) {
if( capacity < 0 ) {
throw new ArgumentOutOfRangeException(=20
"Capacity must be greater than 0." );
}
if( capacity <=3D sCapacity ) {
return sCapacity;
} else {
Capacity =3D capacity;
return sCapacity;
}
}
public bool Equals( StringBuilder sb ) {
if(sLength =3D=3D sb.Length && this.ToString() =3D=3D sb.ToString() ) =
{
return true;
} else {
return false;
}
}
public StringBuilder Remove (int startIndex, int length)
{
if( startIndex < 0 || length < 0 || startIndex + length > sLength )
throw new ArgumentOutOfRangeException();
// Copy everything after the 'removed' part to the start=20
// of the removed part and truncate the sLength
Array.Copy (sString, startIndex + length, sString, startIndex,
sLength - (startIndex + length));
sLength -=3D length;
return this;
} =20
public StringBuilder Replace( char oldChar, char newChar ) {
=09
return Replace( oldChar, newChar, 0, sLength);
}
public StringBuilder Replace( char oldChar, char newChar, int =
startIndex, int count ) {
if( startIndex + count > sLength || startIndex < 0 || count < 0 ) {
throw new ArgumentOutOfRangeException();
}
for( int replaceIterate =3D startIndex; replaceIterate < startIndex + =
count; replaceIterate++ ) {
if( this[replaceIterate] =3D=3D oldChar ) {
this[replaceIterate] =3D newChar;
}
}
return this;
}
public StringBuilder Replace( string oldValue, string newValue ) {
return Replace( oldValue, newValue, 0, sLength );
}
public StringBuilder Replace( string oldValue, string newValue, int =
startIndex, int count ) {
string startString =3D this.ToString();
StringBuilder newStringB =3D new StringBuilder();
if( oldValue =3D=3D null ) {=20
throw new ArgumentNullException(
"The old value cannot be null.");
}
if( startIndex < 0 || count < 0 || startIndex + count > sLength ) {
throw new ArgumentOutOfRangeException();
}
if( oldValue.Length =3D=3D 0 ) {
throw new ArgumentException(
"The old value cannot be zero length.");
}
int nextIndex =3D startIndex; // Where to start the next search
int lastIndex =3D nextIndex; // Where the last search finished
while( nextIndex !=3D -1 ) {
nextIndex =3D startString.IndexOf( oldValue, lastIndex); =20
if( nextIndex !=3D -1 ) {
// The MS implementation won't replace a substring=20
// if that substring goes over the "count"
// boundary, so we'll make sure the behaviour=20
// here is the same.
if( nextIndex + oldValue.Length <=3D startIndex + count ) {
// Add everything to the left of the old=20
// string
newStringB.Append( startString.Substring( lastIndex, nextIndex - =
lastIndex ) );
=09
// Add the replacement string
newStringB.Append( newValue );
=09
// Set the next start point to the=20
// end of the last match
lastIndex =3D nextIndex + oldValue.Length;
} else {
// We're past the "count" we're supposed to replace within
nextIndex =3D -1;
newStringB.Append(=20
startString.Substring( lastIndex ) );
}
} else {
// Append everything left over
newStringB.Append( startString.Substring( lastIndex ) );
}
}=20
sCapacity =3D newStringB.sCapacity;
sString =3D newStringB.sString;
sLength =3D newStringB.sLength;
return this;
}
=20
/* The Append Methods */
public StringBuilder Append( char[] value ) {
if( sLength + value.Length > sCapacity ) {
// Need more capacity, double the capacity StringBuilder=20
// and make sure we have at least enough for the value=20
// if that's going to go over double.=20
=20
Capacity =3D value.Length + ( sCapacity + sCapacity);
}
Array.Copy( value, 0, sString, sLength, value.Length );
sLength +=3D value.Length;
return this;
}=20
=09
public StringBuilder Append( string value ) {
if( value !=3D null ) {
int new_size =3D sLength + value.Length;
if (new_size > sCapacity)
Capacity =3D value.Length + sCapacity * 2;
value.CopyTo (0, sString, sLength, value.Length);
sLength =3D new_size;
return this;
} else {
return null;
}
}
public StringBuilder Append( bool value ) {
return Append (value.ToString());
}
=09
public StringBuilder Append( byte value ) {
return Append (value.ToString());
}
public StringBuilder Append( decimal value ) {
return Append (value.ToString());
}
public StringBuilder Append( double value ) {
return Append (value.ToString());
}
public StringBuilder Append( short value ) {
return Append (value.ToString());
}
public StringBuilder Append( int value ) {
return Append (value.ToString());
}
public StringBuilder Append( long value ) {
return Append (value.ToString());
}
public StringBuilder Append( object value ) {
return Append (value.ToString());
}
[CLSCompliant(false)]
public StringBuilder Append( sbyte value ) {
return Append (value.ToString());
}
public StringBuilder Append( float value ) {
return Append (value.ToString());
}
[CLSCompliant(false)]
public StringBuilder Append( ushort value ) {
return Append (value.ToString());
}=09
=09
[CLSCompliant(false)]
public StringBuilder Append( uint value ) {
return Append (value.ToString());
}
[CLSCompliant(false)]
public StringBuilder Append( ulong value ) {
return Append (value.ToString());
}
public StringBuilder Append( char value ) {
if( sLength + 1 > sCapacity ) {
// Need more capacity, double the capacity StringBuilder=20
// and make sure we have at least enough for the value=20
// if that's going to go over double.=20
=20
Capacity =3D 1 + ( sCapacity + sCapacity);
}
sString [sLength] =3D value;
sLength++;
return this;
}
public StringBuilder Append( char value, int repeatCount ) {
if( repeatCount < 0 ) {
throw new ArgumentOutOfRangeException();
}
return Append( new String( value, repeatCount) );
}
public StringBuilder Append( char[] value, int startIndex, int =
charCount ) {
if( (charCount < 0 || startIndex < 0) ||=20
( charCount + startIndex > value.Length ) ) {
throw new ArgumentOutOfRangeException();
}
=09
if( value =3D=3D null ) {
if( !(startIndex =3D=3D 0 && charCount =3D=3D 0) ) {
throw new ArgumentNullException();
} else {
return this;
}
} else {
char[] appendChars =3D new char[ charCount ];
=09
Array.Copy( value, startIndex, appendChars, 0, charCount );
return Append( appendChars );
}
}
public StringBuilder Append( string value, int startIndex, int count ) =
{
if( (count < 0 || startIndex < 0) ||=20
( startIndex + count > value.Length ) ) {=20
throw new ArgumentOutOfRangeException();
}
return Append (value.Substring (startIndex, count));
}
public StringBuilder AppendFormat (string format, object arg0 )
{
string result =3D String.Format (format, arg0);
return Append (result);
}
public StringBuilder AppendFormat (string format, params object[] args =
)
{
string result =3D String.Format (format, args);
return Append (result);
}
public StringBuilder AppendFormat (IFormatProvider provider,
string format,
params object[] args)
{
string result =3D String.Format (provider, format, args);
return Append (result);
}
public StringBuilder AppendFormat (string format, object arg0, object =
arg1 )
{
string result =3D String.Format (format, arg0, arg1);
return Append (result);
}
public StringBuilder AppendFormat (string format, object arg0, object =
arg1, object arg2 )
{
string result =3D String.Format (format, arg0, arg1, arg2);
return Append (result);
}
/* The Insert Functions */
=09
public StringBuilder Insert( int index, char[] value ) {
if( index > sLength || index < 0) {
throw new ArgumentOutOfRangeException();
}
if( value =3D=3D null || value.Length =3D=3D 0 ) {
return this;
} else {
// Check we have the capacity to insert this array
if( sCapacity < sLength + value.Length ) {
Capacity =3D value.Length + ( sCapacity + sCapacity );
}
// Move everything to the right of the insert point across
Array.Copy( sString, index, sString, index + value.Length, sLength - =
index);
=09
// Copy in stuff from the insert buffer
Array.Copy( value, 0, sString, index, value.Length );
=09
sLength +=3D value.Length;
return this;
}
}
=09
public StringBuilder Insert( int index, string value ) {
if (index > sLength || index < 0)
throw new ArgumentOutOfRangeException ("index");
if (value =3D=3D null || value.Length =3D=3D 0)
return this;
int len =3D value.Length;
// Check we have the capacity to insert this array
if (sCapacity < sLength + len)
Capacity =3D len + ( sCapacity + sCapacity );
// Move everything to the right of the insert point across
Array.Copy (sString, index, sString, index + len, sLength - index);
=09
value.CopyTo (0, sString, index, len);
=09
sLength +=3D len;
return this;
}
public StringBuilder Insert( int index, bool value ) {
return Insert( index, value.ToString());
}
=09
public StringBuilder Insert( int index, byte value ) {
return Insert( index, value.ToString());
}
public StringBuilder Insert( int index, char value) {
char[] insertChar =3D new char[1];
=09
insertChar[0] =3D value;
return Insert( index, insertChar );
}
public StringBuilder Insert( int index, decimal value ) {
return Insert( index, value.ToString() );
}
public StringBuilder Insert( int index, double value ) {
return Insert( index, value.ToString() );
}
=09
public StringBuilder Insert( int index, short value ) {
return Insert( index, value.ToString() );
}
public StringBuilder Insert( int index, int value ) {
return Insert( index, value.ToString() );
}
public StringBuilder Insert( int index, long value ) {
return Insert( index, value.ToString() );
}
=09
public StringBuilder Insert( int index, object value ) {
return Insert( index, value.ToString() );
}
=09
[CLSCompliant(false)]
public StringBuilder Insert( int index, sbyte value ) {
return Insert( index, value.ToString() );
}
public StringBuilder Insert( int index, float value ) {
return Insert( index, value.ToString() );
}
[CLSCompliant(false)]
public StringBuilder Insert( int index, ushort value ) {
return Insert( index, value.ToString() );
}
[CLSCompliant(false)]
public StringBuilder Insert( int index, uint value ) {
return Insert( index, value.ToString() );
}
=09
[CLSCompliant(false)]
public StringBuilder Insert( int index, ulong value ) {
return Insert( index, value.ToString() );
}
public StringBuilder Insert( int index, string value, int count ) {
if ( count < 0 ) {
throw new ArgumentOutOfRangeException();
}
if( value !=3D null ) {
if( value !=3D "" ) {
for( int insertCount =3D 0; insertCount < count;=20
insertCount++ ) {
Insert( index, value ); =20
}
}
}
return this;
}
public StringBuilder Insert( int index, char[] value, int startIndex,=20
int charCount ) {
if( value !=3D null ) {
if( charCount < 0 || startIndex < 0 || startIndex + charCount > =
value.Length ) {
throw new ArgumentOutOfRangeException();
}
=09
char[] insertChars =3D new char[ charCount ];
Array.Copy( value, startIndex, insertChars, 0, charCount );
return Insert( index, insertChars );
} else {
return this;
}
}
}
} =20
------=_NextPart_000_0001_01C2C7BE.41120990
Content-Type: application/octet-stream;
name="StringBuilderTest.cs"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="StringBuilderTest.cs"
//
// StringBuilderTest.dll - NUnit Test Cases for the =
System.Text.StringBuilder class
//=20
// Author: Marcin Szczepanski (marcins@zipworld.com.au)
//
// NOTES: I've also run all these tests against the MS implementation of =
// System.Text.StringBuilder to confirm that they return the same =
results
// and they do.
//
// TODO: Add tests for the AppendFormat methods once the AppendFormat =
methods
// are implemented in the StringBuilder class itself
//
// TODO: Potentially add more variations on Insert / Append tests for =
all the
// possible types. I don't really think that's necessary as they all
// pretty much just do .ToString().ToCharArray() and then use the Append =
/ Insert
// CharArray function. The ToString() bit for each type should be in =
the unit
// tests for those types, and the unit test for ToCharArray should be in =
the=20
// string test type. If someone wants to add those tests here for =
completness=20
// (and some double checking) then feel free :)
//
using NUnit.Framework;
using System.Text;
using System;
namespace MonoTests.System.Text {
=09
[TestFixture]
public class StringBuilderTest {
private StringBuilder sb;
[Test]
public void Constructor1()=20
{
// check the parameterless ctor
sb =3D new StringBuilder();
Assertion.AssertEquals(String.Empty, sb.ToString());
Assertion.AssertEquals(0, sb.Length);
Assertion.AssertEquals(16, sb.Capacity);
}
[Test]
public void Constructor2()=20
{
// check ctor that specifies the capacity
sb =3D new StringBuilder(10);
Assertion.AssertEquals(String.Empty, sb.ToString());
Assertion.AssertEquals(0, sb.Length);
// check that capacity is set
Assertion.AssertEquals(10, sb.Capacity);
sb =3D new StringBuilder(42);
Assertion.AssertEquals(String.Empty, sb.ToString());
Assertion.AssertEquals(0, sb.Length);
// check that capacity is set
Assertion.AssertEquals(42, sb.Capacity);
}
=09
[Test]
public void Constructor3() {
// check ctor that specifies the capacity & maxCapacity
sb =3D new StringBuilder(444, 1234);
Assertion.AssertEquals(String.Empty, sb.ToString());
Assertion.AssertEquals(0, sb.Length);
Assertion.AssertEquals(444, sb.Capacity);
Assertion.AssertEquals(1234, sb.MaxCapacity);
}
[Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Constructor4()=20
{
// check for exception in ctor that specifies the capacity & =
maxCapacity
sb =3D new StringBuilder(9999, 15);
=09
}
[Test]
public void Constructor5() {
String someString =3D null;
sb =3D new StringBuilder(someString);
Assertion.AssertEquals("Should be empty string", String.Empty, =
sb.ToString());
}
[Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Constructor6() {
// check for exception in ctor that prevents startIndex less than =
zero
String someString =3D "someString";
sb =3D new StringBuilder(someString, -1, 3, 18);
}
[Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Constructor7() {
// check for exception in ctor that prevents length less than zero
String someString =3D "someString";
sb =3D new StringBuilder(someString, 2, -222, 18);
}
[Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Constructor8() {
// check for exception in ctor that ensures substring is contained in =
given string
// check that startIndex is not too big
String someString =3D "someString";
sb =3D new StringBuilder(someString, 10000, 4, 18);
}
[Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Constructor9() {
// check for exception in ctor that ensures substring is contained in =
given string
// check that length doesn't go beyond end of string
String someString =3D "someString";
sb =3D new StringBuilder(someString, 4, 4000, 18);
}
[Test]
public void Constructor10() {
// check that substring is taken properly and made into a =
StringBuilder
String someString =3D "someString";
sb =3D new StringBuilder(someString, 4, 6, 18);
string expected =3D "String";
Assertion.AssertEquals( expected, sb.ToString());
}
[Test]
public void Append() {
StringBuilder sb =3D new StringBuilder( "Foo" );
sb.Append( "Two" );
string expected =3D "FooTwo";
Assertion.AssertEquals( expected, sb.ToString() );
}
[Test]
public void Insert() {
StringBuilder sb =3D new StringBuilder();
=09
Assertion.AssertEquals( String.Empty, sb.ToString() );=20
/* Test empty StringBuilder conforms to spec */
=09
sb.Insert( 0, "Foo" ); /* Test insert at start of empty string */
=09
Assertion.AssertEquals( "Foo", sb.ToString() );
=09
sb.Insert( 1, "!!" ); /* Test insert not at start of string */
=09
Assertion.AssertEquals( "F!!oo", sb.ToString() );
=09
sb.Insert( 5, ".." ); /* Test insert at end of string */
=09
Assertion.AssertEquals( "F!!oo..", sb.ToString() );
=09
sb.Insert( 0, 1234 ); /* Test insert of a number (at start of string) =
*/
=09
// FIX: Why does this test fail?
//Assertion.AssertEquals( "1234F!!oo..", sb.ToString() );
=09
sb.Insert( 5, 1.5 ); /* Test insert of a decimal (and end of string) =
*/
=09
// FIX: Why does this test fail?
//Assertion.AssertEquals( "1234F1.5!!oo..", sb.ToString() );
=09
sb.Insert( 4, 'A' ); /* Test char insert in middle of string */
=09
// FIX: Why does this test fail?
//Assertion.AssertEquals( "1234AF1.5!!oo..", sb.ToString() );
=09
}
[Test]
public void Replace() {
StringBuilder sb =3D new StringBuilder( "Foobarbaz" );
=09
sb.Replace( "bar", "!!!" ); /* Test same length replace =
in middle of string */
=09
Assertion.AssertEquals( "Foo!!!baz", sb.ToString() );
=09
sb.Replace( "Foo", "ABcD" ); /* Test longer replace at =
start of string */
=09
Assertion.AssertEquals( "ABcD!!!baz", sb.ToString() );
=09
sb.Replace( "baz", "00" ); /* Test shorter replace at =
end of string */
=09
Assertion.AssertEquals( "ABcD!!!00", sb.ToString() );
=09
sb.Replace( sb.ToString(), null ); /* Test string clear as in =
spec */
=09
Assertion.AssertEquals( String.Empty, sb.ToString() );
=09
/* | 10 20 30
/* |0123456789012345678901234567890| */
sb.Append( "abc this is testing abc the abc abc partial replace abc" =
);
=09
sb.Replace( "abc", "!!!", 0, 31 ); /* Partial replace at start of =
string */
=09
Assertion.AssertEquals( "!!! this is testing !!! the !!! abc partial =
replace abc", sb.ToString() );
=09
sb.Replace( "testing", "", 0, 15 ); /* Test replace across boundary =
*/
=09
Assertion.AssertEquals( "!!! this is testing !!! the !!! abc partial =
replace abc", sb.ToString() );
=09
sb.Replace( "!!!", "" ); /* Test replace with empty string */
=09
Assertion.AssertEquals(" this is testing the abc partial replace =
abc", sb.ToString() );
}
[Test]
public void AppendFormat() {
}
}
}
------=_NextPart_000_0001_01C2C7BE.41120990
Content-Type: application/octet-stream;
name="run_test.sh"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="run_test.sh"
#!/bin/sh=0A=
=0A=
if [ $# -eq 0 ]; then=0A=
echo "You should give a list of test names such as: "=0A=
echo "$0 System.IO.FileTest System.Text.StringBuilderTest"=0A=
echo "or"=0A=
echo "$0 System.AllTests"=0A=
echo "and so on..."=0A=
exit 1=0A=
fi=0A=
=0A=
topdir=3D../../..=0A=
NUNITCONSOLE=3D${topdir}/nunit20/nunit-console.exe=0A=
=0A=
for i in $@; do=0A=
MONO_PATH=3D${topdir}/nunit20:. \=0A=
mono ${NUNITCONSOLE} /fixture:MonoTests.${i} corlib_test.dll=0A=
done=0A=
=0A=
------=_NextPart_000_0001_01C2C7BE.41120990--