private static void FixStructs(AinFile ainFile) { foreach (var structInfo in ainFile.Structs) { structInfo.NumberOfMembers = structInfo.Members.Count; var constructor = ainFile.GetFunction(structInfo.Name + "@0"); var destructor = ainFile.GetFunction(structInfo.Name + "@1"); if (constructor != null) { structInfo.Constructor = constructor.Index; } if (destructor != null) { structInfo.Destructor = destructor.Index; } } }
public void projectWriter_BeforeWritingInstruction(object sender, InstructionInfoEventArgs e) { var instructionInfo = e.InstructionInfo; if (instructionInfo.instruction == Instruction.MSG) { string messageText = e.Text; //string messageText = ainFile.Messages[instructionInfo.word1]; messageText = CombineRemainingText(messageText); e.Text = messageText; HandleMessage(e, messageText); } else if (instructionInfo.instruction == Instruction.CALLFUNC) { var function = ainFile.GetFunction(instructionInfo.word1); string functionName = null; if (function != null) { functionName = function.Name; } if (functionName == NextLineFunctionName) { if (remainingText != "") { e.Handled = true; } else { NextLine(e); } } else if (functionName == NextMessageFunctionName) { if (remainingText != "") { while (remainingText != "") { e.Handled = true; HandleMessage(e, remainingText); } GenerateNextMessage(e); } else { NextMessage(); } } else if (ReduceMarginFunctionNames.Contains(functionName)) { this.maxCharactersPerLine = this.MaxCharactersPerLineReduced; } } }
public Variable[] GetVariables(AinFile ainFile) { List <Variable> list = new List <Variable>(); foreach (var variableName in VariableNames) { int dotPosition = variableName.IndexOf('.'); if (dotPosition == -1) { dotPosition = variableName.Length; } if (dotPosition > 0) { string functionName = variableName.Substring(0, dotPosition); string parameterName = ""; if (dotPosition + 1 <= variableName.Length) { parameterName = variableName.Substring(dotPosition + 1); } var function = ainFile.GetFunction(functionName); if (function != null) { Variable variable = null; for (int i = 0; i < function.ParameterCount; i++) { if (function.Parameters[i].Name == parameterName) { variable = function.Parameters[i]; break; } } if (variable == null) { int variableIndex = 0; if (!int.TryParse(parameterName, out variableIndex)) { variableIndex = 0; } variable = function.GetNonVoidFunctionParameter(variableIndex) as Variable; } if (variable != null) { list.Add((Variable)variable); } } } } return(list.ToArray()); }
//private static bool MatchFunction(AinFile ainFile, WordWrapOptions2 wordWrapOptions, int maxCharactersPerLineNormal, int maxCharactersPerLineReduced, string functionName, params DataType[] dataTypes) //{ // var function = ainFile.GetFunction(functionName); // if (function != null && function.ParameterCount == dataTypes.Length && function.Parameters.Take(function.ParameterCount).Select(a => a.DataType).SequenceEqual(dataTypes)) // { // //if we specified values for the max lengths, set them // if (maxCharactersPerLineNormal > 0) // { // wordWrapOptions.MaxCharactersPerLineNormal = maxCharactersPerLineNormal; // } // if (maxCharactersPerLineReduced > 0) // { // wordWrapOptions.MaxCharactersPerLineReduced = maxCharactersPerLineReduced; // } // //set the function name // wordWrapOptions.ReduceMarginFunctionName = functionName; // //indicate success // return true; // } // return false; //} private static bool ContainsFunction(AinFile ainFile, string functionName, params object[] dataTypesAndParamaterNames) { var func = ainFile.GetFunction(functionName); if (func == null) { return(false); } if ((dataTypesAndParamaterNames.Length & 1) != 0) { throw new ArgumentException("Number of parameter for dataTypesAndParameterNames must be even"); } if (func.ParameterCount == 0 && dataTypesAndParamaterNames.Length == 0) { return(true); } for (int i = 0; i + 1 < dataTypesAndParamaterNames.Length; i += 2) { DataType?dataType = dataTypesAndParamaterNames[i] as DataType?; string parameterName = dataTypesAndParamaterNames[i + 1] as string; if (dataType == null || parameterName == null) { throw new ArgumentException("Wrong type for data type or parameter name"); } var arg = func.GetNonVoidFunctionParameter(i / 2); if (arg == null) { return(false); } if (dataType == arg.DataType && parameterName == arg.Name) { } else { return(false); } } return(true); }
/// <summary> /// Checks if a variable object is a reference to a variable registered in the AinFile, and returns the original variable from the AinFile if it exists, otherwise returns null. /// </summary> /// <param name="variable">The variable to find</param> /// <param name="ainFile">The AinFile to find the variable in.</param> /// <returns>returns the original variable from the AinFile if it exists, otherwise returns null</returns> public static IVariable Canonicalize(this IVariable variable, AinFile ainFile) { int index = variable.Index; int parentIndex = -1; if (variable == null || ainFile == null) { return(null); } var root = variable.Root; var parent = variable.Parent; if (parent != null) { parentIndex = parent.Index; } if (root == ainFile || root == null) { if (parent is Function) { if (parent.Name.StartsWith("system.")) { return(AinFile.GetSystemCallParameter(parentIndex, index)); } return(ainFile.GetFunctionParameter(parentIndex, index)); } if (parent is Struct) { return(ainFile.GetStructMember(parentIndex, index)); } if (variable is Global) { return(ainFile.GetGlobal(index)); } if (parent is FunctionType) { return(ainFile.GetFuncTypeParameter(parentIndex, index)); } if (parent is HllFunction) { if (parent.Parent != null) { return(ainFile.GetLibraryFunctionParameter(parent.Parent.Index, parentIndex, index)); } else { return(null); } } if (variable is Function) { if (variable.Name.StartsWith("system.")) { return(AinFile.GetSystemCall(index)); } return(ainFile.GetFunction(index)); } if (variable is Struct) { return(ainFile.GetStruct(index)); } if (variable is HllFunction) { return(ainFile.GetLibraryFunction(parentIndex, index)); } if (variable is FunctionType) { return(ainFile.GetFuncType(index)); } } else { if (parent is Function) { if (parent.Name.StartsWith("system.")) { return(AinFile.GetSystemCallParameter(parentIndex, index)); } return(ainFile.GetFunctionParameter(parent.Name, variable.Name)); } if (variable is Global) { return(ainFile.GetGlobal(variable.Name)); } if (parent is Struct) { return(ainFile.GetStructMember(parent.Name, variable.Name)); } if (parent is FunctionType) { return(ainFile.GetFuncTypeParameter(parent.Name, variable.Index)); } if (parent is HllFunction) { if (parent.Parent != null) { return(ainFile.GetLibraryFunctionParameter(parent.Parent.Name, parent.Name, index)); } else { return(null); } } if (variable is Function) { if (variable.Name.StartsWith("system.")) { return(AinFile.GetSystemCall(index)); } return(ainFile.GetFunction(variable.Name)); } if (variable is Struct) { return(ainFile.GetStruct(variable.Name)); } if (variable is HllFunction) { return(ainFile.GetLibraryFunction(parent.Name, variable.Name)); } if (variable is FunctionType) { return(ainFile.GetFuncType(variable.Name)); } } return(null); }
public static void DoRance01(AinFile ainFile, TextImportExport exportImport) { //TEMPORARY CODE FOR RANCE 01 NAME EXTRACTION var dic = new Dictionary <string, string>(); dic["*"] = "*"; dic["*/B"] = "*"; dic["**"] = "**"; dic["**/B"] = "**"; dic["***"] = "***"; dic["TADA"] = "TADA"; dic["アイ"] = "Ai"; dic["アキ"] = "Aki"; dic["アリス"] = "Alice"; dic["イェリコ"] = "Yeriko"; dic["ウィリス"] = "Willis"; dic["ウェンズディング"] = "Wendsding"; dic["ウェンズディング/B"] = "Wendsding/B"; dic["エンエン"] = "Enen"; dic["カルピス"] = "Calpis"; dic["キース"] = "Keith"; dic["クリン"] = "Kurin"; dic["シィル"] = "Sill"; dic["ジャン"] = "Jean"; dic["スアマ"] = "Suama"; dic["ニウ"] = "Niu"; dic["ネカイ"] = "Nekai"; dic["ハイジ"] = "Heidi"; dic["パティ"] = "Pattie"; dic["パルプテンクス"] = "Pulptenks"; dic["ヒカリ"] = "Hikari"; dic["ブリティシュ"] = "British"; dic["ボブザ"] = "Bobza"; dic["マリス"] = "Maris"; dic["ミ"] = "Mi"; dic["ミリー"] = "Milly"; dic["ムララ"] = "Murara"; dic["メナド"] = "Menad"; dic["ユキ"] = "Yuki"; dic["ユラン"] = "Yulang"; dic["ライハルト"] = "Reichardt"; dic["ラベンダー"] = "Lavender"; dic["ランス"] = "Rance"; dic["リア"] = "Lia"; dic["ルイス"] = "Luis"; dic["魚介"] = "Gyokai"; dic["奈美"] = "Nami"; dic["忍者"] = "Ninja"; dic["美樹"] = "Miki"; dic["変態ネズミ"] = "Pervert Mouse"; dic["諭吉"] = "Yukichi"; dic["葉月"] = "Hazuki"; dic["DJC++"] = "DJC++"; dic["TADA/1"] = "TADA"; dic["TADA/2"] = "TADA"; dic["TADA/3"] = "TADA"; dic["TADA/ウィリス"] = "Willis"; dic["TADA/ハイジ"] = "Heidi"; dic["TADA/パティ"] = "Pattie"; dic["TADA/パルプテンクス"] = "Pulptenks"; dic["TADA/ラベンダー"] = "Lavender"; dic["TADA/葉月"] = "Hazuki"; dic["ふみゃ"] = "Fumya"; dic["アイ/基本"] = "Ai"; dic["アキ/基本"] = "Aki"; dic["アリスマン/基本"] = "Alice man"; dic["イェリコ/基本"] = "Yeriko"; dic["イェリコ/通せんぼ"] = "Yeriko"; dic["ウィリス/基本"] = "Willis"; dic["キース/基本/遠距離"] = "Keith"; dic["クリン/基本"] = "Kurin"; dic["シィル/学生服"] = "Sill"; dic["シィル/基本"] = "Sill"; dic["ジャン/基本"] = "Jean"; dic["ネカイ/基本"] = "Nekai"; dic["ハイジ/基本"] = "Heidi"; dic["ハイジ/基本/盗む"] = "Heidi"; dic["パティ/基本"] = "Pattie"; dic["パルプテンクス/基本"] = "Pulptenks"; dic["パルプテンクス/救出前"] = "Pulptenks"; dic["ヒカリ/基本"] = "Hikari"; dic["ブリティシュ/基本"] = "British"; dic["ブリティシュ/基本/泣く"] = "British"; dic["ボブザ/基本"] = "Bobza"; dic["マリス/学生服"] = "Maris"; dic["マリス/基本"] = "Maris"; dic["ミ/基本"] = "Mi"; dic["ミリー/眼鏡"] = "Milly"; dic["ミリー/眼帯"] = "Milly"; dic["ミリー/基本"] = "Milly"; dic["ムララ/基本"] = "Murara"; dic["メナド/基本"] = "Menad"; dic["ユキ/基本"] = "Yuki"; dic["ユラン/基本"] = "Yulang"; dic["ユラン/私服"] = "Yulang"; dic["ユラン/私服/レイプ後"] = "Yulang"; dic["ラベンダー/基本"] = "Lavender"; dic["ラベンダー/基本/泣く"] = "Lavender"; dic["リア/基本"] = "Lia"; dic["ルイス/基本"] = "Luis"; dic["魚介"] = "Gyokai"; dic["都市守備隊/基本"] = "City defense corps"; dic["都市守備隊/基本/B"] = "City defense corps"; dic["盗賊団/基本"] = "Band of thieves"; dic["盗賊団/基本/B"] = "Band of thieves"; dic["奈美/基本"] = "Nami"; dic["忍者/学生服"] = "Ninja"; dic["忍者/学生服/驚く"] = "Ninja"; dic["忍者/学生服/笑う"] = "Ninja"; dic["忍者/基本"] = "Ninja"; dic["汎用女生徒/基本"] = "Generic schoolgirl"; dic["汎用女生徒/基本/B"] = "Generic schoolgirl"; dic["美樹/基本"] = "Miki"; dic["変態ネズミ/基本"] = "Pervert Mouse"; dic["葉月/ボディペイント"] = "Hazuki"; dic["葉月/ボディペイント/笑う"] = "Hazuki"; dic["葉月/基本"] = "Hazuki"; dic["葉月/基本/笑う"] = "Hazuki"; dic["葉月/脱ぐ04"] = "Hazuki"; dic["葉月/脱ぐ04/笑う"] = "Hazuki"; dic["葉月/脱ぐ06"] = "Hazuki"; dic["葉月/脱ぐ06/笑う"] = "Hazuki"; dic["葉月/脱ぐ07"] = "Hazuki"; dic["葉月/脱ぐ07/笑う"] = "Hazuki"; dic["葉月/脱ぐ08"] = "Hazuki"; dic["葉月/脱ぐ08/笑う"] = "Hazuki"; var func = ainFile.GetFunction("●名札"); var parameter = func.Parameters[0]; var func2 = ainFile.GetFunction("●立ち絵"); var parameter2 = func2.Parameters[0]; exportImport.AnnotateParameterWithStrings(dic, parameter, parameter2); }
internal void ExportFiles(string destinationPath) { ainFile.FindFunctionTypes(); stopwatch.Start(); var encoding = Extensions.BinaryEncoding; var enumerator = new FunctionEnumerator(this.ainFile); var results = enumerator.GetFilesAndFunctions(); HashSet <Struct> UnvisitedStructs = new HashSet <Struct>(ainFile.Structs); HashSet <int> VisitedFunctions = new HashSet <int>(); int functionsVisited = 0; int totalFunctions = ainFile.Functions.Count; codeDisplayOptions.DisplayDefaultValuesForMethods = false; var displayer = new ExpressionDisplayer(ainFile, codeDisplayOptions); StringBuilder mainIncludeFile = new StringBuilder(); mainIncludeFile.AppendLine("Source = {"); mainIncludeFile.AppendLine("\t\"constants.jaf\","); mainIncludeFile.AppendLine("\t\"classes.jaf\","); mainIncludeFile.AppendLine("\t\"globals.jaf\","); this.SeenFilenames.Add("classes.jaf"); this.SeenFilenames.Add("globals.jaf"); this.SeenFilenames.Add("constants.jaf"); this.SeenFilenames.Add("HLL\\hll.inc"); if (ainFile.Libraries.Count > 0) { mainIncludeFile.AppendLine("\t\"HLL\\hll.inc\","); } foreach (var fileNode in results) { string fileName = fileNode.name.Replace("\r", "\\r").Replace("\n", "\\n"); //fix filenames that went through bad tools if (fileNode.children.Count > 0) { using (FileStream fs = CreateFileUnique(ref fileName, destinationPath)) { mainIncludeFile.AppendLine("\t\"" + fileName + "\","); using (var streamWriter = new StreamWriter(fs, encoding)) { foreach (var functionNode in fileNode.children) { if (backgroundWorker != null) { if (backgroundWorker.CancellationPending == true) { //abort return; } } int functionNumber = functionNode.id; var function = ainFile.GetFunction(functionNumber); if (function.ToString().Contains("SP_SET_CG_REAL")) { Console.WriteLine("SP_SET_CG_REAL"); } if (!VisitedFunctions.Contains(functionNumber)) { VisitedFunctions.Add(functionNumber); if (this.backgroundWorker != null && stopwatch.ElapsedTime >= 250) { stopwatch.Start(); backgroundWorker.ReportProgress(100 * functionsVisited / totalFunctions, "Function " + functionNumber.ToString() + " of " + totalFunctions.ToString() + ", currently decompiling" + Environment.NewLine + function.Name); } if (function.Name == "0" || function.Name.EndsWith("@2")) { //exclude global array initializer and struct array initializer functions } else { //var structInfo = function.GetClass(); //if (structInfo != null) //{ // if (UnvisitedStructs.Contains(structInfo)) // { // UnvisitedStructs.Remove(structInfo); // string classDeclaration = displayer.GetClassDeclaration(structInfo); // streamWriter.Write(classDeclaration); // } //} if (Debugger.IsAttached) { //no exception handling when debugging - we want to see the exceptions try { var expression = decompiler.DecompileFunction(function); string text = displayer.PrintExpression2(expression, true); streamWriter.WriteLine(text); } finally { } } else { try { var expression = decompiler.DecompileFunction(function); string text = displayer.PrintExpression2(expression, true); streamWriter.WriteLine(text); } catch (Exception ex) { string errorMessage = "Function " + functionNode.name + " failed to decompile."; RaiseError(errorMessage, ex); } finally { } } } functionsVisited++; } } streamWriter.Flush(); streamWriter.Close(); } } } } mainIncludeFile.AppendLine("}"); if (UnvisitedStructs.Count > 0) { var remainingStructs = UnvisitedStructs.OrderByIndex().ToArray(); if (this.backgroundWorker != null) { backgroundWorker.ReportProgress(100, "Generating class declarations..."); } using (var fs = CreateFile("classes.jaf", destinationPath)) { using (var sw = new StreamWriter(fs, encoding)) { foreach (var structInfo in remainingStructs) { string classDeclaration = displayer.GetClassDeclaration(structInfo); sw.Write(classDeclaration); sw.WriteLine(); } foreach (var funcType in ainFile.FunctionTypes) { string funcTypeDeclaration = displayer.GetFunctypeDeclaration(funcType); sw.WriteLine(funcTypeDeclaration); } foreach (var delg in ainFile.Delegates) { string delegateDeclaration = displayer.GetDelegateDeclaration(delg); sw.WriteLine(delegateDeclaration); } sw.Flush(); sw.Close(); } } } Dictionary <Global, Expression> globalInitializers = GetGlobalInitializers(); if (this.backgroundWorker != null) { backgroundWorker.ReportProgress(100, "Listing global variables..."); } using (var fs = CreateFile("globals.jaf", destinationPath)) { string lastGlobalGroupName = null; using (var sw = new MyIndentedTextWriter(new StreamWriter(fs, encoding))) { Dictionary <int, GlobalInitialValue> initialValues = new Dictionary <int, GlobalInitialValue>(); foreach (var globalInitialValue in ainFile.GlobalInitialValues) { initialValues[globalInitialValue.GlobalIndex] = globalInitialValue; } foreach (var global in ainFile.Globals) { if (global.DataType != DataType.Void) { string globalGroupName = global.GroupName; if (globalGroupName != lastGlobalGroupName) { if (lastGlobalGroupName != null) { sw.Indent--; sw.WriteLine("}"); } if (globalGroupName != null) { sw.WriteLine("globalgroup " + globalGroupName); sw.WriteLine("{"); sw.Indent++; } } lastGlobalGroupName = globalGroupName; sw.Write(global.GetDataTypeName()); sw.Write(" "); sw.Write(global.Name); if (global.DataType.IsArray()) { if (globalInitializers.ContainsKey(global)) { var expr = globalInitializers[global]; foreach (var e in expr.Args) { if (e.ExpressionType == Instruction.PUSH) { sw.Write("[" + e.Value.ToString() + "]"); } } } } else { if (initialValues.ContainsKey(global.Index)) { sw.Write(" = "); var initialValue = initialValues[global.Index]; sw.Write(initialValue.GetValueQuoted()); } } sw.WriteLine(";"); } } if (lastGlobalGroupName != null) { sw.Indent--; sw.WriteLine("}"); } sw.Flush(); sw.Close(); } } using (var fs = CreateFile("constants.jaf", destinationPath)) { using (StreamWriter sw = new StreamWriter(fs, encoding)) { sw.WriteLine("const int true = 1;"); sw.WriteLine("const int false = 0;"); sw.WriteLine(); if (ainFile.MetadataFile != null) { foreach (var pair in ainFile.MetadataFile.EnumerationTypes) { var enumerationType = pair.Value; sw.WriteLine("//" + enumerationType.Name); foreach (var pair2 in enumerationType) { sw.WriteLine("const int " + pair2.Value + " = " + pair2.Key.ToString() + ";"); } sw.WriteLine(); } } sw.Flush(); fs.Flush(); sw.Close(); fs.Close(); } } if (this.backgroundWorker != null) { backgroundWorker.ReportProgress(100, "Creating project file..."); } if (ainFile.Libraries.Count > 0) { StringBuilder libraryIncludeFile = new StringBuilder(); libraryIncludeFile.AppendLine("SystemSource = {"); string hllDirectory = Path.Combine(destinationPath, "HLL"); foreach (var library in ainFile.Libraries) { string hllFileName = library.LibraryName + ".hll"; using (var fs = CreateFileUnique(ref hllFileName, hllDirectory)) { libraryIncludeFile.AppendLine("\t\"" + hllFileName + "\",\t\"" + library.LibraryName + "\","); using (var sw = new StreamWriter(fs, encoding)) { foreach (var func in library.Functions) { string declaration = func.GetDeclaration() + ";"; sw.WriteLine(declaration); } sw.Flush(); sw.Close(); } } } libraryIncludeFile.AppendLine("}"); string includeFileContents = libraryIncludeFile.ToString(); using (var fs = CreateFile("hll.inc", hllDirectory)) { using (var sw = new StreamWriter(fs, encoding)) { sw.Write(includeFileContents); } } } File.WriteAllText(Path.Combine(destinationPath, "main.inc"), mainIncludeFile.ToString(), encoding); //build a PJE file { StringBuilder pje = new StringBuilder(); pje.AppendLine("// Project Environment File"); pje.AppendLine("ProjectName = \"" + Path.GetFileNameWithoutExtension(this.ainFile.OriginalFilename) + "\""); pje.AppendLine(); pje.AppendLine("CodeName = \"" + Path.GetFileNameWithoutExtension(this.ainFile.OriginalFilename) + ".ain\""); pje.AppendLine(); pje.AppendLine("#define _AINVERSION " + ainFile.Version.ToString()); pje.AppendLine("#define _KEYCODE 0x" + ainFile.KeyCode.ToString("X8")); pje.AppendLine("#define _ISAI2FILE " + (ainFile.IsAi2File ? "true" : "false")); if (ainFile.Version >= 6) { pje.AppendLine("#define _USESMSG1 " + (ainFile.UsesMsg1 ? "true" : "false")); } pje.AppendLine("#define _TARGETVM " + ainFile.TargetVMVersion.ToString()); pje.AppendLine(); pje.AppendLine("GameVersion = " + ainFile.GameVersion.ToString()); pje.AppendLine(); pje.AppendLine("// Settings for each directory"); pje.AppendLine("SourceDir = \".\""); pje.AppendLine("HLLDir = \"HLL\""); pje.AppendLine("ObjDir = \"OBJ\""); pje.AppendLine("OutputDir = \"Run\""); pje.AppendLine(); pje.AppendLine("Source = {"); pje.AppendLine(" \"main.inc\","); pje.AppendLine("}"); string pjeFileName = Path.Combine(destinationPath, Path.GetFileNameWithoutExtension(this.ainFile.OriginalFilename) + ".pje"); File.WriteAllText(pjeFileName, pje.ToString(), encoding); } }
private void ReadReplacementFile(TextReaderWrapper tr, string textFileName) { textFileName = Path.GetFullPath(textFileName); if (IncludedFiles.Contains(textFileName.ToUpperInvariant())) { return; } IncludedFiles.Set(textFileName.ToUpperInvariant()); string line; while (true) { line = tr.ReadLine(); if (line == null) { break; } //remove initial whitespace line = line.TrimStart(); //check for "#include" if (line.StartsWith("#include ")) { string filenameToInclude = line.Substring("#include ".Length); //check for quotes? if (filenameToInclude.StartsWith("\"") && filenameToInclude.EndsWith("\"")) { filenameToInclude = filenameToInclude.Substring(1, filenameToInclude.Length - 2); } string basePath = tr.DirectoryName; filenameToInclude = Path.Combine(basePath, filenameToInclude); if (!File.Exists(filenameToInclude)) { throw new FileNotFoundException("Cannot find file: " + filenameToInclude, filenameToInclude); } if (File.Exists(filenameToInclude) && !IncludedFiles.Contains(filenameToInclude.ToUpperInvariant())) { IncludedFiles.Add(filenameToInclude.ToUpperInvariant()); var encoding = EncodingDetector.DetectEncoding(filenameToInclude); tr.IncludeTextReader(new StreamReader(filenameToInclude, encoding)); } continue; } //remove commented text int indexOfComment = line.IndexOf('#'); if (indexOfComment >= 0) { line = line.Substring(0, indexOfComment); } //reading one of these lines: //CODE //function x functionName (or func, f) //string x text (or str, s) //message x text (or msg, m) //id x text (or i) //x text (same as id x text) string lineTrim = line.Trim(); if (lineTrim.Equals("CODE", StringComparison.OrdinalIgnoreCase) || lineTrim.Equals("CODE2", StringComparison.OrdinalIgnoreCase)) { bool isCode2 = lineTrim.Equals("CODE2", StringComparison.OrdinalIgnoreCase); StringBuilder codeText = new StringBuilder(); while (true) { line = tr.ReadLine(); lineTrim = line.Trim(); if (lineTrim.StartsWith("#include")) { string filenameToInclude = lineTrim.Substring("#include ".Length); //check for quotes? if (filenameToInclude.StartsWith("\"") && filenameToInclude.EndsWith("\"")) { filenameToInclude = filenameToInclude.Substring(1, filenameToInclude.Length - 2); } string basePath = tr.DirectoryName; if (!Path.IsPathRooted(filenameToInclude)) { filenameToInclude = Path.Combine(basePath, filenameToInclude); } filenameToInclude = Path.GetFullPath(filenameToInclude); if (!File.Exists(filenameToInclude)) { throw new FileNotFoundException("Cannot find file: " + filenameToInclude, filenameToInclude); } if (File.Exists(filenameToInclude) && !IncludedFiles.Contains(filenameToInclude.ToUpperInvariant())) { IncludedFiles.Add(filenameToInclude.ToUpperInvariant()); if (isCode2) { //replace with #include <fullpath>, let the compiler handle the actual include codeText.AppendLine("#include " + AssemblerProjectWriter.EscapeAndQuoteString(filenameToInclude)); } else { var encoding = EncodingDetector.DetectEncoding(filenameToInclude); tr.IncludeTextReader(new StreamReader(filenameToInclude, encoding)); } } continue; } if (lineTrim.ToUpperInvariant() == "ENDCODE") { if (isCode2) { CodePatches2.AppendLine(codeText.ToString()); } else { CodePatches.Set(currentFunctionName, codeText.ToString()); } break; } else { codeText.AppendLine(line); } } continue; } //find first space int spaceIndex = line.IndexOf(' '); if (spaceIndex == -1) { continue; } string tagName = line.Substring(0, spaceIndex); line = line.Substring(spaceIndex + 1); int number; //if it starts with a number, it's a legacy text replacement if (IntUtil.TryParse(tagName, out number) == true) { tagName = "id"; } else { bool isFunction = false; string tagNameLower = tagName.ToLowerInvariant(); if (tagNameLower == "f" || tagNameLower == "func" || tagNameLower == "function") { isFunction = true; } line = line.TrimStart(); spaceIndex = line.IndexOf(' '); if (spaceIndex == -1) { if (isFunction) { number = -1; } else { continue; } } else { string numberString = line.Substring(0, spaceIndex); line = line.Substring(spaceIndex + 1); if (IntUtil.TryParse(numberString, out number) == false) { if (isFunction) { line = numberString + " " + line; number = -1; } else { continue; } } } } line = StringExportImport.UnescapeText(line); switch (tagName.ToLowerInvariant()) { case "f": case "func": case "function": string nextFunctionName = line.Trim(); var function = ainFile.GetFunction(number); if (function == null) { function = ainFile.GetFunction(nextFunctionName); if (function == null) { continue; } } currentFunctionName = function.Name; stringDictionary = stringEntries.GetOrAddNew(currentFunctionName); messageDictionary = messageEntries.GetOrAddNew(currentFunctionName); break; case "string": case "str": case "s": stringDictionary.Set(number, line); break; case "msg": case "message": case "m": messageDictionary.Set(number, line); break; case "i": case "id": numberedStrings.Set(number, line); break; } } }
private List <string> GetTextFromFunction(Function function) { int numberOfNonCommentedLines = 0; int numberOfStrings = 0; int numberOfMessages = 0; //Expression expression = null; //int expressionLastAddress = function.Address; useStringsToMatch = StringsToMatch != null && StringsToMatch.Count > 0; //List<string> strings = new List<string>(); //List<string> messages = new List<string>(); List <string> functionLines = new List <string>(); string functionLineString = "FUNCTION " + /*function.Index.ToString() + " " + */ AssemblerProjectWriter.SanitizeVariableName(function.Name); functionLines.Add(functionLineString); functionLines.Add("#x strings, x messages"); //this line gets changed later (it's index 1) int address = function.Address; string lastName = null; while (address < ainFile.Code.Length) { var instructionInfo = ainFile.Peek(address); if (instructionInfo.instruction == Instruction.ENDFUNC || instructionInfo.instruction == Instruction.FUNC) { break; } if (this.AnnotateEnumerationType != null && instructionInfo.instruction == Instruction.CALLFUNC) { var func = ainFile.GetFunction(instructionInfo.word1); if (VariablesUsingEnumerationType.Contains(func)) { var parameters = GetParametersThatUsesEnumerationType(func); if (parameters.FirstOrDefault() != null) { foreach (var parameter in parameters) { int i = parameter.Index; int addr = instructionInfo.CurrentAddress - (func.ParameterCount) * 6 + i * 6; var ins2 = ainFile.Peek(addr); if (ins2.instruction == Instruction.PUSH) { string enumerationValue = this.AnnotateEnumerationType.GetOrDefault(ins2.word1, ""); if (!String.IsNullOrEmpty(enumerationValue)) { functionLines.Add(""); functionLines.Add("#" + enumerationValue); } } else if (ins2.instruction == Instruction.S_PUSH) { string str = ainFile.GetString(ins2.word1); if (!String.IsNullOrEmpty(str)) { if (this.replacementStringsForAnnotations != null && this.replacementStringsForAnnotations.ContainsKey(str)) { string nextStr = this.replacementStringsForAnnotations[str]; if (!nextStr.StartsWith("*")) { str = nextStr; } else { str = lastName; } } else { } if (lastName != str) { lastName = str; functionLines.Add(""); functionLines.Add("#" + str); } } } } } } } if (instructionInfo.instruction == Instruction.MSG) { //if (this.AnnotateEnumerationType != null) //{ // if (expression == null) // { // expression = ainFile.DecompiledCodeCache.GetDecompiledCode(function); // } // CatchUpToAddress(ref expression, functionLines, address); //} int messageNumber = instructionInfo.word1; string message = ainFile.GetMessage(messageNumber); if (message != null) { if (useStringsToMatch == false || StringsToMatch.Contains(message)) { string messageLine = "m " + numberOfMessages.ToString("000") + " " + StringExportImport.EscapeText(message); functionLines.Add(messageLine); } numberOfMessages++; numberOfNonCommentedLines++; } } else if (instructionInfo.instruction == Instruction.STRSWITCH) { int switchBlockNumber = instructionInfo.word1; var switchBlock = ainFile.Switches.GetOrNull(switchBlockNumber); if (switchBlock != null) { foreach (var switchCase in switchBlock.SwitchCases) { int stringNumber = switchCase.Value; string str = ainFile.GetString(stringNumber); if (str != null) { AddString(ref numberOfNonCommentedLines, ref numberOfStrings, functionLines, stringNumber, str); } } } } else { int indexOfStringArgument = instructionInfo.instruction.IndexOfStringArgument(); if (indexOfStringArgument != -1) { int stringNumber = instructionInfo.words[indexOfStringArgument]; string str = ainFile.GetString(stringNumber); if (str != null) { AddString(ref numberOfNonCommentedLines, ref numberOfStrings, functionLines, stringNumber, str); } } } address = instructionInfo.nextAddress; } functionLines[1] = "#" + numberOfStrings.ToString() + " strings, " + numberOfMessages.ToString() + " messages"; if (numberOfNonCommentedLines == 0) { functionLines.Clear(); } return(functionLines); }
public void GetExclusionList() { this.exclusionFlags = (this.ExcludeFunctionNames ? (int)StringExclusionReason.IsFunctionName : 0) | (this.ExcludeSystemFunctions ? (int)StringExclusionReason.IsInsideSystemFunction : 0) | (this.ExcludeTestFunctions ? (int)StringExclusionReason.IsInsideTestFunction : 0) | (this.ExcludeUnusedStrings ? (int)StringExclusionReason.IsUnused : 0) | (this.ExcludeAsserts ? (int)StringExclusionReason.IsAssert : 0) | (this.ExcludeEventFlags ? (int)StringExclusionReason.IsEvent : 0); if (alreadyBuilt) { return; } alreadyBuilt = true; //if (currentExclusionFlags == newExclusionFlags) //{ // return; //} //currentExclusionFlags = newExclusionFlags; stringsToExclude.Clear(); //build list of "System" functions var functionEnumerator = new FunctionEnumerator(ainFile); var filesAndFunctions = functionEnumerator.GetFilesAndFunctions(); var systemFiles = filesAndFunctions.Where(f => f.name.StartsWith("System\\", StringComparison.OrdinalIgnoreCase)); var systemFunctions = new HashSet <int>(systemFiles.SelectMany(f => f.children).Select(res => res.id)); Dictionary <int, HashSet <int> > assertStringNumberToFunctionIndex = GetStringsUsedInAsserts(); HashSet <Function> functionsThatCallEv = new HashSet <Function>(); //get functions that call "EV()" var evFunction = ainFile.GetFunction("EV"); if (evFunction != null) { functionsThatCallEv = ainFile.CodeSearchCache.FunctionsCache.GetUsedBy(evFunction); } //Is it used as part of a function call to EV? foreach (var function in functionsThatCallEv) { int address = function.Address; int codeLength = ainFile.Code.Length; int evFunctionIndex = evFunction.Index; int evFunctionArgs = evFunction.ParameterCount; int evFunctionOffset = evFunctionArgs * 6; while (address < codeLength) { var instructionInfo = Decompiler.Peek(ainFile.Code, address); if (instructionInfo.instruction == Instruction.CALLFUNC && instructionInfo.word1 == evFunctionIndex) { var ins1 = Decompiler.Peek(ainFile.Code, instructionInfo.CurrentAddress - evFunctionOffset); if (ins1.instruction == Instruction.S_PUSH) { stringsToExclude.SetBit(ins1.word1, StringExclusionReason.IsEvent); } } else if (instructionInfo.instruction == Instruction.FUNC || instructionInfo.instruction == Instruction.ENDFUNC) { break; } address = instructionInfo.nextAddress; } //var expression = ainFile.DecompiledCodeCache.GetDecompiledCode(function); //var childExpressions = expression.GetChildExpressions(); //var evCalls = childExpressions.Where(e => e.ExpressionType == Instruction.CALLFUNC && e.Variable == evFunction); //var stringNumbers = evCalls.SelectMany(evCall => evCall.GetChildExpressions()) // .Where(e => e.ExpressionType == Instruction.S_PUSH) // .Select(e => e.Value); //foreach (var stringNumber in stringNumbers) //{ // stringsToExclude.SetBit(stringNumber, ExclusionReason.IsEvent); //} } for (int i = 0; i < ainFile.Strings.Count; i++) { string str = ainFile.Strings[i]; if (String.IsNullOrEmpty(str)) { continue; } //Is it a function name? if (ainFile.FunctionNameToIndex.ContainsKey(str)) { stringsToExclude.SetBit(i, StringExclusionReason.IsFunctionName); } var usedBy = ainFile.CodeSearchCache.StringsCache.GetUsedBy(str); //Is it used only by a function containing TEST or DEBUG in its name? if (usedBy.All(f => f.Name.Contains("テスト") || f.Name.Contains("デバッグ"))) //TEST or DEBUG { stringsToExclude.SetBit(i, StringExclusionReason.IsInsideTestFunction); } //Is it used only by a system function? if (usedBy.All(f => systemFunctions.Contains(f.Index))) { stringsToExclude.SetBit(i, StringExclusionReason.IsInsideSystemFunction); } //Is it never used? if (usedBy.Count == 0) { stringsToExclude.SetBit(i, StringExclusionReason.IsUnused); } //Is it used only in an assert? if (assertStringNumberToFunctionIndex.ContainsKey(i)) { var assertFunctionIndexes = assertStringNumberToFunctionIndex[i]; var usedByFunctionIndexes = usedBy.Select(f => f.Index); if (assertFunctionIndexes.SetEquals(usedByFunctionIndexes)) { stringsToExclude.SetBit(i, StringExclusionReason.IsAssert); } } } if (stringsToExclude.ContainsKey(0)) { stringsToExclude.Remove(0); } ////part 1: function names //if (ExcludeFunctionNames) //{ // for (int i = 0; i < ainFile.Strings.Count; i++) // { // string str = ainFile.Strings[i]; // if (ainFile.FunctionNameToIndex.ContainsKey(str)) // { // stringsToExclude.SetBit(i, ExclusionReason.IsFunctionName); // } // } //} ////part 2: Test functions //if (ExcludeTestFunctions) //{ // for (int i = 0; i < ainFile.Strings.Count; i++) // { // string str = ainFile.Strings[i]; // var usedBy = ainFile.CodeSearchCache.StringsCache.GetUsedBy(str); // if (usedBy.All(f => f.Name.Contains("テスト") || f.Name.Contains("デバッグ"))) //TEST or DEBUG // { // stringsToExclude.SetBit(i, ExclusionReason.IsInsideTestFunction); // } // } //} ////part 3: System functions //if (ExcludeSystemFunctions) //{ // for (int i = 0; i < ainFile.Strings.Count; i++) // { // string str = ainFile.Strings[i]; // var usedBy = ainFile.CodeSearchCache.StringsCache.GetUsedBy(str); // if (usedBy.All(f => systemFunctions.Contains(f.Index))) // { // stringsToExclude.SetBit(i, ExclusionReason.IsInsideSystemFunction); // } // } //} ////part 4: Unused strings //if (ExcludeUnusedStrings) //{ // for (int i = 0; i < ainFile.Strings.Count; i++) // { // string str = ainFile.Strings[i]; // var usedBy = ainFile.CodeSearchCache.StringsCache.GetUsedBy(str); // if (usedBy.Count == 0) // { // stringsToExclude.SetBit(i, ExclusionReason.IsUnused); // } // } //} }
public void LoadFile(string fileName) { var text = File.ReadAllText(fileName); var document = XDocument.Parse(text); var rootElement = document.Element(XNamespace.None + "root"); if (rootElement == null) { return; } foreach (var element in rootElement.Elements()) { if (element.IsNamed("variable")) { var metaData = TryReadMetadata(element); string name = element.GetAttribute("name"); if (name != null && metaData != null) { IVariable variable = null; string parentFunctionName = element.GetAttribute("function"); string parentStructName = element.GetAttribute("struct"); var parentFunction = ainFile.GetFunction(parentFunctionName); var parentStruct = ainFile.GetStruct(parentStructName); var function = ainFile.GetFunction(name); var structInfo = ainFile.GetStruct(name); var global = ainFile.GetGlobal(name); if (parentFunction != null) { int index; if (!int.TryParse(name, out index)) { variable = ainFile.GetFunctionParameter(parentFunction, name); } else { variable = ainFile.GetFunctionParameter(parentFunction, index); } } else if (parentStruct != null) { variable = ainFile.GetStructMember(parentStruct, name); } else if (function != null) { variable = function; } else if (structInfo != null) { variable = structInfo; } else if (global != null) { variable = global; } if (variable != null) { Metadata[variable] = metaData; } } } else if (element.IsNamed("enumeration")) { string name = element.GetAttribute("name"); if (name != null) { var enumeration = this.EnumerationTypes.GetOrAddNew(name); enumeration.Name = name; foreach (var enumerationElement in element.Elements()) { if (enumerationElement.IsNamed("item")) { string itemName = enumerationElement.GetAttribute("name"); string itemValueString = enumerationElement.GetAttribute("value"); if (itemName != null && itemValueString != null) { int itemValue; if (int.TryParse(itemValueString, out itemValue)) { enumeration.Add(itemValue, itemName); } } } } } } else if (element.IsNamed("globalgroup")) { string indexString = element.GetAttribute("index"); int index; if (IntUtil.TryParse(indexString, out index)) { var metaData = TryReadMetadata(element); if (metaData != null) { this.GlobalGroupMetadata.Set(index, metaData); } } } } }
private bool FindFunctionTypeForVariable(IVariable variable, Expression code, bool MakeNewStuffUp) { bool variableIsFunction = variable as Function != null; bool variableIsFuncType = variable.DataType.IsFuncType(); bool variableIsDelegate = variable.DataType.IsDelegate(); foreach (var e in code.GetChildExpressions()) { Expression otherExpression = null; IVariable expVariable = null; if (e.ExpressionType == Instruction.CALLFUNC2 && variableIsFuncType) { bool isVoid = e.IsVoidContext(); if (!isVoid) { otherExpression = e.GetOtherSideOfBinaryExpression(); } IVariable otherExpressionVariable = null; if (otherExpression != null) { otherExpressionVariable = otherExpression.Variable; } DataType otherExpressionDataType = DataType.Void; int otherExpressionStructType = -1; if (otherExpressionVariable != null) { otherExpressionDataType = otherExpressionVariable.DataType; otherExpressionStructType = otherExpressionVariable.StructType; } else { if (isVoid) { otherExpressionDataType = DataType.Void; } else { otherExpressionDataType = DataType.AnyNonVoidType; } } var argExpressions = (e.Arg3 ?? Expression.Empty).FlattenContainerExpression(Instruction.Comma).ToArray(); var variables = GetVariablesFromExpressions(argExpressions); var matchingFuncTypes = ainFile.MatchingFunctionTypes(otherExpressionDataType, otherExpressionStructType, variables, variables.Length).Distinct().ToArray(); var firstMatchingFuncType = matchingFuncTypes.FirstOrDefault(); if (firstMatchingFuncType != null) { if (MakeNewStuffUp || matchingFuncTypes.Skip(1).FirstOrDefault() == null) { variable.StructType = firstMatchingFuncType.Index; } } } if (variableIsFunction && e.ExpressionType == Instruction.RETURN) { otherExpression = e.Arg1; expVariable = variable; } else { expVariable = e.Variable; if (variable == expVariable) { otherExpression = e.GetOtherSideOfBinaryExpression(); } } if (otherExpression != null) { Function otherFunction = null; if (otherExpression.ExpressionType == Instruction.PUSH) { otherFunction = ainFile.GetFunction(otherExpression.Value); } else if (otherExpression.ExpressionType == Instruction.S_PUSH) { otherFunction = ainFile.GetFunction(ainFile.GetString(otherExpression.Value)); } else { var otherVariable = otherExpression.Variable; if (otherVariable != null && !variableIsDelegate && otherVariable.DataType.IsFuncType() && otherVariable.StructType != -1) { variable.StructType = otherVariable.StructType; return(true); } if (otherVariable != null && variableIsDelegate && otherVariable.DataType.IsDelegate() && otherVariable.StructType != -1) { variable.StructType = otherVariable.StructType; return(true); } } if (otherFunction != null) { FunctionType matchingFuncType = null; if (!variableIsDelegate) { if (!MakeNewStuffUp) { matchingFuncType = ainFile.GetFuncTypeUnique(otherFunction); } else { matchingFuncType = ainFile.GetFuncType(otherFunction); } if (matchingFuncType != null) { variable.StructType = matchingFuncType.Index; return(true); } } else { if (!MakeNewStuffUp) { matchingFuncType = ainFile.GetDelegateUnique(otherFunction); } else { matchingFuncType = ainFile.GetDelegateType(otherFunction); } if (matchingFuncType != null) { variable.StructType = matchingFuncType.Index; return(true); } } } } else { var functionParameter = e.GetFunctionCallParameter(); if (functionParameter != null) { if (functionParameter != null && !variableIsDelegate && functionParameter.DataType.IsFuncType() && functionParameter.StructType != -1) { variable.StructType = functionParameter.StructType; return(true); } if (functionParameter != null && variableIsDelegate && functionParameter.DataType.IsDelegate() && functionParameter.StructType != -1) { variable.StructType = functionParameter.StructType; return(true); } } else if (variable.DataType.IsArray()) { var parent = e.Parent; if (parent != null && (parent.ExpressionType == Instruction.A_PUSHBACK || parent.ExpressionType == Instruction.A_INSERT)) { var arg2 = parent.Arg2; IVariable var2 = null; if (arg2 != null) { var2 = arg2.Variable; } if (var2 != null) { if (!variableIsDelegate && var2.DataType.IsFuncType() && var2.StructType != -1) { variable.StructType = var2.StructType; return(true); } if (variableIsDelegate && var2.DataType.IsDelegate() && var2.StructType != -1) { variable.StructType = var2.StructType; return(true); } } } } else if (e.ExpressionType == Instruction.CALLFUNC2) { } } } return(false); }