You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
5.0 KiB

  1. using Mono.Cecil;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. namespace CollectDependencies
  7. {
  8. static class Program
  9. {
  10. static void Main(string[] args)
  11. {
  12. var depsFile = File.ReadAllText(args[0]);
  13. var directoryName = Path.GetDirectoryName(args[0]);
  14. var files = new List<Tuple<string, int>>();
  15. { // Create files from stuff in depsfile
  16. var stack = new Stack<string>();
  17. void Push(string val)
  18. {
  19. string pre = "";
  20. if (stack.Count > 0)
  21. pre = stack.First();
  22. stack.Push(pre + val);
  23. }
  24. string Pop() => stack.Pop();
  25. string Replace(string val)
  26. {
  27. var v2 = Pop();
  28. Push(val);
  29. return v2;
  30. }
  31. var lineNo = 0;
  32. foreach (var line in depsFile.Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.None))
  33. {
  34. var parts = line.Split('"');
  35. var path = parts.Last();
  36. var level = parts.Length - 1;
  37. if (path.StartsWith("::"))
  38. { // pseudo-command
  39. parts = path.Split(' ');
  40. var command = parts[0].Substring(2);
  41. parts = parts.Skip(1).ToArray();
  42. var arglist = string.Join(" ", parts);
  43. if (command == "from")
  44. { // an "import" type command
  45. path = File.ReadAllText(Path.Combine(directoryName ?? throw new InvalidOperationException(), arglist));
  46. }
  47. else if (command == "prompt")
  48. {
  49. Console.Write(arglist);
  50. path = Console.ReadLine();
  51. }
  52. else
  53. {
  54. path = "";
  55. Console.Error.WriteLine($"Invalid command {command}");
  56. }
  57. }
  58. if (level > stack.Count - 1)
  59. Push(path);
  60. else if (level == stack.Count - 1)
  61. files.Add(new Tuple<string, int>(Replace(path), lineNo));
  62. else if (level < stack.Count - 1)
  63. {
  64. files.Add(new Tuple<string, int>(Pop(), lineNo));
  65. while (level < stack.Count)
  66. Pop();
  67. Push(path);
  68. }
  69. lineNo++;
  70. }
  71. files.Add(new Tuple<string, int>(Pop(), lineNo));
  72. }
  73. foreach (var file in files)
  74. {
  75. try
  76. {
  77. var fparts = file.Item1.Split('?');
  78. var fname = fparts[0];
  79. if (fname == "") continue;
  80. var outp = Path.Combine(directoryName ?? throw new InvalidOperationException(),
  81. Path.GetFileName(fname) ?? throw new InvalidOperationException());
  82. Console.WriteLine($"Copying \"{fname}\" to \"{outp}\"");
  83. if (File.Exists(outp)) File.Delete(outp);
  84. if (Path.GetExtension(fname)?.ToLower() == ".dll")
  85. {
  86. // ReSharper disable once StringLiteralTypo
  87. if (fparts.Length > 1 && fparts[1] == "virt")
  88. {
  89. var module = VirtualizedModule.Load(fname);
  90. module.Virtualize(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName(),
  91. Path.GetFileName(fname) ?? throw new InvalidOperationException()));
  92. }
  93. var modl = ModuleDefinition.ReadModule(fparts[0]);
  94. foreach (var t in modl.Types)
  95. {
  96. foreach (var m in t.Methods)
  97. {
  98. if (m.Body != null)
  99. {
  100. m.Body.Instructions.Clear();
  101. m.Body.InitLocals = false;
  102. m.Body.Variables.Clear();
  103. }
  104. }
  105. }
  106. modl.Write(outp);
  107. }
  108. else
  109. {
  110. File.Copy(fname, outp);
  111. }
  112. }
  113. catch (Exception e)
  114. {
  115. Console.WriteLine($"{Path.Combine(Environment.CurrentDirectory, args[0])}({file.Item2}): error: {e}");
  116. }
  117. }
  118. }
  119. }
  120. }