bool EvaluateReference(string str, List <MSBuildItemEvaluated> evaluatedItemsCollection, ref int i, out object val, out bool needsItemEvaluation) { needsItemEvaluation = false; val = null; var tag = str[i]; int start = i; i += 2; int j = FindClosingChar(str, i, ')'); if (j == -1) { val = StringInternPool.AddShared(str, start, str.Length - start); i = str.Length; return(false); } string prop = StringInternPool.AddShared(str, i, j - i).Trim(); i = j + 1; bool res = false; if (prop.Length > 0) { switch (tag) { case '$': { bool nie; res = EvaluateProperty(prop, evaluatedItemsCollection != null, out val, out nie); needsItemEvaluation |= nie; break; } case '%': res = EvaluateMetadata(prop, out val); break; case '@': if (evaluatedItemsCollection != null) { res = EvaluateList(prop, evaluatedItemsCollection, out val); } else { res = false; needsItemEvaluation = true; } break; } } if (!res) { val = StringInternPool.AddShared(str, start, j - start + 1); } return(res); }
string Evaluate(string str, StringBuilder sb, List <MSBuildItemEvaluated> evaluatedItemsCollection, out bool needsItemEvaluation) { needsItemEvaluation = false; if (str == null) { return(null); } int i = FindNextTag(str, 0); if (i == -1) { return(str); } int last = 0; if (sb == null) { sb = GetEvaluationSb(); } try { do { sb.Append(str, last, i - last); int j = i; object val; bool nie; if (!EvaluateReference(str, evaluatedItemsCollection, ref j, out val, out nie)) { allResolved = false; } needsItemEvaluation |= nie; sb.Append(ValueToString(val)); last = j; i = FindNextTag(str, last); }while (i != -1); sb.Append(str, last, str.Length - last); return(StringInternPool.AddShared(sb)); } finally { evaluationSbs.Enqueue(sb); } }
public static object ConsumeUntilNewLine(ref object ws) { if (ws == null) { return(null); } var s = ws as string; if (s != null) { for (int n = s.Length - 1; n >= 0; n--) { var c = s [n]; if (c == '\r' || c == '\n') { if (n == s.Length - 1) { break; // Default case, consume the whole string } int len = n + 1; string res = StringInternPool.AddShared(s, 0, len); ws = StringInternPool.AddShared(s, len, s.Length - len); return(res); } } var result = ws; ws = null; return(result); } var sb = ws as StringBuilder; if (sb != null) { for (int n = sb.Length - 1; n >= 0; n--) { var c = sb [n]; if (c == '\r' || c == '\n') { if (n == sb.Length - 1) { break; // Default case, consume the whole string } var res = sb.ToString(0, n + 1); sb.Remove(0, n + 1); return(res); } } string result = StringInternPool.AddShared(sb); ws = null; return(result); } // It's a MSBuildWhitespace var mw = (MSBuildWhitespace)ws; mw.GenerateStrings(); var toSplit = mw.FindLastWithNewLine(); if (toSplit == null) { var result = ws; ws = null; return(result); } else { var remaining = toSplit.content; var result = ConsumeUntilNewLine(ref remaining); // Set the remaining value if (toSplit.next == null) { // New line found in last node. The remaining is just the split string ws = remaining; } else { if (remaining == null) { return(toSplit.next); // Consumed the whole string of this node. The remaining is the next node } // New line found in the middle of the chain. A new node with the remaining has to be created ws = new MSBuildWhitespace { content = remaining, next = toSplit.next }; } // Generate the consumed value if (toSplit != mw) { // New line found in the middle of the chain. Update the node content and split the chain. toSplit.content = result; toSplit.next = null; return(mw); } else { // New line found in first node. The result is just the consumed string. Nothing else to do. return(result); } } }