added example for running an internal compiler

This commit is contained in:
mattias 2022-12-03 01:51:30 +01:00
parent 10ba6d4322
commit d27a77b2f2
4 changed files with 199 additions and 0 deletions

1
examples/internalcompiler/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
lib

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<Package Version="5">
<Name Value="DemoInternalCompiler"/>
<Type Value="DesignTime"/>
<Author Value="Mattias Gaertner"/>
<CompilerOptions>
<Version Value="11"/>
<SearchPaths>
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)/"/>
</SearchPaths>
</CompilerOptions>
<Description Value="Demo how to run a thread producing output shown in the IDE Messages window."/>
<License Value="modified LGPL-2"/>
<Version Major="1"/>
<Files>
<Item>
<Filename Value="demointernalcompilerreg.pas"/>
<HasRegisterProc Value="True"/>
<UnitName Value="DemoInternalCompilerReg"/>
</Item>
</Files>
<RequiredPkgs>
<Item>
<PackageName Value="IDEIntf"/>
</Item>
<Item>
<PackageName Value="FCL"/>
</Item>
</RequiredPkgs>
<UsageOptions>
<UnitPath Value="$(PkgOutDir)"/>
</UsageOptions>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
</Package>
</CONFIG>

View File

@ -0,0 +1,22 @@
{ This file was automatically created by Lazarus. Do not edit!
This source is only used to compile and install the package.
}
unit DemoInternalCompiler;
{$warn 5023 off : no warning about unused units}
interface
uses
DemoInternalCompilerReg, LazarusPackageIntf;
implementation
procedure Register;
begin
RegisterUnit('DemoInternalCompilerReg', @DemoInternalCompilerReg.Register);
end;
initialization
RegisterPackage('DemoInternalCompiler', @Register);
end.

View File

@ -0,0 +1,137 @@
{
Demonstrating how to run a thread, that produces output shown in the IDE
Messages window.
}
unit DemoInternalCompilerReg;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, IDECommands, MenuIntf, LazIDEIntf, IDEMsgIntf,
IDEExternToolIntf, ProjectIntf;
type
{ TMyPascalCompiler }
TMyPascalCompiler = class(TThread)
protected
procedure Execute; override;
public
Filename: string;
Tool: TAbstractExternalTool;
end;
procedure Register;
implementation
procedure RunMyPascalCompiler(Sender: TObject);
var
Title: String;
View: TExtToolView;
Tool: TAbstractExternalTool;
MyThread: TMyPascalCompiler;
Proj: TLazProject;
begin
Title:='Running my internal demo compiler';
// add a view (a block of lines in the IDE's Messages window)
View:=IDEMessagesWindow.CreateView(Title);
// add a tool - the connection between the IDE and the thread
Tool:=ExternalToolList.Add(Title);
Tool.AddView(View);
// adding a parser for the compiler messages
Tool.AddParser(IDEFPCParser);
if not Tool.InitParsers then exit;
// create the thread
MyThread:=TMyPascalCompiler.Create(true);
MyThread.Tool:=Tool;
Tool.Reference(MyThread,'RunMyPascalCompiler');
Tool.UserThread:=MyThread;
// set WorkerDirectory needed by the parser
Proj:=LazarusIDE.ActiveProject;
if (Proj<>nil) and (Proj.MainFile<>nil) then
MyThread.Filename:=Proj.MainFile.Filename
else
MyThread.Filename:='test123.pas';
Tool.WorkerDirectory:=ExtractFilePath(MyThread.Filename);
if Tool.WorkerDirectory='' then
Tool.WorkerDirectory:=GetCurrentDir;
// start thread
MyThread.Start;
end;
procedure Register;
var
CmdCatTools: TIDECommandCategory;
RunMyCompilerCmd: TIDECommand;
MenuCaption, MenuName: String;
begin
MenuName:='RunInternalDemoCompiler';
MenuCaption:='Run internal demo compiler';
// create a command
CmdCatTools:=IDECommandList.FindCategoryByName(CommandCategoryToolMenuName);
if CmdCatTools=nil then
raise Exception.Create('DemoInternalCompiler: command category '+CommandCategoryToolMenuName+' not found');
RunMyCompilerCmd:=RegisterIDECommand(CmdCatTools, MenuName, MenuCaption,
CleanIDEShortCut,CleanIDEShortCut,nil,@RunMyPascalCompiler);
// add a menu item
RegisterIDEMenuCommand(itmSecondaryTools,MenuName,MenuCaption,
nil,nil,RunMyCompilerCmd);
end;
{ TMyPascalCompiler }
procedure TMyPascalCompiler.Execute;
var
i, j: Integer;
sl: TStringList;
Tick: QWord;
begin
Tool.UserThreadRunning;
try
if Tool.Stage<>etsRunning then
exit;
j:=1;
sl:=TStringList.Create;
try
for i:=1 to 30 do begin
// emulate some load
Tick:=GetTickCount64;
while GetTickCount64-Tick<100 do ;
if Tool.Stage<>etsRunning then
exit;
sl.Add(Filename+'('+IntToStr(j)+',1) Hint: This could be from an internal compiler');
inc(j);
// feed output
Tool.AddOutputLines(sl);
sl.Clear;
end;
finally
sl.Free;
end;
Tool.ExitCode:=0;
Tool.ErrorMessage:='';
finally
if Tool.Stage<etsStopped then
Tool.UserThreadStopped;
Tool.UserThread:=nil;
Tool.Release(Self);
Tool:=nil;
end;
end;
end.