From d32a6a733e0fd7918517f7233ab2d11d6f01c6d3 Mon Sep 17 00:00:00 2001 From: Fedor Baart Date: Sun, 1 Jun 2014 18:13:26 +0200 Subject: [PATCH 1/4] working under mono --- .../BasicModelInterface.Tests.csproj | 4 +- src/BasicModelInterface.Tests/packages.config | 6 +- .../BasicModelInterfaceRunner.csproj | 17 ++-- src/BasicModelInterfaceRunner/Main.usage.txt | 78 +++++++++---------- src/BasicModelInterfaceRunner/packages.config | 6 +- 5 files changed, 56 insertions(+), 55 deletions(-) diff --git a/src/BasicModelInterface.Tests/BasicModelInterface.Tests.csproj b/src/BasicModelInterface.Tests/BasicModelInterface.Tests.csproj index 19b6fd2..6e5fb5c 100644 --- a/src/BasicModelInterface.Tests/BasicModelInterface.Tests.csproj +++ b/src/BasicModelInterface.Tests/BasicModelInterface.Tests.csproj @@ -1,5 +1,5 @@  - + Debug @@ -51,7 +51,7 @@ - {b973019e-5674-4e23-9b1e-c4ca5eac381b} + {B973019E-5674-4E23-9B1E-C4CA5EAC381B} BasicModelInterface diff --git a/src/BasicModelInterface.Tests/packages.config b/src/BasicModelInterface.Tests/packages.config index ad37a52..d4e241a 100644 --- a/src/BasicModelInterface.Tests/packages.config +++ b/src/BasicModelInterface.Tests/packages.config @@ -1,4 +1,4 @@ - - - + + + \ No newline at end of file diff --git a/src/BasicModelInterfaceRunner/BasicModelInterfaceRunner.csproj b/src/BasicModelInterfaceRunner/BasicModelInterfaceRunner.csproj index 813abf9..eb64f3f 100644 --- a/src/BasicModelInterfaceRunner/BasicModelInterfaceRunner.csproj +++ b/src/BasicModelInterfaceRunner/BasicModelInterfaceRunner.csproj @@ -1,5 +1,5 @@  - + Debug @@ -32,9 +32,6 @@ 4 - - ..\packages\docopt.net.0.6.1.5\lib\net40\DocoptNet.dll - @@ -42,6 +39,9 @@ + + ..\..\packages\docopt.net.0.6.1.5\lib\net40\DocoptNet.dll + @@ -49,20 +49,21 @@ + + + + - {b973019e-5674-4e23-9b1e-c4ca5eac381b} + {B973019E-5674-4E23-9B1E-C4CA5EAC381B} BasicModelInterface - - - diff --git a/src/BasicModelInterfaceRunner/Main.usage.txt b/src/BasicModelInterfaceRunner/Main.usage.txt index 6a68397..777bf5a 100644 --- a/src/BasicModelInterfaceRunner/Main.usage.txt +++ b/src/BasicModelInterfaceRunner/Main.usage.txt @@ -1,39 +1,39 @@ -Example usage for T4 Docopt.NET - -Usage: - prog command ARG [OPTIONALARG] [-o -s= --long=ARG --switch] - prog files FILE... - -Options: - -o Short switch. - -s= Short option with arg. - --long=ARG Long option with arg. - --swith Long switch. - -Explanation: - This is an example usage file that needs to be customized. - Every time you change this file, run the Custom Tool command - on T4DocoptNet.tt to re-generate the MainArgs class - (defined in T4DocoptNet.cs). - You can then use the MainArgs classed as follows: - - class Program - { - - static void DoStuff(string arg, bool flagO, string longValue) - { - // ... - } - - static void Main(string[] argv) - { - // Automatically exit(1) if invalid arguments - var args = new MainArgs(argv, exit: true); - if (args.CmdCommand) - { - Console.WriteLine("First command"); - DoStuff(args.ArgArg, args.OptO, args.OptLong); - } - } - } - +Example usage for T4 Docopt.NET + +Usage: + prog command ARG [OPTIONALARG] [-o -s= --long=ARG --switch] + prog files FILE... + +Options: + -o Short switch. + -s= Short option with arg. + --long=ARG Long option with arg. + --swith Long switch. + +Explanation: + This is an example usage file that needs to be customized. + Every time you change this file, run the Custom Tool command + on T4DocoptNet.tt to re-generate the MainArgs class + (defined in T4DocoptNet.cs). + You can then use the MainArgs classed as follows: + + class Program + { + + static void DoStuff(string arg, bool flagO, string longValue) + { + // ... + } + + static void Main(string[] argv) + { + // Automatically exit(1) if invalid arguments + var args = new MainArgs(argv, exit: true); + if (args.CmdCommand) + { + Console.WriteLine("First command"); + DoStuff(args.ArgArg, args.OptO, args.OptLong); + } + } + } + diff --git a/src/BasicModelInterfaceRunner/packages.config b/src/BasicModelInterfaceRunner/packages.config index 11f8d4f..962e876 100644 --- a/src/BasicModelInterfaceRunner/packages.config +++ b/src/BasicModelInterfaceRunner/packages.config @@ -1,4 +1,4 @@ - - - + + + \ No newline at end of file From f4a20f1db7d0f9d1d9196f0ad7c15a22f3230262 Mon Sep 17 00:00:00 2001 From: Fedor Baart Date: Sun, 1 Jun 2014 18:14:04 +0200 Subject: [PATCH 2/4] not sure if this is needed --- src/BasicModelInterfaceRunner/T4DocoptNet.tt | 112 ++++++++++++++++++ .../T4DocoptNet.tt.hooks.t4 | 18 +++ .../T4DocoptNet.tt.settings.xml | 11 ++ 3 files changed, 141 insertions(+) create mode 100644 src/BasicModelInterfaceRunner/T4DocoptNet.tt create mode 100644 src/BasicModelInterfaceRunner/T4DocoptNet.tt.hooks.t4 create mode 100644 src/BasicModelInterfaceRunner/T4DocoptNet.tt.settings.xml diff --git a/src/BasicModelInterfaceRunner/T4DocoptNet.tt b/src/BasicModelInterfaceRunner/T4DocoptNet.tt new file mode 100644 index 0000000..871fa2b --- /dev/null +++ b/src/BasicModelInterfaceRunner/T4DocoptNet.tt @@ -0,0 +1,112 @@ +<# +/* +T4DocopNet Version 0.1.0 +*/ +#> +<#@ template language="C#" debug="true" hostspecific="true" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="Microsoft.VisualStudio.Shell.Interop" #> +<#@ assembly name="EnvDTE" #> +<#@ assembly name="EnvDTE80" #> +<#@ assembly name="VSLangProj" #> +<#@ assembly name="System.Xml" #> +<#@ assembly name="System.Xml.Linq" #> +<# +// This directive will be updated at package install time +// by install.ps1. It can also be set manually to point +// to the right path. +#> +<#@ assembly name="$(ProjectDir)$(OutDir)DocoptNet.dll" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.IO" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="DocoptNet" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Text.RegularExpressions" #> +<#@ import namespace="Microsoft.VisualStudio.Shell.Interop" #> +<#@ import namespace="EnvDTE" #> +<#@ import namespace="EnvDTE80" #> +<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #> + +using System.Collections; +using System.Collections.Generic; +using DocoptNet; + +namespace <#= System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("NamespaceHint") #> +{ +<# + var templateDir = Path.GetDirectoryName(Host.TemplateFile); + var files = Directory.EnumerateFiles(templateDir).Where(f => f.EndsWith(".usage.txt")); + foreach (var file in files) + { + var entry = new UsageFileEntry(file); +#> + // Generated class for <#= Path.GetFileName(entry.FileName) #> + public class <#= entry.Name #>Args + { + public const string USAGE = @"<#= entry.Usage #>"; + private readonly IDictionary _args; + public <#= entry.Name #>Args(ICollection argv, bool help = true, + object version = null, bool optionsFirst = false, bool exit = false) + { + _args = new Docopt().Apply(USAGE, argv, help, version, optionsFirst, exit); + } + + public IDictionary Args + { + get { return _args; } + } + +<# + var s = new Docopt().GenerateCode(entry.Usage); + PushIndent(" "); + Write(s); + ClearIndent(); +#> + } + +<# + } + +#> +} + +<#+ + class UsageFileEntry + { + public string FileName; + public string Name; + public string Usage; + public UsageFileEntry(string fileName) + { + FileName = fileName; + Name = ExtractName(fileName); + Usage = File.ReadAllText(fileName).Replace("\"", "\"\""); + } + + private static string ExtractName(string fileName) + { + + var s = Path.GetFileName(fileName).Replace(".usage.txt", ""); + var res = ""; + var first = true; + foreach (char c in s) + { + if (char.IsLetterOrDigit(c)) + { + res += first ? char.ToUpperInvariant(c) : char.ToLowerInvariant(c); + first = false; + } + else + { + res += "_"; + } + } + return res; + } + } + +/* IMPORTANT: Do not add blanks after this last tag as it would break the T4 generation + * See http://stackoverflow.com/questions/11379471/error-a-template-containing-a-class-feature-must-end-with-a-class-feature + */ +#> \ No newline at end of file diff --git a/src/BasicModelInterfaceRunner/T4DocoptNet.tt.hooks.t4 b/src/BasicModelInterfaceRunner/T4DocoptNet.tt.hooks.t4 new file mode 100644 index 0000000..8a7e209 --- /dev/null +++ b/src/BasicModelInterfaceRunner/T4DocoptNet.tt.hooks.t4 @@ -0,0 +1,18 @@ +<#+ +/* + +This file contains hooks and extra code used by T4DocoptNet.tt. The main goal is to avoid the need for users +to fork the 'official' template in order to achieve what they want. + +*/ + +void RenderAdditionalCode() { +#> +[GeneratedCode("T4DocoptNet", "2.0"), DebuggerNonUserCode] +internal static class T4DocoptNetHelpers { +// TODO +} + +<#+ +} +#> diff --git a/src/BasicModelInterfaceRunner/T4DocoptNet.tt.settings.xml b/src/BasicModelInterfaceRunner/T4DocoptNet.tt.settings.xml new file mode 100644 index 0000000..225229f --- /dev/null +++ b/src/BasicModelInterfaceRunner/T4DocoptNet.tt.settings.xml @@ -0,0 +1,11 @@ + + + + T4DocoptNet + + Args + + + + + \ No newline at end of file From 2b41a443ad65ea68b77c3964b3e190823617dc9b Mon Sep 17 00:00:00 2001 From: Fedor Baart Date: Sun, 1 Jun 2014 20:06:13 +0200 Subject: [PATCH 3/4] find library logic --- .../BasicModelInterfaceLibraryTest.cs | 5 +-- .../BasicModelInterfaceLibrary.cs | 34 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/BasicModelInterface.Tests/BasicModelInterfaceLibraryTest.cs b/src/BasicModelInterface.Tests/BasicModelInterfaceLibraryTest.cs index 170c3f7..8ccf34a 100644 --- a/src/BasicModelInterface.Tests/BasicModelInterfaceLibraryTest.cs +++ b/src/BasicModelInterface.Tests/BasicModelInterfaceLibraryTest.cs @@ -7,13 +7,14 @@ namespace BasicModelInterface.Tests public class BasicModelInterfaceLibraryTest { private const string LibraryC = @"..\..\..\..\bin\Debug\model-c.dll"; - + private const string Engine = @"modelc"; private IBasicModelInterface library; [SetUp] public void SetUp() { - library = new BasicModelInterfaceLibrary(LibraryC); + string libraryPath = BasicModelInterfaceLibrary.LibraryPath (Engine); + library = new BasicModelInterfaceLibrary(libraryPath); } [Test] diff --git a/src/BasicModelInterface/BasicModelInterfaceLibrary.cs b/src/BasicModelInterface/BasicModelInterfaceLibrary.cs index fbb6531..087042a 100644 --- a/src/BasicModelInterface/BasicModelInterfaceLibrary.cs +++ b/src/BasicModelInterface/BasicModelInterfaceLibrary.cs @@ -1,6 +1,8 @@ using System; using System.Diagnostics; using System.IO; +using System.Collections; +using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; @@ -31,6 +33,38 @@ public BasicModelInterfaceLibrary(string libraryPath, CallingConvention callingC lib.ReturnTypes["update"] = typeof(int); lib.ReturnTypes["finalize"] = typeof(int); } + public static string LibraryName(string engine) + { + string extension = ".dll"; + string prefix = ""; + int p = (int) Environment.OSVersion.Platform; + if ((p == 4) || (p == 128)) { + prefix = "lib"; + extension = ".so"; + } + else if (p == 6) + { + prefix = "lib"; + extension = ".dylib"; + } + else { + prefix = ""; + extension = ".dll"; + }; + return prefix + engine + extension; + } + public static string LibraryPath(string engine) + { + string[] knownPaths = { + "~/.local/lib", + "/usr/local/lib", + "/usr/lib" + }; + // TODO loop over paths to find the library. + + string expandedPath = knownPaths[0].Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); + return Path.GetFullPath(Path.Combine(expandedPath, LibraryName(engine))) ; + } public DateTime StartTime { From be883997b7e244716f91f4f25a1693e65b529c50 Mon Sep 17 00:00:00 2001 From: Fedor Baart Date: Mon, 30 Nov 2015 17:04:23 +0100 Subject: [PATCH 4/4] testing under mono --- .../BasicModelInterface.Tests.csproj | 7 +++ .../BasicModelInterfaceLibraryTest.cs | 22 +++++++-- src/BasicModelInterface.Tests/app.config | 4 ++ .../BasicModelInterface.csproj | 5 +- .../BasicModelInterfaceLibrary.cs | 47 +++++++++++++++---- .../Interop/DynamicDllImportMetaObject.cs | 2 + 6 files changed, 72 insertions(+), 15 deletions(-) create mode 100644 src/BasicModelInterface.Tests/app.config diff --git a/src/BasicModelInterface.Tests/BasicModelInterface.Tests.csproj b/src/BasicModelInterface.Tests/BasicModelInterface.Tests.csproj index 6e5fb5c..cf1dfa5 100644 --- a/src/BasicModelInterface.Tests/BasicModelInterface.Tests.csproj +++ b/src/BasicModelInterface.Tests/BasicModelInterface.Tests.csproj @@ -21,6 +21,11 @@ prompt 4 true + + + + + pdbonly @@ -29,6 +34,7 @@ TRACE prompt 4 + true @@ -48,6 +54,7 @@ + diff --git a/src/BasicModelInterface.Tests/BasicModelInterfaceLibraryTest.cs b/src/BasicModelInterface.Tests/BasicModelInterfaceLibraryTest.cs index 8ccf34a..b80ae4d 100644 --- a/src/BasicModelInterface.Tests/BasicModelInterfaceLibraryTest.cs +++ b/src/BasicModelInterface.Tests/BasicModelInterfaceLibraryTest.cs @@ -1,19 +1,21 @@ using System; using NUnit.Framework; +using System.Runtime.InteropServices; namespace BasicModelInterface.Tests { [TestFixture] public class BasicModelInterfaceLibraryTest { - private const string LibraryC = @"..\..\..\..\bin\Debug\model-c.dll"; - private const string Engine = @"modelc"; + private const string EngineName = @"modelc"; + private string libraryPath; + private const string LibraryC = @"..\..\..\..\bin\Debug\model-c.dll"; private IBasicModelInterface library; [SetUp] public void SetUp() { - string libraryPath = BasicModelInterfaceLibrary.LibraryPath (Engine); + libraryPath = BasicModelInterfaceLibrary.GetLibraryPath(EngineName); library = new BasicModelInterfaceLibrary(libraryPath); } @@ -21,7 +23,6 @@ public void SetUp() public void InitializeAndFinish() { const string configFilePath = "empty"; - library.Initialize(configFilePath); library.Finish(); } @@ -46,7 +47,7 @@ public void GetVariableNames() [Test] public void Run() { - BasicModelInterfaceLibrary.Run(LibraryC, "test.config"); + BasicModelInterfaceLibrary.Run(libraryPath, "test.config"); } [Test] @@ -112,5 +113,16 @@ public void SetLogger() library.Initialize(string.Empty); library.Finish(); } + + [Test] + public void InitializeDirect() + { + initialize (""); + } + + [DllImport ("modelc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public static extern int initialize (string configPath); + + } } \ No newline at end of file diff --git a/src/BasicModelInterface.Tests/app.config b/src/BasicModelInterface.Tests/app.config new file mode 100644 index 0000000..9885737 --- /dev/null +++ b/src/BasicModelInterface.Tests/app.config @@ -0,0 +1,4 @@ + + + + diff --git a/src/BasicModelInterface/BasicModelInterface.csproj b/src/BasicModelInterface/BasicModelInterface.csproj index 2bbd8b1..a3256c0 100644 --- a/src/BasicModelInterface/BasicModelInterface.csproj +++ b/src/BasicModelInterface/BasicModelInterface.csproj @@ -1,5 +1,5 @@  - + Debug @@ -38,6 +38,9 @@ + + ..\..\..\..\.local\lib\libmodelc-csharp.dll + diff --git a/src/BasicModelInterface/BasicModelInterfaceLibrary.cs b/src/BasicModelInterface/BasicModelInterfaceLibrary.cs index 087042a..356ad2f 100644 --- a/src/BasicModelInterface/BasicModelInterfaceLibrary.cs +++ b/src/BasicModelInterface/BasicModelInterfaceLibrary.cs @@ -33,27 +33,54 @@ public BasicModelInterfaceLibrary(string libraryPath, CallingConvention callingC lib.ReturnTypes["update"] = typeof(int); lib.ReturnTypes["finalize"] = typeof(int); } + public static string LibraryName(string engine) { string extension = ".dll"; string prefix = ""; - int p = (int) Environment.OSVersion.Platform; - if ((p == 4) || (p == 128)) { + var p = Environment.OSVersion.Platform; + if (p == PlatformID.Unix || p == PlatformID.MacOSX) + { prefix = "lib"; extension = ".so"; + + // HACK: Mono implements Platform incorrectly + if (IsRunningOnMac ()) { + extension = ".dylib"; + extension = ""; + } } - else if (p == 6) - { - prefix = "lib"; - extension = ".dylib"; - } else { prefix = ""; extension = ".dll"; }; return prefix + engine + extension; } - public static string LibraryPath(string engine) + + //From Managed.Windows.Forms/XplatUI + [DllImport ("libc")] + static extern int uname (IntPtr buf); + + static bool IsRunningOnMac () + { + IntPtr buf = IntPtr.Zero; + try { + buf = Marshal.AllocHGlobal (8192); + // This is a hacktastic way of getting sysname from uname () + if (uname (buf) == 0) { + string os = Marshal.PtrToStringAnsi (buf); + if (os == "Darwin") + return true; + } + } catch { + } finally { + if (buf != IntPtr.Zero) + Marshal.FreeHGlobal (buf); + } + return false; + } + + public static string GetLibraryPath(string engine) { string[] knownPaths = { "~/.local/lib", @@ -63,7 +90,9 @@ public static string LibraryPath(string engine) // TODO loop over paths to find the library. string expandedPath = knownPaths[0].Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); - return Path.GetFullPath(Path.Combine(expandedPath, LibraryName(engine))) ; + var fullPath = Path.GetFullPath (Path.Combine (expandedPath, LibraryName (engine))); + Debug.Assert (new FileInfo (fullPath).Exists); + return fullPath; } public DateTime StartTime diff --git a/src/BasicModelInterface/Interop/DynamicDllImportMetaObject.cs b/src/BasicModelInterface/Interop/DynamicDllImportMetaObject.cs index c260fd2..a7ed1d8 100644 --- a/src/BasicModelInterface/Interop/DynamicDllImportMetaObject.cs +++ b/src/BasicModelInterface/Interop/DynamicDllImportMetaObject.cs @@ -54,12 +54,14 @@ public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, Dy private Type GetMethodReturnType(InvokeMemberBinder binder) { + /* var types = binder.GetType().GetField("m_typeArguments", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(binder) as IList; if ((types != null) && (types.Count > 0)) { return types[0]; } + */ Type type; lib.ReturnTypes.TryGetValue(binder.Name, out type);