fpc/utils/debugsvr/dbugintf.pp
marco ded3e530e3 * modernized to 2.0.x unix rtl
git-svn-id: trunk@6709 -
2007-03-03 23:14:29 +00:00

283 lines
5.6 KiB
ObjectPascal

{
This file is part of the Free Pascal run time library.
Copyright (c) 2003 by the Free Pascal development team
User interface for debug server.
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
{$ifdef fpc}
{$mode objfpc}
{$h+}
{$endif}
unit dbugintf;
interface
uses
{$ifdef fpc}
baseunix,
{$else}
Libc,
{$endif}
msgintf,
classes,
ssockets;
Type
TDebugLevel = (dlInformation,dlWarning,dlError);
{$ifdef fpc}
pid_t = longint;
{$endif}
procedure SendBoolean(const Identifier: string; const Value: Boolean);
procedure SendDateTime(const Identifier: string; const Value: TDateTime);
procedure SendDebugEx(const Msg: string; MType: TDebugLevel);
procedure SendDebug(const Msg: string);
procedure SendInteger(const Identifier: string; const Value: Integer);
procedure SendMethodEnter(const MethodName: string);
procedure SendMethodExit(const MethodName: string);
procedure SendSeparator;
procedure SendDebugFmt(const Msg: string; const Args: array of const);
procedure SendDebugFmtEx(const Msg: string; const Args: array of const; MType: TDebugLevel);
{ low-level routines }
procedure SendDebugMessage(Const Msg : TDebugMessage);
function CreateDebugStream : TStream;
function StartDebugServer : pid_t;
Procedure InitDebugStream;
Const
SendError : String = '';
ResourceString
SProcessID = 'Process %d: %s';
SEntering = '> Entering ';
SExiting = '< Exiting ';
SSeparator = '>-=-=-=-=-=-=-=-=-=-=-=-=-=-=-<';
implementation
Uses SysUtils,process;
// UnixProcessUtils;
Const
DmtInformation = lctInformation;
DmtWarning = lctWarning;
DmtError = lctError;
ErrorLevel : Array[TDebugLevel] of integer
= (dmtInformation,dmtWarning,dmtError);
Const
DebugStream : TStream = nil;
Procedure WriteMessage(S : TStream; Const Msg : TDebugMessage);
Var
MsgSize : Integer;
begin
S.WriteBuffer(Msg.MsgType,SizeOf(Integer));
S.WriteBuffer(Msg.MsgTimeStamp,SizeOf(TDateTime));
MsgSize:=Length(Msg.Msg);
S.WriteBuffer(MsgSize,SizeOf(Integer));
S.WriteBuffer(Msg.msg[1],MsgSize);
end;
procedure SendDebugMessage(Const Msg : TDebugMessage);
begin
try
If DebugStream=Nil then
begin
InitDebugStream;
end;
WriteMessage(debugStream,Msg);
except
On E : Exception do
SendError:=E.Message;
end;
end;
procedure SendBoolean(const Identifier: string; const Value: Boolean);
Const
Booleans : Array[Boolean] of string = ('False','True');
begin
SendDebugFmt('%s = %s',[Identifier,Booleans[value]]);
end;
procedure SendDateTime(const Identifier: string; const Value: TDateTime);
begin
SendDebugFmt('%s = %s',[Identifier,DateTimeToStr(Value)]);
end;
procedure SendDebugEx(const Msg: string; MType: TDebugLevel);
Var
Mesg : TDebugMessage;
begin
Mesg.MsgTimeStamp:=Now;
Mesg.MsgType:=ErrorLevel[MTYpe];
Mesg.Msg:=Msg;
SendDebugMessage(Mesg);
end;
procedure SendDebug(const Msg: string);
Var
Mesg : TDebugMessage;
begin
Mesg.MsgTimeStamp:=Now;
Mesg.MsgType:=dmtInformation;
Mesg.Msg:=Msg;
SendDebugMessage(Mesg);
end;
procedure SendInteger(const Identifier: string; const Value: Integer);
begin
SendDebugFmt('%s = %d',[identifier,Value]);
end;
procedure SendMethodEnter(const MethodName: string);
begin
SendDebug(SEntering+MethodName);
end;
procedure SendMethodExit(const MethodName: string);
begin
SendDebug(SExiting+MethodName);
end;
procedure SendSeparator;
begin
SendDebug(SSeparator);
end;
procedure SendDebugFmt(const Msg: string; const Args: array of const);
Var
Mesg : TDebugMessage;
begin
Mesg.MsgTimeStamp:=Now;
Mesg.MsgType:=dmtInformation;
Mesg.Msg:=Format(Msg,Args);
SendDebugMessage(Mesg);
end;
procedure SendDebugFmtEx(const Msg: string; const Args: array of const; MType: TDebugLevel);
Var
Mesg : TDebugMessage;
begin
Mesg.MsgTimeStamp:=Now;
Mesg.MsgType:=ErrorLevel[mType];
Mesg.Msg:=Format(Msg,Args);
SendDebugMessage(Mesg);
end;
function StartDebugServer : pid_t;
begin
With TProcess.Create(Nil) do
Try
CommandLine:='debugserver';
Execute;
Finally
Free;
end;
end;
function CreateUnixDebugStream(SocketFile : String) : TStream;
{$ifdef fpc}
Var
tv,tr : timespec;
{$endif}
begin
If Not FileExists(DebugSocket) then
begin
StartDebugServer;
{$ifndef fpc}
sleep(1000);
{$else}
tv.tv_sec:=1;
tv.tv_nsec:=0;
fpnanosleep(@tv,@tr);
{$endif}
end;
{$ifdef fpc}
Result:=TUnixSocket.Create(SocketFile);
{$else}
Result:=TUnixSocket.CreateFromFile(SocketFile);
{$endif}
end;
Function CreateInetDebugStream (HostName : String; Port : Word) : TStream;
begin
Result:=TInetSocket.Create(HostName,Port);
end;
function CreateDebugStream : TStream;
Var
Msg : TDebugMessage;
begin
Case DebugConnection of
dcUnix : Result:=CreateUnixDebugStream(DebugSocket);
dcInet : Result:=CreateInetDebugStream(DebugHostName,DebugPort);
end;
Msg.MsgType:=lctIdentify;
Msg.MsgTimeStamp:=Now;
Msg.Msg:=Format(SProcessID,[fpgetPID,ExtractFileName(Paramstr(0))]);
WriteMessage(REsult,Msg);
end;
procedure FreeDebugStream;
Var i : Integer;
begin
If (DebugStream<>Nil) then
try
i:=-1;
DebugStream.WriteBuffer(I,SizeOf(I));
DebugStream.Free;
except
end;
end;
Procedure InitDebugStream;
begin
debugstream:=CreateDebugStream;
end;
Initialization
Finalization
FreeDebugStream;
end.