static StructsAndTypes ExtractStructsAndTypes(string src) { var types = new StructsAndTypes(); var lines = File.ReadAllLines(src); for (var i = 0; i < lines.Length; i++) { var line = lines[i]; if (line.StartsWith("typedef struct")) { if (line.EndsWith(";")) { types.Structs.Add(new Struct { Name = Regex.Match(line, @"([A-Z0-9_]+);$").Groups[1].Value }); } else { types.Structs.Add(ExtractStruct(lines, ref i)); } } else if (line.StartsWith("typedef enum")) { types.Enums.Add(ExtractEnum(lines, ref i)); } else if (line.StartsWith("#define")) { var parts = line.Replace("#define ", "").Split(' ', StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 2 && parts[1].StartsWith("0x")) { types.Consts.Add(new Const { Name = EscapeReservedWords(parts[0]), Value = parts[1] }); } } else if (line.StartsWith("typedef")) { //typedef unsigned int FMOD_DRIVER_STATE; var fmodType = Regex.Match(line, @"([A-Z0-9_]+);$").Groups[1].Value; if (!string.IsNullOrEmpty(fmodType)) { var t = line.Replace(fmodType, "").Replace("typedef", "").TrimEnd(';').Trim(); types.TypeDefs.Add(new TypeDef { Type = t.Replace(" ", ""), FMODType = fmodType }); } else { // this is the callback function typedefs var name = Regex.Match(line, @".*?\(F_CALL \*([A-Z0-9_]+)").Groups[1].Value; // types.TypeDefs.Add(new TypeDef // { // Type = "fn()", // FMODType = name // }); // typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_OPEN_CALLBACK) (FMOD_CODEC_STATE *codec_state, FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo); if (string.IsNullOrEmpty(name)) { name = Regex.Match(line, @".*?\(F_CALLBACK \*([A-Z0-9_]+)").Groups[1].Value; } } } } return(types); }
static void WriteTypesToFile(StreamWriter writer, StreamWriter vWriter, StructsAndTypes types, string module, string vModule) { writer.WriteLine($"module {module}"); writer.WriteLine(); vWriter.WriteLine($"module {vModule}"); vWriter.WriteLine(); // writer.WriteLine("pub const ("); foreach (var c in types.Consts) { // Console.WriteLine($"skipping const: {c.Name}"); // writer.WriteLine($"\t{c.Name} = {c.Value}"); } // writer.WriteLine(")"); // writer.WriteLine(); foreach (var t in types.TypeDefs) { // dont write typedefs. it dupes them. //writer.WriteLine($"type {t.FMODType} {Statics.GetVTypeForCType(t.Type)}"); } writer.WriteLine(); foreach (var s in types.Structs) { if (s.Parameters.Count == 0) { writer.WriteLine($"pub struct C.{s.Name} {{}}"); continue; } writer.WriteLine(); } writer.WriteLine(); foreach (var e in types.Enums) { if (e.HasNegativeValues) { Console.WriteLine($"skipping enum with negative values: {e.Name}"); continue; } // we strip this prefix from the enum values var enumPrefix = e.Name + "_"; if (e.Name == "FMOD_RESULT") { enumPrefix = "FMOD_"; } var enumName = GetVEnumName(e.Name); vWriter.WriteLine($"pub enum {enumName} {{"); foreach (var name in e.Enums) { var newName = EscapeReservedWords(name.Replace(enumPrefix, "").ToLower()); if (char.IsDigit(newName[0])) { newName = "_" + newName; } vWriter.WriteLine($"\t{newName}"); } vWriter.WriteLine("}"); vWriter.WriteLine(); } }