/* * Copyright (c) 2005 Kamil Skalski * Copyright (c) 2005-2008 The University of Wroclaw. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the University may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE UNIVERSITY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ using System; using System.IO; using System.Collections; using System.Reflection; using Microsoft.Build.Framework; using Microsoft.Build.Tasks; using Microsoft.Build.Utilities; using Microsoft.Win32; using Nemerle.Utility; [assembly: AssemblyVersionFromSVN ("0.9.4.SVN")] namespace Nemerle.Tools.MSBuildTask { [Record] class p { public a : string; public b : int; public c : int; public d : int; public e : int; } public class Ncc : ManagedCompiler { protected override ToolName : string { get { "ncc.exe"; } } private static FindExecutable(toolName : string) : string { def my_file = Uri(typeof(Ncc).Assembly.CodeBase).LocalPath; def ncc_file = Path.Combine (Path.GetDirectoryName(my_file), toolName); if (File.Exists(ncc_file)) { // The tool found in the same folder. // ncc_file; } else { // Query the shell association. // def regKey = Registry.LocalMachine.OpenSubKey( $@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\$toolName"); if (regKey != null) { // The tool is registered with the Shell API. // regKey.GetValue(null) :> string; } else { // Return the tool name itself. // The environment will search common paths for the tool. // toolName; } } } protected override GenerateFullPathToTool () : string { FindExecutable(ToolName); } protected override AddResponseFileCommands(commandLine : CommandLineBuilderExtension) : void { //System.Diagnostics.Debug.Assert(false); when (RunDebugger) commandLine.AppendSwitch("-debugger"); commandLine.AppendSwitch ("/no-color"); commandLine.AppendSwitchIfNotNull("/lib:", base.AdditionalLibPaths, ","); commandLine.AppendSwitchIfNotNull("/nowarn:", this.DisabledWarnings, ","); commandLine.AppendSwitchIfNotNull("/dowarn:", this.EnabledWarnings, ","); when (NoStdLib) commandLine.AppendSwitch("/no-stdlib"); when (NoStdMacros) commandLine.AppendSwitch("/no-stdmacros"); when (!GreedyReferences) commandLine.AppendSwitch("/greedy-references:-"); when (WarningLevel != 4) commandLine.AppendSwitchIfNotNull("/warn:", WarningLevel.ToString()); when (IndentationSyntax) commandLine.AppendSwitch("/indentation-syntax"); commandLine.AppendSwitchIfNotNull("/doc:", this.DocumentationFile); commandLine.AppendSwitchUnquotedIfNotNull("/define:", base.DefineConstants); Bag ["Optimize"] = null; // prevent standard handling by ManagedCompiler base.AddResponseFileCommands(commandLine); when (base.ResponseFiles != null) { def items = base.ResponseFiles; foreach (it in items) commandLine.AppendSwitchIfNotNull("/fromfile:", it.ItemSpec); } when (base.References != null) { def items = base.References; foreach (it in items) commandLine.AppendSwitchIfNotNull("/ref:", it.ItemSpec); } } static Colon : array[char] = array[':']; protected override LogEventsFromTextOutput(singleLine : string, _ : MessageImportance) : void { // System.Diagnostics.Trace.Assert(false); def get_location (before) : p { def str = singleLine.Substring (0, singleLine.IndexOf (before)); if (string.IsNullOrEmpty (str)) p(null, 0,0,0,0) else { // Path can contain ':'. We should skip it... def dir = if (str.StartsWith(":")) "" else System.IO.Path.GetDirectoryName(str); // Find first location separator (it's a end of path) def locIndex = str.IndexOf(':', dir.Length); def path = if (locIndex <= 0) dir else str.Substring(0, locIndex); def locStr = str.Substring(locIndex); def parts = locStr.Trim().Trim(Colon).Split(':'); def parse(part) { int.Parse(parts[part]) } match (parts.Length) { | 2 => def ln = parse(0); def cl = parse(1); p(path, ln, cl, ln, cl + 1) | 4 => p(path, parse(0), parse(1), parse(2), parse(3)) | _ => p(path, 0, 0, 0, 0) } } } def tryReport(tagStr, func) { def index = singleLine.IndexOf (tagStr); if (index != -1) { def (file, l1, c1, l2, c2) = get_location (tagStr); func (file, l1, c1, l2, c2, singleLine.Substring (index + if (tagStr == "hint:") 0 else tagStr.Length + 1)); true } else false } def logError (file, l1, c1, l2, c2, msg) { Log.LogError (null, null, null, file, l1, c1, l2, c2, msg) } def logWarning(file, l1, c1, l2, c2, msg) { Log.LogWarning (null, null, null, file, l1, c1, l2, c2, msg) } _ = tryReport ("error:", logError) || tryReport ("warning:", logWarning) || tryReport ("debug:", logError) || tryReport ("hint:", logWarning) || Log.LogMessageFromText(singleLine, MessageImportance.High); } protected override GetResponseFileSwitch(responseFilePath : string) : string { $<#/from-file:"$responseFilePath"#>; } /*protected override LogToolCommand(message : string) : void { _ = Log.LogMessageFromText("Command:", MessageImportance.Low); _ = Log.LogMessageFromText(message, MessageImportance.Normal); }*/ public DisabledWarnings : array[string] { get; set; } public EnabledWarnings : array[string] { get; set; } public DocumentationFile : string { get; set; } public NoStdLib : bool { get; set; } public NoStdMacros : bool { get; set; } public WarningsAsErrors : bool { get; set; } public IndentationSyntax : bool { get; set; } public GreedyReferences : bool { get; set; } public RunDebugger : bool { get; set; } [Accessor (flags = WantSetter)] mutable _warning_level : int = 4; } }