2 using System.Reflection;
3 using System.Collections;
4 using System.Collections.Generic;
5 using System.Text.RegularExpressions;
8 using Mono.CompilerServices.SymbolWriter;
11 namespace Mono.MdbRebase
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; }
23 Regex inputPatternRegex;
25 public bool Validate ()
27 return InputPattern != null && OutputPattern != null;
30 public string Replace (string input)
32 if (InputPatternIsRegex) {
33 if (inputPatternRegex == null)
34 inputPatternRegex = new Regex (InputPattern);
35 return inputPatternRegex.Replace (input, OutputPattern);
37 if (input.StartsWith (InputPattern))
38 return OutputPattern + input.Substring (InputPattern.Length);
49 public MdbRebase (Settings settings)
51 this.settings = settings;
54 public void RewriteMdbFile (string inputFile)
56 Console.WriteLine ("Processing {0}", inputFile);
57 var input = MonoSymbolFile.ReadSymbolFile (inputFile);
59 var output = new MonoSymbolFile ();
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);
67 Console.WriteLine ("{0} -> {1}", s.FileName, newFileName);
69 s.FileName = newFileName;
73 foreach (var cu in input.CompileUnits) {
75 output.AddCompileUnit (cu);
78 foreach (var m in input.Methods) {
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);
90 using (var stream = new FileStream (tmpMdb, FileMode.Create)) {
91 output.CreateSymbolFile (input.Guid, stream);
95 File.Delete (finalMdb);
96 File.Move (tmpMdb, finalMdb);
101 static void Usage (OptionSet options)
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);
109 Console.WriteLine ();
111 Environment.Exit (-1);
114 static int Main (string[] args) {
115 var s = new Settings ();
116 bool showHelp = false;
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 },
128 List <string> extra = p.Parse (args);
130 if (showHelp || extra.Count < 1 || !s.Validate ())
133 var m = new MdbRebase (s);
134 foreach (var a in extra)
135 m.RewriteMdbFile (a);