List<StructMember> GetStructMembers(string code, CommentMap map, int begin, int end) { List<StructMember> members = new List<StructMember>(); StructMemberParseState state = StructMemberParseState.TypeAndName; string typeAndName = ""; string comment = ""; for (int i = begin; i < end; i++) { char c = code[i]; bool isComment = map.IsComment(i); bool isWhitespace = IsWhitespace(c); switch (state) { case StructMemberParseState.TypeAndName: if (!isComment && c == ';') { state = StructMemberParseState.MaybeComment; continue; } if (!isComment) { typeAndName += c; } break; case StructMemberParseState.MaybeComment: if (!isComment && !isWhitespace) { string type, name; GetTypeAndName(typeAndName, out type, out name); StructMember member = new StructMember(); member.Type = type.Clean(); member.Name = name.Clean(); member.Comment = comment.Clean(); members.Add(member); typeAndName = ""; comment = ""; // Add the first letter to the next type typeAndName += c; state = StructMemberParseState.TypeAndName; continue; } if (isComment) { comment += c; } break; } } // Add the last struct member if (typeAndName.Clean().Length > 0) { string type, name; GetTypeAndName(typeAndName, out type, out name); StructMember member = new StructMember(); member.Type = type.Clean(); member.Name = name.Clean(); member.Comment = comment.Clean(); members.Add(member); } return members; }
List<EnumMember> GetEnumMembers(string code, CommentMap map, int begin, int end) { // Prepare variables List<EnumMember> members = new List<EnumMember>(); EnumMemberParseState state = EnumMemberParseState.Name; string name = ""; string value = ""; string comment = ""; string lastComment = ""; // Loop through code for (int i = begin; i < end; i++) { char c = code[i]; bool isComment = map.IsComment(i); bool isWhitespace = IsWhitespace(c); switch (state) { case EnumMemberParseState.Name: // We're currently parsing the name of the enum member if (!isComment && c == '=') { state = EnumMemberParseState.Value; continue; } if (!isComment && c == ',') { state = EnumMemberParseState.MaybeComment; continue; } if (!isComment) { name += c; } else { lastComment += c; } break; case EnumMemberParseState.Value: // We're currently parsing the value of the enum member if (!isComment && c == ',') { state = EnumMemberParseState.MaybeComment; continue; } if (!isComment) { value += c; } else { lastComment += c; } break; case EnumMemberParseState.MaybeComment: // We may be parsing the comment AFTER the enum member if (!isComment && !isWhitespace) { EnumMember member = new EnumMember(); member.Name = name.Clean(); member.Value = value.Clean(); member.Comment = comment.Clean(); members.Add(member); name = ""; value = ""; comment = ""; lastComment = ""; // Add the first letter to the next name name += c; state = EnumMemberParseState.Name; continue; } if (isComment) { comment += c; } break; } } // Process the last member (without a trailing comma) if (name.Clean().Length > 0) { EnumMember member = new EnumMember(); member.Name = name.Clean(); member.Value = value.Clean(); member.Comment = lastComment.Clean(); members.Add(member); } return members; }
bool GetScopedConstruct(string code, CommentMap map, string needle, ref int pos, out ScopedConstruct result) { // Initialize result result = new ScopedConstruct(); // Find needle int a = code.IndexOf(needle, pos, map); if (a == -1) { return false; } // Find next opening bracket string targetOpenBracket = "{"; int b = code.IndexOf(targetOpenBracket, a, map); if (b == -1) { return false; } // Find next closing bracket string targetCloseBracket = "}"; int c = code.IndexOf(targetCloseBracket, b, map); if (c == -1) { return false; } // Get the construct name int nameBegin = a + needle.Length; int nameEnd = b; string name = GetConstructName(code, map, nameBegin, nameEnd); // Get the data contained in the scope int dataBegin = b + targetOpenBracket.Length; int dataEnd = c; // Populate scope result.Name = name; result.Begin = dataBegin; result.End = dataEnd; // Update position pos = c; return true; }
string GetConstructName(string code, CommentMap map, int begin, int end) { string res = ""; for (int i = begin; i < end; i++) { if (!map.IsComment(i)) { res += code[i]; } } return res.Clean(); }
DefineObject GetDefine(string code, CommentMap map, int pos) { DefineParseState state = DefineParseState.Name; int i = pos; char lastValid = ' '; string name = ""; string expression = ""; while (i < code.Length) { char c = code[i]; bool isComment = map.IsComment(i); bool isWhitespace = IsWhitespace(c); i++; if (!isComment && c == '\n' && lastValid != '\\') { break; } if (!isComment && !isWhitespace) { lastValid = c; } switch (state) { case DefineParseState.Name: if (!isComment && isWhitespace && name.Clean().Length > 0) { state = DefineParseState.Expression; continue; } if (!isComment) { name += c; } break; case DefineParseState.Expression: if (!isComment) { expression += c; } break; } } DefineObject define = new DefineObject(); define.Name = name.Clean(); define.Expression = expression.Clean(); return define; }
List<StructObject> FindStructs(string code, CommentMap map) { List<StructObject> structs = new List<StructObject>(); int pos = 0; while (true) { // Get region containing the struct ScopedConstruct structData; if (!GetScopedConstruct(code, map, "struct ", ref pos, out structData)) { break; } // Extract struct members var list = GetStructMembers(code, map, structData.Begin, structData.End); // Create a struct object, representing one struct StructObject structObject = new StructObject(); structObject.Name = structData.Name; structObject.Members = list; // Add the struct object to the list structs.Add(structObject); } return structs; }
List<EnumObject> FindEnums(string code, CommentMap map) { List<EnumObject> enums = new List<EnumObject>(); int pos = 0; while (true) { // Get region containing the enum ScopedConstruct enumData; if (!GetScopedConstruct(code, map, "enum ", ref pos, out enumData)) { break; } // Extract enum members var list = GetEnumMembers(code, map, enumData.Begin, enumData.End); // Create an enum object, representing one enumeration EnumObject enumObject = new EnumObject(); enumObject.Name = enumData.Name; enumObject.Members = list; // Add the enum object to the list enums.Add(enumObject); } return enums; }
List<DefineObject> FindDefines(string code, CommentMap map) { List<DefineObject> defines = new List<DefineObject>(); int pos = 0; while (true) { string targetDefine = "#define "; pos = code.IndexOf(targetDefine, pos, map); if (pos == -1) { break; } pos += targetDefine.Length; DefineObject define = GetDefine(code, map, pos); defines.Add(define); } return defines; }
public void ProcessSource(Stream stream) { using (StreamReader reader = new StreamReader(stream)) { string code = reader.ReadToEnd(); CommentMap map = new CommentMap(code); var enums = FindEnums(code, map); var structs = FindStructs(code, map); var defines = FindDefines(code, map); _enums.AddRange(enums); _structs.AddRange(structs); _defines.AddRange(defines); } }
public static int IndexOf(this string haystack, string needle, int pos, CommentMap map) { while (true) { int a = haystack.IndexOf(needle, pos); if (a == -1) { return -1; } if (!map.IsComment(a)) { return a; } else { pos = a + needle.Length; } } }