Move internals from Microsoft.Build.Tasks to new dll Mono.XBuild.Tasks
authorAntonius Riha <antoniusriha@gmail.com>
Mon, 30 Dec 2013 20:41:32 +0000 (21:41 +0100)
committerAntonius Riha <antoniusriha@gmail.com>
Thu, 2 Jan 2014 20:14:53 +0000 (21:14 +0100)
All internal members (such as PcFileCache) have been made public to make them unit-testable.

* mcs/class/Makefile: Add Mono.XBuild.Tasks as build target

* mcs/class/Microsoft.Build.Tasks/Makefile: Add Mono.XBuild.Tasks.dll as build
  reference of Microsoft.Build.Tasks.dll

* mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks-net_2_0.csproj:
* mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks-net_3_5.csproj:
* mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks-net_4_0.csproj:
* mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks-net_4_5.csproj: Remove
  source files, which have been moved to Mono.XBuild.Tasks.dll and add a
  project reference to Mono.XBuild.Tasks.dll

* mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks.dll.sources: Remove
  files that have been moved to Mono.XBuild.Tasks.dll from
  Microsoft.Build.Tasks.dll

* mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/PcFileCache.cs:
* mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/LibraryPcFileCache.cs:
  This file was moved to Mono.XBuild.Tasks.dll

* mcs/class/Mono.XBuild.Tasks/Assembly/AssemblyInfo.cs: Moved from
  Microsoft.Build.Tasks.dll. Signing key is mono.pub.

* mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks/PcFileCache.cs:
* mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks/LibraryPcFileCache.cs:
  Moved from Microsoft.Build.Tasks.dll. All internal members have been made
  public.

* mcs/class/Mono.XBuild.Tasks/Test/Mono.XBuild.Tasks/PcFileCacheTest.cs: Create
  test file stub.

24 files changed:
mcs/class/Makefile
mcs/class/Microsoft.Build.Tasks/Makefile
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks-net_2_0.csproj
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks-net_3_5.csproj
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks-net_4_0.csproj
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks-net_4_5.csproj
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks.dll.sources
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/LibraryPcFileCache.cs [deleted file]
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/PcFileCache.cs [deleted file]
mcs/class/Mono.XBuild.Tasks/Assembly/AssemblyInfo.cs [new file with mode: 0644]
mcs/class/Mono.XBuild.Tasks/Makefile [new file with mode: 0644]
mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-net_2_0.csproj [new file with mode: 0644]
mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-net_3_5.csproj [new file with mode: 0644]
mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-net_4_0.csproj [new file with mode: 0644]
mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-net_4_5.csproj [new file with mode: 0644]
mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-tests-net_2_0.csproj [new file with mode: 0644]
mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-tests-net_3_5.csproj [new file with mode: 0644]
mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-tests-net_4_0.csproj [new file with mode: 0644]
mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-tests-net_4_5.csproj [new file with mode: 0644]
mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks.dll.sources [new file with mode: 0644]
mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks/LibraryPcFileCache.cs [new file with mode: 0644]
mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks/PcFileCache.cs [new file with mode: 0644]
mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks_test.dll.sources [new file with mode: 0644]
mcs/class/Mono.XBuild.Tasks/Test/Mono.XBuild.Tasks/PcFileCacheTest.cs [new file with mode: 0644]

index aa37aebd10e8a2a0a96a9fbaa5bbdb1aaca23d49..79f1f9d618cb5a86c15cfe9d0aede507e04316a3 100644 (file)
@@ -91,6 +91,7 @@ net_2_0_dirs := \
        Microsoft.Build.Framework       \
        Microsoft.Build.Utilities       \
        Microsoft.Build.Engine          \
+       Mono.XBuild.Tasks                       \
        Microsoft.Build.Tasks           \
        System.Xml.Linq                 \
        System.Runtime.Serialization    \
@@ -173,6 +174,7 @@ net_3_5_only_dirs := \
        Microsoft.Build.Framework       \
        Microsoft.Build.Utilities       \
        Microsoft.Build.Engine          \
+       Mono.XBuild.Tasks                       \
        Microsoft.Build.Tasks
 
 net_4_0_dirs := \
index 18288e01177436838159bc48827d8928cf7cdcf3..4161a45b51cb2134b7443ffd3ce69a194c7fdba3 100644 (file)
@@ -5,11 +5,13 @@ include ../../build/rules.make
 LIBRARY = Microsoft.Build.Tasks.dll
 BUILD_FRAMEWORK = Microsoft.Build.Framework.dll
 BUILD_ENGINE = Microsoft.Build.Engine.dll
+XBUILD_TASKS = Mono.XBuild.Tasks.dll
 
 ifeq (3.5, $(FRAMEWORK_VERSION))
 NAME_SUFFIX = .v3.5
 BUILD_FRAMEWORK := $(topdir)/class/lib/$(PROFILE)/$(BUILD_FRAMEWORK)
 BUILD_ENGINE := $(topdir)/class/lib/$(PROFILE)/$(BUILD_ENGINE)
+XBUILD_TASKS := $(topdir)/class/lib/$(PROFILE)/$(XBUILD_TASKS)
 else
 ifeq (4, $(FRAMEWORK_VERSION_MAJOR))
 NAME_SUFFIX = .v4.0
@@ -29,11 +31,13 @@ LIB_MCS_FLAGS = \
        /r:System.Windows.Forms.dll             \
        /r:Microsoft.Build.Utilities$(NAME_SUFFIX).dll  \
        /r:$(BUILD_FRAMEWORK)   \
-       /r:$(BUILD_ENGINE)
+       /r:$(BUILD_ENGINE)              \
+       /r:$(XBUILD_TASKS)
 
 TEST_MCS_FLAGS = \
        /r:$(BUILD_ENGINE)      \
        /r:$(BUILD_FRAMEWORK)   \
+       /r:$(XBUILD_TASKS)              \
        /r:Microsoft.Build.Utilities$(NAME_SUFFIX).dll \
        /r:System.Core.dll
 
index 6d196e931da88ceb9913181ff9ed13321cf1cc4a..39fdfbca0de2c3e077779c04a8275230bb97b2e4 100644 (file)
     <Compile Include="Microsoft.Build.Tasks\GetFrameworkSdkPath.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\GetReferenceAssemblyPaths.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\LC.cs" />\r
-    <Compile Include="Microsoft.Build.Tasks\LibraryPcFileCache.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\MakeDir.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\ManagedCompiler.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\Message.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\MSBuild.cs" />\r
-    <Compile Include="Microsoft.Build.Tasks\PcFileCache.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\ReadLinesFromFile.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\RegisterAssembly.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\RemoveDir.cs" />\r
       <Project>{E8E948B8-6DCF-48F2-A6BC-04309AED8740}</Project>\r
       <Name>Microsoft.Build.Engine\Microsoft.Build.Engine-net_2_0</Name>\r
     </ProjectReference>\r
+    <ProjectReference Include="..\Mono.XBuild.Tasks\Mono.XBuild.Tasks-net_2_0.csproj">\r
+      <Project>{F5F84165-0541-4828-A81E-0AA1836E50C1}</Project>\r
+      <Name>Mono.XBuild.Tasks-net_2_0</Name>\r
+    </ProjectReference>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Folder Include="Properties\" />\r
index 014cf446e0446a6135d1431d7e59eb07140f9ca2..7f9ae420975a0b661a21a94959f6a5fe0ab08d78 100644 (file)
     <Compile Include="Microsoft.Build.Tasks\GetFrameworkSdkPath.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\GetReferenceAssemblyPaths.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\LC.cs" />\r
-    <Compile Include="Microsoft.Build.Tasks\LibraryPcFileCache.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\MakeDir.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\ManagedCompiler.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\Message.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\MSBuild.cs" />\r
-    <Compile Include="Microsoft.Build.Tasks\PcFileCache.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\ReadLinesFromFile.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\RegisterAssembly.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\RemoveDir.cs" />\r
       <Project>{874516A3-F5F6-4EAB-B005-4D1A567C5E4D}</Project>\r
       <Name>Microsoft.Build.Engine\Microsoft.Build.Engine-net_3_5</Name>\r
     </ProjectReference>\r
+    <ProjectReference Include="..\Mono.XBuild.Tasks\Mono.XBuild.Tasks-net_3_5.csproj">\r
+      <Project>{7B888FCD-9064-4F4A-954E-795B43F98127}</Project>\r
+      <Name>Mono.XBuild.Tasks-net_3_5</Name>\r
+    </ProjectReference>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Folder Include="Properties\" />\r
index b52f6278696e80854bf61bbe12ab5c503c973d1a..f883f4f7889cbf93f6531eecc2ac9cb16a5ff254 100644 (file)
     <Compile Include="Microsoft.Build.Tasks\GetFrameworkSdkPath.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\GetReferenceAssemblyPaths.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\LC.cs" />\r
-    <Compile Include="Microsoft.Build.Tasks\LibraryPcFileCache.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\MakeDir.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\ManagedCompiler.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\Message.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\MSBuild.cs" />\r
-    <Compile Include="Microsoft.Build.Tasks\PcFileCache.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\ReadLinesFromFile.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\RegisterAssembly.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\RemoveDir.cs" />\r
       <Project>{9B0AC297-CB85-43C1-8C18-12997CF1B78D}</Project>\r
       <Name>Microsoft.Build.Engine\Microsoft.Build.Engine-net_4_0</Name>\r
     </ProjectReference>\r
+    <ProjectReference Include="..\Mono.XBuild.Tasks\Mono.XBuild.Tasks-net_4_0.csproj">\r
+      <Project>{F7F03F9B-6E7A-43BD-993A-7F197A440150}</Project>\r
+      <Name>Mono.XBuild.Tasks-net_4_0</Name>\r
+    </ProjectReference>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Folder Include="Properties\" />\r
index 657ee6fc25111e8556221d54f3fc488832749005..7af8b85741ec45b24968f14295eade24e958e192 100644 (file)
     <Compile Include="Microsoft.Build.Tasks\GetFrameworkSdkPath.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\GetReferenceAssemblyPaths.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\LC.cs" />\r
-    <Compile Include="Microsoft.Build.Tasks\LibraryPcFileCache.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\MakeDir.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\ManagedCompiler.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\Message.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\MSBuild.cs" />\r
-    <Compile Include="Microsoft.Build.Tasks\PcFileCache.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\ReadLinesFromFile.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\RegisterAssembly.cs" />\r
     <Compile Include="Microsoft.Build.Tasks\RemoveDir.cs" />\r
       <Project>{0DA63190-E6E1-41C5-B683-A54FADBE61CB}</Project>\r
       <Name>Microsoft.Build.Engine\Microsoft.Build.Engine-net_4_5</Name>\r
     </ProjectReference>\r
+    <ProjectReference Include="..\Mono.XBuild.Tasks\Mono.XBuild.Tasks-net_4_5.csproj">\r
+      <Project>{9AC58525-C730-4552-A8FA-332979FCD055}</Project>\r
+      <Name>Mono.XBuild.Tasks-net_4_5</Name>\r
+    </ProjectReference>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Folder Include="Properties\" />\r
index fb30b46bc2a0166be16fc780c7c45a557fb45b0b..e61c90c6300a94d142169618f4124eb64eab0144 100644 (file)
@@ -87,8 +87,6 @@ Microsoft.Build.Tasks/MakeDir.cs
 Microsoft.Build.Tasks/ManagedCompiler.cs
 Microsoft.Build.Tasks/Message.cs
 Microsoft.Build.Tasks/MSBuild.cs
-Microsoft.Build.Tasks/PcFileCache.cs
-Microsoft.Build.Tasks/LibraryPcFileCache.cs
 Microsoft.Build.Tasks/ReadLinesFromFile.cs
 Microsoft.Build.Tasks/RegisterAssembly.cs
 Microsoft.Build.Tasks/RemoveDir.cs
diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/LibraryPcFileCache.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/LibraryPcFileCache.cs
deleted file mode 100644 (file)
index f29a591..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-// 
-// PcFileCacheAssembly.cs
-//  
-// Author:
-//       Lluis Sanchez Gual <lluis@novell.com>
-// 
-// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
-// 
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-// 
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-using System;
-using System.Text;
-using System.Xml;
-using System.IO;
-using System.Collections.Generic;
-
-// IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
-// This code is shared with xbuild, which has to build with .NET 2.0,
-// so no c# 3.0 syntax is allowed here.
-
-namespace Mono.PkgConfig
-{
-       internal class LibraryPcFileCache: PcFileCache<LibraryPackageInfo>
-       {
-               Dictionary<string, PackageAssemblyInfo> assemblyLocations;
-               
-               public LibraryPcFileCache (IPcFileCacheContext<LibraryPackageInfo> ctx): base (ctx)
-               {
-               }
-               
-               protected override string CacheDirectory {
-                       get {
-                               string path = Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData);
-                               path = Path.Combine (path, "xbuild");
-                               return path;
-                       }
-               }
-               
-               // Returns the location of an assembly, given the full name
-               public PackageAssemblyInfo GetAssemblyLocation (string fullName)
-               {
-                       return GetAssemblyLocation (fullName, null);
-               }
-               
-               public PackageAssemblyInfo GetAssemblyLocation (string fullName, IEnumerable<string> searchPaths)
-               {
-                       lock (SyncRoot) {
-                               if (assemblyLocations == null) {
-                                       // Populate on demand
-                                       assemblyLocations = new Dictionary<string, PackageAssemblyInfo> ();
-                                       foreach (LibraryPackageInfo info in GetPackages (searchPaths)) {
-                                               if (info.IsValidPackage) {
-                                                       foreach (PackageAssemblyInfo asm in info.Assemblies)
-                                                               assemblyLocations [NormalizeAsmName (asm.FullName)] = asm;
-                                               }
-                                       }
-                               }
-                       }
-                       // This collection is read-only once built, so there is no need for a lock
-                       PackageAssemblyInfo pasm;
-                       assemblyLocations.TryGetValue (NormalizeAsmName (fullName), out pasm);
-                       return pasm;
-               }
-               
-               public IEnumerable<PackageAssemblyInfo> ResolveAssemblyName (string name)
-               {
-                       return ResolveAssemblyName (name, null);
-               }
-               
-               public IEnumerable<PackageAssemblyInfo> ResolveAssemblyName (string name, IEnumerable<string> searchPaths)
-               {
-                       foreach (LibraryPackageInfo pinfo in GetPackages (searchPaths)) {
-                               if (pinfo.IsValidPackage) {
-                                       foreach (PackageAssemblyInfo asm in pinfo.Assemblies) {
-                                               if (asm.Name == name)
-                                                       yield return asm;
-                                       }
-                               }
-                       }
-               }
-               
-               protected override void WritePackageContent (XmlTextWriter tw, string file, LibraryPackageInfo pinfo)
-               {
-                       foreach (PackageAssemblyInfo asm in pinfo.Assemblies) {
-                               tw.WriteStartElement ("Assembly");
-                               tw.WriteAttributeString ("name", asm.Name);
-                               tw.WriteAttributeString ("version", asm.Version);
-                               tw.WriteAttributeString ("culture", asm.Culture);
-                               tw.WriteAttributeString ("publicKeyToken", asm.PublicKeyToken);
-                               tw.WriteAttributeString ("file", asm.File);
-                               tw.WriteEndElement (); // Assembly
-                       }
-               }
-               
-               protected override void ReadPackageContent (XmlReader tr, LibraryPackageInfo pinfo)
-               {
-                       while (tr.NodeType == XmlNodeType.Element) {
-                               PackageAssemblyInfo asm = new PackageAssemblyInfo ();
-                               asm.Name = tr.GetAttribute ("name");
-                               asm.Version = tr.GetAttribute ("version");
-                               asm.Culture = tr.GetAttribute ("culture");
-                               asm.PublicKeyToken = tr.GetAttribute ("publicKeyToken");
-                               asm.File = tr.GetAttribute ("file");
-                               if (pinfo.Assemblies == null)
-                                       pinfo.Assemblies = new List<PackageAssemblyInfo> ();
-                               asm.ParentPackage = pinfo;
-                               pinfo.Assemblies.Add (asm);
-                               tr.Read ();
-                               tr.MoveToContent ();
-                       }
-               }
-               
-               protected override void ParsePackageInfo (PcFile file, LibraryPackageInfo pinfo)
-               {
-                       List<string> fullassemblies = null;
-                       bool gacPackageSet = false;
-                       
-                       if (file.Libs != null && file.Libs.IndexOf (".dll") != -1) {
-                               if (file.Libs.IndexOf ("-lib:") != -1 || file.Libs.IndexOf ("/lib:") != -1) {
-                                       fullassemblies = GetAssembliesWithLibInfo (file.Libs);
-                               } else {
-                                       fullassemblies = GetAssembliesWithoutLibInfo (file.Libs);
-                               }
-                       }
-                       
-                       string value = file.GetVariable ("Libraries");
-                       if (!string.IsNullOrEmpty (value))
-                               fullassemblies = GetAssembliesFromLibrariesVar (value);
-                       
-                       value = file.GetVariable ("GacPackage");
-                       if (value != null) {
-                               pinfo.IsGacPackage = 
-                                       string.Equals (value, "yes", StringComparison.OrdinalIgnoreCase) ||
-                                       string.Equals (value, "true", StringComparison.OrdinalIgnoreCase);
-                               gacPackageSet = true;
-                       }
-       
-                       if (fullassemblies == null)
-                               return;
-                       
-                       string pcDir = Path.GetDirectoryName (file.FilePath);
-                       string monoPrefix = Path.GetDirectoryName (Path.GetDirectoryName (pcDir));
-                       monoPrefix = Path.GetFullPath (monoPrefix + Path.DirectorySeparatorChar + "lib" + Path.DirectorySeparatorChar + "mono" + Path.DirectorySeparatorChar);
-
-                       List<PackageAssemblyInfo> list = new List<PackageAssemblyInfo> ();
-                       foreach (string assembly in fullassemblies) {
-                               string asm;
-                               if (Path.IsPathRooted (assembly))
-                                       asm = Path.GetFullPath (assembly);
-                               else {
-                                       if (Path.GetDirectoryName (assembly).Length == 0) {
-                                               asm = assembly;
-                                       } else {
-                                               asm = Path.GetFullPath (Path.Combine (pcDir, assembly));
-                                       }
-                               }
-                               if (File.Exists (asm)) {
-                                       PackageAssemblyInfo pi = new PackageAssemblyInfo ();
-                                       pi.File = asm;
-                                       pi.ParentPackage = pinfo;
-                                       pi.UpdateFromFile (pi.File);
-                                       list.Add (pi);
-                                       if (!gacPackageSet && !asm.StartsWith (monoPrefix) && Path.IsPathRooted (asm)) {
-                                               // Assembly installed outside $(prefix)/lib/mono. It is most likely not a gac package.
-                                               gacPackageSet = true;
-                                               pinfo.IsGacPackage = false;
-                                       }
-                               }
-                       }
-                       pinfo.Assemblies = list;
-               }
-               
-               private List<string> GetAssembliesWithLibInfo (string line)
-               {
-                       List<string> references = new List<string> ();
-                       List<string> libdirs = new List<string> ();
-                       List<string> retval = new List<string> ();
-                       foreach (string piece in line.Split (' ')) {
-                               if (IsReferenceParameter (piece)) {
-                                       references.Add (piece.Substring (3).Trim ());
-                               } else if (piece.TrimStart ().StartsWith ("/lib:", StringComparison.OrdinalIgnoreCase) ||
-                                               piece.TrimStart ().StartsWith ("-lib:", StringComparison.OrdinalIgnoreCase)) {
-                                       libdirs.Add (piece.Substring (5).Trim ());
-                               }
-                       }
-       
-                       foreach (string refrnc in references) {
-                               foreach (string libdir in libdirs) {
-                                       if (File.Exists (libdir + Path.DirectorySeparatorChar + refrnc)) {
-                                               retval.Add (libdir + Path.DirectorySeparatorChar + refrnc);
-                                       }
-                               }
-                       }
-       
-                       return retval;
-               }
-
-               static bool IsReferenceParameter (string value)
-               {
-                       return value.TrimStart ().StartsWith ("/r:", StringComparison.OrdinalIgnoreCase) ||
-                               value.TrimStart ().StartsWith ("-r:", StringComparison.OrdinalIgnoreCase);
-               }
-               
-               List<string> GetAssembliesFromLibrariesVar (string line)
-               {
-                       List<string> references = new List<string> ();
-                       foreach (string reference in line.Split (' ')) {
-                               if (!string.IsNullOrEmpty (reference))
-                                       references.Add (reference);
-                       }
-                       return references;
-               }
-       
-               private List<string> GetAssembliesWithoutLibInfo (string line)
-               {
-                       List<string> references = new List<string> ();
-                       foreach (string reference in line.Split (' ')) {
-                               if (IsReferenceParameter (reference)) {
-                                       string final_ref = reference.Substring (3).Trim ();
-                                       references.Add (final_ref);
-                               }
-                       }
-                       return references;
-               }
-               
-               public static string NormalizeAsmName (string name)
-               {
-                       int i = name.IndexOf (", publickeytoken=null", StringComparison.OrdinalIgnoreCase);
-                       if (i != -1)
-                               name = name.Substring (0, i).Trim ();
-                       i = name.IndexOf (", processorarchitecture=", StringComparison.OrdinalIgnoreCase);
-                       if (i != -1)
-                               name = name.Substring (0, i).Trim ();
-                       return name;
-               }
-       }
-       
-       internal class LibraryPackageInfo: PackageInfo
-       {
-               public bool IsGacPackage {
-                       get { return GetData ("gacPackage") != "false"; }
-                       set {
-                               if (value)
-                                       RemoveData ("gacPackage");
-                               else
-                                       SetData ("gacPackage", "false");
-                       }
-               }
-               
-               internal List<PackageAssemblyInfo> Assemblies { get; set; }
-               
-               internal protected override bool IsValidPackage {
-                       get { return Assemblies != null && Assemblies.Count > 0; }
-               }
-       }
-       
-       internal class PackageAssemblyInfo
-       {
-               public string File { get; set; }
-               
-               public string Name;
-               
-               public string Version;
-               
-               public string Culture;
-               
-               public string PublicKeyToken;
-               
-               public string FullName {
-                       get {
-                               string fn = Name + ", Version=" + Version;
-                               if (!string.IsNullOrEmpty (Culture))
-                                       fn += ", Culture=" + Culture;
-                               if (!string.IsNullOrEmpty (PublicKeyToken))
-                                       fn += ", PublicKeyToken=" + PublicKeyToken;
-                               return fn;
-                       }
-               }
-               
-               public LibraryPackageInfo ParentPackage { get; set; }
-               
-               public void UpdateFromFile (string file)
-               {
-                       Update (System.Reflection.AssemblyName.GetAssemblyName (file));
-               }
-               
-               public void Update (System.Reflection.AssemblyName aname)
-               {
-                       Name = aname.Name;
-                       Version = aname.Version.ToString ();
-                       if (aname.CultureInfo != null) {
-                               if (aname.CultureInfo.LCID == System.Globalization.CultureInfo.InvariantCulture.LCID)
-                                       Culture = "neutral";
-                               else
-                                       Culture = aname.CultureInfo.Name;
-                       }
-                       string fn = aname.ToString ();
-                       string key = "publickeytoken=";
-                       int i = fn.IndexOf (key, StringComparison.OrdinalIgnoreCase) + key.Length;
-                       int j = fn.IndexOf (',', i);
-                       if (j == -1) j = fn.Length;
-                       PublicKeyToken = fn.Substring (i, j - i);
-               }
-       }
-}
diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/PcFileCache.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/PcFileCache.cs
deleted file mode 100644 (file)
index aa96a31..0000000
+++ /dev/null
@@ -1,646 +0,0 @@
-// 
-// PcFileCache.cs
-//  
-// Author:
-//       Lluis Sanchez Gual <lluis@novell.com>
-// 
-// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
-// 
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-// 
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-using System;
-using System.Text;
-using System.Xml;
-using System.IO;
-using System.Collections.Generic;
-
-// IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
-// This code is shared with xbuild, which has to build with .NET 2.0,
-// so no c# 3.0 syntax is allowed here.
-
-namespace Mono.PkgConfig
-{
-       internal interface IPcFileCacheContext<TP> where TP:PackageInfo, new()
-       {
-               // In the implementation of this method, the host application can extract
-               // information from the pc file and store it in the PackageInfo object
-               void StoreCustomData (PcFile pcfile, TP pkg);
-               
-               // Should return false if the provided package does not have required
-               // custom data
-               bool IsCustomDataComplete (string pcfile, TP pkg);
-               
-               // Called to report errors
-               void ReportError (string message, Exception ex);
-       }
-       
-       internal interface IPcFileCacheContext: IPcFileCacheContext<PackageInfo>
-       {
-       }
-       
-       internal abstract class PcFileCache: PcFileCache<PackageInfo>
-       {
-               public PcFileCache (IPcFileCacheContext ctx): base (ctx)
-               {
-               }
-       }
-       
-       internal abstract class PcFileCache<TP> where TP:PackageInfo, new()
-       {
-               const string CACHE_VERSION = "2";
-               const string MacOSXExternalPkgConfigDir = "/Library/Frameworks/Mono.framework/External/pkgconfig";
-               
-               Dictionary<string, TP> infos = new Dictionary<string, TP> ();
-               Dictionary<string, List<TP>> filesByFolder = new Dictionary<string, List<TP>> ();
-               
-               string cacheFile;
-               bool hasChanges;
-               IPcFileCacheContext<TP> ctx;
-               IEnumerable<string> defaultPaths;
-               
-               public PcFileCache (IPcFileCacheContext<TP> ctx)
-               {
-                       this.ctx = ctx;
-                       try {
-                               string path = CacheDirectory;
-                               if (!Directory.Exists (path))
-                                       Directory.CreateDirectory (path);
-                               cacheFile = Path.Combine (path, "pkgconfig-cache-" + CACHE_VERSION + ".xml");
-                               
-                               if (File.Exists (cacheFile))
-                                       Load ();
-                               
-                       } catch (Exception ex) {
-                               ctx.ReportError ("pc file cache could not be loaded.", ex);
-                       }
-               }
-               
-               protected abstract string CacheDirectory { get; }
-               
-               // Updates the pkg-config index, using the default search directories
-               public void Update ()
-               {
-                       Update (GetDefaultPaths ());
-               }
-
-               // Updates the pkg-config index, looking for .pc files in the provided directories
-               public void Update (IEnumerable<string> pkgConfigDirs)
-               {
-                       foreach (string pcdir in pkgConfigDirs) {
-                               foreach (string pcfile in Directory.GetFiles (pcdir, "*.pc"))
-                                       GetPackageInfo (pcfile);
-                       }
-                       Save ();
-               }
-               
-               public IEnumerable<TP> GetPackages ()
-               {
-                       return GetPackages (null);
-               }
-               
-               public IEnumerable<TP> GetPackages (IEnumerable<string> pkgConfigDirs)
-               {
-                       if (pkgConfigDirs == null)
-                               pkgConfigDirs = GetDefaultPaths ();
-
-                       foreach (string sp in pkgConfigDirs) {
-                               List<TP> list;
-                               if (filesByFolder.TryGetValue (Path.GetFullPath (sp), out list)) {
-                                       foreach (TP p in list)
-                                               yield return p;
-                               }
-                       }
-               }
-               
-               public TP GetPackageInfoByName (string name)
-               {
-                       return GetPackageInfoByName (name, null);
-               }
-               
-               public TP GetPackageInfoByName (string name, IEnumerable<string> pkgConfigDirs)
-               {
-                       foreach (TP p in GetPackages (pkgConfigDirs))
-                               if (p.Name == name)
-                                       return p;
-                       return null;
-               }
-               
-               // Returns information about a .pc file
-               public TP GetPackageInfo (string file)
-               {
-                       TP info, oldInfo = null;
-                       file = Path.GetFullPath (file);
-                       
-                       DateTime wtime = File.GetLastWriteTime (file);
-                       
-                       lock (infos) {
-                               if (infos.TryGetValue (file, out info)) {
-                                       if (info.LastWriteTime == wtime)
-                                               return info;
-                                       oldInfo = info;
-                               }
-                       }
-
-                       try {
-                               info = ParsePackageInfo (file);
-                       } catch (Exception ex) {
-                               ctx.ReportError ("Error while parsing .pc file: " + file, ex);
-                               info = new TP ();
-                       }
-                       
-                       lock (infos) {
-                               if (!info.IsValidPackage)
-                                       info = new TP (); // Create a default empty instance
-                               info.LastWriteTime = wtime;
-                               Add (file, info, oldInfo);
-                               hasChanges = true;
-                       }
-                       
-                       return info;
-               }
-               
-               void Add (string file, TP info, TP replacedInfo)
-               {
-                       infos [file] = info;
-                       string dir = Path.GetFullPath (Path.GetDirectoryName (file));
-                       List<TP> list;
-                       if (!filesByFolder.TryGetValue (dir, out list)) {
-                               list = new List<TP> ();
-                               filesByFolder [dir] = list;
-                       }
-                       if (replacedInfo != null) {
-                               int i = list.IndexOf (replacedInfo);
-                               if (i != -1) {
-                                       list [i] = info;
-                                       return;
-                               }
-                       }
-                       list.Add (info);
-               }
-               
-               FileStream OpenFile (FileAccess access)
-               {
-                       int retries = 6;
-                       FileMode mode = access == FileAccess.Read ? FileMode.Open : FileMode.Create;
-                       Exception lastException = null;
-                       
-                       while (retries > 0) {
-                               try {
-                                       return new FileStream (cacheFile, mode, access, FileShare.None);
-                               } catch (Exception ex) {
-                                       // the file may be locked by another app. Wait a bit and try again
-                                       lastException = ex;
-                                       System.Threading.Thread.Sleep (200);
-                                       retries--;
-                               }
-                       }
-                       ctx.ReportError ("File could not be opened: " + cacheFile, lastException);
-                       return null;
-               }
-               
-               void Load ()
-               {
-                       // The serializer can't be used because this file is reused in xbuild
-                       using (FileStream fs = OpenFile (FileAccess.Read)) {
-                               if (fs == null)
-                                       return;
-                               XmlTextReader xr = new XmlTextReader (fs);
-                               xr.MoveToContent ();
-                               xr.ReadStartElement ();
-                               xr.MoveToContent ();
-                               
-                               while (xr.NodeType == XmlNodeType.Element)
-                                       ReadPackage (xr);
-                       }
-               }
-               
-               public void Save ()
-               {
-                       // The serializer can't be used because this file is reused in xbuild
-                       lock (infos) {
-                               if (!hasChanges)
-                                       return;
-                               
-                               using (FileStream fs = OpenFile (FileAccess.Write)) {
-                                       if (fs == null)
-                                               return;
-                                       XmlTextWriter tw = new XmlTextWriter (new StreamWriter (fs));
-                                       tw.Formatting = Formatting.Indented;
-                                       
-                                       tw.WriteStartElement ("PcFileCache");
-                                       foreach (KeyValuePair<string,TP> file in infos) {
-                                               WritePackage (tw, file.Key, file.Value);
-                                       }
-                                       tw.WriteEndElement (); // PcFileCache
-                                       tw.Flush ();
-                                       
-                                       hasChanges = false;
-                               }
-                       }
-               }
-               
-               void WritePackage (XmlTextWriter tw, string file, TP pinfo)
-               {
-                       tw.WriteStartElement ("File");
-                       tw.WriteAttributeString ("path", file);
-                       tw.WriteAttributeString ("lastWriteTime", XmlConvert.ToString (pinfo.LastWriteTime, XmlDateTimeSerializationMode.Local));
-                       
-                       if (pinfo.IsValidPackage) {
-                               if (pinfo.Name != null)
-                                       tw.WriteAttributeString ("name", pinfo.Name);
-                               if (pinfo.Version != null)
-                                       tw.WriteAttributeString ("version", pinfo.Version);
-                               if (!string.IsNullOrEmpty (pinfo.Description))
-                                       tw.WriteAttributeString ("description", pinfo.Description);
-                               if (!string.IsNullOrEmpty (pinfo.Requires))
-                                       tw.WriteAttributeString ("requires", pinfo.Requires);
-                               if (pinfo.CustomData != null) {
-                                       foreach (KeyValuePair<string,string> cd in pinfo.CustomData)
-                                               tw.WriteAttributeString (cd.Key, cd.Value);
-                               }
-                               WritePackageContent (tw, file, pinfo);
-                       }
-                       tw.WriteEndElement (); // File
-               }
-               
-               protected virtual void WritePackageContent (XmlTextWriter tw, string file, TP pinfo)
-               {
-               }
-               
-               void ReadPackage (XmlReader tr)
-               {
-                       TP pinfo = new TP ();
-                       string file = null;
-                       
-                       tr.MoveToFirstAttribute ();
-                       do {
-                               switch (tr.LocalName) {
-                                       case "path": file = tr.Value; break;
-                                       case "lastWriteTime": pinfo.LastWriteTime = XmlConvert.ToDateTime (tr.Value, XmlDateTimeSerializationMode.Local); break;
-                                       case "name": pinfo.Name = tr.Value; break;
-                                       case "version": pinfo.Version = tr.Value; break;
-                                       case "description": pinfo.Description = tr.Value; break;
-                                       case "requires": pinfo.Requires = tr.Value; break;
-                                       default: pinfo.SetData (tr.LocalName, tr.Value); break;
-                               }
-                       } while (tr.MoveToNextAttribute ());
-                       
-                       tr.MoveToElement ();
-                       
-                       if (!tr.IsEmptyElement) {
-                               tr.ReadStartElement ();
-                               tr.MoveToContent ();
-                               ReadPackageContent (tr, pinfo);
-                               tr.MoveToContent ();
-                               tr.ReadEndElement ();
-                       } else
-                               tr.Read ();
-                       tr.MoveToContent ();
-                       
-                       if (!pinfo.IsValidPackage || ctx.IsCustomDataComplete (file, pinfo))
-                               Add (file, pinfo, null);
-               }
-               
-               protected virtual void ReadPackageContent (XmlReader tr, TP pinfo)
-               {
-               }
-               
-               public object SyncRoot {
-                       get { return infos; }
-               }
-               
-               
-               TP ParsePackageInfo (string pcfile)
-               {
-                       PcFile file = new PcFile ();
-                       file.Load (pcfile);
-                       
-                       TP pinfo = new TP ();
-                       pinfo.Name = Path.GetFileNameWithoutExtension (file.FilePath);
-                       
-                       if (!file.HasErrors) {
-                               pinfo.Version = file.Version;
-                               pinfo.Description = file.Description;
-                               pinfo.Requires = file.Requires;
-                               ParsePackageInfo (file, pinfo);
-                               if (pinfo.IsValidPackage)
-                                       ctx.StoreCustomData (file, pinfo);
-                       }
-                       return pinfo;
-               }
-               
-               protected virtual void ParsePackageInfo (PcFile file, TP pinfo)
-               {
-               }
-               
-               IEnumerable<string> GetDefaultPaths ()
-               {
-                       if (defaultPaths == null) {
-                               // For mac osx, look in the 'External' dir on macosx,
-                               // see bug #663180
-                               string pkgConfigPath = String.Format ("{0}:{1}",
-                                               Mono.XBuild.Utilities.MSBuildUtils.RunningOnMac ? MacOSXExternalPkgConfigDir : String.Empty,
-                                               Environment.GetEnvironmentVariable ("PKG_CONFIG_PATH") ?? String.Empty);
-
-                               string pkgConfigDir = Environment.GetEnvironmentVariable ("PKG_CONFIG_LIBDIR");
-                               defaultPaths = GetPkgconfigPaths (null, pkgConfigPath, pkgConfigDir);
-                       }
-                       return defaultPaths;
-               }
-               
-               public IEnumerable<string> GetPkgconfigPaths (string prefix, string pkgConfigPath, string pkgConfigLibdir)
-               {
-                       char[] sep = new char[] { Path.PathSeparator };
-                       
-                       string[] pkgConfigPaths = null;
-                       if (!String.IsNullOrEmpty (pkgConfigPath)) {
-                               pkgConfigPaths = pkgConfigPath.Split (sep, StringSplitOptions.RemoveEmptyEntries);
-                               if (pkgConfigPaths.Length == 0)
-                                       pkgConfigPaths = null;
-                       }
-                       
-                       string[] pkgConfigLibdirs = null;
-                       if (!String.IsNullOrEmpty (pkgConfigLibdir)) {
-                               pkgConfigLibdirs = pkgConfigLibdir.Split (sep, StringSplitOptions.RemoveEmptyEntries);
-                               if (pkgConfigLibdirs.Length == 0)
-                                       pkgConfigLibdirs = null;
-                       }
-                       
-                       if (prefix == null)
-                               prefix = PathUp (typeof (int).Assembly.Location, 4);
-                       
-                       IEnumerable<string> paths = GetUnfilteredPkgConfigDirs (pkgConfigPaths, pkgConfigLibdirs, new string [] { prefix });
-                       return NormaliseAndFilterPaths (paths, Environment.CurrentDirectory);
-               }
-               
-               IEnumerable<string> GetUnfilteredPkgConfigDirs (IEnumerable<string> pkgConfigPaths, IEnumerable<string> pkgConfigLibdirs, IEnumerable<string> systemPrefixes)
-               {
-                       if (pkgConfigPaths != null) {
-                               foreach (string dir in pkgConfigPaths)
-                                       yield return dir;
-                       }
-                       
-                       if (pkgConfigLibdirs != null) {
-                               foreach (string dir in pkgConfigLibdirs)
-                                       yield return dir;
-                       } else if (systemPrefixes != null) {
-                               string[] suffixes = new string [] {
-                                       //FIXME: is this the correct order? share should be before lib but not sure about others.
-                                       Path.Combine ("share", "pkgconfig"),
-                                       Path.Combine ("lib", "pkgconfig"),
-                                       Path.Combine ("lib64", "pkgconfig"),
-                                       Path.Combine ("libdata", "pkgconfig"),
-                               };
-                               foreach (string prefix in systemPrefixes)
-                                       foreach (string suffix in suffixes)
-                                               yield return Path.Combine (prefix, suffix);
-                       }
-               }
-               
-               IEnumerable<string> NormaliseAndFilterPaths (IEnumerable<string> paths, string workingDirectory)
-               {
-                       Dictionary<string,string> filtered = new Dictionary<string,string> ();
-                       foreach (string p in paths) {
-                               string path = p;
-                               if (!Path.IsPathRooted (path))
-                                       path = Path.Combine (workingDirectory, path);
-                               path = Path.GetFullPath (path);
-                               if (filtered.ContainsKey (path))
-                                       continue;
-                               filtered.Add (path,path);
-                               try {
-                                       if (!Directory.Exists (path))
-                                               continue;
-                               } catch (IOException ex) {
-                                       ctx.ReportError ("Error checking for directory '" + path + "'.", ex);
-                               }
-                               yield return path;
-                       }
-               }
-               
-               static string PathUp (string path, int up)
-               {
-                       if (up == 0)
-                               return path;
-                       for (int i = path.Length -1; i >= 0; i--) {
-                               if (path[i] == Path.DirectorySeparatorChar) {
-                                       up--;
-                                       if (up == 0)
-                                               return path.Substring (0, i);
-                               }
-                       }
-                       return null;
-               }
-       }
-
-       internal class PcFile
-       {
-               Dictionary<string,string> variables = new Dictionary<string, string> ();
-               
-               string description;
-               public string Description {
-                       get { return description; }
-                       set { description = value; }
-               }
-               
-               string filePath;
-               public string FilePath {
-                       get { return filePath; }
-                       set { filePath = value; }
-               }
-               
-               bool hasErrors;
-               public bool HasErrors {
-                       get { return hasErrors; }
-                       set { hasErrors = value; }
-               }
-               
-               string libs;
-               public string Libs {
-                       get { return libs; }
-                       set { libs = value; }
-               }
-               
-               string name;
-               public string Name {
-                       get { return name; }
-                       set { name = value; }
-               }
-               
-               string version;
-               public string Version {
-                       get { return version; }
-                       set { version = value; }
-               }
-               
-               string requires;
-               public string Requires {
-                       get { return requires; }
-                       set { requires = value; }
-               }
-               
-               public string GetVariable (string varName)
-               {
-                       string val;
-                       variables.TryGetValue (varName, out val);
-                       return val;
-               }
-               
-               public void Load (string pcfile)
-               {
-                       FilePath = pcfile;
-                       variables.Add ("pcfiledir", Path.GetDirectoryName (pcfile));
-                       using (StreamReader reader = new StreamReader (pcfile)) {
-                               string line;
-                               while ((line = reader.ReadLine ()) != null) {
-                                       int i = line.IndexOf (':');
-                                       int j = line.IndexOf ('=');
-                                       int k = System.Math.Min (i != -1 ? i : int.MaxValue, j != -1 ? j : int.MaxValue);
-                                       if (k == int.MaxValue)
-                                               continue;
-                                       string var = line.Substring (0, k).Trim ();
-                                       string value = line.Substring (k + 1).Trim ();
-                                       value = Evaluate (value);
-                                       
-                                       if (k == j) {
-                                               // Is variable
-                                               variables [var] = value;
-                                       }
-                                       else {
-                                               switch (var) {
-                                                       case "Name": Name = value; break;
-                                                       case "Description": Description = value; break;
-                                                       case "Version": Version = value; break;
-                                                       case "Libs": Libs = value; break;
-                                                       case "Requires": Requires = value; break;
-                                               }
-                                       }
-                               }
-                       }
-               }
-               
-               string Evaluate (string value)
-               {
-                       int i = value.IndexOf ("${");
-                       if (i == -1)
-                               return value;
-
-                       StringBuilder sb = new StringBuilder ();
-                       int last = 0;
-                       while (i != -1 && i < value.Length) {
-                               sb.Append (value.Substring (last, i - last));
-                               if (i == 0 || value [i - 1] != '$') {
-                                       // Evaluate if var is not escaped
-                                       i += 2;
-                                       int n = value.IndexOf ('}', i);
-                                       if (n == -1 || n == i) {
-                                               // Closing bracket not found or empty name
-                                               HasErrors = true;
-                                               return value;
-                                       }
-                                       string rname = value.Substring (i, n - i);
-                                       string rval;
-                                       if (variables.TryGetValue (rname, out rval))
-                                               sb.Append (rval);
-                                       else {
-                                               HasErrors = true;
-                                               return value;
-                                       }
-                                       i = n + 1;
-                                       last = i;
-                               } else
-                                       last = i++;
-                               
-                               if (i < value.Length)
-                                       i = value.IndexOf ("${", i);
-                       }
-                       sb.Append (value.Substring (last, value.Length - last));
-                       return sb.ToString ();
-               }
-       }
-       
-       internal class PackageInfo
-       {
-               Dictionary<string,string> customData;
-               DateTime lastWriteTime;
-               
-               string name;
-               public string Name {
-                       get { return name; }
-                       set { name = value; }
-               }
-               
-               string version;
-               public string Version {
-                       get { return version; }
-                       set { version = value; }
-               }
-               
-               string description;
-               public string Description {
-                       get { return description; }
-                       set { description = value; }
-               }
-               
-               string requires;
-               public string Requires {
-                       get { return requires; }
-                       set { requires = value; }
-               }
-               
-               public string GetData (string name)
-               {
-                       if (customData == null)
-                               return null;
-                       string res;
-                       customData.TryGetValue (name, out res);
-                       return res;
-               }
-               
-               public void SetData (string name, string value)
-               {
-                       if (customData == null)
-                               customData = new Dictionary<string, string> ();
-                       customData [name] = value;
-               }
-               
-               public void RemoveData (string name)
-               {
-                       if (customData != null)
-                               customData.Remove (name);
-               }
-               
-               internal Dictionary<string,string> CustomData {
-                       get { return customData; }
-               }
-               
-               internal DateTime LastWriteTime {
-                       get { return lastWriteTime; }
-                       set { lastWriteTime = value; }
-               }
-               
-               internal bool HasCustomData {
-                       get { return customData != null && customData.Count > 0; }
-               }
-               
-               internal protected virtual bool IsValidPackage {
-                       get { return HasCustomData; }
-               }
-       }
-}
diff --git a/mcs/class/Mono.XBuild.Tasks/Assembly/AssemblyInfo.cs b/mcs/class/Mono.XBuild.Tasks/Assembly/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..c5543a4
--- /dev/null
@@ -0,0 +1,53 @@
+//
+// AssemblyInfo.cs
+//
+// Author:
+//       Antonius Riha <antoniusriha@gmail.com>
+//
+// Copyright (c) 2013 Antonius Riha
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Runtime.InteropServices;
+
+// General Information about the Mono.XBuild.Tasks assembly
+
+[assembly: AssemblyTitle ("Mono.XBuild.Tasks.dll")]
+[assembly: AssemblyDescription ("Mono.XBuild.Tasks.dll")]
+[assembly: AssemblyDefaultAlias ("Mono.XBuild.Tasks.dll")]
+
+[assembly: AssemblyCompany (Consts.MonoCompany)]
+[assembly: AssemblyProduct (Consts.MonoProduct)]
+[assembly: AssemblyCopyright (Consts.MonoCopyright)]
+[assembly: AssemblyVersion (Consts.FxVersion)]
+[assembly: SatelliteContractVersion (Consts.FxVersion)]
+[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
+
+[assembly: NeutralResourcesLanguage ("en-US")]
+
+[assembly: ComVisible (false)]
+[assembly: CLSCompliant (true)]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile("../mono.pub")]
+
+[assembly: AssemblyFileVersion (Consts.FxFileVersion)]
diff --git a/mcs/class/Mono.XBuild.Tasks/Makefile b/mcs/class/Mono.XBuild.Tasks/Makefile
new file mode 100644 (file)
index 0000000..824eaf7
--- /dev/null
@@ -0,0 +1,16 @@
+thisdir = class/Mono.XBuild.Tasks
+SUBDIRS = 
+include ../../build/rules.make
+
+LIBRARY = Mono.XBuild.Tasks.dll
+
+LIB_MCS_FLAGS = \
+       /r:$(corlib)                            \
+       /r:System.dll                           \
+       /r:System.Xml.dll
+
+export TESTING_MONO=a
+XBUILD_DIR=../../tools/xbuild
+include $(XBUILD_DIR)/xbuild_targets.make
+
+include ../../build/library.make
diff --git a/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-net_2_0.csproj b/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-net_2_0.csproj
new file mode 100644 (file)
index 0000000..a2ade4a
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <PropertyGroup>\r
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+    <ProductVersion>9.0.30729</ProductVersion>\r
+    <SchemaVersion>2.0</SchemaVersion>\r
+    <ProjectGuid>{F5F84165-0541-4828-A81E-0AA1836E50C1}</ProjectGuid>\r
+    <OutputType>Library</OutputType>\r
+    <NoWarn>1699</NoWarn>\r
+    <OutputPath>bin\Debug\Mono.XBuild.Tasks-net_2_0</OutputPath>\r
+    <NoStdLib>True</NoStdLib>\r
+    <NoConfig>True</NoConfig>\r
+    <AppDesignerFolder>Properties</AppDesignerFolder>\r
+    <AssemblyName>Mono.XBuild.Tasks</AssemblyName>\r
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>\r
+    <FileAlignment>512</FileAlignment>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+    <DebugSymbols>true</DebugSymbols>\r
+    <DebugType>full</DebugType>\r
+    <Optimize>false</Optimize>\r
+    <DefineConstants>DEBUG;TRACE;NET_2_0</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+    <Optimize>true</Optimize>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+    <DefineConstants>NET_2_0</DefineConstants>\r
+  </PropertyGroup>\r
+  <!-- Set AddAdditionalExplicitAssemblyReferences to false, otherwise if targetting .NET4.0, \r
+  Microsoft.NETFramework.props will force a dependency on the assembly System.Core. This\r
+  is a problem to compile the Mono mscorlib.dll -->\r
+  <PropertyGroup>\r
+    <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>\r
+  </PropertyGroup>\r
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
+  <ItemGroup>\r
+    <Compile Include="..\..\build\common\Consts.cs" />\r
+    <Compile Include="..\..\build\common\MonoTODOAttribute.cs" />\r
+    <Compile Include="..\Microsoft.Build.Utilities\Mono.XBuild.Utilities\MSBuildUtils.cs" />\r
+    <Compile Include="Mono.XBuild.Tasks\LibraryPcFileCache.cs" />\r
+    <Compile Include="Mono.XBuild.Tasks\PcFileCache.cs" />\r
+    <Compile Include="Assembly\AssemblyInfo.cs" />\r
+  </ItemGroup>\r
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
+       Other similar extension points exist, see Microsoft.Common.targets.\r
+  <Target Name="BeforeBuild">\r
+  </Target>\r
+  <Target Name="AfterBuild">\r
+  </Target>\r
+  -->\r
+  <PropertyGroup>\r
+    <PreBuildEvent>\r
+    </PreBuildEvent>\r
+    <PostBuildEvent>\r
+      xcopy $(TargetName).* $(ProjectDir)..\lib\net_2_0\ /Y /R /D\r
+    </PostBuildEvent>\r
+  </PropertyGroup>\r
+  <ItemGroup>\r
+    <Folder Include="Assembly\" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <Reference Include="mscorlib">\r
+      <HintPath>..\lib\net_2_0\mscorlib.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="System">\r
+      <HintPath>..\lib\net_2_0\System.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="System.Xml">\r
+      <HintPath>..\lib\net_2_0\System.Xml.dll</HintPath>\r
+    </Reference>\r
+  </ItemGroup>\r
+</Project>\r
diff --git a/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-net_3_5.csproj b/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-net_3_5.csproj
new file mode 100644 (file)
index 0000000..f162637
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <PropertyGroup>\r
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+    <ProductVersion>9.0.30729</ProductVersion>\r
+    <SchemaVersion>2.0</SchemaVersion>\r
+    <ProjectGuid>{7B888FCD-9064-4F4A-954E-795B43F98127}</ProjectGuid>\r
+    <OutputType>Library</OutputType>\r
+    <NoWarn>1699</NoWarn>\r
+    <OutputPath>bin\Debug\Mono.XBuild.Tasks-net_3_5</OutputPath>\r
+    <NoStdLib>True</NoStdLib>\r
+    <NoConfig>True</NoConfig>\r
+    <AppDesignerFolder>Properties</AppDesignerFolder>\r
+    <AssemblyName>Mono.XBuild.Tasks.v3.5</AssemblyName>\r
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>\r
+    <FileAlignment>512</FileAlignment>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+    <DebugSymbols>true</DebugSymbols>\r
+    <DebugType>full</DebugType>\r
+    <Optimize>false</Optimize>\r
+    <DefineConstants>DEBUG;TRACE;NET_2_0;NET_3_5</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+    <DebugType>pdbonly</DebugType>\r
+    <Optimize>true</Optimize>\r
+    <DefineConstants>NET_2_0;NET_3_5</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <!-- Set AddAdditionalExplicitAssemblyReferences to false, otherwise if targetting .NET4.0, \r
+  Microsoft.NETFramework.props will force a dependency on the assembly System.Core. This\r
+  is a problem to compile the Mono mscorlib.dll -->\r
+  <PropertyGroup>\r
+    <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>\r
+  </PropertyGroup>\r
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
+  <ItemGroup>\r
+    <Compile Include="..\..\build\common\Consts.cs" />\r
+    <Compile Include="..\..\build\common\MonoTODOAttribute.cs" />\r
+    <Compile Include="..\Microsoft.Build.Utilities\Mono.XBuild.Utilities\MSBuildUtils.cs" />\r
+    <Compile Include="Mono.XBuild.Tasks\LibraryPcFileCache.cs" />\r
+    <Compile Include="Mono.XBuild.Tasks\PcFileCache.cs" />\r
+    <Compile Include="Assembly\AssemblyInfo.cs" />\r
+  </ItemGroup>\r
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
+       Other similar extension points exist, see Microsoft.Common.targets.\r
+  <Target Name="BeforeBuild">\r
+  </Target>\r
+  <Target Name="AfterBuild">\r
+  </Target>\r
+  -->\r
+  <PropertyGroup>\r
+    <PreBuildEvent>\r
+    </PreBuildEvent>\r
+    <PostBuildEvent>\r
+      xcopy $(TargetName).* $(ProjectDir)..\lib\net_3_5\ /Y /R /D\r
+    </PostBuildEvent>\r
+  </PropertyGroup>\r
+  <ItemGroup>\r
+    <Reference Include="mscorlib">\r
+      <HintPath>..\lib\net_3_5\mscorlib.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="System">\r
+      <HintPath>..\lib\net_3_5\System.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="System.Xml">\r
+      <HintPath>..\lib\net_3_5\System.Xml.dll</HintPath>\r
+    </Reference>\r
+  </ItemGroup>\r
+</Project>\r
diff --git a/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-net_4_0.csproj b/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-net_4_0.csproj
new file mode 100644 (file)
index 0000000..e556034
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <PropertyGroup>\r
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+    <ProductVersion>9.0.30729</ProductVersion>\r
+    <SchemaVersion>2.0</SchemaVersion>\r
+    <ProjectGuid>{F7F03F9B-6E7A-43BD-993A-7F197A440150}</ProjectGuid>\r
+    <OutputType>Library</OutputType>\r
+    <NoWarn>1699</NoWarn>\r
+    <OutputPath>bin\Debug\Mono.XBuild.Tasks-net_4_0</OutputPath>\r
+    <NoStdLib>True</NoStdLib>\r
+    <NoConfig>True</NoConfig>\r
+    <AppDesignerFolder>Properties</AppDesignerFolder>\r
+    <AssemblyName>Mono.XBuild.Tasks.v4.0</AssemblyName>\r
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>\r
+    <FileAlignment>512</FileAlignment>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+    <DebugSymbols>true</DebugSymbols>\r
+    <DebugType>full</DebugType>\r
+    <Optimize>false</Optimize>\r
+    <DefineConstants>DEBUG;TRACE;NET_2_0;NET_3_0;NET_3_5;NET_4_0</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+    <DebugType>pdbonly</DebugType>\r
+    <Optimize>true</Optimize>\r
+    <DefineConstants>NET_2_0;NET_3_0;NET_3_5;NET_4_0</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <!-- Set AddAdditionalExplicitAssemblyReferences to false, otherwise if targetting .NET4.0, \r
+  Microsoft.NETFramework.props will force a dependency on the assembly System.Core. This\r
+  is a problem to compile the Mono mscorlib.dll -->\r
+  <PropertyGroup>\r
+    <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>\r
+  </PropertyGroup>\r
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
+  <ItemGroup>\r
+    <Compile Include="..\..\build\common\Consts.cs" />\r
+    <Compile Include="..\..\build\common\MonoTODOAttribute.cs" />\r
+    <Compile Include="..\Microsoft.Build.Utilities\Mono.XBuild.Utilities\MSBuildUtils.cs" />\r
+    <Compile Include="Mono.XBuild.Tasks\LibraryPcFileCache.cs" />\r
+    <Compile Include="Mono.XBuild.Tasks\PcFileCache.cs" />\r
+    <Compile Include="Assembly\AssemblyInfo.cs" />\r
+  </ItemGroup>\r
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
+       Other similar extension points exist, see Microsoft.Common.targets.\r
+  <Target Name="BeforeBuild">\r
+  </Target>\r
+  <Target Name="AfterBuild">\r
+  </Target>\r
+  -->\r
+  <PropertyGroup>\r
+    <PreBuildEvent>\r
+    </PreBuildEvent>\r
+    <PostBuildEvent>\r
+      xcopy $(TargetName).* $(ProjectDir)..\lib\net_4_0\ /Y /R /D\r
+    </PostBuildEvent>\r
+  </PropertyGroup>\r
+  <ItemGroup>\r
+    <Reference Include="mscorlib">\r
+      <HintPath>..\lib\net_4_0\mscorlib.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="System">\r
+      <HintPath>..\lib\net_4_0\System.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="System.Xml">\r
+      <HintPath>..\lib\net_4_0\System.Xml.dll</HintPath>\r
+    </Reference>\r
+  </ItemGroup>\r
+</Project>\r
diff --git a/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-net_4_5.csproj b/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-net_4_5.csproj
new file mode 100644 (file)
index 0000000..9bf6342
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <PropertyGroup>\r
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+    <ProductVersion>9.0.30729</ProductVersion>\r
+    <SchemaVersion>2.0</SchemaVersion>\r
+    <ProjectGuid>{9AC58525-C730-4552-A8FA-332979FCD055}</ProjectGuid>\r
+    <OutputType>Library</OutputType>\r
+    <NoWarn>1699</NoWarn>\r
+    <OutputPath>bin\Debug\Mono.XBuild.Tasks-net_4_5</OutputPath>\r
+    <NoStdLib>True</NoStdLib>\r
+    <NoConfig>True</NoConfig>\r
+    <AppDesignerFolder>Properties</AppDesignerFolder>\r
+    <AssemblyName>Mono.XBuild.Tasks.v4.0</AssemblyName>\r
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\r
+    <FileAlignment>512</FileAlignment>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+    <DebugSymbols>true</DebugSymbols>\r
+    <DebugType>full</DebugType>\r
+    <Optimize>false</Optimize>\r
+    <DefineConstants>DEBUG;TRACE;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+    <DebugType>pdbonly</DebugType>\r
+    <Optimize>true</Optimize>\r
+    <DefineConstants>NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <!-- Set AddAdditionalExplicitAssemblyReferences to false, otherwise if targetting .NET4.0, \r
+  Microsoft.NETFramework.props will force a dependency on the assembly System.Core. This\r
+  is a problem to compile the Mono mscorlib.dll -->\r
+  <PropertyGroup>\r
+    <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>\r
+  </PropertyGroup>\r
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
+  <ItemGroup>\r
+    <Compile Include="..\..\build\common\Consts.cs" />\r
+    <Compile Include="..\..\build\common\MonoTODOAttribute.cs" />\r
+    <Compile Include="..\Microsoft.Build.Utilities\Mono.XBuild.Utilities\MSBuildUtils.cs" />\r
+    <Compile Include="Mono.XBuild.Tasks\LibraryPcFileCache.cs" />\r
+    <Compile Include="Mono.XBuild.Tasks\PcFileCache.cs" />\r
+    <Compile Include="Assembly\AssemblyInfo.cs" />\r
+  </ItemGroup>\r
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
+       Other similar extension points exist, see Microsoft.Common.targets.\r
+  <Target Name="BeforeBuild">\r
+  </Target>\r
+  <Target Name="AfterBuild">\r
+  </Target>\r
+  -->\r
+  <PropertyGroup>\r
+    <PreBuildEvent>\r
+    </PreBuildEvent>\r
+    <PostBuildEvent>\r
+      xcopy $(TargetName).* $(ProjectDir)..\lib\net_4_5\ /Y /R /D\r
+    </PostBuildEvent>\r
+  </PropertyGroup>\r
+  <ItemGroup>\r
+    <Reference Include="mscorlib">\r
+      <HintPath>..\lib\net_4_5\mscorlib.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="System">\r
+      <HintPath>..\lib\net_4_5\System.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="System.Xml">\r
+      <HintPath>..\lib\net_4_5\System.Xml.dll</HintPath>\r
+    </Reference>\r
+  </ItemGroup>\r
+</Project>\r
diff --git a/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-tests-net_2_0.csproj b/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-tests-net_2_0.csproj
new file mode 100644 (file)
index 0000000..0412ea8
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <PropertyGroup>\r
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+    <ProductVersion>9.0.30729</ProductVersion>\r
+    <SchemaVersion>2.0</SchemaVersion>\r
+    <ProjectGuid>{0E03221E-BC2B-4C7C-AA7B-F26B8FFA3014}</ProjectGuid>\r
+    <OutputType>Library</OutputType>\r
+    <NoWarn>1699</NoWarn>\r
+    <OutputPath>bin\Debug\Mono.XBuild.Tasks-tests-net_2_0</OutputPath>\r
+    <NoStdLib>True</NoStdLib>\r
+    <NoConfig>False</NoConfig>\r
+    <AppDesignerFolder>Properties</AppDesignerFolder>\r
+    <AssemblyName>Mono.XBuild.Tasks_test_net_2_0</AssemblyName>\r
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>\r
+    <FileAlignment>512</FileAlignment>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+    <DebugSymbols>true</DebugSymbols>\r
+    <DebugType>full</DebugType>\r
+    <Optimize>false</Optimize>\r
+    <DefineConstants>DEBUG;TRACE;NET_2_0</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+    <DebugType>pdbonly</DebugType>\r
+    <Optimize>true</Optimize>\r
+    <DefineConstants>NET_2_0</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <!-- Set AddAdditionalExplicitAssemblyReferences to false, otherwise if targetting .NET4.0, \r
+  Microsoft.NETFramework.props will force a dependency on the assembly System.Core. This\r
+  is a problem to compile the Mono mscorlib.dll -->\r
+  <PropertyGroup>\r
+    <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>\r
+  </PropertyGroup>\r
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
+  <ItemGroup>\r
+    <Compile Include="Test\Mono.XBuild.Tasks\PcFileCacheTest.cs" />\r
+  </ItemGroup>\r
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
+       Other similar extension points exist, see Microsoft.Common.targets.\r
+  <Target Name="BeforeBuild">\r
+  </Target>\r
+  <Target Name="AfterBuild">\r
+  </Target>\r
+  -->\r
+  <PropertyGroup>\r
+    <PreBuildEvent>\r
+    </PreBuildEvent>\r
+    <PostBuildEvent>\r
+      xcopy $(TargetName).* $(ProjectDir)..\lib\net_2_0\ /Y /R /D\r
+    </PostBuildEvent>\r
+  </PropertyGroup>\r
+  <ItemGroup>\r
+    <Reference Include="mscorlib">\r
+      <HintPath>..\lib\net_2_0\mscorlib.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="System.Core">\r
+      <HintPath>..\lib\net_2_0\System.Core.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="nunit.framework">\r
+      <HintPath>..\lib\net_2_0\nunit.framework.dll</HintPath>\r
+    </Reference>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ProjectReference Include="Mono.XBuild.Tasks-net_2_0.csproj">\r
+      <Project>{F5F84165-0541-4828-A81E-0AA1836E50C1}</Project>\r
+      <Name>Mono.XBuild.Tasks-net_2_0</Name>\r
+    </ProjectReference>\r
+  </ItemGroup>\r
+</Project>\r
diff --git a/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-tests-net_3_5.csproj b/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-tests-net_3_5.csproj
new file mode 100644 (file)
index 0000000..77ffd64
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <PropertyGroup>\r
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+    <ProductVersion>9.0.30729</ProductVersion>\r
+    <SchemaVersion>2.0</SchemaVersion>\r
+    <ProjectGuid>{B1C8C446-5C28-4352-BA7A-A30171FEA614}</ProjectGuid>\r
+    <OutputType>Library</OutputType>\r
+    <NoWarn>1699</NoWarn>\r
+    <OutputPath>bin\Debug\Mono.XBuild.Tasks-tests-net_3_5</OutputPath>\r
+    <NoStdLib>True</NoStdLib>\r
+    <NoConfig>False</NoConfig>\r
+    <AppDesignerFolder>Properties</AppDesignerFolder>\r
+    <AssemblyName>Mono.XBuild.Tasks_test_net_3_5</AssemblyName>\r
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>\r
+    <FileAlignment>512</FileAlignment>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+    <DebugSymbols>true</DebugSymbols>\r
+    <DebugType>full</DebugType>\r
+    <Optimize>false</Optimize>\r
+    <DefineConstants>DEBUG;TRACE;NET_2_0;NET_3_5</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+    <DebugType>pdbonly</DebugType>\r
+    <Optimize>true</Optimize>\r
+    <DefineConstants>NET_2_0;NET_3_5</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <!-- Set AddAdditionalExplicitAssemblyReferences to false, otherwise if targetting .NET4.0, \r
+  Microsoft.NETFramework.props will force a dependency on the assembly System.Core. This\r
+  is a problem to compile the Mono mscorlib.dll -->\r
+  <PropertyGroup>\r
+    <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>\r
+  </PropertyGroup>\r
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
+  <ItemGroup>\r
+    <Compile Include="Test\Mono.XBuild.Tasks\PcFileCacheTest.cs" />\r
+  </ItemGroup>\r
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
+       Other similar extension points exist, see Microsoft.Common.targets.\r
+  <Target Name="BeforeBuild">\r
+  </Target>\r
+  <Target Name="AfterBuild">\r
+  </Target>\r
+  -->\r
+  <PropertyGroup>\r
+    <PreBuildEvent>\r
+    </PreBuildEvent>\r
+    <PostBuildEvent>\r
+      xcopy $(TargetName).* $(ProjectDir)..\lib\net_3_5\ /Y /R /D\r
+    </PostBuildEvent>\r
+  </PropertyGroup>\r
+  <ItemGroup>\r
+    <Reference Include="mscorlib">\r
+      <HintPath>..\lib\net_3_5\mscorlib.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="System.Core">\r
+      <HintPath>..\lib\net_3_5\System.Core.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="nunit.framework">\r
+      <HintPath>..\lib\net_3_5\nunit.framework.dll</HintPath>\r
+    </Reference>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ProjectReference Include="Mono.XBuild.Tasks-net_3_5.csproj">\r
+      <Project>{7B888FCD-9064-4F4A-954E-795B43F98127}</Project>\r
+      <Name>Mono.XBuild.Tasks-net_3_5</Name>\r
+    </ProjectReference>\r
+  </ItemGroup>\r
+</Project>\r
diff --git a/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-tests-net_4_0.csproj b/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-tests-net_4_0.csproj
new file mode 100644 (file)
index 0000000..0e005df
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <PropertyGroup>\r
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+    <ProductVersion>9.0.30729</ProductVersion>\r
+    <SchemaVersion>2.0</SchemaVersion>\r
+    <ProjectGuid>{0C851F1F-CF06-4440-8E69-F33FBF07D605}</ProjectGuid>\r
+    <OutputType>Library</OutputType>\r
+    <NoWarn>1699</NoWarn>\r
+    <OutputPath>bin\Debug\Mono.XBuild.Tasks-tests-net_4_0</OutputPath>\r
+    <NoStdLib>True</NoStdLib>\r
+    <NoConfig>False</NoConfig>\r
+    <AppDesignerFolder>Properties</AppDesignerFolder>\r
+    <AssemblyName>Mono.XBuild.Tasks_test_net_4_0</AssemblyName>\r
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>\r
+    <FileAlignment>512</FileAlignment>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+    <DebugSymbols>true</DebugSymbols>\r
+    <DebugType>full</DebugType>\r
+    <Optimize>false</Optimize>\r
+    <DefineConstants>DEBUG;TRACE;NET_2_0;NET_3_0;NET_3_5;NET_4_0</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+    <DebugType>pdbonly</DebugType>\r
+    <Optimize>true</Optimize>\r
+    <DefineConstants>NET_2_0;NET_3_0;NET_3_5;NET_4_0</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <!-- Set AddAdditionalExplicitAssemblyReferences to false, otherwise if targetting .NET4.0, \r
+  Microsoft.NETFramework.props will force a dependency on the assembly System.Core. This\r
+  is a problem to compile the Mono mscorlib.dll -->\r
+  <PropertyGroup>\r
+    <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>\r
+  </PropertyGroup>\r
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
+  <ItemGroup>\r
+    <Compile Include="Test\Mono.XBuild.Tasks\PcFileCacheTest.cs" />\r
+  </ItemGroup>\r
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
+       Other similar extension points exist, see Microsoft.Common.targets.\r
+  <Target Name="BeforeBuild">\r
+  </Target>\r
+  <Target Name="AfterBuild">\r
+  </Target>\r
+  -->\r
+  <PropertyGroup>\r
+    <PreBuildEvent>\r
+    </PreBuildEvent>\r
+    <PostBuildEvent>\r
+      xcopy $(TargetName).* $(ProjectDir)..\lib\net_4_0\ /Y /R /D\r
+    </PostBuildEvent>\r
+  </PropertyGroup>\r
+  <ItemGroup>\r
+    <Reference Include="mscorlib">\r
+      <HintPath>..\lib\net_4_0\mscorlib.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="System.Core">\r
+      <HintPath>..\lib\net_4_0\System.Core.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="nunit.framework">\r
+      <HintPath>..\lib\net_4_0\nunit.framework.dll</HintPath>\r
+    </Reference>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ProjectReference Include="Mono.XBuild.Tasks-net_4_0.csproj">\r
+      <Project>{F7F03F9B-6E7A-43BD-993A-7F197A440150}</Project>\r
+      <Name>Mono.XBuild.Tasks-net_4_0</Name>\r
+    </ProjectReference>\r
+  </ItemGroup>\r
+</Project>\r
diff --git a/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-tests-net_4_5.csproj b/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks-tests-net_4_5.csproj
new file mode 100644 (file)
index 0000000..e1c568b
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <PropertyGroup>\r
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+    <ProductVersion>9.0.30729</ProductVersion>\r
+    <SchemaVersion>2.0</SchemaVersion>\r
+    <ProjectGuid>{74FC4C23-BF2E-4514-82D2-E99561BF352C}</ProjectGuid>\r
+    <OutputType>Library</OutputType>\r
+    <NoWarn>1699</NoWarn>\r
+    <OutputPath>bin\Debug\Mono.XBuild.Tasks-tests-net_4_5</OutputPath>\r
+    <NoStdLib>True</NoStdLib>\r
+    <NoConfig>False</NoConfig>\r
+    <AppDesignerFolder>Properties</AppDesignerFolder>\r
+    <AssemblyName>Mono.XBuild.Tasks_test_net_4_5</AssemblyName>\r
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\r
+    <FileAlignment>512</FileAlignment>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+    <DebugSymbols>true</DebugSymbols>\r
+    <DebugType>full</DebugType>\r
+    <Optimize>false</Optimize>\r
+    <DefineConstants>DEBUG;TRACE;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+    <DebugType>pdbonly</DebugType>\r
+    <Optimize>true</Optimize>\r
+    <DefineConstants>NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <!-- Set AddAdditionalExplicitAssemblyReferences to false, otherwise if targetting .NET4.0, \r
+  Microsoft.NETFramework.props will force a dependency on the assembly System.Core. This\r
+  is a problem to compile the Mono mscorlib.dll -->\r
+  <PropertyGroup>\r
+    <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>\r
+  </PropertyGroup>\r
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
+  <ItemGroup>\r
+    <Compile Include="Test\Mono.XBuild.Tasks\PcFileCacheTest.cs" />\r
+  </ItemGroup>\r
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
+       Other similar extension points exist, see Microsoft.Common.targets.\r
+  <Target Name="BeforeBuild">\r
+  </Target>\r
+  <Target Name="AfterBuild">\r
+  </Target>\r
+  -->\r
+  <PropertyGroup>\r
+    <PreBuildEvent>\r
+    </PreBuildEvent>\r
+    <PostBuildEvent>\r
+      xcopy $(TargetName).* $(ProjectDir)..\lib\net_4_5\ /Y /R /D\r
+    </PostBuildEvent>\r
+  </PropertyGroup>\r
+  <ItemGroup>\r
+    <Reference Include="mscorlib">\r
+      <HintPath>..\lib\net_4_5\mscorlib.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="System.Core">\r
+      <HintPath>..\lib\net_4_5\System.Core.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="nunit.framework">\r
+      <HintPath>..\lib\net_4_5\nunit.framework.dll</HintPath>\r
+    </Reference>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ProjectReference Include="Mono.XBuild.Tasks-net_4_5.csproj">\r
+      <Project>{9AC58525-C730-4552-A8FA-332979FCD055}</Project>\r
+      <Name>Mono.XBuild.Tasks-net_4_5</Name>\r
+    </ProjectReference>\r
+  </ItemGroup>\r
+</Project>\r
diff --git a/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks.dll.sources b/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks.dll.sources
new file mode 100644 (file)
index 0000000..60955c0
--- /dev/null
@@ -0,0 +1,6 @@
+Assembly/AssemblyInfo.cs
+../../build/common/Consts.cs
+../../build/common/MonoTODOAttribute.cs
+Mono.XBuild.Tasks/PcFileCache.cs
+Mono.XBuild.Tasks/LibraryPcFileCache.cs
+../Microsoft.Build.Utilities/Mono.XBuild.Utilities/MSBuildUtils.cs
diff --git a/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks/LibraryPcFileCache.cs b/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks/LibraryPcFileCache.cs
new file mode 100644 (file)
index 0000000..c89cba9
--- /dev/null
@@ -0,0 +1,321 @@
+// 
+// PcFileCacheAssembly.cs
+//  
+// Author:
+//       Lluis Sanchez Gual <lluis@novell.com>
+// 
+// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Text;
+using System.Xml;
+using System.IO;
+using System.Collections.Generic;
+
+// IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
+// This code is shared with xbuild, which has to build with .NET 2.0,
+// so no c# 3.0 syntax is allowed here.
+
+namespace Mono.PkgConfig
+{
+       public class LibraryPcFileCache: PcFileCache<LibraryPackageInfo>
+       {
+               Dictionary<string, PackageAssemblyInfo> assemblyLocations;
+               
+               public LibraryPcFileCache (IPcFileCacheContext<LibraryPackageInfo> ctx): base (ctx)
+               {
+               }
+               
+               protected override string CacheDirectory {
+                       get {
+                               string path = Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData);
+                               path = Path.Combine (path, "xbuild");
+                               return path;
+                       }
+               }
+               
+               // Returns the location of an assembly, given the full name
+               public PackageAssemblyInfo GetAssemblyLocation (string fullName)
+               {
+                       return GetAssemblyLocation (fullName, null);
+               }
+               
+               public PackageAssemblyInfo GetAssemblyLocation (string fullName, IEnumerable<string> searchPaths)
+               {
+                       lock (SyncRoot) {
+                               if (assemblyLocations == null) {
+                                       // Populate on demand
+                                       assemblyLocations = new Dictionary<string, PackageAssemblyInfo> ();
+                                       foreach (LibraryPackageInfo info in GetPackages (searchPaths)) {
+                                               if (info.IsValidPackage) {
+                                                       foreach (PackageAssemblyInfo asm in info.Assemblies)
+                                                               assemblyLocations [NormalizeAsmName (asm.FullName)] = asm;
+                                               }
+                                       }
+                               }
+                       }
+                       // This collection is read-only once built, so there is no need for a lock
+                       PackageAssemblyInfo pasm;
+                       assemblyLocations.TryGetValue (NormalizeAsmName (fullName), out pasm);
+                       return pasm;
+               }
+               
+               public IEnumerable<PackageAssemblyInfo> ResolveAssemblyName (string name)
+               {
+                       return ResolveAssemblyName (name, null);
+               }
+               
+               public IEnumerable<PackageAssemblyInfo> ResolveAssemblyName (string name, IEnumerable<string> searchPaths)
+               {
+                       foreach (LibraryPackageInfo pinfo in GetPackages (searchPaths)) {
+                               if (pinfo.IsValidPackage) {
+                                       foreach (PackageAssemblyInfo asm in pinfo.Assemblies) {
+                                               if (asm.Name == name)
+                                                       yield return asm;
+                                       }
+                               }
+                       }
+               }
+               
+               protected override void WritePackageContent (XmlTextWriter tw, string file, LibraryPackageInfo pinfo)
+               {
+                       foreach (PackageAssemblyInfo asm in pinfo.Assemblies) {
+                               tw.WriteStartElement ("Assembly");
+                               tw.WriteAttributeString ("name", asm.Name);
+                               tw.WriteAttributeString ("version", asm.Version);
+                               tw.WriteAttributeString ("culture", asm.Culture);
+                               tw.WriteAttributeString ("publicKeyToken", asm.PublicKeyToken);
+                               tw.WriteAttributeString ("file", asm.File);
+                               tw.WriteEndElement (); // Assembly
+                       }
+               }
+               
+               protected override void ReadPackageContent (XmlReader tr, LibraryPackageInfo pinfo)
+               {
+                       while (tr.NodeType == XmlNodeType.Element) {
+                               PackageAssemblyInfo asm = new PackageAssemblyInfo ();
+                               asm.Name = tr.GetAttribute ("name");
+                               asm.Version = tr.GetAttribute ("version");
+                               asm.Culture = tr.GetAttribute ("culture");
+                               asm.PublicKeyToken = tr.GetAttribute ("publicKeyToken");
+                               asm.File = tr.GetAttribute ("file");
+                               if (pinfo.Assemblies == null)
+                                       pinfo.Assemblies = new List<PackageAssemblyInfo> ();
+                               asm.ParentPackage = pinfo;
+                               pinfo.Assemblies.Add (asm);
+                               tr.Read ();
+                               tr.MoveToContent ();
+                       }
+               }
+               
+               protected override void ParsePackageInfo (PcFile file, LibraryPackageInfo pinfo)
+               {
+                       List<string> fullassemblies = null;
+                       bool gacPackageSet = false;
+                       
+                       if (file.Libs != null && file.Libs.IndexOf (".dll") != -1) {
+                               if (file.Libs.IndexOf ("-lib:") != -1 || file.Libs.IndexOf ("/lib:") != -1) {
+                                       fullassemblies = GetAssembliesWithLibInfo (file.Libs);
+                               } else {
+                                       fullassemblies = GetAssembliesWithoutLibInfo (file.Libs);
+                               }
+                       }
+                       
+                       string value = file.GetVariable ("Libraries");
+                       if (!string.IsNullOrEmpty (value))
+                               fullassemblies = GetAssembliesFromLibrariesVar (value);
+                       
+                       value = file.GetVariable ("GacPackage");
+                       if (value != null) {
+                               pinfo.IsGacPackage = 
+                                       string.Equals (value, "yes", StringComparison.OrdinalIgnoreCase) ||
+                                       string.Equals (value, "true", StringComparison.OrdinalIgnoreCase);
+                               gacPackageSet = true;
+                       }
+       
+                       if (fullassemblies == null)
+                               return;
+                       
+                       string pcDir = Path.GetDirectoryName (file.FilePath);
+                       string monoPrefix = Path.GetDirectoryName (Path.GetDirectoryName (pcDir));
+                       monoPrefix = Path.GetFullPath (monoPrefix + Path.DirectorySeparatorChar + "lib" + Path.DirectorySeparatorChar + "mono" + Path.DirectorySeparatorChar);
+
+                       List<PackageAssemblyInfo> list = new List<PackageAssemblyInfo> ();
+                       foreach (string assembly in fullassemblies) {
+                               string asm;
+                               if (Path.IsPathRooted (assembly))
+                                       asm = Path.GetFullPath (assembly);
+                               else {
+                                       if (Path.GetDirectoryName (assembly).Length == 0) {
+                                               asm = assembly;
+                                       } else {
+                                               asm = Path.GetFullPath (Path.Combine (pcDir, assembly));
+                                       }
+                               }
+                               if (File.Exists (asm)) {
+                                       PackageAssemblyInfo pi = new PackageAssemblyInfo ();
+                                       pi.File = asm;
+                                       pi.ParentPackage = pinfo;
+                                       pi.UpdateFromFile (pi.File);
+                                       list.Add (pi);
+                                       if (!gacPackageSet && !asm.StartsWith (monoPrefix) && Path.IsPathRooted (asm)) {
+                                               // Assembly installed outside $(prefix)/lib/mono. It is most likely not a gac package.
+                                               gacPackageSet = true;
+                                               pinfo.IsGacPackage = false;
+                                       }
+                               }
+                       }
+                       pinfo.Assemblies = list;
+               }
+               
+               private List<string> GetAssembliesWithLibInfo (string line)
+               {
+                       List<string> references = new List<string> ();
+                       List<string> libdirs = new List<string> ();
+                       List<string> retval = new List<string> ();
+                       foreach (string piece in line.Split (' ')) {
+                               if (IsReferenceParameter (piece)) {
+                                       references.Add (piece.Substring (3).Trim ());
+                               } else if (piece.TrimStart ().StartsWith ("/lib:", StringComparison.OrdinalIgnoreCase) ||
+                                               piece.TrimStart ().StartsWith ("-lib:", StringComparison.OrdinalIgnoreCase)) {
+                                       libdirs.Add (piece.Substring (5).Trim ());
+                               }
+                       }
+       
+                       foreach (string refrnc in references) {
+                               foreach (string libdir in libdirs) {
+                                       if (File.Exists (libdir + Path.DirectorySeparatorChar + refrnc)) {
+                                               retval.Add (libdir + Path.DirectorySeparatorChar + refrnc);
+                                       }
+                               }
+                       }
+       
+                       return retval;
+               }
+
+               static bool IsReferenceParameter (string value)
+               {
+                       return value.TrimStart ().StartsWith ("/r:", StringComparison.OrdinalIgnoreCase) ||
+                               value.TrimStart ().StartsWith ("-r:", StringComparison.OrdinalIgnoreCase);
+               }
+               
+               List<string> GetAssembliesFromLibrariesVar (string line)
+               {
+                       List<string> references = new List<string> ();
+                       foreach (string reference in line.Split (' ')) {
+                               if (!string.IsNullOrEmpty (reference))
+                                       references.Add (reference);
+                       }
+                       return references;
+               }
+       
+               private List<string> GetAssembliesWithoutLibInfo (string line)
+               {
+                       List<string> references = new List<string> ();
+                       foreach (string reference in line.Split (' ')) {
+                               if (IsReferenceParameter (reference)) {
+                                       string final_ref = reference.Substring (3).Trim ();
+                                       references.Add (final_ref);
+                               }
+                       }
+                       return references;
+               }
+               
+               public static string NormalizeAsmName (string name)
+               {
+                       int i = name.IndexOf (", publickeytoken=null", StringComparison.OrdinalIgnoreCase);
+                       if (i != -1)
+                               name = name.Substring (0, i).Trim ();
+                       i = name.IndexOf (", processorarchitecture=", StringComparison.OrdinalIgnoreCase);
+                       if (i != -1)
+                               name = name.Substring (0, i).Trim ();
+                       return name;
+               }
+       }
+       
+       public class LibraryPackageInfo: PackageInfo
+       {
+               public bool IsGacPackage {
+                       get { return GetData ("gacPackage") != "false"; }
+                       set {
+                               if (value)
+                                       RemoveData ("gacPackage");
+                               else
+                                       SetData ("gacPackage", "false");
+                       }
+               }
+               
+               internal List<PackageAssemblyInfo> Assemblies { get; set; }
+               
+               internal protected override bool IsValidPackage {
+                       get { return Assemblies != null && Assemblies.Count > 0; }
+               }
+       }
+       
+       public class PackageAssemblyInfo
+       {
+               public string File { get; set; }
+               
+               public string Name;
+               
+               public string Version;
+               
+               public string Culture;
+               
+               public string PublicKeyToken;
+               
+               public string FullName {
+                       get {
+                               string fn = Name + ", Version=" + Version;
+                               if (!string.IsNullOrEmpty (Culture))
+                                       fn += ", Culture=" + Culture;
+                               if (!string.IsNullOrEmpty (PublicKeyToken))
+                                       fn += ", PublicKeyToken=" + PublicKeyToken;
+                               return fn;
+                       }
+               }
+               
+               public LibraryPackageInfo ParentPackage { get; set; }
+               
+               public void UpdateFromFile (string file)
+               {
+                       Update (System.Reflection.AssemblyName.GetAssemblyName (file));
+               }
+               
+               public void Update (System.Reflection.AssemblyName aname)
+               {
+                       Name = aname.Name;
+                       Version = aname.Version.ToString ();
+                       if (aname.CultureInfo != null) {
+                               if (aname.CultureInfo.LCID == System.Globalization.CultureInfo.InvariantCulture.LCID)
+                                       Culture = "neutral";
+                               else
+                                       Culture = aname.CultureInfo.Name;
+                       }
+                       string fn = aname.ToString ();
+                       string key = "publickeytoken=";
+                       int i = fn.IndexOf (key, StringComparison.OrdinalIgnoreCase) + key.Length;
+                       int j = fn.IndexOf (',', i);
+                       if (j == -1) j = fn.Length;
+                       PublicKeyToken = fn.Substring (i, j - i);
+               }
+       }
+}
diff --git a/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks/PcFileCache.cs b/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks/PcFileCache.cs
new file mode 100644 (file)
index 0000000..515f463
--- /dev/null
@@ -0,0 +1,646 @@
+// 
+// PcFileCache.cs
+//  
+// Author:
+//       Lluis Sanchez Gual <lluis@novell.com>
+// 
+// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Text;
+using System.Xml;
+using System.IO;
+using System.Collections.Generic;
+
+// IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
+// This code is shared with xbuild, which has to build with .NET 2.0,
+// so no c# 3.0 syntax is allowed here.
+
+namespace Mono.PkgConfig
+{
+       public interface IPcFileCacheContext<TP> where TP:PackageInfo, new()
+       {
+               // In the implementation of this method, the host application can extract
+               // information from the pc file and store it in the PackageInfo object
+               void StoreCustomData (PcFile pcfile, TP pkg);
+               
+               // Should return false if the provided package does not have required
+               // custom data
+               bool IsCustomDataComplete (string pcfile, TP pkg);
+               
+               // Called to report errors
+               void ReportError (string message, Exception ex);
+       }
+       
+       public interface IPcFileCacheContext: IPcFileCacheContext<PackageInfo>
+       {
+       }
+       
+       public abstract class PcFileCache: PcFileCache<PackageInfo>
+       {
+               public PcFileCache (IPcFileCacheContext ctx): base (ctx)
+               {
+               }
+       }
+       
+       public abstract class PcFileCache<TP> where TP:PackageInfo, new()
+       {
+               const string CACHE_VERSION = "2";
+               const string MacOSXExternalPkgConfigDir = "/Library/Frameworks/Mono.framework/External/pkgconfig";
+               
+               Dictionary<string, TP> infos = new Dictionary<string, TP> ();
+               Dictionary<string, List<TP>> filesByFolder = new Dictionary<string, List<TP>> ();
+               
+               string cacheFile;
+               bool hasChanges;
+               IPcFileCacheContext<TP> ctx;
+               IEnumerable<string> defaultPaths;
+               
+               public PcFileCache (IPcFileCacheContext<TP> ctx)
+               {
+                       this.ctx = ctx;
+                       try {
+                               string path = CacheDirectory;
+                               if (!Directory.Exists (path))
+                                       Directory.CreateDirectory (path);
+                               cacheFile = Path.Combine (path, "pkgconfig-cache-" + CACHE_VERSION + ".xml");
+                               
+                               if (File.Exists (cacheFile))
+                                       Load ();
+                               
+                       } catch (Exception ex) {
+                               ctx.ReportError ("pc file cache could not be loaded.", ex);
+                       }
+               }
+               
+               protected abstract string CacheDirectory { get; }
+               
+               // Updates the pkg-config index, using the default search directories
+               public void Update ()
+               {
+                       Update (GetDefaultPaths ());
+               }
+
+               // Updates the pkg-config index, looking for .pc files in the provided directories
+               public void Update (IEnumerable<string> pkgConfigDirs)
+               {
+                       foreach (string pcdir in pkgConfigDirs) {
+                               foreach (string pcfile in Directory.GetFiles (pcdir, "*.pc"))
+                                       GetPackageInfo (pcfile);
+                       }
+                       Save ();
+               }
+               
+               public IEnumerable<TP> GetPackages ()
+               {
+                       return GetPackages (null);
+               }
+               
+               public IEnumerable<TP> GetPackages (IEnumerable<string> pkgConfigDirs)
+               {
+                       if (pkgConfigDirs == null)
+                               pkgConfigDirs = GetDefaultPaths ();
+
+                       foreach (string sp in pkgConfigDirs) {
+                               List<TP> list;
+                               if (filesByFolder.TryGetValue (Path.GetFullPath (sp), out list)) {
+                                       foreach (TP p in list)
+                                               yield return p;
+                               }
+                       }
+               }
+               
+               public TP GetPackageInfoByName (string name)
+               {
+                       return GetPackageInfoByName (name, null);
+               }
+               
+               public TP GetPackageInfoByName (string name, IEnumerable<string> pkgConfigDirs)
+               {
+                       foreach (TP p in GetPackages (pkgConfigDirs))
+                               if (p.Name == name)
+                                       return p;
+                       return null;
+               }
+               
+               // Returns information about a .pc file
+               public TP GetPackageInfo (string file)
+               {
+                       TP info, oldInfo = null;
+                       file = Path.GetFullPath (file);
+                       
+                       DateTime wtime = File.GetLastWriteTime (file);
+                       
+                       lock (infos) {
+                               if (infos.TryGetValue (file, out info)) {
+                                       if (info.LastWriteTime == wtime)
+                                               return info;
+                                       oldInfo = info;
+                               }
+                       }
+
+                       try {
+                               info = ParsePackageInfo (file);
+                       } catch (Exception ex) {
+                               ctx.ReportError ("Error while parsing .pc file: " + file, ex);
+                               info = new TP ();
+                       }
+                       
+                       lock (infos) {
+                               if (!info.IsValidPackage)
+                                       info = new TP (); // Create a default empty instance
+                               info.LastWriteTime = wtime;
+                               Add (file, info, oldInfo);
+                               hasChanges = true;
+                       }
+                       
+                       return info;
+               }
+               
+               void Add (string file, TP info, TP replacedInfo)
+               {
+                       infos [file] = info;
+                       string dir = Path.GetFullPath (Path.GetDirectoryName (file));
+                       List<TP> list;
+                       if (!filesByFolder.TryGetValue (dir, out list)) {
+                               list = new List<TP> ();
+                               filesByFolder [dir] = list;
+                       }
+                       if (replacedInfo != null) {
+                               int i = list.IndexOf (replacedInfo);
+                               if (i != -1) {
+                                       list [i] = info;
+                                       return;
+                               }
+                       }
+                       list.Add (info);
+               }
+               
+               FileStream OpenFile (FileAccess access)
+               {
+                       int retries = 6;
+                       FileMode mode = access == FileAccess.Read ? FileMode.Open : FileMode.Create;
+                       Exception lastException = null;
+                       
+                       while (retries > 0) {
+                               try {
+                                       return new FileStream (cacheFile, mode, access, FileShare.None);
+                               } catch (Exception ex) {
+                                       // the file may be locked by another app. Wait a bit and try again
+                                       lastException = ex;
+                                       System.Threading.Thread.Sleep (200);
+                                       retries--;
+                               }
+                       }
+                       ctx.ReportError ("File could not be opened: " + cacheFile, lastException);
+                       return null;
+               }
+               
+               void Load ()
+               {
+                       // The serializer can't be used because this file is reused in xbuild
+                       using (FileStream fs = OpenFile (FileAccess.Read)) {
+                               if (fs == null)
+                                       return;
+                               XmlTextReader xr = new XmlTextReader (fs);
+                               xr.MoveToContent ();
+                               xr.ReadStartElement ();
+                               xr.MoveToContent ();
+                               
+                               while (xr.NodeType == XmlNodeType.Element)
+                                       ReadPackage (xr);
+                       }
+               }
+               
+               public void Save ()
+               {
+                       // The serializer can't be used because this file is reused in xbuild
+                       lock (infos) {
+                               if (!hasChanges)
+                                       return;
+                               
+                               using (FileStream fs = OpenFile (FileAccess.Write)) {
+                                       if (fs == null)
+                                               return;
+                                       XmlTextWriter tw = new XmlTextWriter (new StreamWriter (fs));
+                                       tw.Formatting = Formatting.Indented;
+                                       
+                                       tw.WriteStartElement ("PcFileCache");
+                                       foreach (KeyValuePair<string,TP> file in infos) {
+                                               WritePackage (tw, file.Key, file.Value);
+                                       }
+                                       tw.WriteEndElement (); // PcFileCache
+                                       tw.Flush ();
+                                       
+                                       hasChanges = false;
+                               }
+                       }
+               }
+               
+               void WritePackage (XmlTextWriter tw, string file, TP pinfo)
+               {
+                       tw.WriteStartElement ("File");
+                       tw.WriteAttributeString ("path", file);
+                       tw.WriteAttributeString ("lastWriteTime", XmlConvert.ToString (pinfo.LastWriteTime, XmlDateTimeSerializationMode.Local));
+                       
+                       if (pinfo.IsValidPackage) {
+                               if (pinfo.Name != null)
+                                       tw.WriteAttributeString ("name", pinfo.Name);
+                               if (pinfo.Version != null)
+                                       tw.WriteAttributeString ("version", pinfo.Version);
+                               if (!string.IsNullOrEmpty (pinfo.Description))
+                                       tw.WriteAttributeString ("description", pinfo.Description);
+                               if (!string.IsNullOrEmpty (pinfo.Requires))
+                                       tw.WriteAttributeString ("requires", pinfo.Requires);
+                               if (pinfo.CustomData != null) {
+                                       foreach (KeyValuePair<string,string> cd in pinfo.CustomData)
+                                               tw.WriteAttributeString (cd.Key, cd.Value);
+                               }
+                               WritePackageContent (tw, file, pinfo);
+                       }
+                       tw.WriteEndElement (); // File
+               }
+               
+               protected virtual void WritePackageContent (XmlTextWriter tw, string file, TP pinfo)
+               {
+               }
+               
+               void ReadPackage (XmlReader tr)
+               {
+                       TP pinfo = new TP ();
+                       string file = null;
+                       
+                       tr.MoveToFirstAttribute ();
+                       do {
+                               switch (tr.LocalName) {
+                                       case "path": file = tr.Value; break;
+                                       case "lastWriteTime": pinfo.LastWriteTime = XmlConvert.ToDateTime (tr.Value, XmlDateTimeSerializationMode.Local); break;
+                                       case "name": pinfo.Name = tr.Value; break;
+                                       case "version": pinfo.Version = tr.Value; break;
+                                       case "description": pinfo.Description = tr.Value; break;
+                                       case "requires": pinfo.Requires = tr.Value; break;
+                                       default: pinfo.SetData (tr.LocalName, tr.Value); break;
+                               }
+                       } while (tr.MoveToNextAttribute ());
+                       
+                       tr.MoveToElement ();
+                       
+                       if (!tr.IsEmptyElement) {
+                               tr.ReadStartElement ();
+                               tr.MoveToContent ();
+                               ReadPackageContent (tr, pinfo);
+                               tr.MoveToContent ();
+                               tr.ReadEndElement ();
+                       } else
+                               tr.Read ();
+                       tr.MoveToContent ();
+                       
+                       if (!pinfo.IsValidPackage || ctx.IsCustomDataComplete (file, pinfo))
+                               Add (file, pinfo, null);
+               }
+               
+               protected virtual void ReadPackageContent (XmlReader tr, TP pinfo)
+               {
+               }
+               
+               public object SyncRoot {
+                       get { return infos; }
+               }
+               
+               
+               TP ParsePackageInfo (string pcfile)
+               {
+                       PcFile file = new PcFile ();
+                       file.Load (pcfile);
+                       
+                       TP pinfo = new TP ();
+                       pinfo.Name = Path.GetFileNameWithoutExtension (file.FilePath);
+                       
+                       if (!file.HasErrors) {
+                               pinfo.Version = file.Version;
+                               pinfo.Description = file.Description;
+                               pinfo.Requires = file.Requires;
+                               ParsePackageInfo (file, pinfo);
+                               if (pinfo.IsValidPackage)
+                                       ctx.StoreCustomData (file, pinfo);
+                       }
+                       return pinfo;
+               }
+               
+               protected virtual void ParsePackageInfo (PcFile file, TP pinfo)
+               {
+               }
+               
+               IEnumerable<string> GetDefaultPaths ()
+               {
+                       if (defaultPaths == null) {
+                               // For mac osx, look in the 'External' dir on macosx,
+                               // see bug #663180
+                               string pkgConfigPath = String.Format ("{0}:{1}",
+                                               Mono.XBuild.Utilities.MSBuildUtils.RunningOnMac ? MacOSXExternalPkgConfigDir : String.Empty,
+                                               Environment.GetEnvironmentVariable ("PKG_CONFIG_PATH") ?? String.Empty);
+
+                               string pkgConfigDir = Environment.GetEnvironmentVariable ("PKG_CONFIG_LIBDIR");
+                               defaultPaths = GetPkgconfigPaths (null, pkgConfigPath, pkgConfigDir);
+                       }
+                       return defaultPaths;
+               }
+               
+               public IEnumerable<string> GetPkgconfigPaths (string prefix, string pkgConfigPath, string pkgConfigLibdir)
+               {
+                       char[] sep = new char[] { Path.PathSeparator };
+                       
+                       string[] pkgConfigPaths = null;
+                       if (!String.IsNullOrEmpty (pkgConfigPath)) {
+                               pkgConfigPaths = pkgConfigPath.Split (sep, StringSplitOptions.RemoveEmptyEntries);
+                               if (pkgConfigPaths.Length == 0)
+                                       pkgConfigPaths = null;
+                       }
+                       
+                       string[] pkgConfigLibdirs = null;
+                       if (!String.IsNullOrEmpty (pkgConfigLibdir)) {
+                               pkgConfigLibdirs = pkgConfigLibdir.Split (sep, StringSplitOptions.RemoveEmptyEntries);
+                               if (pkgConfigLibdirs.Length == 0)
+                                       pkgConfigLibdirs = null;
+                       }
+                       
+                       if (prefix == null)
+                               prefix = PathUp (typeof (int).Assembly.Location, 4);
+                       
+                       IEnumerable<string> paths = GetUnfilteredPkgConfigDirs (pkgConfigPaths, pkgConfigLibdirs, new string [] { prefix });
+                       return NormaliseAndFilterPaths (paths, Environment.CurrentDirectory);
+               }
+               
+               IEnumerable<string> GetUnfilteredPkgConfigDirs (IEnumerable<string> pkgConfigPaths, IEnumerable<string> pkgConfigLibdirs, IEnumerable<string> systemPrefixes)
+               {
+                       if (pkgConfigPaths != null) {
+                               foreach (string dir in pkgConfigPaths)
+                                       yield return dir;
+                       }
+                       
+                       if (pkgConfigLibdirs != null) {
+                               foreach (string dir in pkgConfigLibdirs)
+                                       yield return dir;
+                       } else if (systemPrefixes != null) {
+                               string[] suffixes = new string [] {
+                                       //FIXME: is this the correct order? share should be before lib but not sure about others.
+                                       Path.Combine ("share", "pkgconfig"),
+                                       Path.Combine ("lib", "pkgconfig"),
+                                       Path.Combine ("lib64", "pkgconfig"),
+                                       Path.Combine ("libdata", "pkgconfig"),
+                               };
+                               foreach (string prefix in systemPrefixes)
+                                       foreach (string suffix in suffixes)
+                                               yield return Path.Combine (prefix, suffix);
+                       }
+               }
+               
+               IEnumerable<string> NormaliseAndFilterPaths (IEnumerable<string> paths, string workingDirectory)
+               {
+                       Dictionary<string,string> filtered = new Dictionary<string,string> ();
+                       foreach (string p in paths) {
+                               string path = p;
+                               if (!Path.IsPathRooted (path))
+                                       path = Path.Combine (workingDirectory, path);
+                               path = Path.GetFullPath (path);
+                               if (filtered.ContainsKey (path))
+                                       continue;
+                               filtered.Add (path,path);
+                               try {
+                                       if (!Directory.Exists (path))
+                                               continue;
+                               } catch (IOException ex) {
+                                       ctx.ReportError ("Error checking for directory '" + path + "'.", ex);
+                               }
+                               yield return path;
+                       }
+               }
+               
+               static string PathUp (string path, int up)
+               {
+                       if (up == 0)
+                               return path;
+                       for (int i = path.Length -1; i >= 0; i--) {
+                               if (path[i] == Path.DirectorySeparatorChar) {
+                                       up--;
+                                       if (up == 0)
+                                               return path.Substring (0, i);
+                               }
+                       }
+                       return null;
+               }
+       }
+
+       public class PcFile
+       {
+               Dictionary<string,string> variables = new Dictionary<string, string> ();
+               
+               string description;
+               public string Description {
+                       get { return description; }
+                       set { description = value; }
+               }
+               
+               string filePath;
+               public string FilePath {
+                       get { return filePath; }
+                       set { filePath = value; }
+               }
+               
+               bool hasErrors;
+               public bool HasErrors {
+                       get { return hasErrors; }
+                       set { hasErrors = value; }
+               }
+               
+               string libs;
+               public string Libs {
+                       get { return libs; }
+                       set { libs = value; }
+               }
+               
+               string name;
+               public string Name {
+                       get { return name; }
+                       set { name = value; }
+               }
+               
+               string version;
+               public string Version {
+                       get { return version; }
+                       set { version = value; }
+               }
+               
+               string requires;
+               public string Requires {
+                       get { return requires; }
+                       set { requires = value; }
+               }
+               
+               public string GetVariable (string varName)
+               {
+                       string val;
+                       variables.TryGetValue (varName, out val);
+                       return val;
+               }
+               
+               public void Load (string pcfile)
+               {
+                       FilePath = pcfile;
+                       variables.Add ("pcfiledir", Path.GetDirectoryName (pcfile));
+                       using (StreamReader reader = new StreamReader (pcfile)) {
+                               string line;
+                               while ((line = reader.ReadLine ()) != null) {
+                                       int i = line.IndexOf (':');
+                                       int j = line.IndexOf ('=');
+                                       int k = System.Math.Min (i != -1 ? i : int.MaxValue, j != -1 ? j : int.MaxValue);
+                                       if (k == int.MaxValue)
+                                               continue;
+                                       string var = line.Substring (0, k).Trim ();
+                                       string value = line.Substring (k + 1).Trim ();
+                                       value = Evaluate (value);
+                                       
+                                       if (k == j) {
+                                               // Is variable
+                                               variables [var] = value;
+                                       }
+                                       else {
+                                               switch (var) {
+                                                       case "Name": Name = value; break;
+                                                       case "Description": Description = value; break;
+                                                       case "Version": Version = value; break;
+                                                       case "Libs": Libs = value; break;
+                                                       case "Requires": Requires = value; break;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               
+               string Evaluate (string value)
+               {
+                       int i = value.IndexOf ("${");
+                       if (i == -1)
+                               return value;
+
+                       StringBuilder sb = new StringBuilder ();
+                       int last = 0;
+                       while (i != -1 && i < value.Length) {
+                               sb.Append (value.Substring (last, i - last));
+                               if (i == 0 || value [i - 1] != '$') {
+                                       // Evaluate if var is not escaped
+                                       i += 2;
+                                       int n = value.IndexOf ('}', i);
+                                       if (n == -1 || n == i) {
+                                               // Closing bracket not found or empty name
+                                               HasErrors = true;
+                                               return value;
+                                       }
+                                       string rname = value.Substring (i, n - i);
+                                       string rval;
+                                       if (variables.TryGetValue (rname, out rval))
+                                               sb.Append (rval);
+                                       else {
+                                               HasErrors = true;
+                                               return value;
+                                       }
+                                       i = n + 1;
+                                       last = i;
+                               } else
+                                       last = i++;
+                               
+                               if (i < value.Length)
+                                       i = value.IndexOf ("${", i);
+                       }
+                       sb.Append (value.Substring (last, value.Length - last));
+                       return sb.ToString ();
+               }
+       }
+       
+       public class PackageInfo
+       {
+               Dictionary<string,string> customData;
+               DateTime lastWriteTime;
+               
+               string name;
+               public string Name {
+                       get { return name; }
+                       set { name = value; }
+               }
+               
+               string version;
+               public string Version {
+                       get { return version; }
+                       set { version = value; }
+               }
+               
+               string description;
+               public string Description {
+                       get { return description; }
+                       set { description = value; }
+               }
+               
+               string requires;
+               public string Requires {
+                       get { return requires; }
+                       set { requires = value; }
+               }
+               
+               public string GetData (string name)
+               {
+                       if (customData == null)
+                               return null;
+                       string res;
+                       customData.TryGetValue (name, out res);
+                       return res;
+               }
+               
+               public void SetData (string name, string value)
+               {
+                       if (customData == null)
+                               customData = new Dictionary<string, string> ();
+                       customData [name] = value;
+               }
+               
+               public void RemoveData (string name)
+               {
+                       if (customData != null)
+                               customData.Remove (name);
+               }
+               
+               internal Dictionary<string,string> CustomData {
+                       get { return customData; }
+               }
+               
+               internal DateTime LastWriteTime {
+                       get { return lastWriteTime; }
+                       set { lastWriteTime = value; }
+               }
+               
+               internal bool HasCustomData {
+                       get { return customData != null && customData.Count > 0; }
+               }
+               
+               internal protected virtual bool IsValidPackage {
+                       get { return HasCustomData; }
+               }
+       }
+}
diff --git a/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks_test.dll.sources b/mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks_test.dll.sources
new file mode 100644 (file)
index 0000000..0dbb126
--- /dev/null
@@ -0,0 +1 @@
+Mono.XBuild.Tasks/PcFileCacheTest.cs
diff --git a/mcs/class/Mono.XBuild.Tasks/Test/Mono.XBuild.Tasks/PcFileCacheTest.cs b/mcs/class/Mono.XBuild.Tasks/Test/Mono.XBuild.Tasks/PcFileCacheTest.cs
new file mode 100644 (file)
index 0000000..2c3b3ab
--- /dev/null
@@ -0,0 +1,34 @@
+//
+// PcFileCacheTest.cs
+//
+// Author:
+//       Antonius Riha <antoniusriha@gmail.com>
+//
+// Copyright (c) 2013 Antonius Riha
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using NUnit.Framework;
+
+namespace MonoTests.Microsoft.Build.Tasks
+{
+       [TestFixture]
+       public class PcFileCacheTest
+       {
+       }
+}