mirror of https://github.com/buggins/dlangide.git
DMD profiler trace.log viewer, part 1 - #344
This commit is contained in:
parent
645090ec31
commit
f620e3e286
|
@ -71,9 +71,9 @@
|
||||||
<doXGeneration>1</doXGeneration>
|
<doXGeneration>1</doXGeneration>
|
||||||
<xfilename>$(IntDir)\$(TargetName).json</xfilename>
|
<xfilename>$(IntDir)\$(TargetName).json</xfilename>
|
||||||
<debuglevel>0</debuglevel>
|
<debuglevel>0</debuglevel>
|
||||||
<debugids>KeyInput DCD</debugids>
|
<debugids>DCD</debugids>
|
||||||
<versionlevel>0</versionlevel>
|
<versionlevel>0</versionlevel>
|
||||||
<versionids>EmbedStandardResources NO_OPENGL USE_FREETYPE</versionids>
|
<versionids>EmbedStandardResources USE_FREETYPE NO_OPENGL</versionids>
|
||||||
<dump_source>0</dump_source>
|
<dump_source>0</dump_source>
|
||||||
<mapverbosity>0</mapverbosity>
|
<mapverbosity>0</mapverbosity>
|
||||||
<createImplib>0</createImplib>
|
<createImplib>0</createImplib>
|
||||||
|
@ -176,7 +176,7 @@
|
||||||
<debuglevel>0</debuglevel>
|
<debuglevel>0</debuglevel>
|
||||||
<debugids />
|
<debugids />
|
||||||
<versionlevel>0</versionlevel>
|
<versionlevel>0</versionlevel>
|
||||||
<versionids>EmbedStandardResources</versionids>
|
<versionids>EmbedStandardResources NO_OPENGL USE_FREETYPE</versionids>
|
||||||
<dump_source>0</dump_source>
|
<dump_source>0</dump_source>
|
||||||
<mapverbosity>0</mapverbosity>
|
<mapverbosity>0</mapverbosity>
|
||||||
<createImplib>0</createImplib>
|
<createImplib>0</createImplib>
|
||||||
|
@ -214,7 +214,7 @@
|
||||||
<multiobj>0</multiobj>
|
<multiobj>0</multiobj>
|
||||||
<singleFileCompilation>0</singleFileCompilation>
|
<singleFileCompilation>0</singleFileCompilation>
|
||||||
<oneobj>0</oneobj>
|
<oneobj>0</oneobj>
|
||||||
<mscoff>1</mscoff>
|
<mscoff>0</mscoff>
|
||||||
<trace>0</trace>
|
<trace>0</trace>
|
||||||
<quiet>0</quiet>
|
<quiet>0</quiet>
|
||||||
<verbose>0</verbose>
|
<verbose>0</verbose>
|
||||||
|
@ -277,9 +277,9 @@
|
||||||
<doXGeneration>1</doXGeneration>
|
<doXGeneration>1</doXGeneration>
|
||||||
<xfilename>$(IntDir)\$(TargetName).json</xfilename>
|
<xfilename>$(IntDir)\$(TargetName).json</xfilename>
|
||||||
<debuglevel>0</debuglevel>
|
<debuglevel>0</debuglevel>
|
||||||
<debugids>KeyInput DCD</debugids>
|
<debugids>DCD</debugids>
|
||||||
<versionlevel>0</versionlevel>
|
<versionlevel>0</versionlevel>
|
||||||
<versionids>EmbedStandardResources NO_OPENGL USE_FREETYPE</versionids>
|
<versionids>EmbedStandardResources USE_FREETYPE NO_OPENGL</versionids>
|
||||||
<dump_source>0</dump_source>
|
<dump_source>0</dump_source>
|
||||||
<mapverbosity>0</mapverbosity>
|
<mapverbosity>0</mapverbosity>
|
||||||
<createImplib>0</createImplib>
|
<createImplib>0</createImplib>
|
||||||
|
@ -382,7 +382,7 @@
|
||||||
<debuglevel>0</debuglevel>
|
<debuglevel>0</debuglevel>
|
||||||
<debugids />
|
<debugids />
|
||||||
<versionlevel>0</versionlevel>
|
<versionlevel>0</versionlevel>
|
||||||
<versionids>EmbedStandardResources</versionids>
|
<versionids>EmbedStandardResources NO_OPENGL USE_FREETYPE</versionids>
|
||||||
<dump_source>0</dump_source>
|
<dump_source>0</dump_source>
|
||||||
<mapverbosity>0</mapverbosity>
|
<mapverbosity>0</mapverbosity>
|
||||||
<createImplib>0</createImplib>
|
<createImplib>0</createImplib>
|
||||||
|
@ -618,6 +618,212 @@
|
||||||
<postBuildCommand />
|
<postBuildCommand />
|
||||||
<filesToClean>*.obj;*.cmd;*.build;*.json;*.dep</filesToClean>
|
<filesToClean>*.obj;*.cmd;*.build;*.json;*.dep</filesToClean>
|
||||||
</Config>
|
</Config>
|
||||||
|
<Config name="DSFMLDebug" platform="Win32">
|
||||||
|
<obj>0</obj>
|
||||||
|
<link>0</link>
|
||||||
|
<lib>0</lib>
|
||||||
|
<subsystem>2</subsystem>
|
||||||
|
<multiobj>0</multiobj>
|
||||||
|
<singleFileCompilation>0</singleFileCompilation>
|
||||||
|
<oneobj>0</oneobj>
|
||||||
|
<mscoff>0</mscoff>
|
||||||
|
<trace>1</trace>
|
||||||
|
<quiet>0</quiet>
|
||||||
|
<verbose>0</verbose>
|
||||||
|
<vtls>0</vtls>
|
||||||
|
<vgc>0</vgc>
|
||||||
|
<symdebug>1</symdebug>
|
||||||
|
<optimize>0</optimize>
|
||||||
|
<cpu>0</cpu>
|
||||||
|
<isX86_64>0</isX86_64>
|
||||||
|
<isLinux>0</isLinux>
|
||||||
|
<isOSX>0</isOSX>
|
||||||
|
<isWindows>0</isWindows>
|
||||||
|
<isFreeBSD>0</isFreeBSD>
|
||||||
|
<isSolaris>0</isSolaris>
|
||||||
|
<scheduler>0</scheduler>
|
||||||
|
<useDeprecated>1</useDeprecated>
|
||||||
|
<errDeprecated>0</errDeprecated>
|
||||||
|
<useAssert>0</useAssert>
|
||||||
|
<useInvariants>0</useInvariants>
|
||||||
|
<useIn>0</useIn>
|
||||||
|
<useOut>0</useOut>
|
||||||
|
<useArrayBounds>0</useArrayBounds>
|
||||||
|
<noboundscheck>0</noboundscheck>
|
||||||
|
<useSwitchError>0</useSwitchError>
|
||||||
|
<useUnitTests>0</useUnitTests>
|
||||||
|
<useInline>0</useInline>
|
||||||
|
<release>0</release>
|
||||||
|
<preservePaths>0</preservePaths>
|
||||||
|
<warnings>0</warnings>
|
||||||
|
<infowarnings>0</infowarnings>
|
||||||
|
<checkProperty>0</checkProperty>
|
||||||
|
<genStackFrame>0</genStackFrame>
|
||||||
|
<pic>0</pic>
|
||||||
|
<cov>0</cov>
|
||||||
|
<nofloat>0</nofloat>
|
||||||
|
<Dversion>2</Dversion>
|
||||||
|
<ignoreUnsupportedPragmas>0</ignoreUnsupportedPragmas>
|
||||||
|
<allinst>0</allinst>
|
||||||
|
<stackStomp>0</stackStomp>
|
||||||
|
<compiler>0</compiler>
|
||||||
|
<otherDMD>0</otherDMD>
|
||||||
|
<cccmd>$(CC) -c</cccmd>
|
||||||
|
<ccTransOpt>1</ccTransOpt>
|
||||||
|
<addDepImp>0</addDepImp>
|
||||||
|
<program>$(DMDInstallDir)windows\bin\dmd.exe</program>
|
||||||
|
<imppath>$(ProjectDir)/../dlangui/src $(ProjectDir)/../dlangui/3rdparty $(ProjectDir)/../dlangui/deps/DerelictGL3/source $(ProjectDir)/../dlangui/deps/DerelictUtil/source $(ProjectDir)/../dlangui/deps/DerelictFT/source $(ProjectDir)/../dlangui/deps/DerelictSDL2/source $(ProjectDir)/../dlangui/deps/libdparse/src $(ProjectDir)/../DerelictLLDB/source</imppath>
|
||||||
|
<fileImppath>views views/res views/res/i18n views/res/mdpi views/res/hdpi</fileImppath>
|
||||||
|
<outdir>$(ConfigurationName)</outdir>
|
||||||
|
<objdir>$(OutDir)</objdir>
|
||||||
|
<objname />
|
||||||
|
<libname />
|
||||||
|
<doDocComments>0</doDocComments>
|
||||||
|
<docdir />
|
||||||
|
<docname />
|
||||||
|
<modules_ddoc />
|
||||||
|
<ddocfiles />
|
||||||
|
<doHdrGeneration>0</doHdrGeneration>
|
||||||
|
<hdrdir />
|
||||||
|
<hdrname />
|
||||||
|
<doXGeneration>1</doXGeneration>
|
||||||
|
<xfilename>$(IntDir)\$(TargetName).json</xfilename>
|
||||||
|
<debuglevel>0</debuglevel>
|
||||||
|
<debugids>KeyInput DCD</debugids>
|
||||||
|
<versionlevel>0</versionlevel>
|
||||||
|
<versionids>EmbedStandardResources USE_FREETYPE NO_OPENGL</versionids>
|
||||||
|
<dump_source>0</dump_source>
|
||||||
|
<mapverbosity>0</mapverbosity>
|
||||||
|
<createImplib>0</createImplib>
|
||||||
|
<defaultlibname />
|
||||||
|
<debuglibname />
|
||||||
|
<moduleDepsFile />
|
||||||
|
<run>0</run>
|
||||||
|
<runargs />
|
||||||
|
<runCv2pdb>1</runCv2pdb>
|
||||||
|
<pathCv2pdb>$(VisualDInstallDir)cv2pdb\cv2pdb.exe</pathCv2pdb>
|
||||||
|
<cv2pdbPre2043>0</cv2pdbPre2043>
|
||||||
|
<cv2pdbNoDemangle>0</cv2pdbNoDemangle>
|
||||||
|
<cv2pdbEnumType>0</cv2pdbEnumType>
|
||||||
|
<cv2pdbOptions />
|
||||||
|
<objfiles />
|
||||||
|
<linkswitches />
|
||||||
|
<libfiles />
|
||||||
|
<libpaths />
|
||||||
|
<deffile />
|
||||||
|
<resfile />
|
||||||
|
<exefile>$(OutDir)\$(ProjectName).exe</exefile>
|
||||||
|
<useStdLibPath>1</useStdLibPath>
|
||||||
|
<cRuntime>2</cRuntime>
|
||||||
|
<privatePhobos>0</privatePhobos>
|
||||||
|
<additionalOptions />
|
||||||
|
<preBuildCommand />
|
||||||
|
<postBuildCommand />
|
||||||
|
<filesToClean>*.obj;*.cmd;*.build;*.json;*.dep</filesToClean>
|
||||||
|
</Config>
|
||||||
|
<Config name="DSFMLDebug" platform="x64">
|
||||||
|
<obj>0</obj>
|
||||||
|
<link>0</link>
|
||||||
|
<lib>0</lib>
|
||||||
|
<subsystem>2</subsystem>
|
||||||
|
<multiobj>0</multiobj>
|
||||||
|
<singleFileCompilation>0</singleFileCompilation>
|
||||||
|
<oneobj>0</oneobj>
|
||||||
|
<mscoff>0</mscoff>
|
||||||
|
<trace>1</trace>
|
||||||
|
<quiet>0</quiet>
|
||||||
|
<verbose>0</verbose>
|
||||||
|
<vtls>0</vtls>
|
||||||
|
<vgc>0</vgc>
|
||||||
|
<symdebug>1</symdebug>
|
||||||
|
<optimize>0</optimize>
|
||||||
|
<cpu>0</cpu>
|
||||||
|
<isX86_64>1</isX86_64>
|
||||||
|
<isLinux>0</isLinux>
|
||||||
|
<isOSX>0</isOSX>
|
||||||
|
<isWindows>0</isWindows>
|
||||||
|
<isFreeBSD>0</isFreeBSD>
|
||||||
|
<isSolaris>0</isSolaris>
|
||||||
|
<scheduler>0</scheduler>
|
||||||
|
<useDeprecated>1</useDeprecated>
|
||||||
|
<errDeprecated>0</errDeprecated>
|
||||||
|
<useAssert>0</useAssert>
|
||||||
|
<useInvariants>0</useInvariants>
|
||||||
|
<useIn>0</useIn>
|
||||||
|
<useOut>0</useOut>
|
||||||
|
<useArrayBounds>0</useArrayBounds>
|
||||||
|
<noboundscheck>0</noboundscheck>
|
||||||
|
<useSwitchError>0</useSwitchError>
|
||||||
|
<useUnitTests>0</useUnitTests>
|
||||||
|
<useInline>0</useInline>
|
||||||
|
<release>0</release>
|
||||||
|
<preservePaths>0</preservePaths>
|
||||||
|
<warnings>0</warnings>
|
||||||
|
<infowarnings>0</infowarnings>
|
||||||
|
<checkProperty>0</checkProperty>
|
||||||
|
<genStackFrame>0</genStackFrame>
|
||||||
|
<pic>0</pic>
|
||||||
|
<cov>0</cov>
|
||||||
|
<nofloat>0</nofloat>
|
||||||
|
<Dversion>2</Dversion>
|
||||||
|
<ignoreUnsupportedPragmas>0</ignoreUnsupportedPragmas>
|
||||||
|
<allinst>0</allinst>
|
||||||
|
<stackStomp>0</stackStomp>
|
||||||
|
<compiler>0</compiler>
|
||||||
|
<otherDMD>0</otherDMD>
|
||||||
|
<cccmd>$(CC) -c -v</cccmd>
|
||||||
|
<ccTransOpt>1</ccTransOpt>
|
||||||
|
<addDepImp>0</addDepImp>
|
||||||
|
<program>$(DMDInstallDir)windows\bin\dmd.exe</program>
|
||||||
|
<imppath>$(ProjectDir)/../dlangui/src $(ProjectDir)/../dlangui/3rdparty $(ProjectDir)/../dlangui/deps/DerelictGL3/source $(ProjectDir)/../dlangui/deps/DerelictUtil/source $(ProjectDir)/../dlangui/deps/DerelictFT/source $(ProjectDir)/../dlangui/deps/DerelictSDL2/source $(ProjectDir)/../dlangui/deps/libdparse/src $(ProjectDir)/../DerelictLLDB/source</imppath>
|
||||||
|
<fileImppath>views views/res views/res/i18n views/res/mdpi views/res/hdpi</fileImppath>
|
||||||
|
<outdir>$(ConfigurationName)</outdir>
|
||||||
|
<objdir>$(OutDir)</objdir>
|
||||||
|
<objname />
|
||||||
|
<libname />
|
||||||
|
<doDocComments>0</doDocComments>
|
||||||
|
<docdir />
|
||||||
|
<docname />
|
||||||
|
<modules_ddoc />
|
||||||
|
<ddocfiles />
|
||||||
|
<doHdrGeneration>0</doHdrGeneration>
|
||||||
|
<hdrdir />
|
||||||
|
<hdrname />
|
||||||
|
<doXGeneration>1</doXGeneration>
|
||||||
|
<xfilename>$(IntDir)\$(TargetName).json</xfilename>
|
||||||
|
<debuglevel>0</debuglevel>
|
||||||
|
<debugids>KeyInput DCD</debugids>
|
||||||
|
<versionlevel>0</versionlevel>
|
||||||
|
<versionids>EmbedStandardResources USE_FREETYPE NO_OPENGL</versionids>
|
||||||
|
<dump_source>0</dump_source>
|
||||||
|
<mapverbosity>0</mapverbosity>
|
||||||
|
<createImplib>0</createImplib>
|
||||||
|
<defaultlibname />
|
||||||
|
<debuglibname />
|
||||||
|
<moduleDepsFile />
|
||||||
|
<run>0</run>
|
||||||
|
<runargs />
|
||||||
|
<runCv2pdb>1</runCv2pdb>
|
||||||
|
<pathCv2pdb>$(VisualDInstallDir)cv2pdb\cv2pdb.exe</pathCv2pdb>
|
||||||
|
<cv2pdbPre2043>0</cv2pdbPre2043>
|
||||||
|
<cv2pdbNoDemangle>0</cv2pdbNoDemangle>
|
||||||
|
<cv2pdbEnumType>0</cv2pdbEnumType>
|
||||||
|
<cv2pdbOptions />
|
||||||
|
<objfiles />
|
||||||
|
<linkswitches />
|
||||||
|
<libfiles />
|
||||||
|
<libpaths />
|
||||||
|
<deffile />
|
||||||
|
<resfile />
|
||||||
|
<exefile>$(OutDir)\$(ProjectName).exe</exefile>
|
||||||
|
<useStdLibPath>1</useStdLibPath>
|
||||||
|
<cRuntime>2</cRuntime>
|
||||||
|
<privatePhobos>1</privatePhobos>
|
||||||
|
<additionalOptions />
|
||||||
|
<preBuildCommand />
|
||||||
|
<postBuildCommand />
|
||||||
|
<filesToClean>*.obj;*.cmd;*.build;*.json;*.dep</filesToClean>
|
||||||
|
</Config>
|
||||||
<Folder name="dlangide">
|
<Folder name="dlangide">
|
||||||
<Folder name="3rdparty">
|
<Folder name="3rdparty">
|
||||||
<Folder name="containers">
|
<Folder name="containers">
|
||||||
|
@ -718,6 +924,7 @@
|
||||||
<Folder name="d">
|
<Folder name="d">
|
||||||
<File path="src\dlangide\tools\d\dcdinterface.d" />
|
<File path="src\dlangide\tools\d\dcdinterface.d" />
|
||||||
<File path="src\dlangide\tools\d\deditortool.d" />
|
<File path="src\dlangide\tools\d\deditortool.d" />
|
||||||
|
<File path="src\dlangide\tools\d\dmdtrace.d" />
|
||||||
<File path="src\dlangide\tools\d\dparser.d" />
|
<File path="src\dlangide\tools\d\dparser.d" />
|
||||||
<File path="src\dlangide\tools\d\dsyntax.d" />
|
<File path="src\dlangide\tools\d\dsyntax.d" />
|
||||||
</Folder>
|
</Folder>
|
||||||
|
@ -726,6 +933,7 @@
|
||||||
<Folder name="ui">
|
<Folder name="ui">
|
||||||
<File path="src\dlangide\ui\commands.d" />
|
<File path="src\dlangide\ui\commands.d" />
|
||||||
<File path="src\dlangide\ui\debuggerui.d" />
|
<File path="src\dlangide\ui\debuggerui.d" />
|
||||||
|
<File path="src\dlangide\ui\dmdprofilerview.d" />
|
||||||
<File path="src\dlangide\ui\dsourceedit.d" />
|
<File path="src\dlangide\ui\dsourceedit.d" />
|
||||||
<File path="src\dlangide\ui\frame.d" />
|
<File path="src\dlangide\ui\frame.d" />
|
||||||
<File path="src\dlangide\ui\homescreen.d" />
|
<File path="src\dlangide\ui\homescreen.d" />
|
||||||
|
|
|
@ -13,6 +13,14 @@ mixin APP_ENTRY_POINT;
|
||||||
/// entry point for dlangui based application
|
/// entry point for dlangui based application
|
||||||
extern (C) int UIAppMain(string[] args) {
|
extern (C) int UIAppMain(string[] args) {
|
||||||
|
|
||||||
|
//debug(TestDMDTraceParser) {
|
||||||
|
// import dlangide.tools.d.dmdtrace;
|
||||||
|
// long start = currentTimeMillis;
|
||||||
|
// DMDTraceLogParser parser = parseDMDTraceLog("trace.log");
|
||||||
|
// if (parser) {
|
||||||
|
// Log.d("trace.log is parsed ok in ", currentTimeMillis - start, " seconds");
|
||||||
|
// }
|
||||||
|
//}
|
||||||
debug(TestParser) {
|
debug(TestParser) {
|
||||||
import ddc.lexer.parser;
|
import ddc.lexer.parser;
|
||||||
runParserTests();
|
runParserTests();
|
||||||
|
|
|
@ -0,0 +1,365 @@
|
||||||
|
/// DMD trace.log parser
|
||||||
|
module dlangide.tools.d.dmdtrace;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Based on d-profile-viewer: https://bitbucket.org/andrewtrotman/d-profile-viewer
|
||||||
|
|
||||||
|
Copyright (c) 2015-2016 eBay Software Foundation
|
||||||
|
Written by Andrew Trotman
|
||||||
|
Licensed under the 3-clause BSD license (see here:https://en.wikipedia.org/wiki/BSD_licenses)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import dlangui.core.logger;
|
||||||
|
//import core.stdc.stdlib;
|
||||||
|
import std.file;
|
||||||
|
import std.stdio;
|
||||||
|
import std.string;
|
||||||
|
//import dlangide.tools.d.demangle;
|
||||||
|
import core.runtime;
|
||||||
|
import std.conv;
|
||||||
|
import std.algorithm;
|
||||||
|
import std.exception;
|
||||||
|
//import std.demangle;
|
||||||
|
import dlangide.ui.outputpanel;
|
||||||
|
import dlangide.builders.extprocess;
|
||||||
|
import dlangui.widgets.appframe;
|
||||||
|
import core.thread;
|
||||||
|
|
||||||
|
class DMDTraceLogParser {
|
||||||
|
string filename;
|
||||||
|
string content;
|
||||||
|
string[] lines;
|
||||||
|
bool _cancelRequested;
|
||||||
|
|
||||||
|
FunctionNode[string] nodes;
|
||||||
|
//FunctionEdge[string] caller_graph;
|
||||||
|
//FunctionEdge[string] called_graph;
|
||||||
|
ulong ticks_per_second;
|
||||||
|
|
||||||
|
this(string fname) {
|
||||||
|
filename = fname;
|
||||||
|
}
|
||||||
|
void requestCancel() {
|
||||||
|
_cancelRequested = true;
|
||||||
|
}
|
||||||
|
private void splitLines(void[] buffer) {
|
||||||
|
lines.assumeSafeAppend;
|
||||||
|
content = cast(string)buffer;
|
||||||
|
int lineStart = 0;
|
||||||
|
for (int i = 0; i < content.length; i++) {
|
||||||
|
char ch = content.ptr[i];
|
||||||
|
if (ch == '\r' || ch == '\n') {
|
||||||
|
if (lineStart < i) {
|
||||||
|
lines ~= content[lineStart .. i];
|
||||||
|
}
|
||||||
|
lineStart = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// append last line if any
|
||||||
|
if (lineStart < content.length)
|
||||||
|
lines ~= content[lineStart .. $];
|
||||||
|
}
|
||||||
|
bool load() {
|
||||||
|
void[] file;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
file = read(filename);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.e("Cannot open trace file ", filename);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (file.length == 0) {
|
||||||
|
Log.e("Trace log ", filename, " is empty");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Log.d("Opened file ", filename, " ", file.length, " bytes");
|
||||||
|
splitLines(file);
|
||||||
|
Log.d("Lines: ", lines.length);
|
||||||
|
return lines.length > 0;
|
||||||
|
}
|
||||||
|
bool parse() {
|
||||||
|
bool caller = true;
|
||||||
|
string function_name;
|
||||||
|
FunctionEdge[string] caller_graph;
|
||||||
|
FunctionEdge[string] called_graph;
|
||||||
|
ulong function_times;
|
||||||
|
ulong function_and_descendant;
|
||||||
|
ulong function_only;
|
||||||
|
foreach(i, line; lines) {
|
||||||
|
if (_cancelRequested)
|
||||||
|
return false;
|
||||||
|
if (line.length == 0) {
|
||||||
|
continue; // Ignore blank lines
|
||||||
|
} else if (line[0] == '=') { // Seperator between call graph and summary data
|
||||||
|
auto number = indexOfAny(line, "1234567890");
|
||||||
|
if (number < 0)
|
||||||
|
{
|
||||||
|
Log.e("Corrupt trace.log (can't compute ticks per second), please re-profile and try again");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto space = indexOf(line[number .. $], ' ') + number;
|
||||||
|
ticks_per_second = to!ulong(line[number .. space]);
|
||||||
|
break;
|
||||||
|
} else if (line[0] == '-') { //Seperator between each function call graph
|
||||||
|
caller = true;
|
||||||
|
if (function_name.length != 0)
|
||||||
|
nodes[text(function_name)] = new FunctionNode(function_name,
|
||||||
|
function_times, function_and_descendant, function_only,
|
||||||
|
caller_graph, called_graph);
|
||||||
|
caller_graph = null;
|
||||||
|
called_graph = null;
|
||||||
|
} else if (line[0] == '\t')
|
||||||
|
{
|
||||||
|
// A function either calling or called by this function
|
||||||
|
/*
|
||||||
|
We can't assume a name starts with an '_' because it might be an extern "C" which hasn't been mangled.
|
||||||
|
We also can't assume the character encodin of what ever language that is so we look for the last tab
|
||||||
|
and asusme the identifier starts on the next character.
|
||||||
|
*/
|
||||||
|
// auto pos = indexOfAny(line, "_");
|
||||||
|
auto pos = lastIndexOf(line, '\t') + 1;
|
||||||
|
auto start_pos = indexOfAny(line, "1234567890");
|
||||||
|
if (start_pos < 0 || pos < 0 || pos < start_pos)
|
||||||
|
{
|
||||||
|
Log.e("Corrupt trace.log (call count is non-numeric), please re-profile and try again");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
immutable times = to!ulong(line[start_pos .. pos - 1]);
|
||||||
|
auto name = line[pos .. $];
|
||||||
|
if (caller)
|
||||||
|
{
|
||||||
|
caller_graph[text(name)] = new FunctionEdge(name, times);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
called_graph[text(name)] = new FunctionEdge(name, times);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
In the case of a call to a non-D function, the identifier might not start with an '_' (e.g. extern "C"). But, we can't know
|
||||||
|
how those identifiers are stored so we can't assume an encoding - and hence we must assume that what ever we have is correct.
|
||||||
|
*/
|
||||||
|
// else if (indexOf("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", line[0]) >= 0) //The name of the function were're currently examining the call graph for (seperates callers from called)
|
||||||
|
else //The name of the function were're currently examining the call graph for (seperates callers from called)
|
||||||
|
{
|
||||||
|
auto start_tab = indexOf(line, '\t');
|
||||||
|
auto middle_tab = indexOf(line[start_tab + 1 .. $], '\t') + start_tab + 1;
|
||||||
|
auto last_tab = indexOf(line[middle_tab + 1 .. $], '\t') + middle_tab + 1;
|
||||||
|
function_name = line[0 .. start_tab];
|
||||||
|
//if (function_name.length > 1024)
|
||||||
|
// Log.d("long function name: ", function_name);
|
||||||
|
function_times = to!ulong(line[start_tab + 1 .. middle_tab]);
|
||||||
|
function_and_descendant = to!ulong(line[middle_tab + 1 .. last_tab]);
|
||||||
|
function_only = to!ulong(line[last_tab + 1 .. $]);
|
||||||
|
caller = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private __gshared static char[] demangleBuffer;
|
||||||
|
|
||||||
|
private string demangle(string mangled_name) {
|
||||||
|
import core.demangle : demangle;
|
||||||
|
//const (char) [] demangled_name;
|
||||||
|
string demangled_name; // = dlangide.tools.d.demangle.demangle(mangled_name);
|
||||||
|
//if (demangled_name[0] == '_') { // in the unlikely event that we fail to demangle, fall back to the phobos demangler
|
||||||
|
try {
|
||||||
|
if (demangleBuffer.length < mangled_name.length + 16384)
|
||||||
|
demangleBuffer.length = mangled_name.length * 2 + 16384;
|
||||||
|
demangled_name = cast(string)core.demangle.demangle(mangled_name, demangleBuffer[]);
|
||||||
|
} catch (Exception e) {
|
||||||
|
demangled_name = mangled_name;
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
if (demangled_name.length > 1024)
|
||||||
|
return demangled_name[0..1024] ~ "...";
|
||||||
|
return demangled_name.dup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
CLASS FUNCTION_EDGE
|
||||||
|
-------------------
|
||||||
|
There's one of these objects for each function in program being profiled.
|
||||||
|
*/
|
||||||
|
class FunctionEdge
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
string name; // the demangled name of the function
|
||||||
|
string mangled_name; // the mangled name
|
||||||
|
ulong calls; // number of times the function is called
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
THIS()
|
||||||
|
------
|
||||||
|
Constructor
|
||||||
|
*/
|
||||||
|
this(string mangled_name, ulong calls)
|
||||||
|
{
|
||||||
|
this.mangled_name = mangled_name;
|
||||||
|
|
||||||
|
this.name = demangle(mangled_name);
|
||||||
|
|
||||||
|
this.calls = calls;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
CLASS FUNCTION_NODE
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
*/
|
||||||
|
class FunctionNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FunctionEdge[string] called_by;
|
||||||
|
FunctionEdge[string] calls_to;
|
||||||
|
string name;
|
||||||
|
string mangled_name;
|
||||||
|
ulong number_of_calls;
|
||||||
|
ulong function_and_descendant_time; // in cycles
|
||||||
|
ulong function_time; // in cycles
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*
|
||||||
|
PERCENT()
|
||||||
|
---------
|
||||||
|
Compute top/bottom to 2 decimal places
|
||||||
|
*/
|
||||||
|
double percent(double top, double bottom)
|
||||||
|
{
|
||||||
|
return cast(double)(cast(size_t)((top / bottom * 100_00.0))) / 100.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TO_US()
|
||||||
|
-------
|
||||||
|
Convert from ticks to micro-seconds
|
||||||
|
*/
|
||||||
|
size_t to_us(double ticks, double ticks_per_second)
|
||||||
|
{
|
||||||
|
return cast(size_t)(ticks / ticks_per_second * 1000 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
THIS()
|
||||||
|
------
|
||||||
|
*/
|
||||||
|
this(string mangled_name, ulong calls, ulong function_and_descendant_time,
|
||||||
|
ulong function_time, FunctionEdge[string] called_by, FunctionEdge[string] calls_to)
|
||||||
|
{
|
||||||
|
this.mangled_name = mangled_name;
|
||||||
|
|
||||||
|
this.name = demangle(mangled_name);
|
||||||
|
|
||||||
|
this.number_of_calls = calls;
|
||||||
|
this.function_and_descendant_time = function_and_descendant_time;
|
||||||
|
this.function_time = function_time;
|
||||||
|
this.called_by = called_by;
|
||||||
|
this.calls_to = calls_to;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DMDTraceLogParser parseDMDTraceLog(string filename) {
|
||||||
|
scope(exit) demangleBuffer = null;
|
||||||
|
DMDTraceLogParser parser = new DMDTraceLogParser(filename);
|
||||||
|
if (!parser.load())
|
||||||
|
return null;
|
||||||
|
if (!parser.parse())
|
||||||
|
return null;
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DMDProfilerLogParserThread : Thread {
|
||||||
|
private DMDTraceLogParser _parser;
|
||||||
|
private bool _finished;
|
||||||
|
private bool _success;
|
||||||
|
|
||||||
|
this(string filename) {
|
||||||
|
super(&run);
|
||||||
|
_parser = new DMDTraceLogParser(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
@property bool finished() { return _finished; }
|
||||||
|
@property DMDTraceLogParser parser() { return _success ? _parser : null; }
|
||||||
|
|
||||||
|
void requestCancel() {
|
||||||
|
_parser.requestCancel();
|
||||||
|
}
|
||||||
|
void run() {
|
||||||
|
scope(exit) demangleBuffer = null;
|
||||||
|
if (!_parser.load()) {
|
||||||
|
_finished = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!_parser.parse()) {
|
||||||
|
_finished = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_success = true;
|
||||||
|
_finished = true;
|
||||||
|
// Done
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
alias DMDProfilerLogParserListener = void delegate(DMDTraceLogParser parser);
|
||||||
|
|
||||||
|
class DMDProfilerLogParserOperation : BackgroundOperationWatcher {
|
||||||
|
|
||||||
|
string _filename;
|
||||||
|
DMDProfilerLogParserListener _listener;
|
||||||
|
dstring _description;
|
||||||
|
DMDProfilerLogParserThread _thread;
|
||||||
|
DMDTraceLogParser _result;
|
||||||
|
|
||||||
|
this(AppFrame frame, string filename, OutputPanel log, DMDProfilerLogParserListener listener) {
|
||||||
|
super(frame);
|
||||||
|
_filename = filename;
|
||||||
|
_listener = listener;
|
||||||
|
_description = "Parsing DMD trace log file"d;
|
||||||
|
_thread = new DMDProfilerLogParserThread(filename);
|
||||||
|
_thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// returns description of background operation to show in status line
|
||||||
|
override @property dstring description() { return _description; }
|
||||||
|
/// returns icon of background operation to show in status line
|
||||||
|
override @property string icon() { return "folder"; }
|
||||||
|
/// update background operation status
|
||||||
|
override void update() {
|
||||||
|
if (_finished) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_thread.finished) {
|
||||||
|
_thread.join();
|
||||||
|
_result = _thread.parser;
|
||||||
|
//_extprocess.kill();
|
||||||
|
//_extprocess.wait();
|
||||||
|
_finished = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_cancelRequested) {
|
||||||
|
_thread.requestCancel();
|
||||||
|
_thread.join();
|
||||||
|
_result = _thread.parser;
|
||||||
|
//_extprocess.kill();
|
||||||
|
//_extprocess.wait();
|
||||||
|
_finished = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.update();
|
||||||
|
}
|
||||||
|
override void removing() {
|
||||||
|
super.removing();
|
||||||
|
//if (_exitCode != int.min && _listener)
|
||||||
|
_listener(_result);
|
||||||
|
}
|
||||||
|
}
|
|
@ -80,6 +80,8 @@ enum IDEActions : int {
|
||||||
ViewToggleTabPositionMarks,
|
ViewToggleTabPositionMarks,
|
||||||
ViewToggleToolbar,
|
ViewToggleToolbar,
|
||||||
ViewToggleStatusbar,
|
ViewToggleStatusbar,
|
||||||
|
|
||||||
|
ToolsOpenDMDTraceLog,
|
||||||
}
|
}
|
||||||
|
|
||||||
__gshared static this() {
|
__gshared static this() {
|
||||||
|
@ -175,6 +177,8 @@ const Action ACTION_GET_PAREN_COMPLETION = (new Action(IDEActions.GetParenComple
|
||||||
const Action ACTION_GO_TO_LINE = (new Action(IDEActions.GotoLine, "GO_TO_LINE"c, ""c, KeyCode.KEY_L, KeyFlag.Control|KeyFlag.Option)).disableByDefault();;
|
const Action ACTION_GO_TO_LINE = (new Action(IDEActions.GotoLine, "GO_TO_LINE"c, ""c, KeyCode.KEY_L, KeyFlag.Control|KeyFlag.Option)).disableByDefault();;
|
||||||
|
|
||||||
const Action ACTION_FIND_TEXT = (new Action(IDEActions.FindInFiles, "FIND_IN_FILES"c, "edit-find"c, KeyCode.KEY_F, KeyFlag.Control | KeyFlag.Shift)).disableByDefault();
|
const Action ACTION_FIND_TEXT = (new Action(IDEActions.FindInFiles, "FIND_IN_FILES"c, "edit-find"c, KeyCode.KEY_F, KeyFlag.Control | KeyFlag.Shift)).disableByDefault();
|
||||||
|
const Action ACTION_TOOLS_OPEN_DMD_TRACE_LOG = (new Action(IDEActions.ToolsOpenDMDTraceLog, "OPEN_DMD_TRACE_LOG"c));
|
||||||
|
|
||||||
|
|
||||||
const Action[] STD_IDE_ACTIONS = [
|
const Action[] STD_IDE_ACTIONS = [
|
||||||
ACTION_EDIT_COPY, ACTION_EDIT_PASTE, ACTION_EDIT_CUT,
|
ACTION_EDIT_COPY, ACTION_EDIT_PASTE, ACTION_EDIT_CUT,
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
module dlangide.ui.dmdprofilerview;
|
||||||
|
|
||||||
|
import dlangui.widgets.layouts;
|
||||||
|
import dlangui.widgets.widget;
|
||||||
|
import dlangui.widgets.scroll;
|
||||||
|
import dlangui.widgets.controls;
|
||||||
|
import dlangide.ui.frame;
|
||||||
|
import dlangide.ui.commands;
|
||||||
|
import dlangui.core.i18n;
|
||||||
|
import dlangide.tools.d.dmdtrace;
|
||||||
|
|
||||||
|
class DMDProfilerView : ScrollWidget {
|
||||||
|
protected IDEFrame _frame;
|
||||||
|
protected DMDTraceLogParser _data;
|
||||||
|
this(string ID, IDEFrame frame, DMDTraceLogParser data) {
|
||||||
|
super(ID);
|
||||||
|
_frame = frame;
|
||||||
|
_data = data;
|
||||||
|
contentWidget = new TextWidget(null, "DMD profiler view"d);
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,6 +36,7 @@ import ddebug.common.execution;
|
||||||
import ddebug.common.nodebug;
|
import ddebug.common.nodebug;
|
||||||
import ddebug.common.debugger;
|
import ddebug.common.debugger;
|
||||||
import ddebug.gdb.gdbinterface;
|
import ddebug.gdb.gdbinterface;
|
||||||
|
import dlangide.tools.d.dmdtrace;
|
||||||
|
|
||||||
import std.conv;
|
import std.conv;
|
||||||
import std.utf;
|
import std.utf;
|
||||||
|
@ -805,6 +806,9 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
MenuItem toolsItem = new MenuItem(new Action(33, "MENU_TOOLS"c));
|
||||||
|
toolsItem.add(ACTION_TOOLS_OPEN_DMD_TRACE_LOG);
|
||||||
|
|
||||||
MenuItem windowItem = new MenuItem(new Action(3, "MENU_WINDOW"c));
|
MenuItem windowItem = new MenuItem(new Action(3, "MENU_WINDOW"c));
|
||||||
//windowItem.add(new Action(30, "MENU_WINDOW_PREFERENCES"));
|
//windowItem.add(new Action(30, "MENU_WINDOW_PREFERENCES"));
|
||||||
windowItem.add(ACTION_WINDOW_CLOSE_DOCUMENT, ACTION_WINDOW_CLOSE_ALL_DOCUMENTS);
|
windowItem.add(ACTION_WINDOW_CLOSE_DOCUMENT, ACTION_WINDOW_CLOSE_ALL_DOCUMENTS);
|
||||||
|
@ -818,6 +822,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
|
||||||
mainMenuItems.add(navItem);
|
mainMenuItems.add(navItem);
|
||||||
mainMenuItems.add(buildItem);
|
mainMenuItems.add(buildItem);
|
||||||
mainMenuItems.add(debugItem);
|
mainMenuItems.add(debugItem);
|
||||||
|
mainMenuItems.add(toolsItem);
|
||||||
//mainMenuItems.add(viewItem);
|
//mainMenuItems.add(viewItem);
|
||||||
mainMenuItems.add(windowItem);
|
mainMenuItems.add(windowItem);
|
||||||
mainMenuItems.add(helpItem);
|
mainMenuItems.add(helpItem);
|
||||||
|
@ -1002,6 +1007,50 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static immutable TRACE_LOG_ID = "TRACE_LOG";
|
||||||
|
void showDMDTraceLog(DMDTraceLogParser data) {
|
||||||
|
import dlangide.ui.dmdprofilerview;
|
||||||
|
int index = _tabs.tabIndex(TRACE_LOG_ID);
|
||||||
|
if (index >= 0) {
|
||||||
|
_tabs.removeTab(TRACE_LOG_ID);
|
||||||
|
}
|
||||||
|
DMDProfilerView home = new DMDProfilerView(TRACE_LOG_ID, this, data);
|
||||||
|
_tabs.addTab(home, UIString.fromId("PROFILER_WINDOW"c), null, true);
|
||||||
|
_tabs.selectTab(TRACE_LOG_ID, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void showDMDTraceLog()
|
||||||
|
void openDMDTraceLog(string filename) {
|
||||||
|
DMDProfilerLogParserOperation op = new DMDProfilerLogParserOperation(this, filename, _logPanel,
|
||||||
|
delegate(DMDTraceLogParser parser) {
|
||||||
|
if (parser) {
|
||||||
|
Log.d("Trace log is ready");
|
||||||
|
showDMDTraceLog(parser);
|
||||||
|
} else {
|
||||||
|
Log.e("Trace log is failed");
|
||||||
|
window.showMessageBox(UIString.fromId("ERROR"c), UIString.fromId("ERROR_FAILED_TO_PARSE_FILE"c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
setBackgroundOperation(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
void openDMDTraceLog() {
|
||||||
|
UIString caption;
|
||||||
|
caption = UIString.fromId("HEADER_OPEN_DMD_PROFILER_LOG"c);
|
||||||
|
FileDialog dlg = createFileDialog(caption);
|
||||||
|
dlg.addFilter(FileFilterEntry(UIString.fromId("PROFILER_LOG_FILES"c), "*.log"));
|
||||||
|
dlg.path = _settings.getRecentPath("FILE_OPEN_PATH");
|
||||||
|
dlg.dialogResult = delegate(Dialog d, const Action result) {
|
||||||
|
if (result.id == ACTION_OPEN.id) {
|
||||||
|
string filename = result.stringParam;
|
||||||
|
_settings.setRecentPath(dlg.path, "FILE_OPEN_PATH");
|
||||||
|
openDMDTraceLog(filename);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dlg.show();
|
||||||
|
}
|
||||||
|
|
||||||
FileDialog createFileDialog(UIString caption, int fileDialogFlags = DialogFlag.Modal | DialogFlag.Resizable | FileDialogFlag.FileMustExist) {
|
FileDialog createFileDialog(UIString caption, int fileDialogFlags = DialogFlag.Modal | DialogFlag.Resizable | FileDialogFlag.FileMustExist) {
|
||||||
FileDialog dlg = new FileDialog(caption, window, null, fileDialogFlags);
|
FileDialog dlg = new FileDialog(caption, window, null, fileDialogFlags);
|
||||||
dlg.filetypeIcons[".d"] = "text-d";
|
dlg.filetypeIcons[".d"] = "text-d";
|
||||||
|
@ -1026,6 +1075,9 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
|
||||||
case IDEActions.HelpDonate:
|
case IDEActions.HelpDonate:
|
||||||
Platform.instance.openURL(HELP_DONATION_URL);
|
Platform.instance.openURL(HELP_DONATION_URL);
|
||||||
return true;
|
return true;
|
||||||
|
case IDEActions.ToolsOpenDMDTraceLog:
|
||||||
|
openDMDTraceLog();
|
||||||
|
return true;
|
||||||
case IDEActions.HelpAbout:
|
case IDEActions.HelpAbout:
|
||||||
//debug {
|
//debug {
|
||||||
// testDCDFailAfterThreadCreation();
|
// testDCDFailAfterThreadCreation();
|
||||||
|
|
|
@ -19,10 +19,13 @@ DLANG_IDE_DONATE=Support DlangIDE
|
||||||
DLANG_IDE_DONATE_PAYPAL=Donate via PayPal
|
DLANG_IDE_DONATE_PAYPAL=Donate via PayPal
|
||||||
EXIT=Exit
|
EXIT=Exit
|
||||||
|
|
||||||
|
PROFILER_WINDOW=Profiler
|
||||||
|
|
||||||
ALL_FILES=All files
|
ALL_FILES=All files
|
||||||
SOURCE_FILES=Source files
|
SOURCE_FILES=Source files
|
||||||
WORKSPACE_AND_PROJECT_FILES=Workspace and project files
|
WORKSPACE_AND_PROJECT_FILES=Workspace and project files
|
||||||
IDE_FILES=DlangIDE files
|
IDE_FILES=DlangIDE files
|
||||||
|
PROFILER_LOG_FILES=DMD Profiler Logs
|
||||||
|
|
||||||
EDITOR_CONTENT=Editors content
|
EDITOR_CONTENT=Editors content
|
||||||
LOCATION=Location
|
LOCATION=Location
|
||||||
|
@ -127,6 +130,9 @@ MENU_VIEW_THEME=&Theme
|
||||||
MENU_VIEW_THEME_DEFAULT=&Default
|
MENU_VIEW_THEME_DEFAULT=&Default
|
||||||
MENU_VIEW_THEME_CUSTOM1=&Custom 1
|
MENU_VIEW_THEME_CUSTOM1=&Custom 1
|
||||||
|
|
||||||
|
MENU_TOOLS=Tools
|
||||||
|
OPEN_DMD_TRACE_LOG=Open DMD profiler log
|
||||||
|
|
||||||
TAB_LONG_LIST=Long list
|
TAB_LONG_LIST=Long list
|
||||||
TAB_BUTTONS=Buttons
|
TAB_BUTTONS=Buttons
|
||||||
TAB_ANIMATION=Animation
|
TAB_ANIMATION=Animation
|
||||||
|
@ -145,6 +151,7 @@ MENU_PROJECT_FOLDER_COLLAPSE_ALL=Collapse all
|
||||||
HEADER_SETTINGS=DlangIDE settings
|
HEADER_SETTINGS=DlangIDE settings
|
||||||
HEADER_OPEN_WORKSPACE_OR_PROJECT=Open Workspace or Project
|
HEADER_OPEN_WORKSPACE_OR_PROJECT=Open Workspace or Project
|
||||||
HEADER_OPEN_TEXT_FILE=Open Text File
|
HEADER_OPEN_TEXT_FILE=Open Text File
|
||||||
|
HEADER_OPEN_DMD_PROFILER_LOG=Open DMD Profiler Log File
|
||||||
HEADER_CLOSE_FILE=Close file
|
HEADER_CLOSE_FILE=Close file
|
||||||
HEADER_CLOSE_TAB=Close tab
|
HEADER_CLOSE_TAB=Close tab
|
||||||
HEADER_PROJECT_SETTINGS=project settings
|
HEADER_PROJECT_SETTINGS=project settings
|
||||||
|
@ -235,6 +242,7 @@ ERROR_OPEN_WORKSPACE=Cannot open workspace
|
||||||
ERROR_OPENING_FILE=Failed to open file
|
ERROR_OPENING_FILE=Failed to open file
|
||||||
ERROR_OPENING_PROJECT=Error occured while opening project
|
ERROR_OPENING_PROJECT=Error occured while opening project
|
||||||
ERROR_OPENING_WORKSPACE=Error occured while opening workspace
|
ERROR_OPENING_WORKSPACE=Error occured while opening workspace
|
||||||
|
ERROR_FAILED_TO_PARSE_TRACE_LOG_FILE=Failed to parse trace log file
|
||||||
|
|
||||||
MSG_FILE_CONTENT_CHANGED=Content of this file has been changed.
|
MSG_FILE_CONTENT_CHANGED=Content of this file has been changed.
|
||||||
MSG_TAB_CONTENT_CHANGED=Content of tab has been changed
|
MSG_TAB_CONTENT_CHANGED=Content of tab has been changed
|
||||||
|
|
|
@ -19,10 +19,13 @@ DLANG_IDE_DONATE=Поддержать DlangIDE
|
||||||
DLANG_IDE_DONATE_PAYPAL=PayPal
|
DLANG_IDE_DONATE_PAYPAL=PayPal
|
||||||
EXIT=Выход
|
EXIT=Выход
|
||||||
|
|
||||||
|
PROFILER_WINDOW=Профилировщик
|
||||||
|
|
||||||
ALL_FILES=Все файлы
|
ALL_FILES=Все файлы
|
||||||
SOURCE_FILES=Исходники
|
SOURCE_FILES=Исходники
|
||||||
WORKSPACE_AND_PROJECT_FILES=Файлы проектов и раб. прост.
|
WORKSPACE_AND_PROJECT_FILES=Файлы проектов и раб. прост.
|
||||||
IDE_FILES=Файлы DlangIDE
|
IDE_FILES=Файлы DlangIDE
|
||||||
|
PROFILER_LOG_FILES=Файды DMD Profiler
|
||||||
|
|
||||||
EDITOR_CONTENT=Содержимое редактора
|
EDITOR_CONTENT=Содержимое редактора
|
||||||
LOCATION=Место
|
LOCATION=Место
|
||||||
|
@ -126,6 +129,9 @@ MENU_VIEW_THEME=&Тема
|
||||||
MENU_VIEW_THEME_DEFAULT=Стандартная
|
MENU_VIEW_THEME_DEFAULT=Стандартная
|
||||||
MENU_VIEW_THEME_CUSTOM1=Пример 1
|
MENU_VIEW_THEME_CUSTOM1=Пример 1
|
||||||
|
|
||||||
|
MENU_TOOLS=Инструменты
|
||||||
|
OPEN_DMD_TRACE_LOG=Открыть лог DMD profiler
|
||||||
|
|
||||||
TAB_LONG_LIST=Длинный список
|
TAB_LONG_LIST=Длинный список
|
||||||
TAB_BUTTONS=Кнопки
|
TAB_BUTTONS=Кнопки
|
||||||
TAB_ANIMATION=Анимация
|
TAB_ANIMATION=Анимация
|
||||||
|
@ -144,6 +150,7 @@ MENU_PROJECT_FOLDER_COLLAPSE_ALL=Свернуть все
|
||||||
HEADER_SETTINGS=DlangIDE настройки
|
HEADER_SETTINGS=DlangIDE настройки
|
||||||
HEADER_OPEN_WORKSPACE_OR_PROJECT=Открыть рабочее пространство или проект
|
HEADER_OPEN_WORKSPACE_OR_PROJECT=Открыть рабочее пространство или проект
|
||||||
HEADER_OPEN_TEXT_FILE=Открыть текстовый файл
|
HEADER_OPEN_TEXT_FILE=Открыть текстовый файл
|
||||||
|
HEADER_OPEN_DMD_PROFILER_LOG=Открыть файл DMD Profiler Log
|
||||||
HEADER_CLOSE_FILE=Закрыть файл
|
HEADER_CLOSE_FILE=Закрыть файл
|
||||||
HEADER_CLOSE_TAB=Закрыть вкладку
|
HEADER_CLOSE_TAB=Закрыть вкладку
|
||||||
HEADER_PROJECT_SETTINGS=настройки проекта
|
HEADER_PROJECT_SETTINGS=настройки проекта
|
||||||
|
@ -233,6 +240,7 @@ ERROR_OPEN_WORKSPACE=Невозможно открыть рабочее прос
|
||||||
ERROR_OPENING_FILE=Ошибка открытия файла
|
ERROR_OPENING_FILE=Ошибка открытия файла
|
||||||
ERROR_OPENING_PROJECT=Ошибка в ходе открытия проекта
|
ERROR_OPENING_PROJECT=Ошибка в ходе открытия проекта
|
||||||
ERROR_OPENING_WORKSPACE=Ошибка в ходе открытия рабочего пространства
|
ERROR_OPENING_WORKSPACE=Ошибка в ходе открытия рабочего пространства
|
||||||
|
ERROR_FAILED_TO_PARSE_TRACE_LOG_FILE=Не удалось обработать файл DMD trace log
|
||||||
|
|
||||||
MSG_FILE_CONTENT_CHANGED=Содержимое этого файла изменено.
|
MSG_FILE_CONTENT_CHANGED=Содержимое этого файла изменено.
|
||||||
MSG_TAB_CONTENT_CHANGED=Содержимое вкладки изменено
|
MSG_TAB_CONTENT_CHANGED=Содержимое вкладки изменено
|
||||||
|
|
Loading…
Reference in New Issue