From c5190ae74ab8fe13609362efce88fa4b8cc24f34 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Sat, 30 Dec 2017 17:09:15 -0800 Subject: Fix resolution of localizations that are embedded in intermediates --- .../Bind/ResolveDelayedFieldsCommand.cs | 75 +++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) (limited to 'src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs') diff --git a/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs b/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs index 3ded9a87..6f8da9ec 100644 --- a/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs +++ b/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs @@ -5,6 +5,7 @@ namespace WixToolset.Core.Bind using System; using System.Collections.Generic; using System.Globalization; + using System.Text; using WixToolset.Data; using WixToolset.Extensibility; using WixToolset.Extensibility.Services; @@ -46,7 +47,7 @@ namespace WixToolset.Core.Bind // process properties first in case they refer to other binder variables if (delayedField.Row.Definition.Type == TupleDefinitionType.Property) { - var value = WixVariableResolver.ResolveDelayedVariables(propertyRow.SourceLineNumbers, delayedField.Field.AsString(), this.VariableCache); + var value = ResolveDelayedVariables(propertyRow.SourceLineNumbers, delayedField.Field.AsString(), this.VariableCache); // update the variable cache with the new value var key = String.Concat("property.", propertyRow.AsString(0)); @@ -102,7 +103,7 @@ namespace WixToolset.Core.Bind { try { - var value = WixVariableResolver.ResolveDelayedVariables(delayedField.Row.SourceLineNumbers, delayedField.Field.AsString(), this.VariableCache); + var value = ResolveDelayedVariables(delayedField.Row.SourceLineNumbers, delayedField.Field.AsString(), this.VariableCache); delayedField.Field.Set(value); } catch (WixException we) @@ -111,5 +112,75 @@ namespace WixToolset.Core.Bind } } } + + public static string ResolveDelayedVariables(SourceLineNumber sourceLineNumbers, string value, IDictionary resolutionData) + { + var matches = Common.WixVariableRegex.Matches(value); + + if (0 < matches.Count) + { + var sb = new StringBuilder(value); + + // notice how this code walks backward through the list + // because it modifies the string as we go through it + for (int i = matches.Count - 1; 0 <= i; i--) + { + string variableNamespace = matches[i].Groups["namespace"].Value; + string variableId = matches[i].Groups["fullname"].Value; + string variableDefaultValue = null; + string variableScope = null; + + // get the default value if one was specified + if (matches[i].Groups["value"].Success) + { + variableDefaultValue = matches[i].Groups["value"].Value; + } + + // get the scope if one was specified + if (matches[i].Groups["scope"].Success) + { + variableScope = matches[i].Groups["scope"].Value; + if ("bind" == variableNamespace) + { + variableId = matches[i].Groups["name"].Value; + } + } + + // check for an escape sequence of !! indicating the match is not a variable expression + if (0 < matches[i].Index && '!' == sb[matches[i].Index - 1]) + { + sb.Remove(matches[i].Index - 1, 1); + } + else + { + string key = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", variableId, variableScope).ToLower(CultureInfo.InvariantCulture); + string resolvedValue = variableDefaultValue; + + if (resolutionData.ContainsKey(key)) + { + resolvedValue = resolutionData[key]; + } + + if ("bind" == variableNamespace) + { + // insert the resolved value if it was found or display an error + if (null != resolvedValue) + { + sb.Remove(matches[i].Index, matches[i].Length); + sb.Insert(matches[i].Index, resolvedValue); + } + else + { + throw new WixException(ErrorMessages.UnresolvedBindReference(sourceLineNumbers, value)); + } + } + } + } + + value = sb.ToString(); + } + + return value; + } } } -- cgit v1.2.3-55-g6feb