public TextImportExportOld2(AinFile ainFile) { this.ainFile = ainFile; this.stringExportImport = new StringExportImport(ainFile); this.stringExportImport.GetExclusionList(); //this.replacer = new Replacer(ainFile); }
public ExportImportStringsForm(AinFile ainFile) : this() { this.ainFile = ainFile; exportImport = new StringExportImport(ainFile); }
private void ExportAndMerge() { string newDisassembledCode = null; if ((this.CodePatches2 != null && this.CodePatches2.Length > 0) || numberedStrings.Count > 0) { this.ainFile = ainFile.Clone(); } if (this.CodePatches2 != null && this.CodePatches2.Length > 0) { //this.ainFile = ainFile.Clone(); var compiler = new Compiler.Compiler(ainFile); byte[] codeBytes; compiler.CompileCode(this.CodePatches2.ToString(), out codeBytes, out newDisassembledCode, true, this.CodePatches); if (newDisassembledCode == null || compiler.Errors.Count > 0) { var errorsListForm = new ErrorsListForm(); errorsListForm.SetErrorList(compiler.Errors); errorsListForm.Show(); return; } //foreach (var func in functionsToOutput) //{ // this.CodePatches[func.Name] = ""; //} } currentFunctionName = ""; stringDictionary = null; messageDictionary = null; stringNumber = 0; messageNumber = 0; //var ainFile = this.ainFile; if (numberedStrings.Count > 0) { //this.ainFile = ainFile.Clone(); var stringExportImport = new StringExportImport(ainFile); int firstMessage = stringExportImport.GetFirstMessageIdNumber(); int lastMessage = firstMessage + ainFile.Messages.Count; int firstString = stringExportImport.GetFirstStringIdNumber(); int lastString = firstString + ainFile.Strings.Count; foreach (var pair in numberedStrings) { int number = pair.Key; string message = pair.Value; if (number >= firstMessage && number < lastMessage) { ainFile.Messages[number - firstMessage] = message; } else if (number >= firstString && number < lastString) { ainFile.Strings[number - firstString] = message; } } } using (TemporaryFile tempFile = new TemporaryFile("jam", true)) { var saver = new ExplorerForm.SaveProjectInBackground(); var options = new CodeDisplayOptions(); options.AnnotateWithDecompiledCode = false; options.MergeDuplicateStrings = true; options.MergeDuplicateMessages = true; var writer = new AssemblerProjectWriter(ainFile, options); writer.BeforeWritingInstruction += new EventHandler <InstructionInfoEventArgs>(writer_BeforeWritingInstruction); writer.BeforeWritingString += new EventHandler <InstructionInfoEventArgs>(writer_BeforeWritingString); saver.SaveAsProject(writer, tempFile.FileName, true); if (newDisassembledCode != null) { using (var fs = new FileStream(tempFile.FileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)) { using (var sw = new StreamWriter(fs, Extensions.TextEncoding)) { sw.WriteLine(); sw.WriteLine(newDisassembledCode); sw.Flush(); fs.Flush(); sw.Close(); fs.Close(); } } } //WaitForFileLock(tempFile.FileName, 2000); //tempFile.FileName var builder = new ExplorerForm.BuildProjectInBackground(); builder.ForceUniqueMessages = true; builder.Run(tempFile.FileName, this.outputFileName, true); } }
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 void CatchUpToAddress(ref Expression expression, List<string> functionLines, int address) //{ // while (expression != null && expression.address < address) // { // string enumerationName = null; // var variable = expression.Variable.Canonicalize(); // if (variable != null && VariablesUsingEnumerationType.Contains(variable)) // { // var metaData = variable.GetMetadata(); // if (metaData.EnumerationType == AnnotateEnumerationType) // { // var otherExpression = expression.GetOtherSideOfBinaryExpression(); // if (otherExpression != null) // { // otherExpression = otherExpression.SkipChildCastOperations(); // if (otherExpression.ExpressionType == Instruction.PUSH) // { // enumerationName = AnnotateEnumerationType.GetOrDefault(otherExpression.Value, otherExpression.Value.ToString()); // } // else if (otherExpression.ExpressionType == Instruction.SH_LOCALASSIGN) // { // enumerationName = AnnotateEnumerationType.GetOrDefault(otherExpression.Value, otherExpression.Value.ToString()); // } // } // } // else // { // var func = expression as IFunction; // if (func != null) // { // for (int i = 0; i < func.ParameterCount; i++) // { // var para = func.GetNonVoidFunctionParameter(i); // if (para == null) break; // var metaData2 = para.GetMetadata(); // if (metaData2.EnumerationType == AnnotateEnumerationType) // { // var arg = expression.GetFunctionCallArgument(i); // if (arg != null) // { // arg = arg.SkipChildCastOperations(); // if (arg.ExpressionType == Instruction.PUSH) // { // enumerationName = AnnotateEnumerationType.GetOrDefault(arg.Value, arg.Value.ToString()); // } // } // } // } // } // } // } // if (enumerationName != null) // { // functionLines.Add("#" + enumerationName); // } // expression = expression.GetNextExpression(); // } //} private void AddString(ref int numberOfNonCommentedLines, ref int numberOfStrings, List <string> functionLines, int stringNumber, string str) { StringExclusionReason exclude = stringExportImport.stringsToExclude.GetOrDefault(stringNumber, StringExclusionReason.None); string stringLine = "s " + numberOfStrings.ToString("000") + " " + StringExportImport.EscapeText(str); if (exclude != StringExclusionReason.None) { stringLine = "#" + stringLine + "#\t\t" + exclude.GetText(); } else { if (str != "") { numberOfNonCommentedLines++; } } if (!(stringNumber == 0 && str == "")) { if (useStringsToMatch == false || StringsToMatch.Contains(str)) { if (this.IncludeStrings == true) { functionLines.Add(stringLine); } } } numberOfStrings++; }
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 static string GetText(this StringExclusionReason exclusionReason) { return(StringExportImport.GetExcludeReasonText(exclusionReason)); }