using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using Tango.Core.Helpers; using Tango.Core.IO; namespace Tango.Protobuf.Compilers { /// /// Represents a protobuf C Compiler. /// /// public class CCompiler : ProtoCompiler { /// /// Gets or sets a value indicating whether this will minimize the code by omitting hard coded strings. /// public bool Minimize { get; set; } /// /// Gets the compiler language. /// public override CompilerLanguage Language => CompilerLanguage.C; /// /// Gets the protobuf compiler CLI arguments (without input/output files!). /// /// protected override string GetProtoArguments() { return "--c_out"; } /// /// Gets the protobuf compiler CLI file name (override when using a compiler other than the default 'protoc.exe'). /// /// /// /// The compiler program must be located in the compilers folder. /// protected override string GetProtoCompilerName() { return "protoc-c"; } /// /// Compiles all files in the specified folder recursively. /// /// The source folder /// /// Compilation result. /// public override CompilerFolderResult CompileFolder(string sourceFolder, params String[] includeFolders) { var temp = TemporaryManager.Default.CreateFolder(); PathHelper.CopyDirectory(sourceFolder, temp.Path, true); List directories = Directory.GetDirectories(sourceFolder, "*", SearchOption.AllDirectories).Where(x => includeFolders == null || includeFolders.Length == 0 || includeFolders.Contains(Path.GetFileName(x))).ToList(); foreach (var dir in Directory.GetDirectories(temp.Path)) { if (!directories.Select(x => Path.GetFileName(x)).Contains(Path.GetFileName(dir))) { Directory.Delete(dir, true); } } foreach (var file in Directory.GetFiles(temp.Path, "*.proto", SearchOption.AllDirectories)) { String str = File.ReadAllText(file); var lines = str.ToLines(); lines.RemoveAll(x => x.Contains("package ")); for (int i = 0; i < lines.Count; i++) { if (!lines[i].Contains("import ") || lines[i].StartsWith("//")) { string[] wordsAndComments = lines[i].Split('/'); string lineWords = wordsAndComments.FirstOrDefault(); string[] words = lineWords.Split(' '); for (int j = 0; j < words.Length; j++) { words[j] = words[j].Split('.').LastOrDefault(); } lines[i] = String.Join(" ", words); } } str = String.Join(Environment.NewLine, lines); File.WriteAllText(file, str); } var result = base.CompileFolder(temp.Path); if (Minimize) { MinimizeFolder(result); } return result; } private void MinimizeFolder(CompilerFolderResult folder) { foreach (var childFolder in folder.Results.OfType()) { MinimizeFolder(childFolder); } foreach (var childFile in folder.Results.OfType()) { MinimizeFile(childFile); } } private void MinimizeFile(CompilerFileResult file) { file.Content = MinimizeCode(file.Content); } private String MinimizeCode(String code) { Regex reg = new Regex("(?<=\")(\\w{1,})(?=\")"); return reg.Replace(code, ""); } } }