2 using System.Collections.Generic;
6 using System.Threading.Tasks;
8 namespace GenerateHeader
19 private string _baseDirectory;
20 private string[] _modes;
21 private string[] _files;
22 private string _outputFile;
23 private string _header =
"";
24 private string _footer =
"";
26 private string UnEscape(
string text)
28 return text.Replace(
"\\r",
"\r").Replace(
"\\n",
"\n").Replace(
"\\\\",
"\\");
33 string[] lines = File.ReadAllLines(fileName);
35 foreach (
string line
in lines)
37 string[] split = line.Split(
new char[] {
'=' }, 2);
42 _baseDirectory = split[1];
45 _modes = split[1].ToLowerInvariant().Split(
';');
48 _files = split[1].Split(
';');
51 _outputFile = split[1];
54 _header = UnEscape(split[1]);
57 _footer = UnEscape(split[1]);
63 private List<HeaderFile> OrderHeaderFiles(List<HeaderFile> headerFiles)
65 var result =
new List<HeaderFile>();
66 var done =
new HashSet<HeaderFile>();
68 foreach (var h
in headerFiles)
69 OrderHeaderFiles(result, done, h);
74 private void OrderHeaderFiles(List<HeaderFile> result, HashSet<HeaderFile> done, HeaderFile headerFile)
76 if (done.Contains(headerFile))
81 foreach (var h
in headerFile.Dependencies)
82 OrderHeaderFiles(result, done, h);
84 result.Add(headerFile);
87 private List<string> ProcessHeaderLines(IEnumerable<string> lines)
89 var result =
new List<string>();
90 var modes =
new HashSet<string>();
91 var blankLine =
false;
93 foreach (var line
in lines)
97 if (s.StartsWith(
"// begin_"))
99 modes.Add(s.Remove(0,
"// begin_".Length));
101 else if (s.StartsWith(
"// end_"))
103 modes.Remove(s.Remove(0,
"// end_".Length));
107 bool blockMode = _modes.Any(modes.Contains);
108 bool lineMode = _modes.Any(mode =>
110 int indexOfMarker = s.LastIndexOf(
"// " + mode);
111 if (indexOfMarker == -1)
114 return s.Substring(indexOfMarker).Trim().All(c =>
char.IsLetterOrDigit(c) || c ==
' ' || c ==
'/');
117 if (blockMode || lineMode)
119 if (blankLine && result.Count != 0)
120 result.Add(
string.Empty);
125 else if (s.Length == 0)
139 var headerFiles = _files.Select(fileName =>
141 var fullFileName = _baseDirectory +
"\\" + fileName;
142 var lines = File.ReadAllLines(fullFileName).ToList();
144 return new HeaderFile { Name = Path.GetFileName(fullFileName).ToLowerInvariant(), Lines = lines };
145 }).ToDictionary(h => h.Name);
147 foreach (var h
in headerFiles.Values)
153 var trimmed = s.Trim().ToLowerInvariant();
154 if (trimmed.StartsWith(
"#include <") && trimmed.EndsWith(
">"))
157 if (headerFiles.TryGetValue(trimmed.Remove(trimmed.Length - 1).Remove(0,
"#include <".Length), out d))
158 return Tuple.Create(s, d);
160 return Tuple.Create<string,
HeaderFile>(s, null);
162 return Tuple.Create<string,
HeaderFile>(s, null);
164 .ToLookup(p => p.Item2 != null);
166 h.Lines = partitions[
false].Select(p => p.Item1).ToList();
167 h.Dependencies = partitions[
true].Select(p => p.Item2).Distinct().ToList();
169 foreach (var d
in h.Dependencies)
170 Console.WriteLine(
"Dependency: " + h.Name +
" -> " + d.Name);
175 var orderedHeaderFiles = OrderHeaderFiles(_files.Select(s => headerFiles[Path.GetFileName(s).ToLower()]).ToList());
179 foreach (var h
in orderedHeaderFiles)
180 h.Lines = ProcessHeaderLines(h.Lines);
184 StreamWriter sw =
new StreamWriter(_baseDirectory +
"\\" + _outputFile);
192 foreach (var h
in orderedHeaderFiles)
194 Console.WriteLine(
"Header file: " + h.Name);
198 sw.WriteLine(
"// " + Path.GetFileNameWithoutExtension(h.Name));
202 foreach (var line
in h.Lines)