private void StacktraceListView_Parse(EntryInfo entryInfo) { var lines = entryInfo.entry.condition.Split(new char[] { '\n' }, StringSplitOptions.None); entryInfo.stacktraceLineInfos = new List <StacktraceLineInfo>(lines.Length); string rootDirectory = System.IO.Path.Combine(Application.dataPath, ".."); Uri uriRoot = new Uri(rootDirectory); string textBeforeFilePath = ") (at "; string textUnityEngineDebug = "UnityEngine.Debug"; #if UNITY_2019_1_OR_NEWER string fileInBuildSlave = "D:/unity/"; #else string fileInBuildSlave = "C:/buildslave/unity/"; #endif string luaCFunction = "[C]"; string luaMethodBefore = ": in function "; string luaFileExt = ".lua"; string luaAssetPath = "Assets/Lua/"; for (int i = 0; i < lines.Length; i++) { var line = lines[i]; if (i == lines.Length - 1 && string.IsNullOrEmpty(line)) { continue; } if (line.StartsWith(textUnityEngineDebug)) { continue; } StacktraceLineInfo info = new StacktraceLineInfo(); info.plain = line; info.text = info.plain; entryInfo.stacktraceLineInfos.Add(info); if (i == 0) { continue; } if (!StacktraceListView_Parse_CSharp(line, info, textBeforeFilePath, fileInBuildSlave, uriRoot)) { StacktraceListView_Parse_Lua(line, info, luaCFunction, luaMethodBefore, luaFileExt, luaAssetPath); } } }
private bool StacktraceListView_Parse_Lua(string line, StacktraceLineInfo info, string luaCFunction, string luaMethodBefore, string luaFileExt, string luaAssetPath) { if (string.IsNullOrEmpty(line) || line[0] != ' ') { return(false); } string preMethodString = line; string methodString = String.Empty; int methodFirstIndex = line.IndexOf(luaMethodBefore, StringComparison.Ordinal); if (methodFirstIndex > 0) { methodString = line.Substring(methodFirstIndex + luaMethodBefore.Length); preMethodString = preMethodString.Remove(methodFirstIndex + luaMethodBefore.Length); } bool cFunction = line.IndexOf(luaCFunction, 1, StringComparison.Ordinal) == 1; if (!cFunction) { int lineIndex = line.IndexOf(':'); if (lineIndex > 0) { int endLineIndex = line.IndexOf(':', lineIndex + 1); if (endLineIndex > 0) { string lineString = line.Substring(lineIndex + 1, (endLineIndex) - (lineIndex + 1)); string filePath = line.Substring(1, lineIndex - 1); if (!filePath.EndsWith(luaFileExt, StringComparison.Ordinal)) { filePath += luaFileExt; } if (!int.TryParse(lineString, out info.lineNum)) { return(false); } info.filePath = luaAssetPath + filePath; string namespaceString = String.Empty; int classFirstIndex = filePath.LastIndexOf('/'); if (classFirstIndex > 0) { namespaceString = filePath.Substring(0, classFirstIndex + 1); } string classString = filePath.Substring(classFirstIndex + 1, filePath.Length - namespaceString.Length - luaFileExt.Length); info.text = string.Format(" <color=#{0}>{1}</color>", Constants.colorNamespace, namespaceString) + string.Format("<color=#{0}>{1}</color>", Constants.colorClass, classString) + string.Format("<color=#{0}>:{1}</color>", Constants.colorPath, lineString) + string.Format("<color=#{0}>{1}</color>", Constants.colorPath, luaMethodBefore) + string.Format("<color=#{0}>{1}</color>", Constants.colorMethod, methodString); } } } else { info.text = string.Format("<color=#{0}>{1}</color>", Constants.colorPathAlpha, preMethodString) + string.Format("<color=#{0}>{1}</color>", Constants.colorMethodAlpha, methodString); } return(true); }
private bool StacktraceListView_Parse_CSharp(string line, StacktraceLineInfo info, string textBeforeFilePath, string fileInBuildSlave, Uri uriRoot) { int methodLastIndex = line.IndexOf('('); if (methodLastIndex <= 0) { return(false); } int argsLastIndex = line.IndexOf(')', methodLastIndex); if (argsLastIndex <= 0) { return(false); } int methodFirstIndex = line.LastIndexOf(':', methodLastIndex); if (methodFirstIndex <= 0) { methodFirstIndex = line.LastIndexOf('.', methodLastIndex); if (methodFirstIndex <= 0) { return(false); } } string methodString = line.Substring(methodFirstIndex + 1, methodLastIndex - methodFirstIndex - 1); string classString; string namespaceString = String.Empty; int classFirstIndex = line.LastIndexOf('.', methodFirstIndex - 1); if (classFirstIndex <= 0) { classString = line.Substring(0, methodFirstIndex + 1); } else { classString = line.Substring(classFirstIndex + 1, methodFirstIndex - classFirstIndex); namespaceString = line.Substring(0, classFirstIndex + 1); } string argsString = line.Substring(methodLastIndex, argsLastIndex - methodLastIndex + 1); string fileString = String.Empty; string fileNameString = String.Empty; string fileLineString = String.Empty; bool alphaColor = true; int filePathIndex = line.IndexOf(textBeforeFilePath, argsLastIndex, StringComparison.Ordinal); if (filePathIndex > 0) { filePathIndex += textBeforeFilePath.Length; if (line[filePathIndex] != '<') // sometimes no url is given, just an id between <>, we can't do an hyperlink { string filePathPart = line.Substring(filePathIndex); int lineIndex = filePathPart.LastIndexOf(":", StringComparison.Ordinal); // LastIndex because the url can contain ':' ex:"C:" if (lineIndex > 0) { int endLineIndex = filePathPart.LastIndexOf(")", StringComparison.Ordinal); // LastIndex because files or folder in the url can contain ')' if (endLineIndex > 0) { string lineString = filePathPart.Substring(lineIndex + 1, (endLineIndex) - (lineIndex + 1)); string filePath = filePathPart.Substring(0, lineIndex); bool isInBuildSlave = filePath.StartsWith(fileInBuildSlave, StringComparison.Ordinal); if (!isInBuildSlave) { alphaColor = false; } info.filePath = filePath; info.lineNum = int.Parse(lineString); if (filePath.Length > 2 && filePath[1] == ':' && !isInBuildSlave) { Uri uriFile = new Uri(filePath); Uri relativeUri = uriRoot.MakeRelativeUri(uriFile); string relativePath = relativeUri.ToString(); if (!string.IsNullOrEmpty(relativePath)) { info.plain = info.plain.Replace(filePath, relativePath); filePath = relativePath; } } fileNameString = System.IO.Path.GetFileName(filePath); fileString = textBeforeFilePath.Substring(1) + filePath.Substring(0, filePath.Length - fileNameString.Length); fileLineString = filePathPart.Substring(lineIndex, endLineIndex - lineIndex + 1); } } } else { fileString = line.Substring(argsLastIndex + 1); } } if (alphaColor) { info.text = string.Format("<color=#{0}>{1}</color>", Constants.colorNamespaceAlpha, namespaceString) + string.Format("<color=#{0}>{1}</color>", Constants.colorClassAlpha, classString) + string.Format("<color=#{0}>{1}</color>", Constants.colorMethodAlpha, methodString) + string.Format("<color=#{0}>{1}</color>", Constants.colorParametersAlpha, argsString) + string.Format("<color=#{0}>{1}</color>", Constants.colorPathAlpha, fileString) + string.Format("<color=#{0}>{1}</color>", Constants.colorFilenameAlpha, fileNameString) + string.Format("<color=#{0}>{1}</color>", Constants.colorPathAlpha, fileLineString); } else { info.text = string.Format("<color=#{0}>{1}</color>", Constants.colorNamespace, namespaceString) + string.Format("<color=#{0}>{1}</color>", Constants.colorClass, classString) + string.Format("<color=#{0}>{1}</color>", Constants.colorMethod, methodString) + string.Format("<color=#{0}>{1}</color>", Constants.colorParameters, argsString) + string.Format("<color=#{0}>{1}</color>", Constants.colorPath, fileString) + string.Format("<color=#{0}>{1}</color>", Constants.colorFilename, fileNameString) + string.Format("<color=#{0}>{1}</color>", Constants.colorPath, fileLineString); } return(true); }