[MSBuild] Fix minor assembly resolution issue
[mono.git] / mcs / tools / mdbrebase / mdbrebase.cs
1 using System;
2 using System.Reflection;
3 using System.Collections;
4 using System.Collections.Generic;
5 using System.Text.RegularExpressions;
6 using System.IO;
7
8 using Mono.CompilerServices.SymbolWriter;
9 using Mono.Options;
10
11 namespace Mono.MdbRebase
12 {
13
14 class Settings
15 {
16         public string OutputDirectory { get; set; }
17         public string InputPattern { get; set; }
18         public string OutputPattern { get; set; }
19         public bool InputPatternIsRegex { get; set; }
20         public bool FileNamesOnly { get; set; }
21         public bool Verbose { get; set; }
22
23         Regex inputPatternRegex;
24
25         public bool Validate ()
26         {
27                 return InputPattern != null && OutputPattern != null;
28         }
29
30         public string Replace (string input)
31         {
32                 if (InputPatternIsRegex) {
33                         if (inputPatternRegex == null)
34                                 inputPatternRegex = new Regex (InputPattern);
35                         return inputPatternRegex.Replace (input, OutputPattern);
36                 } else {
37                         if (input.StartsWith (InputPattern))
38                                 return OutputPattern + input.Substring (InputPattern.Length);
39                 }
40
41                 return input;
42         }
43 }
44
45 class MdbRebase
46 {
47         Settings settings;
48
49         public MdbRebase (Settings settings)
50         {
51                 this.settings = settings;
52         }
53
54         public void RewriteMdbFile (string inputFile)
55         {
56                 Console.WriteLine ("Processing {0}", inputFile);
57                 var input = MonoSymbolFile.ReadSymbolFile (inputFile);
58
59                 var output = new MonoSymbolFile ();
60
61                 foreach (var s in input.Sources) {
62                         var newFileName = settings.FileNamesOnly
63                                 ? Path.Combine (Path.GetDirectoryName (s.FileName), settings.Replace (Path.GetFileName (s.FileName)))
64                                 : settings.Replace (s.FileName);
65
66                         if (settings.Verbose)
67                                 Console.WriteLine ("{0} -> {1}", s.FileName, newFileName);
68
69                         s.FileName = newFileName;
70                         output.AddSource (s);
71                 }
72
73                 foreach (var cu in input.CompileUnits) {
74                         cu.ReadAll ();
75                         output.AddCompileUnit (cu);
76                 }
77         
78                 foreach (var m in input.Methods) {
79                         m.ReadAll ();
80                         output.AddMethod (m);
81                 }
82
83
84                 var mdbName = new FileInfo (inputFile).Name;
85                 var tmpMdb = Path.Combine (Path.GetTempPath (), mdbName);
86                 var finalMdb = inputFile;
87                 if (settings.OutputDirectory != null)
88                         finalMdb = Path.Combine (settings.OutputDirectory, mdbName);
89
90                 using (var stream = new FileStream (tmpMdb, FileMode.Create)) {
91                         output.CreateSymbolFile (input.Guid, stream);
92                 }
93                 input.Dispose ();
94
95                 File.Delete (finalMdb);
96                 File.Move (tmpMdb, finalMdb);
97         }
98 }
99
100 class Driver {
101         static void Usage (OptionSet options)
102         {
103                 Console.WriteLine (@"Usage: mdbrebase [options] <ASSEMBLY_TO_FIX>");
104                 if (options != null) {
105                         Console.WriteLine ();
106                         Console.WriteLine ("Available options:");
107                         options.WriteOptionDescriptions (Console.Out);
108                 }
109                 Console.WriteLine ();
110                 
111                 Environment.Exit (-1);
112         }
113
114         static int Main (string[] args) {
115                 var s = new Settings ();
116                 bool showHelp = false;
117
118                 var p = new OptionSet () {
119                         { "d=|output=",  "Output directory to the mdb file, replace existing one if ommited", v => s.OutputDirectory = v },
120                         { "v|verbose", "Be verbose with output (show individual path rewrites)", v => s.Verbose = true },
121                         { "f|filenames", "Only operate on file names, not full absolute paths", v => s.FileNamesOnly = true },
122                         { "r|regex", "Input pattern is a regular expression", v => s.InputPatternIsRegex = true },
123                         { "i=|input-pattern=", "Input pattern to replace (must not be a prefix to output-pattern)(required)", v => s.InputPattern = v },
124                         { "o=|output-pattern=", "Output pattern to replace (required)", v => s.OutputPattern = v },
125                         { "h|?|help", v => showHelp = true },
126                 };
127
128                 List <string> extra = p.Parse (args);
129
130                 if (showHelp || extra.Count < 1 || !s.Validate ())
131                         Usage (p);
132
133                 var m = new MdbRebase (s);
134                 foreach (var a in extra)
135                         m.RewriteMdbFile (a);
136                 return 0;
137
138         }
139 }
140 }