Skip to content

Instantly share code, notes, and snippets.

@SLaks
Created December 22, 2013 03:36
Show Gist options
  • Save SLaks/8078184 to your computer and use it in GitHub Desktop.
Save SLaks/8078184 to your computer and use it in GitHub Desktop.
Parses PDBs from http://referencesource.microsoft.com/netframework.aspx and extracts source files to findable locations
//const string OriginalPath = @"C:\Users\SSL\Development\RefSrc\Source";
const string PDBPath = @"C:\Users\SSL\Development\Symbols\RefSrc\Symbols";
const string OriginalPath = @"C:\Users\SSL\Development\Symbols\RefSrc\Source\.NET 4.5\4.6.0.0";
const string TargetPath = @"C:\Users\SSL\Development\3rd-Party Source\Microsoft\.Net 4.5.1";
const string ErrorLog = TargetPath + @"\Errors.log";
static readonly Regex GoodLine = new Regex(@"^[a-zA-Z0-9\\:]{5}");
void Main() {
var pdbs = from file in Directory.EnumerateFiles(PDBPath, "*.pdb", SearchOption.AllDirectories)
group file by Path.GetFileName(file) into g
select g.OrderByDescending(p => new FileInfo(p).Length).First();
var basePath = Path.Combine(OriginalPath, @"net");
foreach(var pdb in pdbs) {
var assemblyName = Regex.Replace(Path.GetFileNameWithoutExtension(pdb), @"(^|\.)[a-z]", m => m.Value.ToUpper())
.Replace("Durableinstancing", "DurableInstancing")
.Replace("Presentationframework", "PresentationFramework")
.Replace("Servicemodel", "ServiceModel");
var assemblyTarget = Path.Combine(TargetPath, assemblyName);
Directory.CreateDirectory(assemblyTarget);
var log = Path.Combine(assemblyTarget, "Errors.log");
foreach(var line in File.ReadLines(pdb)) {
if (line.Length < 3 || line[0] == '\0' || line[1] != ':') continue;
if (!GoodLine.IsMatch(line)) {
Console.WriteLine(line);
continue;
}
try {
//f:\dd\ndp\fx\src\SystemNet\Net\PeerToPeer\Cloud.cs*DEVDIV_TFS*/Dev10/Releases/RTMRel/ndp/fx/src/SystemNet/Net/PeerToPeer/Cloud.cs*1305376
//f:\dd\ndp\clr\src\BCL\System\ValueType.cs*DEVDIV_TFS2*/DevDiv/D11Rel/FX45RTMRel/ndp/clr/src/BCL/System/ValueType.cs*597531
var segments = line.Split('*');
var fileName = Path.GetFileName(segments[2]);
var originalFile = Path.Combine(basePath, segments[0].Replace(@"f:\dd\ndp\", "").Replace(@"f:\dd\wpf\", ""), segments[3], fileName);
var dir = Path.Combine(assemblyTarget, (GetNamespace(originalFile) ?? "Unknown").Replace('.', '\\'));
Directory.CreateDirectory(dir);
var target = Path.Combine(dir, fileName);
if (!File.Exists(target))
File.Copy(originalFile, target);
else
File.AppendAllText(log, "Existing file: " + target + "\t" + fileName + Environment.NewLine);
} catch (Exception ex) {
File.AppendAllText(log, @"
------------------------------------
------------------------------------
ERROR:
PDB: " + assemblyName + @"
Line: " + line + @"
Exception:
" + ex.ToString());
}
}
}
}
static void CopyFlat() { //Ignores assemblies
foreach (var originalFile in Directory.EnumerateFiles(OriginalPath, "*", SearchOption.AllDirectories)) {
var fileName = Path.GetFileName(originalFile);
var dir = Path.Combine(TargetPath, (GetNamespace(originalFile) ?? "Unknown").Replace('.', '\\'));
Directory.CreateDirectory(dir);
var target = Path.Combine(dir, fileName);
if (!File.Exists(target))
File.Copy(originalFile, target);
else
File.AppendAllText(ErrorLog, "Existing file: " + target + "\t" + fileName + Environment.NewLine);
}
}
static string FindLine(string file, Func<string, bool> matches)
{
return File.ReadLines(file).FirstOrDefault(matches);
}
static string GetNamespace(string filePath) {
var fileName = Path.GetFileName(filePath);
switch (Path.GetExtension(filePath))
{
case ".vb": {
var nsLine = FindLine(filePath, s => s.StartsWith("Namespace "));
if (nsLine == null)
return null;
else
return nsLine.Substring("Namespace ".Length).Trim();
}
break;
case ".cs": {
var nsLine = FindLine(filePath, s => s.StartsWith("namespace "));
if (nsLine == null)
return null;
else
return nsLine.Substring("namespace ".Length).Trim().TrimEnd('{',' ','\t').Trim();
//var nsIndex = content.IndexOf(nsText);
//if (nsIndex == -1)
//{
// var nst = "namespace ";
// nsIndex = content.IndexOf(nst);
// if (nsIndex >= 0)
// {
// var ns = content.Substring(nsIndex + nst.Length, content.IndexOf(Environment.NewLine, nsIndex) - (nsIndex + nst.Length)).Replace("{", "").Trim();
// dir = Path.Combine(basePath, ns.Replace('.', '\\'));
// }
// else
// dir = Path.Combine(basePath, "Unknown");
//}
//else
//{
// var ns = content.Substring(nsIndex + nsText.Length, content.IndexOf(Environment.NewLine, nsIndex + 2) - (nsIndex + nsText.Length)).Replace("{", "").Trim();
// dir = Path.Combine(basePath, ns.Replace('.', '\\'));
//}
} break;
}
return null;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment