i've tried different approaches also but they all fail because the
PropertyDictionary.ExpandProperties uses regex to find ${prop} in
strings, and regex is intrinsically lazy. i wouldn't dare change
nant.core directly (!), but indirectly... pls. find attached replacement
code for PropertyDictionary.ExpandProperties, as well as test code. i'm
sorry to not submit a formal patch. i wanted to submit a testable unit
(to prove i didn't break core code).
when/if integrating this, just uncomment the Location stuff and the
BuildException line.
HTH
> -----Original Message-----
> From: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED] On Behalf Of
> Patrick Breen
> Sent: Saturday, December 06, 2003 11:00
> To: [EMAIL PROTECTED]
> Subject: [Nant-users] Property Value Indirection?
>
>
> Is there any way to use indirection when fetching the value
> of a property?
>
> I'd like to be able to establish a set of properties to use
> as data to drive a generic build target implementation. In
> the example below, the per product data is limited to
> version, but there are a handful of properties for each
> product I'd like to define. Then, based on which product is
> active, fetch the appropriate values to drive the build.
>
> I've experimented with different combinations of $,{,} and
> using the 'dynamic' attribute without any luck.
>
>
> <?xml version="1.0" ?>
> <project name="test" default="test">
> <property name="Product1.version" value="1" />
> <property name="Product2.version" value="2" />
> <property name="Product3.version" value="3" />
>
> <property name="products" value="
> Product1,
> Product2,
> Product3" />
>
> <foreach item="String" delim="," trim="Both"
> property="build.product" in="${products}">
> <echo message="${build.product}" />
> <echo message="${${build.product}.version}" />
> </foreach>
> </project>
>
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: SF.net Giveback Program.
> Does SourceForge.net help you be more productive? Does it
> help you create better code? SHARE THE LOVE, and help us
> help YOU! Click Here: http://sourceforge.net/donate/
> _______________________________________________
> Nant-users mailing list
> [EMAIL PROTECTED]
> https://lists.sourceforge.net/lists/listinfo/n> ant-users
>
using System;
using System.Collections;
using System.Text;
namespace propParser
{
class PropertyDictionary : DictionaryBase
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
PropertyDictionary Properties = new PropertyDictionary();
Properties[ "prop1val.prop" ] = "good!";
Properties[ "prop.1" ] = "prop1val";
Properties[ "propr0" ] = "nothing";
Properties[ "prop1" ] = "very good";
Properties[ "prop2" ] = "very ";
Properties[ "prop.dangling" ] = "dangling";
Properties[ "prop.one" ] = "1";
Properties[ "prop.prop" ] = "prop";
AssertEquals( "1 test is good!!", Properties.ExpandProperties("1 test is
${${prop.1}.prop}!") );
AssertEquals( "2 test is good!!", Properties.ExpandProperties( "2 test is
${${${prop.prop}.${prop.one}}.prop}!" ) );
AssertEquals( "3 test is very good!", Properties.ExpandProperties( "3 test is
${prop1}!" ) );
AssertEquals( "4 test is very good!", Properties.ExpandProperties( "4 test is
${prop2}${${prop.1}.prop}" ) );
AssertEquals( "5 dangling ${start", Properties.ExpandProperties( "5 dangling
${start" ) );
AssertEquals( "6 dangling ${start", Properties.ExpandProperties( "6
${prop.dangling} ${start" ) );
AssertEquals( "7 dangling } end", Properties.ExpandProperties( "7
${prop.dangling} } end" ) );
try
{
Properties.ExpandProperties( " not found: ${bozo}");
Console.WriteLine( "SHOULD HAVE NOT FOUND bozo" );
}
catch {}
Console.Write( "press enter..." );
Console.ReadLine();
}
static void AssertEquals( string expected, string actual )
{
if ( ! expected.Equals( actual ) )
Console.WriteLine( string.Format( "Expected \"{0}\" but was \"{1}\"",
expected, actual ) );
}
public virtual string this[string name]
{
get { return (string) Dictionary[(object) name]; }
set
{
Dictionary[name] = value;
}
}
// REAL STUFF STARTS HERE !!!!!!!!
private string ExpandProperties( string input /*, Location location */)
{
// tokenize
ArrayList tokens = new ArrayList();
int pos = 0;
int len;
for( int i = 0; i < input.Length; i++ )
{
len = ( ( input[i]=='$') && (input[i+1]=='{') ) ? 2 : (( input[i]=='}' ) ? 1
: 0 );
if ( len > 0 )
{
if ( i > pos )
tokens.Add( input.Substring( pos, i-pos ));
pos = i + len;
tokens.Add( input.Substring( i, len ));
i += len - 1;
}
}
if ( pos < input.Length )
tokens.Add( input.Substring( pos, input.Length-pos ));
return propResolve( tokens /*, location */) ;
}
private string propResolve( ArrayList tokens /*, Location location */)
{
bool nothing = false;
string propertyName = null;
int start = -1;
string tok = null;
while ( ! nothing )
{
nothing = true;
for( int i=0; i < tokens.Count; i++ )
{
if ( tokens[i] == null ) continue;
tok = tokens[i].ToString();
if ( tok == "${" )
{
propertyName = string.Empty;
start = i;
}
else if ( ( tok == "}") && (start > -1 ) )
{
if ( this[ propertyName ] == null )
// throw new BuildException(String.Format(CultureInfo.InvariantCulture,
"Property '{0}' has not been set!", propertyName), location );
throw new Exception(String.Format( "Property '{0}' has not been set!",
propertyName));
tokens[ start ] = this[ propertyName ] ;
for( int j=start+1; j <= i; j++ )
tokens[ j ] = null;
start = -1;
nothing = false;
}
else if ( start > -1 )
{
propertyName = string.Concat( propertyName, tok );
}
}
}
StringBuilder res = new StringBuilder();
for( int i=0; i < tokens.Count; i++ )
if ( tokens[i] != null )
res.Append( tokens[i] );
return res.ToString();
}
}
}