// Split: Split on ';' // Eg. Property values don't need to be split // // AllowItems: if false, item refs should not be treated as item refs! // it converts them to strings in the final expressionCollection // // AllowMetadata: same as AllowItems, for metadata public void Parse(string expression, ParseOptions options) { bool split = (options & ParseOptions.Split) == ParseOptions.Split; bool allowItems = (options & ParseOptions.AllowItems) == ParseOptions.AllowItems; bool allowMd = (options & ParseOptions.AllowMetadata) == ParseOptions.AllowMetadata; expression = expression.Replace('\\', Path.DirectorySeparatorChar); string [] parts; if (split) { parts = expression.Split(new char [] { ';' }, StringSplitOptions.RemoveEmptyEntries); } else { parts = new string [] { expression } }; // TODO: Too complicated, each part parses only its known part // we should simply do it in one go and avoid all this parts code madness List <ArrayList> p1 = new List <ArrayList> (parts.Length); List <ArrayList> p2 = new List <ArrayList> (parts.Length); List <ArrayList> p3 = new List <ArrayList> (parts.Length); Prepare(p1, parts.Length); Prepare(p2, parts.Length); Prepare(p3, parts.Length); for (int i = 0; i < parts.Length; i++) { p1 [i] = SplitItems(parts [i], allowItems); } for (int i = 0; i < parts.Length; i++) { p2 [i] = new ArrayList(); foreach (object o in p1[i]) { if (o is string) { p2 [i].AddRange(ExtractProperties((string)o)); } else { p2 [i].Add(o); } } } for (int i = 0; i < parts.Length; i++) { p3 [i] = new ArrayList(); foreach (object o in p2[i]) { if (o is string) { p3 [i].AddRange(SplitMetadata((string)o)); } else { p3 [i].Add(o); } } } CopyToExpressionCollection(p3, allowItems, allowMd); } void Prepare(List <ArrayList> l, int length) { for (int i = 0; i < length; i++) { l.Add(null); } } void CopyToExpressionCollection(List <ArrayList> lists, bool allowItems, bool allowMd) { for (int i = 0; i < lists.Count; i++) { foreach (object o in lists[i]) { if (o is string) { expressionCollection.Add(MSBuildUtils.Unescape((string)o)); } else if (!allowItems && o is ItemReference) { expressionCollection.Add(((ItemReference)o).OriginalString); } else if (!allowMd && o is MetadataReference) { expressionCollection.Add(((MetadataReference)o).OriginalString); } else if (o is IReference) { expressionCollection.Add((IReference)o); } } if (i < lists.Count - 1) { expressionCollection.Add(";"); } } } ArrayList SplitItems(string text, bool allowItems) { ArrayList phase1 = new ArrayList(); Match m; m = ItemRegex.Match(text); while (m.Success) { string name = null, transform = null, separator = null; ItemReference ir; name = m.Groups [ItemRegex.GroupNumberFromName("itemname")].Value; if (m.Groups [ItemRegex.GroupNumberFromName("has_transform")].Success) { transform = m.Groups [ItemRegex.GroupNumberFromName("transform")].Value; } if (m.Groups [ItemRegex.GroupNumberFromName("has_separator")].Success) { separator = m.Groups [ItemRegex.GroupNumberFromName("separator")].Value; } ir = new ItemReference(text.Substring(m.Groups [0].Index, m.Groups [0].Length), name, transform, separator, m.Groups [0].Index, m.Groups [0].Length); phase1.Add(ir); m = m.NextMatch(); } ArrayList phase2 = new ArrayList(); int last_end = -1; int end = text.Length - 1; foreach (ItemReference ir in phase1) { int a, b; a = last_end; b = ir.Start; if (b - a - 1 > 0) { phase2.Add(text.Substring(a + 1, b - a - 1)); } last_end = ir.End; phase2.Add(ir); } if (last_end < end) { phase2.Add(text.Substring(last_end + 1, end - last_end)); } return(phase2); }
// Split: Split on ';' // Eg. Property values don't need to be split // // AllowItems: if false, item refs should not be treated as item refs! // it converts them to strings in the final expressionCollection // // AllowMetadata: same as AllowItems, for metadata public void Parse(string expression, ParseOptions options) { bool split = (options & ParseOptions.Split) == ParseOptions.Split; bool allowItems = (options & ParseOptions.AllowItems) == ParseOptions.AllowItems; bool allowMd = (options & ParseOptions.AllowMetadata) == ParseOptions.AllowMetadata; expression = expression.Replace('\\', Path.DirectorySeparatorChar); string [] parts; if (split) { parts = expression.Split(new char [] { ';' }, StringSplitOptions.RemoveEmptyEntries); } else { parts = new string [] { expression } }; List <ArrayList> p1 = new List <ArrayList> (parts.Length); List <ArrayList> p2 = new List <ArrayList> (parts.Length); List <ArrayList> p3 = new List <ArrayList> (parts.Length); Prepare(p1, parts.Length); Prepare(p2, parts.Length); Prepare(p3, parts.Length); for (int i = 0; i < parts.Length; i++) { p1 [i] = SplitItems(parts [i], allowItems); } for (int i = 0; i < parts.Length; i++) { p2 [i] = new ArrayList(); foreach (object o in p1[i]) { if (o is string) { p2 [i].AddRange(SplitProperties((string)o)); } else { p2 [i].Add(o); } } } for (int i = 0; i < parts.Length; i++) { p3 [i] = new ArrayList(); foreach (object o in p2[i]) { if (o is string) { p3 [i].AddRange(SplitMetadata((string)o)); } else { p3 [i].Add(o); } } } CopyToExpressionCollection(p3, allowItems, allowMd); } void Prepare(List <ArrayList> l, int length) { for (int i = 0; i < length; i++) { l.Add(null); } } void CopyToExpressionCollection(List <ArrayList> lists, bool allowItems, bool allowMd) { for (int i = 0; i < lists.Count; i++) { foreach (object o in lists[i]) { if (o is string) { expressionCollection.Add(MSBuildUtils.Unescape((string)o)); } else if (!allowItems && o is ItemReference) { expressionCollection.Add(((ItemReference)o).OriginalString); } else if (!allowMd && o is MetadataReference) { expressionCollection.Add(((MetadataReference)o).OriginalString); } else if (o is IReference) { expressionCollection.Add((IReference)o); } } if (i < lists.Count - 1) { expressionCollection.Add(";"); } } } ArrayList SplitItems(string text, bool allowItems) { ArrayList phase1 = new ArrayList(); Match m; m = ItemRegex.Match(text); while (m.Success) { string name = null, transform = null, separator = null; ItemReference ir; name = m.Groups [ItemRegex.GroupNumberFromName("itemname")].Value; if (m.Groups [ItemRegex.GroupNumberFromName("has_transform")].Success) { transform = m.Groups [ItemRegex.GroupNumberFromName("transform")].Value; } if (m.Groups [ItemRegex.GroupNumberFromName("has_separator")].Success) { separator = m.Groups [ItemRegex.GroupNumberFromName("separator")].Value; } ir = new ItemReference(text.Substring(m.Groups [0].Index, m.Groups [0].Length), name, transform, separator, m.Groups [0].Index, m.Groups [0].Length); phase1.Add(ir); m = m.NextMatch(); } ArrayList phase2 = new ArrayList(); int last_end = -1; int end = text.Length - 1; foreach (ItemReference ir in phase1) { int a, b; a = last_end; b = ir.Start; if (b - a - 1 > 0) { phase2.Add(text.Substring(a + 1, b - a - 1)); } last_end = ir.End; phase2.Add(ir); } if (last_end < end) { phase2.Add(text.Substring(last_end + 1, end - last_end)); } return(phase2); } ArrayList SplitProperties(string text) { ArrayList phase1 = new ArrayList(); Match m; m = PropertyRegex.Match(text); while (m.Success) { PropertyReference pr; Group rg = m.Groups["is_registry"]; if (rg.Success) { string key = m.Groups["key"].Value; string value = ""; if (m.Groups["has_value"].Success) { value = m.Groups["value"].Value; } pr = new PropertyReference(rg.Value, rg.Index, rg.Length, key, value); } else { string name = m.Groups[PropertyRegex.GroupNumberFromName("name")].Value; pr = new PropertyReference(name, m.Groups[0].Index, m.Groups[0].Length); } phase1.Add(pr); m = m.NextMatch(); } ArrayList phase2 = new ArrayList(); int last_end = -1; int end = text.Length - 1; foreach (PropertyReference pr in phase1) { int a, b; a = last_end; b = pr.Start; if (b - a - 1 > 0) { phase2.Add(text.Substring(a + 1, b - a - 1)); } last_end = pr.End; phase2.Add(pr); } if (last_end < end) { phase2.Add(text.Substring(last_end + 1, end - last_end)); } return(phase2); } ArrayList SplitMetadata(string text) { ArrayList phase1 = new ArrayList(); Match m; m = MetadataRegex.Match(text); while (m.Success) { string name = null, meta = null; MetadataReference mr; if (m.Groups [MetadataRegex.GroupNumberFromName("name")].Success) { name = m.Groups [MetadataRegex.GroupNumberFromName("name")].Value; } meta = m.Groups [MetadataRegex.GroupNumberFromName("meta")].Value; mr = new MetadataReference(text.Substring(m.Groups [0].Index, m.Groups [0].Length), name, meta, m.Groups [0].Index, m.Groups [0].Length); phase1.Add(mr); m = m.NextMatch(); } ArrayList phase2 = new ArrayList(); int last_end = -1; int end = text.Length - 1; foreach (MetadataReference mr in phase1) { int a, b; a = last_end; b = mr.Start; if (b - a - 1 > 0) { phase2.Add(text.Substring(a + 1, b - a - 1)); } last_end = mr.End; phase2.Add(mr); } if (last_end < end) { phase2.Add(text.Substring(last_end + 1, end - last_end)); } return(phase2); }