.I \-\-parse
Used for benchmarking. The compiler will only parse its input files.
.TP
+.I \-pathmap:K=V[,Kn=Vn]
+Sets a mapping for source path names used in generated output.
+.TP
.I \-pkg:package1[,packageN]
Reference assemblies for the given packages.
.Sp
byte[] hash;
bool creating;
bool auto_generated;
+ readonly string sourceFile;
public static int Size {
get { return 8; }
creating = true;
}
- public SourceFileEntry (MonoSymbolFile file, string file_name, byte[] guid, byte[] checksum)
- : this (file, file_name)
+ public SourceFileEntry (MonoSymbolFile file, string sourceFile, byte [] guid, byte [] checksum)
+ : this (file, sourceFile, sourceFile, guid, checksum)
+ {
+ }
+
+ public SourceFileEntry (MonoSymbolFile file, string fileName, string sourceFile, byte[] guid, byte[] checksum)
+ : this (file, fileName)
{
this.guid = guid;
this.hash = checksum;
+ this.sourceFile = sourceFile;
}
public byte[] Checksum {
if (hash == null) {
try {
- using (FileStream fs = new FileStream (file_name, FileMode.Open, FileAccess.Read)) {
+ using (FileStream fs = new FileStream (sourceFile, FileMode.Open, FileAccess.Read)) {
MD5 md5 = MD5.Create ();
hash = md5.ComputeHash (fs);
}
int old_pos = (int) reader.BaseStream.Position;
reader.BaseStream.Position = DataOffset;
- file_name = reader.ReadString ();
+ sourceFile = file_name = reader.ReadString ();
guid = reader.ReadBytes (16);
hash = reader.ReadBytes (16);
auto_generated = reader.ReadByte () == 1;
public bool CheckChecksum ()
{
try {
- using (FileStream fs = new FileStream (file_name, FileMode.Open)) {
+ using (FileStream fs = new FileStream (sourceFile, FileMode.Open)) {
MD5 md5 = MD5.Create ();
byte[] data = md5.ComputeHash (fs);
for (int i = 0; i < 16; i++)
--- /dev/null
+// CS8101: The pathmap option was incorrectly formatted
+// Line: 0
+// Compiler options: -pathmap:a=
+
+class X
+{
+}
\ No newline at end of file
if (all_source_files == null) {
all_source_files = new Dictionary<string, SourceFile> ();
foreach (var source in SourceFiles)
- all_source_files[source.FullPathName] = source;
+ all_source_files[source.OriginalFullPathName] = source;
}
string path;
if (!Path.IsPathRooted (name)) {
var loc = comp_unit.SourceFile;
- string root = Path.GetDirectoryName (loc.FullPathName);
+ string root = Path.GetDirectoryName (loc.OriginalFullPathName);
path = Path.GetFullPath (Path.Combine (root, name));
var dir = Path.GetDirectoryName (loc.Name);
if (!string.IsNullOrEmpty (dir))
if ((fp.ModFlags & Parameter.Modifier.CallerLineNumber) != 0) {
e = new IntLiteral (ec.BuiltinTypes, loc.Row, loc);
} else if ((fp.ModFlags & Parameter.Modifier.CallerFilePath) != 0) {
- e = new StringLiteral (ec.BuiltinTypes, loc.NameFullPath, loc);
+ e = new StringLiteral (ec.BuiltinTypes, loc.SourceFile.GetFullPathName (ec.Module.Compiler.Settings.PathMap), loc);
} else if (ec.MemberContext.CurrentMemberDefinition != null) {
e = new StringLiteral (ec.BuiltinTypes, ec.MemberContext.CurrentMemberDefinition.GetCallerMemberName (), loc);
}
using Mono.CompilerServices.SymbolWriter;
using System.Diagnostics;
using System.Linq;
+using System.IO;
namespace Mono.CSharp
{
static readonly byte[] MD5Algorith = { 96, 166, 110, 64, 207, 100, 130, 76, 182, 240, 66, 212, 129, 114, 167, 153 };
public readonly string Name;
- public readonly string FullPathName;
+ public readonly string OriginalFullPathName;
public readonly int Index;
public bool AutoGenerated;
{
this.Index = index;
this.Name = name;
- this.FullPathName = path;
+ this.OriginalFullPathName = path;
}
public byte[] Checksum {
this.checksum = checksum;
}
- public SourceFileEntry CreateSymbolInfo (MonoSymbolFile symwriter)
+ public SourceFileEntry CreateSymbolInfo (MonoSymbolFile symwriter, List<KeyValuePair<string, string>> pathMap)
{
if (hidden_lines != null)
hidden_lines.Sort ();
- file = new SourceFileEntry (symwriter, FullPathName, algGuid, checksum);
+ file = new SourceFileEntry (symwriter, GetFullPathName (pathMap), OriginalFullPathName, algGuid, checksum);
if (AutoGenerated)
file.SetAutoGenerated ();
return file;
}
+ public string GetFullPathName (List<KeyValuePair<string, string>> pathMap)
+ {
+ var path = OriginalFullPathName;
+ if (pathMap != null) {
+ foreach (var map in pathMap) {
+ var prefix = map.Key;
+ if (path.Length <= prefix.Length)
+ continue;
+
+ if (path [prefix.Length] != Path.DirectorySeparatorChar)
+ continue;
+
+ if (!path.StartsWith (prefix, StringComparison.Ordinal))
+ continue;
+
+ path = map.Value + path.Substring (prefix.Length);
+ }
+ }
+
+ return path;
+ }
+
public bool Equals (SourceFile other)
{
- return FullPathName == other.FullPathName;
+ return OriginalFullPathName == other.OriginalFullPathName;
}
public bool IsHiddenLocation (Location loc)
public override string ToString ()
{
- return String.Format ("SourceFile ({0}:{1}:{2})", Name, FullPathName, Index);
+ return String.Format ("SourceFile ({0}:{1}:{2})", Name, OriginalFullPathName, Index);
}
}
public string NameFullPath {
get {
int index = File;
- if (token == 0 || index <= 0)
+ if (index <= 0)
return null;
- return source_list[index - 1].FullPathName;
+ return source_list[index - 1].OriginalFullPathName;
}
}
}
}
- // The ISymbolDocumentWriter interface is used by the symbol writer to
- // describe a single source file - for each source file there's exactly
- // one corresponding ISymbolDocumentWriter instance.
- //
- // This class has an internal hash table mapping source document names
- // to such ISymbolDocumentWriter instances - so there's exactly one
- // instance per document.
- //
- // This property returns the ISymbolDocumentWriter instance which belongs
- // to the location's source file.
- //
- // If we don't have a symbol writer, this property is always null.
public SourceFile SourceFile {
get {
int index = File;
if (include_files == null)
include_files = new Dictionary<string, SourceFile> ();
- if (!include_files.ContainsKey (file.FullPathName))
- include_files.Add (file.FullPathName, file);
+ if (!include_files.ContainsKey (file.OriginalFullPathName))
+ include_files.Add (file.OriginalFullPathName, file);
}
public void AddDefine (string value)
{
var sw = Module.DeclaringAssembly.SymbolWriter;
if (sw != null) {
- CreateUnitSymbolInfo (sw);
+ CreateUnitSymbolInfo (sw, Compiler.Settings.PathMap);
}
base.PrepareEmit ();
//
// Creates symbol file index in debug symbol file
//
- void CreateUnitSymbolInfo (MonoSymbolFile symwriter)
+ void CreateUnitSymbolInfo (MonoSymbolFile symwriter, List<KeyValuePair<string, string>> pathMap)
{
- var si = file.CreateSymbolInfo (symwriter);
+ var si = file.CreateSymbolInfo (symwriter, pathMap);
comp_unit = new CompileUnitEntry (symwriter, si);
if (include_files != null) {
foreach (SourceFile include in include_files.Values) {
- si = include.CreateSymbolInfo (symwriter);
+ si = include.CreateSymbolInfo (symwriter, pathMap);
comp_unit.AddFile (si);
}
}
//
public List<Tuple<string, string>> AssemblyReferencesAliases;
+ public List<KeyValuePair<string, string>> PathMap;
+
//
// Modules to be embedded
//
settings.RuntimeMetadataVersion = value;
return ParseResult.Success;
+ case "/pathmap":
+ if (value.Length == 0) {
+ return ParseResult.Success;
+ }
+
+ foreach (var pair in value.Split (',')) {
+ var kv = pair.Split ('=');
+ if (kv.Length != 2) {
+ report.Error (8101, "The pathmap option was incorrectly formatted");
+ return ParseResult.Error;
+ }
+
+ if (settings.PathMap == null)
+ settings.PathMap = new List<KeyValuePair<string, string>> ();
+
+ var key = kv [0].TrimEnd (Path.DirectorySeparatorChar);
+ var path = kv [1].TrimEnd (Path.DirectorySeparatorChar);
+ if (key.Length == 0 || path.Length == 0)
+ report.Error (8101, "The pathmap option was incorrectly formatted");
+
+ settings.PathMap.Add (new KeyValuePair<string, string> (key, path));
+ }
+
+ return ParseResult.Success;
+
// csc options that we don't support
case "/analyzer":
case "/appconfig":
case "/link":
case "/moduleassemblyname":
case "/nowin32manifest":
- case "/pathmap":
case "/pdb":
case "/preferreduilang":
case "/publicsign":
" -help Lists all compiler options (short: -?)\n" +
" -keycontainer:NAME The key pair container used to sign the output assembly\n" +
" -keyfile:FILE The key file used to strongname the ouput assembly\n" +
- " -langversion:TEXT Specifies language version: ISO-1, ISO-2, 3, 4, 5, Default or Experimental\n" +
+ " -langversion:TEXT Specifies language version: ISO-1, ISO-2, 3, 4, 5, 6, Default or Experimental\n" +
" -lib:PATH1[,PATHn] Specifies the location of referenced assemblies\n" +
" -main:CLASS Specifies the class with the Main method (short: -m)\n" +
" -noconfig Disables implicitly referenced assemblies\n" +
" -nowarn:W1[,Wn] Suppress one or more compiler warnings\n" +
" -optimize[+|-] Enables advanced compiler optimizations (short: -o)\n" +
" -out:FILE Specifies output assembly name\n" +
+ " -pathmap:K=V[,Kn=Vn] Sets a mapping for source path names used in generated output\n" +
" -pkg:P1[,Pn] References packages P1..Pn\n" +
" -platform:ARCH Specifies the target platform of the output assembly\n" +
" ARCH can be one of: anycpu, anycpu32bitpreferred, arm,\n" +
var startup_files = new string [settings.SourceFiles.Count];
int i = 0;
foreach (var source in settings.SourceFiles)
- startup_files [i++] = source.FullPathName;
+ startup_files [i++] = source.OriginalFullPathName;
settings.SourceFiles.Clear ();
TextWriter agent_stderr = null;