static void CheckClearGossipMenu() { foreach (KeyValuePair <String, String> Pair in ScriptFiles) { String Filename = Pair.Key; String Code = Pair.Value; var GossipSelectMatches = Regex.Matches(Code, @"bool\s+GossipSelect_([\w\d]+)\s*\(", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); foreach (Match GossipSelectMatch in GossipSelectMatches) { string FullString = GossipSelectMatch.Groups[0].Value; int index = Code.IndexOf(FullString); string ScriptName = GossipSelectMatch.Groups[1].Value; string BlockCode = CppCode.ExtractBlock(Code, index); int clear_index = BlockCode.IndexOf("ClearMenus"); int add_index = BlockCode.IndexOfAny(new string[] { "SEND_GOSSIP_MENU", "ADD_GOSSIP_ITEM", // Also includes ID and EXTENDED postfixes "SendGossipMenu", "AddMenuItem" }); if (add_index != -1 && (clear_index == -1 || clear_index > add_index)) { ++Warnings; Console.WriteLine("Warning: GossipSelect_{0} in {1} lacks ClearMenus, potential crash.", ScriptName, Path.GetFileName(Filename)); } } } }
static void CheckScriptLoader() { // Load Script Loader Definitions foreach (KeyValuePair <string, string> Pair in ScriptFiles) { string file = Pair.Key; string Code = Pair.Value; var loaderCallMatches = Regex.Matches(Code, @"\s+void\s+AddSC_([\w\d]+)\s*\(", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); foreach (var callmatch in loaderCallMatches) { string loaderName = ((Match)callmatch).Groups[1].Value; ScriptLoader loader = ScriptLoaders.FirstOrDefault((x) => { return(x.ScriptName == loaderName); }); if (loader != null) { ++Errors; Console.WriteLine("Error: Loader '{0}' redefined in file '{1}'", loaderName, Path.GetFileName(file)); } else { ScriptLoaders.Add(new ScriptLoader { ScriptName = loaderName, Defined = true }); } } } // Load Externed Loaders String FullLoaderCode = CppCode.Clean(File.ReadAllText("system/ScriptLoader.cpp")); var externs = Regex.Matches(FullLoaderCode, @"^\s*?extern\s+void\s+AddSC_([\w\d]+)\s*\(", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline); foreach (var externMatch in externs) { string loaderName = ((Match)externMatch).Groups[1].Value; ScriptLoader loader = ScriptLoaders.FirstOrDefault((x) => { return(x.ScriptName == loaderName); }); if (loader != null) { if (!loader.Externed) { loader.Externed = true; } else { ++Errors; Console.WriteLine("Error: Loader '{0}' externed multiple times", loaderName); } } else { ScriptLoaders.Add(new ScriptLoader { ScriptName = loaderName, Externed = true }); } } // Load Called Loaders int function = FullLoaderCode.IndexOf("void AddScripts"); if (function == -1) { Console.WriteLine("Error: Failed to find 'void AddScripts' in ScriptLoader.cpp"); Console.ReadLine(); return; } string LoaderCode = CppCode.ExtractBlock(FullLoaderCode, function); var calls = Regex.Matches(LoaderCode, @"^\s*?AddSC_([\w\d]+)\s*\(", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline); foreach (var callmatch in calls) { string loaderName = ((Match)callmatch).Groups[1].Value; ScriptLoader loader = ScriptLoaders.FirstOrDefault((x) => { return(x.ScriptName == loaderName); }); if (loader != null) { if (!loader.Called) { loader.Called = true; } else { ++Errors; Console.WriteLine("Error: Loader '{0}' called multiple times", loaderName); } } else { ScriptLoaders.Add(new ScriptLoader { ScriptName = loaderName, Called = true }); } } // Output Summary Errors += ScriptLoaders.Count((x) => { bool result = !x.Defined || !x.Externed || !x.Called; if (result) { String output = "Error: Loader '" + x.ScriptName + "'"; if (!x.Defined) { output += ", not defined"; } if (!x.Externed) { output += ", not externed"; } else if (!x.Called) { output += ", not called"; } Console.WriteLine(output); } return(result); }); }