diff --git a/Clojure/Clojure.Compile/Clojure.Compile.csproj b/Clojure/Clojure.Compile/Clojure.Compile.csproj
index a2b3c2ffd..af5a61da7 100644
--- a/Clojure/Clojure.Compile/Clojure.Compile.csproj
+++ b/Clojure/Clojure.Compile/Clojure.Compile.csproj
@@ -73,8 +73,11 @@
AllRules.ruleset
v4.0
+
+ OnBuildSuccess
+
-
+
..\..\lib\DLR\2.0\Microsoft.Scripting.Core.dll
diff --git a/Clojure/Clojure/CljCompiler/Compiler.cs b/Clojure/Clojure/CljCompiler/Compiler.cs
index c644e064a..0f765b035 100644
--- a/Clojure/Clojure/CljCompiler/Compiler.cs
+++ b/Clojure/Clojure/CljCompiler/Compiler.cs
@@ -1394,11 +1394,21 @@ public static void PushNS()
Symbol.intern("*ns*")).setDynamic(), null));
}
-
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
internal static bool LoadAssembly(FileInfo assyInfo)
{
Assembly assy = Assembly.LoadFrom(assyInfo.FullName);
+ return InitAssembly(assy);
+ }
+
+ internal static bool LoadAssembly(byte[] assyData)
+ {
+ Assembly assy = Assembly.Load(assyData);
+ return InitAssembly(assy);
+ }
+
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
+ private static bool InitAssembly(Assembly assy)
+ {
Type initType = assy.GetType("__Init__");
if (initType == null)
{
@@ -1412,7 +1422,7 @@ internal static bool LoadAssembly(FileInfo assyInfo)
}
catch (Exception e)
{
- Console.WriteLine("Error initializing {0}: {1}", assyInfo.FullName, e.Message);
+ Console.WriteLine("Error initializing {0}: {1}", assy.FullName, e.Message);
return false;
}
}
diff --git a/Clojure/Clojure/Clojure.csproj b/Clojure/Clojure/Clojure.csproj
index 0d5524ea9..7eb695b3f 100644
--- a/Clojure/Clojure/Clojure.csproj
+++ b/Clojure/Clojure/Clojure.csproj
@@ -114,6 +114,9 @@
+
+ ResourceHelper.cs
+
diff --git a/Clojure/Clojure/Lib/RT.cs b/Clojure/Clojure/Lib/RT.cs
index 8db7db14e..9b604c6c4 100644
--- a/Clojure/Clojure/Lib/RT.cs
+++ b/Clojure/Clojure/Lib/RT.cs
@@ -23,6 +23,7 @@
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
+using ResPack;
using RTProperties = clojure.runtime.Properties;
using Microsoft.Scripting.Hosting;
using clojure.lang.Runtime;
@@ -280,6 +281,10 @@ public static class RT
// for folks using Cygwin and its ilk.
public const string ClojureLoadPathString = "CLOJURE_LOAD_PATH";
+ public const string ResourceFileName = "Clojure.resources";
+
+ private static readonly string ResourceFilePath;
+
#endregion
#region It's true (or not)
@@ -512,10 +517,30 @@ public override object invoke(object arg1)
#endregion
#region Initialization
+
+ static string GetAssemblyParentDirectory()
+ {
+ Uri uri = new Uri(Assembly.GetExecutingAssembly().CodeBase);
+ return Path.GetDirectoryName(Uri.UnescapeDataString(uri.AbsolutePath));
+ }
+
+ static Assembly ResolveAssembly(object sender, ResolveEventArgs args)
+ {
+ string weakName = args.Name.Split(',').FirstOrDefault();
+ if (String.IsNullOrEmpty(weakName) || weakName.EndsWith(".resources")) return null;
+
+ byte[] data;
+ return ResourceHelper.TryGetResourceData(weakName + ".dll", ResourceFilePath, out data)
+ ? Assembly.Load(data)
+ : null;
+ }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
static RT()
{
+ ResourceFilePath = Path.Combine(GetAssemblyParentDirectory(), ResourceFileName);
+ AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;
+
// TODO: Check for existence of ClojureContext.Default before doing this?
ScriptRuntimeSetup setup = new ScriptRuntimeSetup();
@@ -3081,10 +3106,27 @@ public static void load(String relativePath, Boolean failIfNotFound)
else
LoadScript(cljInfo, cljname); ;
}
- else if (!loaded && failIfNotFound)
- throw new FileNotFoundException(String.Format("Could not locate {0} or {1} on load path.", assemblyname, cljname));
-
+ else if (!loaded)
+ {
+ byte[] data;
+ if (ResourceHelper.TryGetResourceData(assemblyname, ResourceFilePath, out data))
+ {
+ try
+ {
+ Var.pushThreadBindings(RT.map(CurrentNSVar, CurrentNSVar.deref(),
+ WarnOnReflectionVar, WarnOnReflectionVar.deref(),
+ RT.UncheckedMathVar, RT.UncheckedMathVar.deref()));
+ loaded = Compiler.LoadAssembly(data);
+ }
+ finally
+ {
+ Var.popThreadBindings();
+ }
+ }
+ if (!loaded && failIfNotFound)
+ throw new FileNotFoundException(String.Format("Could not locate {0} or {1} on load path.", assemblyname, cljname));
+ }
}
private static void MaybeLoadCljScript(string cljname)
diff --git a/Clojure/ClojureCLR.sln b/Clojure/ClojureCLR.sln
index 6e8ed0ca6..9a9553613 100644
--- a/Clojure/ClojureCLR.sln
+++ b/Clojure/ClojureCLR.sln
@@ -40,6 +40,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DlrConsole", "DlrConsole\DlrConsole.csproj", "{4F303159-0D0D-44D2-885D-B84F406BAF0C}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResPack", "ResPack\ResPack.csproj", "{58194622-8C69-494C-817C-A39EEB9C58DC}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3DBF3359-43B5-47C9-9E4D-CF50D7587F20} = {3DBF3359-43B5-47C9-9E4D-CF50D7587F20}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug 3.5|Any CPU = Debug 3.5|Any CPU
@@ -272,6 +277,36 @@ Global
{4F303159-0D0D-44D2-885D-B84F406BAF0C}.Release|Mixed Platforms.Build.0 = Release|x86
{4F303159-0D0D-44D2-885D-B84F406BAF0C}.Release|x86.ActiveCfg = Release|x86
{4F303159-0D0D-44D2-885D-B84F406BAF0C}.Release|x86.Build.0 = Release|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Debug 3.5|Any CPU.ActiveCfg = Debug|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Debug 3.5|Mixed Platforms.ActiveCfg = Debug|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Debug 3.5|Mixed Platforms.Build.0 = Debug|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Debug 3.5|x86.ActiveCfg = Debug|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Debug 3.5|x86.Build.0 = Debug|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Debug 4.0|Any CPU.ActiveCfg = Debug|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Debug 4.0|Mixed Platforms.ActiveCfg = Debug|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Debug 4.0|Mixed Platforms.Build.0 = Debug|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Debug 4.0|x86.ActiveCfg = Debug|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Debug 4.0|x86.Build.0 = Debug|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Debug|Mixed Platforms.Build.0 = Debug|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Debug|x86.ActiveCfg = Debug|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Debug|x86.Build.0 = Debug|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Release 3.5|Any CPU.ActiveCfg = Release|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Release 3.5|Mixed Platforms.ActiveCfg = Release|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Release 3.5|Mixed Platforms.Build.0 = Release|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Release 3.5|x86.ActiveCfg = Release|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Release 3.5|x86.Build.0 = Release|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Release 4.0|Any CPU.ActiveCfg = Release|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Release 4.0|Mixed Platforms.ActiveCfg = Release|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Release 4.0|Mixed Platforms.Build.0 = Release|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Release 4.0|x86.ActiveCfg = Release|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Release 4.0|x86.Build.0 = Release|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Release|Any CPU.ActiveCfg = Release|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Release|Mixed Platforms.ActiveCfg = Release|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Release|Mixed Platforms.Build.0 = Release|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Release|x86.ActiveCfg = Release|x86
+ {58194622-8C69-494C-817C-A39EEB9C58DC}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Clojure/ResPack/Program.cs b/Clojure/ResPack/Program.cs
new file mode 100644
index 000000000..72b258c18
--- /dev/null
+++ b/Clojure/ResPack/Program.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using System.IO;
+
+namespace ResPack
+{
+ internal static class Program
+ {
+ const string PATH_PROP = "CLOJURE_COMPILE_PATH";
+
+ static Program()
+ {
+ AppDomain.CurrentDomain.UnhandledException +=
+ (sender, args) => LogErrorAndExit(args.ExceptionObject as Exception);
+ }
+
+ private static void LogErrorAndExit(Exception ex)
+ {
+ Console.Error.WriteLine(ex.Message);
+ Environment.Exit(ExitCode.Error);
+ }
+
+ private static void Main(string[] args)
+ {
+ switch (args.Length)
+ {
+ case 0:
+ throw new Exception("missing resource file name");
+
+ case 1:
+ throw new Exception("missing content file name");
+ }
+
+ var dir = Environment.GetEnvironmentVariable(PATH_PROP) ?? Environment.CurrentDirectory;
+ args.Skip(1).PackResources(dir, args[0]);
+ }
+
+ private static void PackResources(this IEnumerable resources, string directory, string fileName)
+ {
+ var entries = new Dictionary();
+
+ foreach (var res in resources.Where(r => !String.IsNullOrWhiteSpace(r)))
+ {
+ var contentFile = Path.Combine(directory, res.Trim());
+ var data = File.ReadAllBytes(contentFile);
+ entries.Add(res, data);
+ }
+
+ var resFile = Path.Combine(directory, fileName);
+ entries.WriteResourceFile(resFile);
+ }
+ }
+
+ internal static class ExitCode
+ {
+ public const int Error = -1;
+ public const int Success = 0;
+ }
+}
\ No newline at end of file
diff --git a/Clojure/ResPack/Properties/AssemblyInfo.cs b/Clojure/ResPack/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..5ba21454f
--- /dev/null
+++ b/Clojure/ResPack/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ResPack")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ResPack")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("5b8c2878-3154-43c1-939d-e365e6a943ea")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Clojure/ResPack/ResPack.csproj b/Clojure/ResPack/ResPack.csproj
new file mode 100644
index 000000000..d7aa97832
--- /dev/null
+++ b/Clojure/ResPack/ResPack.csproj
@@ -0,0 +1,61 @@
+
+
+
+ Debug
+ x86
+ 8.0.30703
+ 2.0
+ {58194622-8C69-494C-817C-A39EEB9C58DC}
+ Exe
+ Properties
+ ResPack
+ ResPack
+ v4.0
+ Client
+ 512
+
+
+ x86
+ true
+ full
+ false
+ ..\..\bin\4.0\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ x86
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "$(TargetPath)" Clojure.resources clojure.clr.io.clj.dll clojure.clr.shell.clj.dll clojure.core.clj.dll clojure.core.protocols.clj.dll clojure.core_clr.clj.dll clojure.core_deftype.clj.dll clojure.core_print.clj.dll clojure.core_proxy.clj.dll clojure.data.clj.dll clojure.genclass.clj.dll clojure.gvec.clj.dll clojure.instant.clj.dll clojure.main.clj.dll clojure.pprint.cl_format.clj.dll clojure.pprint.clj.dll clojure.pprint.column_writer.clj.dll clojure.pprint.dispatch.clj.dll clojure.pprint.pprint_base.clj.dll clojure.pprint.pretty_writer.clj.dll clojure.pprint.print_table.clj.dll clojure.pprint.utilities.clj.dll clojure.reflect.clj.dll clojure.reflect.clr.clj.dll clojure.repl.clj.dll clojure.set.clj.dll clojure.stacktrace.clj.dll clojure.string.clj.dll clojure.template.clj.dll clojure.test.clj.dll clojure.test.junit.clj.dll clojure.test.tap.clj.dll clojure.uuid.clj.dll clojure.walk.clj.dll clojure.zip.clj.dll
+
+
+
\ No newline at end of file
diff --git a/Clojure/ResPack/ResourceHelper.cs b/Clojure/ResPack/ResourceHelper.cs
new file mode 100644
index 000000000..ceff6c83a
--- /dev/null
+++ b/Clojure/ResPack/ResourceHelper.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Resources;
+
+namespace ResPack
+{
+ public static class ResourceHelper
+ {
+ public static void WriteResourceFile(this IEnumerable> pairs, string fileName)
+ {
+ using (var writer = new ResourceWriter(fileName))
+ {
+ foreach (var p in pairs)
+ {
+ writer.AddResourceData(p.Key, String.Empty, p.Value);
+ }
+ }
+ }
+
+ public static bool TryGetResourceData(string key, string fileName, out byte[] data)
+ {
+ try
+ {
+ data = GetResourceData(key, fileName);
+ return (data != null);
+ }
+ catch
+ {
+ data = null;
+ return false;
+ }
+ }
+
+ public static byte[] GetResourceData(string key, string fileName)
+ {
+ return ReadResourceFile(new[] {key}, fileName).First().Value;
+ }
+
+ public static IEnumerable> ReadResourceFile(this IEnumerable keys,
+ string fileName)
+ {
+ using (var reader = new ResourceReader(fileName))
+ {
+ string _;
+ byte[] data;
+ var pairs = new Dictionary();
+
+ foreach (var k in keys)
+ {
+ reader.GetResourceData(k, out _, out data);
+ pairs.Add(k, data);
+ }
+
+ return pairs;
+ }
+ }
+ }
+}
\ No newline at end of file